PR: 2028 Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Approved by: steve@openssl.org Fix DTLS cookie management bugs.
diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index ac09b45..00536ad 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c
@@ -238,11 +238,6 @@ s->state=SSL3_ST_SW_HELLO_REQ_A; } - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) - s->d1->send_cookie = 1; - else - s->d1->send_cookie = 0; - break; case SSL3_ST_SW_HELLO_REQ_A: @@ -273,7 +268,7 @@ dtls1_stop_timer(s); s->new_session = 2; - if (s->d1->send_cookie) + if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; else s->state = SSL3_ST_SW_SRVR_HELLO_A; @@ -287,7 +282,6 @@ dtls1_start_timer(s); ret = dtls1_send_hello_verify_request(s); if ( ret <= 0) goto end; - s->d1->send_cookie = 0; s->state=SSL3_ST_SW_FLUSH; s->s3->tmp.next_state=SSL3_ST_SR_CLNT_HELLO_A; @@ -670,15 +664,13 @@ *(p++) = s->version >> 8; *(p++) = s->version & 0xFF; - if (s->ctx->app_gen_cookie_cb != NULL && - s->ctx->app_gen_cookie_cb(s, s->d1->cookie, - &(s->d1->cookie_len)) == 0) + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) { SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,ERR_R_INTERNAL_ERROR); return 0; } - /* else the cookie is assumed to have - * been initialized by the application */ *(p++) = (unsigned char) s->d1->cookie_len; memcpy(p, s->d1->cookie, s->d1->cookie_len);
diff --git a/ssl/dtls1.h b/ssl/dtls1.h index f27362c..926af1c 100644 --- a/ssl/dtls1.h +++ b/ssl/dtls1.h
@@ -84,7 +84,7 @@ #endif /* lengths of messages */ -#define DTLS1_COOKIE_LENGTH 32 +#define DTLS1_COOKIE_LENGTH 256 #define DTLS1_RT_HEADER_LENGTH 13
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 6c1751a..35e826f 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c
@@ -816,6 +816,21 @@ goto f_err; } + /* If we require cookies and this ClientHello doesn't + * contain one, just return since we do not want to + * allocate any memory yet. So check cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) + { + unsigned int session_length, cookie_length; + + session_length = *(p + SSL3_RANDOM_SIZE); + cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + + if (cookie_len == 0) + return 1; + } + /* load the client random */ memcpy(s->s3->client_random,p,SSL3_RANDOM_SIZE); p+=SSL3_RANDOM_SIZE; @@ -855,23 +870,11 @@ p+=j; - if (s->version == DTLS1_VERSION) + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { /* cookie stuff */ cookie_len = *(p++); - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && - s->d1->send_cookie == 0) - { - /* HelloVerifyMessage has already been sent */ - if ( cookie_len != s->d1->cookie_len) - { - al = SSL_AD_HANDSHAKE_FAILURE; - SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); - goto f_err; - } - } - /* * The ClientHello may contain a cookie even if the * HelloVerify message has not been sent--make sure that it @@ -886,7 +889,7 @@ } /* verify the cookie if appropriate option is set. */ - if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { memcpy(s->d1->rcvd_cookie, p, cookie_len); @@ -911,6 +914,8 @@ SSL_R_COOKIE_MISMATCH); goto f_err; } + + ret = 2; } p += cookie_len; @@ -1185,7 +1190,7 @@ * s->tmp.new_cipher - the new cipher to use. */ - ret=1; + if (ret < 0) ret=1; if (0) { f_err:
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index bd849ac..4d67892 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -1444,6 +1444,14 @@ return 1; if (p >= limit) return -1; + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + { + i = *(p++); + p+= i; + if (p >= limit) + return -1; + } /* Skip past cipher list */ n2s(p, i); p+= i;