add missing parts of reneg port, fix apps patch
authorDr. Stephen Henson <steve@openssl.org>
Wed, 11 Nov 2009 14:51:19 +0000 (14:51 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Wed, 11 Nov 2009 14:51:19 +0000 (14:51 +0000)
apps/s_cb.c
ssl/t1_lib.c
ssl/tls1.h

index 4d0975ab4166b40c62859a66c1138f2cb565ccf2..90a3cb8625a80fd6715df73478f96f492e99e8a4 100644 (file)
@@ -338,9 +338,6 @@ void MS_CALLBACK apps_ssl_info_callback(const SSL *s, int where, int ret)
                }
        }
 
-               case TLSEXT_TYPE_renegotiate:
-               extname = "renegotiate";
-               break;
 
 void MS_CALLBACK msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
        {
@@ -672,6 +669,10 @@ void MS_CALLBACK tlsext_cb(SSL *s, int client_server, int type,
                extname = "server ticket";
                break;
 
+               case TLSEXT_TYPE_renegotiate:
+               extname = "renegotiate";
+               break;
+
 #ifdef TLSEXT_TYPE_opaque_prf_input
                case TLSEXT_TYPE_opaque_prf_input:
                extname = "opaque PRF input";
index db2bd6b6a8edcbcae412c08dc7e477a78fb2d183..af196de3519a84b653e82f07647ed13312cb8833 100644 (file)
@@ -315,6 +315,30 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha
                ret+=size_str;
                }
 
+        /* Add the renegotiation option: TODOEKR switch */
+        {
+          int el;
+          
+          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;
+        }
+
 #ifndef OPENSSL_NO_EC
        if (s->tlsext_ecpointformatlist != NULL)
                {
@@ -490,6 +514,31 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha
                s2n(TLSEXT_TYPE_server_name,ret);
                s2n(0,ret);
                }
+
+        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;
+        }
+
 #ifndef OPENSSL_NO_EC
        if (s->tlsext_ecpointformatlist != NULL)
                {
@@ -574,11 +623,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
        unsigned short size;
        unsigned short len;
        unsigned char *data = *p;
+       int renegotiate_seen = 0;
+
        s->servername_done = 0;
        s->tlsext_status_type = -1;
+       s->s3->send_connection_binding = 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 */
+                       *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+                       return 0;
+                       }
                return 1;
+               }
        n2s(data,len);
 
        if (data > (d+n-len)) 
@@ -790,6 +851,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                                return 0;
                                }
                        }
+               else if (type == TLSEXT_TYPE_renegotiate)
+                       {
+                       if(!ssl_parse_clienthello_renegotiate_ext(s, data, size, al))
+                               return 0;
+                       renegotiate_seen = 1;
+                       }
                else if (type == TLSEXT_TYPE_status_request
                                                && s->ctx->tlsext_status_cb)
                        {
@@ -894,6 +961,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                /* session ticket processed earlier */
                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? */
+               return 0;
+               }
                                
        *p = data;
        return 1;
@@ -905,11 +980,22 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
        unsigned short size;
        unsigned short len;  
        unsigned char *data = *p;
-
        int tlsext_servername = 0;
+       int renegotiate_seen = 0;
 
        if (data >= (d+n-2))
+               {
+               /* Because the client does not see any renegotiation during an
+                  attack, we must enforce this on all server hellos, even the
+                  first */
+               if (!(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+                       {
+                       /* We should always see one extension: the renegotiate extension */
+                       *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+                       return 0;
+                       }
                return 1;
+               }
 
        n2s(data,len);
 
@@ -1025,7 +1111,12 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                        /* Set flag to expect CertificateStatus message */
                        s->tlsext_status_expected = 1;
                        }
-
+               else if (type == TLSEXT_TYPE_renegotiate)
+                       {
+                       if(!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
+                               return 0;
+                       renegotiate_seen = 1;
+                       }
                data+=size;             
                }
 
@@ -1035,6 +1126,13 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
                return 0;
                }
 
+       if (!renegotiate_seen
+               && !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION))
+               {
+               *al = SSL_AD_ILLEGAL_PARAMETER; /* is this the right alert? */
+               return 0;
+               }
+
        if (!s->hit && tlsext_servername == 1)
                {
                if (s->tlsext_hostname)
index a55ffd634b44bcabcf3e2e1a7e6889603cc1c03b..b3cc8f098b7e8a0cb71066711376ca131838b91b 100644 (file)
@@ -201,6 +201,9 @@ extern "C" {
 # define TLSEXT_TYPE_opaque_prf_input          ?? */
 #endif
 
+/* Temporary extension type */
+#define TLSEXT_TYPE_renegotiate                 0xff01
+
 /* NameType value from RFC 3546 */
 #define TLSEXT_NAMETYPE_host_name 0
 /* status request value from RFC 3546 */