PR: 2121
authorDr. Stephen Henson <steve@openssl.org>
Tue, 8 Dec 2009 11:37:40 +0000 (11:37 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Tue, 8 Dec 2009 11:37:40 +0000 (11:37 +0000)
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>

Add extension support to DTLS code mainly using existing implementation for
TLS.

ssl/d1_clnt.c
ssl/d1_lib.c
ssl/d1_srvr.c
ssl/s3_clnt.c
ssl/s3_srvr.c
ssl/ssl_locl.h
ssl/t1_lib.c

index c4f820070f1725b8244a54f89b70853c2fe511ac..57c1033f55400c164f2a296b49ccdb6d5c4c5ecf 100644 (file)
@@ -286,16 +286,44 @@ int dtls1_connect(SSL *s)
 
                case SSL3_ST_CR_CERT_A:
                case SSL3_ST_CR_CERT_B:
 
                case SSL3_ST_CR_CERT_A:
                case SSL3_ST_CR_CERT_B:
+#ifndef OPENSSL_NO_TLSEXT
+                       ret=ssl3_check_finished(s);
+                       if (ret <= 0) goto end;
+                       if (ret == 2)
+                               {
+                               s->hit = 1;
+                               if (s->tlsext_ticket_expected)
+                                       s->state=SSL3_ST_CR_SESSION_TICKET_A;
+                               else
+                                       s->state=SSL3_ST_CR_FINISHED_A;
+                               s->init_num=0;
+                               break;
+                               }
+#endif
                        /* Check if it is anon DH or PSK */
                        if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                            !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                                {
                                ret=ssl3_get_server_certificate(s);
                                if (ret <= 0) goto end;
                        /* Check if it is anon DH or PSK */
                        if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                            !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK))
                                {
                                ret=ssl3_get_server_certificate(s);
                                if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+                               if (s->tlsext_status_expected)
+                                       s->state=SSL3_ST_CR_CERT_STATUS_A;
+                               else
+                                       s->state=SSL3_ST_CR_KEY_EXCH_A;
+                               }
+                       else
+                               {
+                               skip = 1;
+                               s->state=SSL3_ST_CR_KEY_EXCH_A;
+                               }
+#else
                                }
                        else
                                skip=1;
                                }
                        else
                                skip=1;
+
                        s->state=SSL3_ST_CR_KEY_EXCH_A;
                        s->state=SSL3_ST_CR_KEY_EXCH_A;
+#endif
                        s->init_num=0;
                        break;
 
                        s->init_num=0;
                        break;
 
@@ -437,11 +465,36 @@ int dtls1_connect(SSL *s)
                                }
                        else
                                {
                                }
                        else
                                {
+#ifndef OPENSSL_NO_TLSEXT
+                               /* Allow NewSessionTicket if ticket expected */
+                               if (s->tlsext_ticket_expected)
+                                       s->s3->tmp.next_state=SSL3_ST_CR_SESSION_TICKET_A;
+                               else
+#endif
+                               
                                s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
                                }
                        s->init_num=0;
                        break;
 
                                s->s3->tmp.next_state=SSL3_ST_CR_FINISHED_A;
                                }
                        s->init_num=0;
                        break;
 
+#ifndef OPENSSL_NO_TLSEXT
+               case SSL3_ST_CR_SESSION_TICKET_A:
+               case SSL3_ST_CR_SESSION_TICKET_B:
+                       ret=ssl3_get_new_session_ticket(s);
+                       if (ret <= 0) goto end;
+                       s->state=SSL3_ST_CR_FINISHED_A;
+                       s->init_num=0;
+               break;
+
+               case SSL3_ST_CR_CERT_STATUS_A:
+               case SSL3_ST_CR_CERT_STATUS_B:
+                       ret=ssl3_get_cert_status(s);
+                       if (ret <= 0) goto end;
+                       s->state=SSL3_ST_CR_KEY_EXCH_A;
+                       s->init_num=0;
+               break;
+#endif
+
                case SSL3_ST_CR_FINISHED_A:
                case SSL3_ST_CR_FINISHED_B:
                        s->d1->change_cipher_spec_ok = 1;
                case SSL3_ST_CR_FINISHED_A:
                case SSL3_ST_CR_FINISHED_B:
                        s->d1->change_cipher_spec_ok = 1;
@@ -554,8 +607,14 @@ int dtls1_client_hello(SSL *s)
        buf=(unsigned char *)s->init_buf->data;
        if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
                {
        buf=(unsigned char *)s->init_buf->data;
        if (s->state == SSL3_ST_CW_CLNT_HELLO_A)
                {
+               SSL_SESSION *sess = s->session;
                if ((s->session == NULL) ||
                        (s->session->ssl_version != s->version) ||
                if ((s->session == NULL) ||
                        (s->session->ssl_version != s->version) ||
+#ifdef OPENSSL_NO_TLSEXT
+                       !sess->session_id_length ||
+#else
+                       (!sess->session_id_length && !sess->tlsext_tick) ||
+#endif
                        (s->session->not_resumable))
                        {
                        if (!ssl_get_new_session(s,0))
                        (s->session->not_resumable))
                        {
                        if (!ssl_get_new_session(s,0))
@@ -637,7 +696,7 @@ int dtls1_client_hello(SSL *s)
                *(p++)=0; /* Add the NULL method */
 
 #ifndef OPENSSL_NO_TLSEXT
                *(p++)=0; /* Add the NULL method */
 
 #ifndef OPENSSL_NO_TLSEXT
-               if ((p = ssl_add_clienthello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+               if ((p = ssl_add_clienthello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
                        {
                        SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
                        goto err;
                        {
                        SSLerr(SSL_F_SSL3_CLIENT_HELLO,ERR_R_INTERNAL_ERROR);
                        goto err;
index 99935563d1c9f70832a1bcdd0f215cf3ffffd628..2786b61c29618a08b1bbf232e54250b74e50bf8d 100644 (file)
@@ -382,194 +382,3 @@ int dtls1_listen(SSL *s, struct sockaddr *client)
        (void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
        return 1;
        }
        (void) BIO_dgram_get_peer(SSL_get_rbio(s), client);
        return 1;
        }
-
-#ifndef OPENSSL_NO_TLSEXT
-unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
-       {
-       int extdatalen = 0;
-       unsigned char *ret = p;
-       int el;
-
-       ret+=2;
-       
-       if (ret>=limit) return NULL; /* this really never occurs, but ... */
-
-       /* Renegotiate extension */
-       if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0))
-               {
-               SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-               return NULL;
-               }
-
-       if((limit - p - 4 - el) < 0) return NULL;
-         
-       s2n(TLSEXT_TYPE_renegotiate,ret);
-       s2n(el,ret);
-
-       if(!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el))
-               {
-               SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-               return NULL;
-               }
-
-       ret += el;
-
-       if ((extdatalen = ret-p-2)== 0) 
-               return p;
-
-       s2n(extdatalen,p);
-
-       return ret;
-       }
-
-int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
-       {
-       unsigned short type;
-       unsigned short size;
-       unsigned short len;
-       unsigned char *data = *p;
-       int renegotiate_seen = 0;
-
-       if (data >= (d+n-2))
-               {
-               if (s->new_session
-                       && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
-                       {
-                       /* We should always see one extension: the renegotiate extension */
-                       SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-                       *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
-                       return 0;
-                       }
-               return 1;
-               }
-       n2s(data,len);
-
-       if (data > (d+n-len)) 
-               return 1;
-
-       while (data <= (d+n-4))
-               {
-               n2s(data,type);
-               n2s(data,size);
-               
-               if (data+size > (d+n))
-                       return 1;
-               
-               if (type == TLSEXT_TYPE_renegotiate)
-                       {
-                       if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
-                               return 0;
-                       renegotiate_seen = 1;
-                       }
-               
-               data+=size;
-               }
-
-       if (s->new_session && !renegotiate_seen
-               && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
-               {
-               *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
-               SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-               return 0;
-               }
-
-       *p = data;
-       return 1;
-       }
-
-unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit)
-       {
-       int extdatalen = 0;
-       unsigned char *ret = p;
-       
-       ret+=2;
-       
-       if (ret>=limit) return NULL; /* this really never occurs, but ... */
-       
-       if(s->s3->send_connection_binding)
-               {
-               int el;
-
-               if(!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0))
-                       {
-                       SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                       return NULL;
-                       }
-
-               if((limit - p - 4 - el) < 0) return NULL;
-          
-               s2n(TLSEXT_TYPE_renegotiate,ret);
-               s2n(el,ret);
-
-               if(!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el))
-                       {
-                       SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
-                       return NULL;
-                       }
-
-               ret += el;
-               }
-
-       if ((extdatalen = ret-p-2)== 0) 
-               return p;
-
-       s2n(extdatalen,p);
-
-       return ret;
-       }
-
-int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
-       {
-       unsigned short type;
-       unsigned short size;
-       unsigned short len;
-       unsigned char *data = *p;
-       int renegotiate_seen = 0;
-       
-       if (data >= (d+n-2))
-               {
-               if (s->new_session
-                       && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
-                       {
-                       /* We should always see one extension: the renegotiate extension */
-                       SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-                       *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
-                       return 0;
-                       }
-               return 1;
-               }
-       n2s(data,len);
-       
-       if (data > (d+n-len)) 
-               return 1;
-       
-       while (data <= (d+n-4))
-               {
-               n2s(data,type);
-               n2s(data,size);
-               
-               if (data+size > (d+n))
-                       return 1;
-               
-               if (type == TLSEXT_TYPE_renegotiate)
-                       {
-                       if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
-                               return 0;
-                       renegotiate_seen = 1;
-                       }
-               
-               data+=size;
-               }
-
-       if (s->new_session && !renegotiate_seen
-               && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
-               {
-               *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
-               SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
-               return 0;
-               }
-
-       *p = data;
-       return 1;
-       }
-#endif
index cbef062130e69e4d50994d057f7e622db132007a..007542f53482aa4102094428ce72d46437d9894f 100644 (file)
@@ -305,8 +305,18 @@ int dtls1_accept(SSL *s)
                        ret=dtls1_send_server_hello(s);
                        if (ret <= 0) goto end;
 
                        ret=dtls1_send_server_hello(s);
                        if (ret <= 0) goto end;
 
+#ifndef OPENSSL_NO_TLSEXT
                        if (s->hit)
                        if (s->hit)
-                               s->state=SSL3_ST_SW_CHANGE_A;
+                               {
+                               if (s->tlsext_ticket_expected)
+                                       s->state=SSL3_ST_SW_SESSION_TICKET_A;
+                               else
+                                       s->state=SSL3_ST_SW_CHANGE_A;
+                               }
+#else
+                       if (s->hit)
+                                       s->state=SSL3_ST_SW_CHANGE_A;
+#endif
                        else
                                s->state=SSL3_ST_SW_CERT_A;
                        s->init_num=0;
                        else
                                s->state=SSL3_ST_SW_CERT_A;
                        s->init_num=0;
@@ -321,10 +331,24 @@ int dtls1_accept(SSL *s)
                                dtls1_start_timer(s);
                                ret=dtls1_send_server_certificate(s);
                                if (ret <= 0) goto end;
                                dtls1_start_timer(s);
                                ret=dtls1_send_server_certificate(s);
                                if (ret <= 0) goto end;
+#ifndef OPENSSL_NO_TLSEXT
+                               if (s->tlsext_status_expected)
+                                       s->state=SSL3_ST_SW_CERT_STATUS_A;
+                               else
+                                       s->state=SSL3_ST_SW_KEY_EXCH_A;
+                               }
+                       else
+                               {
+                               skip = 1;
+                               s->state=SSL3_ST_SW_KEY_EXCH_A;
+                               }
+#else
                                }
                        else
                                skip=1;
                                }
                        else
                                skip=1;
+
                        s->state=SSL3_ST_SW_KEY_EXCH_A;
                        s->state=SSL3_ST_SW_KEY_EXCH_A;
+#endif
                        s->init_num=0;
                        break;
 
                        s->init_num=0;
                        break;
 
@@ -519,11 +543,34 @@ int dtls1_accept(SSL *s)
                        dtls1_stop_timer(s);
                        if (s->hit)
                                s->state=SSL_ST_OK;
                        dtls1_stop_timer(s);
                        if (s->hit)
                                s->state=SSL_ST_OK;
+#ifndef OPENSSL_NO_TLSEXT
+                       else if (s->tlsext_ticket_expected)
+                               s->state=SSL3_ST_SW_SESSION_TICKET_A;
+#endif
                        else
                                s->state=SSL3_ST_SW_CHANGE_A;
                        s->init_num=0;
                        break;
 
                        else
                                s->state=SSL3_ST_SW_CHANGE_A;
                        s->init_num=0;
                        break;
 
+#ifndef OPENSSL_NO_TLSEXT
+               case SSL3_ST_SW_SESSION_TICKET_A:
+               case SSL3_ST_SW_SESSION_TICKET_B:
+                       ret=dtls1_send_newsession_ticket(s);
+                       if (ret <= 0) goto end;
+                       s->state=SSL3_ST_SW_CHANGE_A;
+                       s->init_num=0;
+                       break;
+
+               case SSL3_ST_SW_CERT_STATUS_A:
+               case SSL3_ST_SW_CERT_STATUS_B:
+                       ret=ssl3_send_cert_status(s);
+                       if (ret <= 0) goto end;
+                       s->state=SSL3_ST_SW_KEY_EXCH_A;
+                       s->init_num=0;
+                       break;
+
+#endif
+
                case SSL3_ST_SW_CHANGE_A:
                case SSL3_ST_SW_CHANGE_B:
 
                case SSL3_ST_SW_CHANGE_A:
                case SSL3_ST_SW_CHANGE_B:
 
@@ -765,7 +812,7 @@ int dtls1_send_server_hello(SSL *s)
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
-               if ((p = ssl_add_serverhello_dtlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
+               if ((p = ssl_add_serverhello_tlsext(s, p, buf+SSL3_RT_MAX_PLAIN_LENGTH)) == NULL)
                        {
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
                        return -1;
                        {
                        SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO,ERR_R_INTERNAL_ERROR);
                        return -1;
@@ -1394,3 +1441,114 @@ int dtls1_send_server_certificate(SSL *s)
        /* SSL3_ST_SW_CERT_B */
        return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        }
        /* SSL3_ST_SW_CERT_B */
        return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
        }
+
+#ifndef OPENSSL_NO_TLSEXT
+int dtls1_send_newsession_ticket(SSL *s)
+       {
+       if (s->state == SSL3_ST_SW_SESSION_TICKET_A)
+               {
+               unsigned char *p, *senc, *macstart;
+               int len, slen;
+               unsigned int hlen, msg_len;
+               EVP_CIPHER_CTX ctx;
+               HMAC_CTX hctx;
+               SSL_CTX *tctx = s->initial_ctx;
+               unsigned char iv[EVP_MAX_IV_LENGTH];
+               unsigned char key_name[16];
+
+               /* get session encoding length */
+               slen = i2d_SSL_SESSION(s->session, NULL);
+               /* Some length values are 16 bits, so forget it if session is
+                * too long
+                */
+               if (slen > 0xFF00)
+                       return -1;
+               /* Grow buffer if need be: the length calculation is as
+                * follows 12 (DTLS handshake message header) +
+                * 4 (ticket lifetime hint) + 2 (ticket length) +
+                * 16 (key name) + max_iv_len (iv length) +
+                * session_length + max_enc_block_size (max encrypted session
+                * length) + max_md_size (HMAC).
+                */
+               if (!BUF_MEM_grow(s->init_buf,
+                       DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
+                       EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
+                       return -1;
+               senc = OPENSSL_malloc(slen);
+               if (!senc)
+                       return -1;
+               p = senc;
+               i2d_SSL_SESSION(s->session, &p);
+
+               p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
+               EVP_CIPHER_CTX_init(&ctx);
+               HMAC_CTX_init(&hctx);
+               /* Initialize HMAC and cipher contexts. If callback present
+                * it does all the work otherwise use generated values
+                * from parent ctx.
+                */
+               if (tctx->tlsext_ticket_key_cb)
+                       {
+                       if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+                                                        &hctx, 1) < 0)
+                               {
+                               OPENSSL_free(senc);
+                               return -1;
+                               }
+                       }
+               else
+                       {
+                       RAND_pseudo_bytes(iv, 16);
+                       EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
+                                       tctx->tlsext_tick_aes_key, iv);
+                       HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
+                                       tlsext_tick_md(), NULL);
+                       memcpy(key_name, tctx->tlsext_tick_key_name, 16);
+                       }
+               l2n(s->session->tlsext_tick_lifetime_hint, p);
+               /* Skip ticket length for now */
+               p += 2;
+               /* Output key name */
+               macstart = p;
+               memcpy(p, key_name, 16);
+               p += 16;
+               /* output IV */
+               memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
+               p += EVP_CIPHER_CTX_iv_length(&ctx);
+               /* Encrypt session data */
+               EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
+               p += len;
+               EVP_EncryptFinal(&ctx, p, &len);
+               p += len;
+               EVP_CIPHER_CTX_cleanup(&ctx);
+
+               HMAC_Update(&hctx, macstart, p - macstart);
+               HMAC_Final(&hctx, p, &hlen);
+               HMAC_CTX_cleanup(&hctx);
+
+               p += hlen;
+               /* Now write out lengths: p points to end of data written */
+               /* Total length */
+               len = p - (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
+               p=(unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
+               s2n(len - 18, p);  /* Ticket length */
+
+               /* number of bytes to write */
+               s->init_num= len;
+               s->state=SSL3_ST_SW_SESSION_TICKET_B;
+               s->init_off=0;
+               OPENSSL_free(senc);
+
+               /* XDTLS:  set message header ? */
+               msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
+               dtls1_set_message_header(s, (void *)s->init_buf->data,
+                       SSL3_MT_NEWSESSION_TICKET, msg_len, 0, msg_len);
+
+               /* buffer the message to handle re-xmits */
+               dtls1_buffer_message(s, 0);
+               }
+
+       /* SSL3_ST_SW_SESSION_TICKET_B */
+       return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+       }
+#endif
index dfd8bf24d64a21e9340ff30550910a50f4039bf6..44f09b84639261302caf99a4aab7afed1d40a2ea 100644 (file)
 
 static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
 
 static const SSL_METHOD *ssl3_get_client_method(int ver);
 static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b);
-#ifndef OPENSSL_NO_TLSEXT
-static int ssl3_check_finished(SSL *s);
-#endif
 
 static const SSL_METHOD *ssl3_get_client_method(int ver)
        {
 
 static const SSL_METHOD *ssl3_get_client_method(int ver)
        {
@@ -915,7 +912,7 @@ int ssl3_get_server_hello(SSL *s)
 
 #ifndef OPENSSL_NO_TLSEXT
        /* TLS extensions*/
 
 #ifndef OPENSSL_NO_TLSEXT
        /* TLS extensions*/
-       if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER)
+       if (s->version > SSL3_VERSION)
                {
                if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
                        {
                {
                if (!ssl_parse_serverhello_tlsext(s,&p,d,n, &al))
                        {
@@ -929,17 +926,6 @@ int ssl3_get_server_hello(SSL *s)
                                goto err;
                        }
                }
                                goto err;
                        }
                }
-
-       /* DTLS extensions */
-       if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
-       {
-               if (!ssl_parse_serverhello_dtlsext(s,&p,d,n, &al))
-               {
-                       /* 'al' set by ssl_parse_serverhello_dtlsext */
-                       SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
-                       goto f_err;
-               }
-       }
 #endif
 
        if (p != (d+n))
 #endif
 
        if (p != (d+n))
@@ -1832,6 +1818,7 @@ int ssl3_get_new_session_ticket(SSL *s)
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
                SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET,SSL_R_LENGTH_MISMATCH);
                goto f_err;
                }
+
        p=d=(unsigned char *)s->init_msg;
        n2l(p, s->session->tlsext_tick_lifetime_hint);
        n2s(p, ticklen);
        p=d=(unsigned char *)s->init_msg;
        n2l(p, s->session->tlsext_tick_lifetime_hint);
        n2s(p, ticklen);
@@ -2996,7 +2983,7 @@ err:
  */
 
 #ifndef OPENSSL_NO_TLSEXT
  */
 
 #ifndef OPENSSL_NO_TLSEXT
-static int ssl3_check_finished(SSL *s)
+int ssl3_check_finished(SSL *s)
        {
        int ok;
        long n;
        {
        int ok;
        long n;
index ef760098b04ec9611546a9760129c35668841390..77d7d878e381cf48dce1af3752ecbc3231d897f1 100644 (file)
@@ -1015,7 +1015,7 @@ int ssl3_get_client_hello(SSL *s)
 
 #ifndef OPENSSL_NO_TLSEXT
        /* TLS extensions*/
 
 #ifndef OPENSSL_NO_TLSEXT
        /* TLS extensions*/
-       if (s->version > SSL3_VERSION && s->version != DTLS1_VERSION && s->version != DTLS1_BAD_VER)
+       if (s->version > SSL3_VERSION)
                {
                if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
                        {
                {
                if (!ssl_parse_clienthello_tlsext(s,&p,d,n, &al))
                        {
@@ -1081,17 +1081,6 @@ int ssl3_get_client_hello(SSL *s)
                        s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
                        }
                }
                        s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
                        }
                }
-
-       /* DTLS extensions */
-       if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
-               {
-               if (!ssl_parse_clienthello_dtlsext(s,&p,d,n, &al))
-                       {
-                               /* 'al' set by ssl_parse_clienthello_dtlsext */
-                               SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_PARSE_TLSEXT);
-                               goto f_err;
-                       }
-               }
 #endif
 
        /* Worst case, we will use the NULL compression, but if we have other
 #endif
 
        /* Worst case, we will use the NULL compression, but if we have other
index 226d4070232a3dd5b346790995a989775becd570..41f0f775978d1932c559ac1f8218deeed1005ec1 100644 (file)
@@ -950,7 +950,7 @@ void dtls1_start_timer(SSL *s);
 void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
-
+int dtls1_send_newsession_ticket(SSL *s);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
@@ -966,6 +966,9 @@ int ssl3_send_client_key_exchange(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
 int ssl3_check_cert_and_algorithm(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
 int ssl3_check_cert_and_algorithm(SSL *s);
+#ifndef OPENSSL_NO_TLSEXT
+int ssl3_check_finished(SSL *s);
+#endif
 
 int dtls1_client_hello(SSL *s);
 int dtls1_send_client_certificate(SSL *s);
 
 int dtls1_client_hello(SSL *s);
 int dtls1_send_client_certificate(SSL *s);
@@ -1055,11 +1058,6 @@ int ssl_prepare_serverhello_tlsext(SSL *s);
 int ssl_check_clienthello_tlsext(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
 int ssl_check_clienthello_tlsext(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
-unsigned char *ssl_add_clienthello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit);
-unsigned char *ssl_add_serverhello_dtlsext(SSL *s, unsigned char *p, unsigned char *limit);
-int ssl_parse_clienthello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
-int ssl_parse_serverhello_dtlsext(SSL *s, unsigned char **data, unsigned char *d, int n, int *al);
-
 #ifdef OPENSSL_NO_SHA256
 #define tlsext_tick_md EVP_sha1
 #else
 #ifdef OPENSSL_NO_SHA256
 #define tlsext_tick_md EVP_sha1
 #else
index ebf9c4fdaee7481ef42a27c282c1a2ad8029ff99..ce53e50aeb58d2cef39bffc025b5735717cbb06d 100644 (file)
@@ -340,7 +340,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
         }
 
 #ifndef OPENSSL_NO_EC
         }
 
 #ifndef OPENSSL_NO_EC
-       if (s->tlsext_ecpointformatlist != NULL)
+       if (s->tlsext_ecpointformatlist != NULL &&
+           s->version != DTLS1_VERSION)
                {
                /* Add TLS extension ECPointFormats to the ClientHello message */
                long lenmax; 
                {
                /* Add TLS extension ECPointFormats to the ClientHello message */
                long lenmax; 
@@ -359,7 +360,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
                ret+=s->tlsext_ecpointformatlist_length;
                }
                memcpy(ret, s->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist_length);
                ret+=s->tlsext_ecpointformatlist_length;
                }
-       if (s->tlsext_ellipticcurvelist != NULL)
+       if (s->tlsext_ellipticcurvelist != NULL &&
+           s->version != DTLS1_VERSION)
                {
                /* Add TLS extension EllipticCurves to the ClientHello message */
                long lenmax; 
                {
                /* Add TLS extension EllipticCurves to the ClientHello message */
                long lenmax; 
@@ -423,7 +425,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                skip_ext:
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
                skip_ext:
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
-       if (s->s3->client_opaque_prf_input != NULL)
+       if (s->s3->client_opaque_prf_input != NULL &&
+           s->version != DTLS1_VERSION)
                {
                size_t col = s->s3->client_opaque_prf_input_len;
                
                {
                size_t col = s->s3->client_opaque_prf_input_len;
                
@@ -440,7 +443,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 #endif
 
                }
 #endif
 
-       if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp)
+       if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp &&
+           s->version != DTLS1_VERSION)
                {
                int i;
                long extlen, idlen, itmp;
                {
                int i;
                long extlen, idlen, itmp;
@@ -515,7 +519,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                s2n(0,ret);
                }
 
                s2n(0,ret);
                }
 
-        if(s->s3->send_connection_binding)
+       if(s->s3->send_connection_binding)
         {
           int el;
           
         {
           int el;
           
@@ -540,7 +544,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
         }
 
 #ifndef OPENSSL_NO_EC
         }
 
 #ifndef OPENSSL_NO_EC
-       if (s->tlsext_ecpointformatlist != NULL)
+       if (s->tlsext_ecpointformatlist != NULL &&
+           s->version != DTLS1_VERSION)
                {
                /* Add TLS extension ECPointFormats to the ServerHello message */
                long lenmax; 
                {
                /* Add TLS extension ECPointFormats to the ServerHello message */
                long lenmax; 
@@ -579,7 +584,8 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                }
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
                }
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
-       if (s->s3->server_opaque_prf_input != NULL)
+       if (s->s3->server_opaque_prf_input != NULL &&
+           s->version != DTLS1_VERSION)
                {
                size_t sol = s->s3->server_opaque_prf_input_len;
                
                {
                size_t sol = s->s3->server_opaque_prf_input_len;
                
@@ -757,7 +763,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        }
 
 #ifndef OPENSSL_NO_EC
                        }
 
 #ifndef OPENSSL_NO_EC
-               else if (type == TLSEXT_TYPE_ec_point_formats)
+               else if (type == TLSEXT_TYPE_ec_point_formats &&
+                    s->version != DTLS1_VERSION)
                        {
                        unsigned char *sdata = data;
                        int ecpointformatlist_length = *(sdata++);
                        {
                        unsigned char *sdata = data;
                        int ecpointformatlist_length = *(sdata++);
@@ -784,7 +791,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        fprintf(stderr,"\n");
 #endif
                        }
                        fprintf(stderr,"\n");
 #endif
                        }
-               else if (type == TLSEXT_TYPE_elliptic_curves)
+               else if (type == TLSEXT_TYPE_elliptic_curves &&
+                    s->version != DTLS1_VERSION)
                        {
                        unsigned char *sdata = data;
                        int ellipticcurvelist_length = (*(sdata++) << 8);
                        {
                        unsigned char *sdata = data;
                        int ellipticcurvelist_length = (*(sdata++) << 8);
@@ -814,7 +822,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        }
 #endif /* OPENSSL_NO_EC */
 #ifdef TLSEXT_TYPE_opaque_prf_input
                        }
 #endif /* OPENSSL_NO_EC */
 #ifdef TLSEXT_TYPE_opaque_prf_input
-               else if (type == TLSEXT_TYPE_opaque_prf_input)
+               else if (type == TLSEXT_TYPE_opaque_prf_input &&
+                    s->version != DTLS1_VERSION)
                        {
                        unsigned char *sdata = data;
 
                        {
                        unsigned char *sdata = data;
 
@@ -858,8 +867,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                return 0;
                        renegotiate_seen = 1;
                        }
                                return 0;
                        renegotiate_seen = 1;
                        }
-               else if (type == TLSEXT_TYPE_status_request
-                                               && s->ctx->tlsext_status_cb)
+               else if (type == TLSEXT_TYPE_status_request &&
+                        s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb)
                        {
                
                        if (size < 5) 
                        {
                
                        if (size < 5) 
@@ -1025,7 +1034,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        }
 
 #ifndef OPENSSL_NO_EC
                        }
 
 #ifndef OPENSSL_NO_EC
-               else if (type == TLSEXT_TYPE_ec_point_formats)
+               else if (type == TLSEXT_TYPE_ec_point_formats &&
+                    s->version != DTLS1_VERSION)
                        {
                        unsigned char *sdata = data;
                        int ecpointformatlist_length = *(sdata++);
                        {
                        unsigned char *sdata = data;
                        int ecpointformatlist_length = *(sdata++);
@@ -1071,7 +1081,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        s->tlsext_ticket_expected = 1;
                        }
 #ifdef TLSEXT_TYPE_opaque_prf_input
                        s->tlsext_ticket_expected = 1;
                        }
 #ifdef TLSEXT_TYPE_opaque_prf_input
-               else if (type == TLSEXT_TYPE_opaque_prf_input)
+               else if (type == TLSEXT_TYPE_opaque_prf_input &&
+                    s->version != DTLS1_VERSION)
                        {
                        unsigned char *sdata = data;
 
                        {
                        unsigned char *sdata = data;
 
@@ -1101,7 +1112,8 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                }
                        }
 #endif
                                }
                        }
 #endif
-               else if (type == TLSEXT_TYPE_status_request)
+               else if (type == TLSEXT_TYPE_status_request &&
+                        s->version != DTLS1_VERSION)
                        {
                        /* MUST be empty and only sent if we've requested
                         * a status request message.
                        {
                        /* MUST be empty and only sent if we've requested
                         * a status request message.