Switch for RFC-compliant version encoding in DTLS. From HEAD with a twist:
authorAndy Polyakov <appro@openssl.org>
Sun, 30 Sep 2007 18:55:59 +0000 (18:55 +0000)
committerAndy Polyakov <appro@openssl.org>
Sun, 30 Sep 2007 18:55:59 +0000 (18:55 +0000)
server accepts even non-compliant encoding in order to enable interop with
pre-0.9.8f clients.

ssl/d1_clnt.c
ssl/d1_pkt.c
ssl/d1_srvr.c
ssl/dtls1.h
ssl/s3_srvr.c

index e8b60a45d225a6a215d7fe99487866a3ebac7b38..6efb248dc892a1624acb6f1cd4c323847db7fdcc 100644 (file)
@@ -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);
index 8270419a8dceac6b69db4cf54733305d885c29b8..24ef9ec3d2b27645303e36cdf6c8eefd0df0e806 100644 (file)
@@ -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; 
index 91cd73baf42ae7dc3b9123c6baaacbd67119e3c1..77431bbe18ad8c898c1bc04becdd984934a7c0a7 100644 (file)
@@ -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);
index b377cc5f6b2d29d8c92c57344229842904d48c53..b02c48e7e10478189df3622478fd23dd89c2f28b 100644 (file)
@@ -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
 
index 8332c65be809465e36edb1f5ef0e92c48185c186..6dba5c1977147ab9004667dd67ca935c65bd9dcf 100644 (file)
@@ -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)