From: Andy Polyakov Date: Sun, 30 Sep 2007 18:55:59 +0000 (+0000) Subject: Switch for RFC-compliant version encoding in DTLS. From HEAD with a twist: X-Git-Tag: OpenSSL_0_9_8f~13 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=c4b0d7879e01ac80db21501d69718c1ff62bbd77;p=oweals%2Fopenssl.git Switch for RFC-compliant version encoding in DTLS. From HEAD with a twist: server accepts even non-compliant encoding in order to enable interop with pre-0.9.8f clients. --- diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c index e8b60a45d2..6efb248dc8 100644 --- a/ssl/d1_clnt.c +++ b/ssl/d1_clnt.c @@ -732,7 +732,7 @@ int dtls1_send_client_key_exchange(SSL *s) s->session->master_key_length=sizeof tmp_buf; q=p; - /* Fix buf for TLS and beyond */ + /* Fix buf for TLS and [incidentally] DTLS */ if (s->version > SSL3_VERSION) p+=2; n=RSA_public_encrypt(sizeof tmp_buf, @@ -747,7 +747,7 @@ int dtls1_send_client_key_exchange(SSL *s) goto err; } - /* Fix buf for TLS and beyond */ + /* Fix buf for TLS and [incidentally] DTLS */ if (s->version > SSL3_VERSION) { s2n(n,q); diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index 8270419a8d..24ef9ec3d2 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -486,9 +486,9 @@ int dtls1_get_record(SSL *s) SSL3_RECORD *rr; SSL_SESSION *sess; unsigned char *p; - short version; + unsigned short version; DTLS1_BITMAP *bitmap; - unsigned int is_next_epoch; + unsigned int is_next_epoch; rr= &(s->s3->rrec); sess=s->session; @@ -524,7 +524,7 @@ again: ssl_minor= *(p++); version=(ssl_major<<8)|ssl_minor; - /* sequence number is 64 bits, with top 2 bytes = epoch */ + /* sequence number is 64 bits, with top 2 bytes = epoch */ n2s(p,rr->epoch); memcpy(&(s->s3->read_sequence[2]), p, 6); @@ -535,7 +535,7 @@ again: /* Lets check version */ if (!s->first_packet) { - if (version != s->version) + if (version != s->version && version != DTLS1_BAD_VER) { SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); /* Send back error using their @@ -546,7 +546,8 @@ again: } } - if ((version & 0xff00) != (DTLS1_VERSION & 0xff00)) + if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && + (version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); goto err; @@ -1341,8 +1342,12 @@ int do_dtls1_write(SSL *s, int type, const unsigned char *buf, unsigned int len, *(p++)=type&0xff; wr->type=type; - *(p++)=(s->version>>8); - *(p++)=s->version&0xff; + if (s->client_version == DTLS1_BAD_VER) + *(p++) = DTLS1_BAD_VER>>8, + *(p++) = DTLS1_BAD_VER&0xff; + else + *(p++)=(s->version>>8), + *(p++)=s->version&0xff; /* field where we are to write out packet epoch, seq num and len */ pseq=p; diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c index 91cd73baf4..77431bbe18 100644 --- a/ssl/d1_srvr.c +++ b/ssl/d1_srvr.c @@ -620,19 +620,24 @@ int dtls1_send_hello_verify_request(SSL *s) buf = (unsigned char *)s->init_buf->data; msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); - *(p++) = s->version >> 8; - *(p++) = s->version & 0xFF; + if (s->client_version == DTLS1_BAD_VER) + *(p++) = DTLS1_BAD_VER>>8, + *(p++) = DTLS1_BAD_VER&0xff; + else + *(p++) = s->version >> 8, + *(p++) = s->version & 0xFF; *(p++) = (unsigned char) s->d1->cookie_len; - 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 */ + return 0; + } + /* else the cookie is assumed to have + * been initialized by the application */ memcpy(p, s->d1->cookie, s->d1->cookie_len); p += s->d1->cookie_len; @@ -672,8 +677,12 @@ int dtls1_send_server_hello(SSL *s) /* Do the message type and length last */ d=p= &(buf[DTLS1_HM_HEADER_LENGTH]); - *(p++)=s->version>>8; - *(p++)=s->version&0xff; + if (s->client_version == DTLS1_BAD_VER) + *(p++)=DTLS1_BAD_VER>>8, + *(p++)=DTLS1_BAD_VER&0xff; + else + *(p++)=s->version>>8, + *(p++)=s->version&0xff; /* Random stuff */ memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE); diff --git a/ssl/dtls1.h b/ssl/dtls1.h index b377cc5f6b..b02c48e7e1 100644 --- a/ssl/dtls1.h +++ b/ssl/dtls1.h @@ -67,9 +67,8 @@ extern "C" { #endif -#define DTLS1_VERSION 0x0100 -#define DTLS1_VERSION_MAJOR 0x01 -#define DTLS1_VERSION_MINOR 0x00 +#define DTLS1_VERSION 0xFEFF +#define DTLS1_BAD_VER 0x0100 #define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index 8332c65be8..6dba5c1977 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -714,7 +714,8 @@ int ssl3_get_client_hello(SSL *s) s->client_version=(((int)p[0])<<8)|(int)p[1]; p+=2; - if (s->client_version < s->version) + if ((s->version == DTLS1_VERSION && s->client_version > s->version) || + (s->version != DTLS1_VERSION && s->client_version < s->version)) { SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); if ((s->client_version>>8) == SSL3_VERSION_MAJOR) @@ -765,7 +766,7 @@ int ssl3_get_client_hello(SSL *s) p+=j; - if (SSL_version(s) == DTLS1_VERSION) + if (s->version == DTLS1_VERSION) { /* cookie stuff */ cookie_len = *(p++); @@ -1748,8 +1749,9 @@ int ssl3_get_client_key_exchange(SSL *s) rsa=pkey->pkey.rsa; } - /* TLS */ - if (s->version > SSL3_VERSION) + /* TLS and [incidentally] DTLS, including pre-0.9.8f */ + if (s->version > SSL3_VERSION && + s->client_version != DTLS1_BAD_VER) { n2s(p,i); if (n != i+2)