X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=cc97258ae5368780e74785454b799e3a73d2dc55;hb=808f55351aa4834a7b358c43fb6cac371e79ff7c;hp=05eb2477b51d3830dbbdb2d3ee1b8b8cc99f9698;hpb=725745d1056d616f7aeeee15b84d383bf16c1d58;p=oweals%2Fopenssl.git diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 05eb2477b5..cc97258ae5 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -174,9 +174,10 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha ret+=size_str; } - - /* Add the renegotiation option: TODOEKR switch */ - { + + /* Add RI if renegotiating */ + if (s->new_session) + { int el; if(!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) @@ -350,32 +351,17 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in unsigned short len; unsigned char *data = *p; int renegotiate_seen = 0; - int need_ri; s->servername_done = 0; s->tlsext_status_type = -1; - /* Need RI if renegotiating unless legacy renegotiation allowed */ - if (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION - || !s->new_session) - need_ri = 0; - else - need_ri = 1; if (data >= (d+n-2)) - { - if (!need_ri) - return 1; - /* We need to see at least one extension: RI */ - /* FIXME: Spec currently doesn't give alert to use */ - *al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } + goto ri_check; + n2s(data,len); if (data > (d+n-len)) - return 1; + goto ri_check; while (data <= (d+n-4)) { @@ -383,7 +369,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in n2s(data,size); if (data+size > (d+n)) - return 1; + goto ri_check; if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 0, type, data, size, @@ -446,14 +432,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in switch (servname_type) { case TLSEXT_NAMETYPE_host_name: - if (s->session->tlsext_hostname == NULL) + if (!s->hit) { - if (len > TLSEXT_MAXLEN_host_name || - ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) + if(s->session->tlsext_hostname) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (len > TLSEXT_MAXLEN_host_name) { *al = TLS1_AD_UNRECOGNIZED_NAME; return 0; } + if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } memcpy(s->session->tlsext_hostname, sdata, len); s->session->tlsext_hostname[len]='\0'; if (strlen(s->session->tlsext_hostname) != len) { @@ -466,7 +461,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } else - s->servername_done = strlen(s->session->tlsext_hostname) == len + s->servername_done = s->session->tlsext_hostname + && strlen(s->session->tlsext_hostname) == len && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; break; @@ -525,6 +521,7 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } n2s(data, idsize); dsize -= 2 + idsize; + size -= 2 + idsize; if (dsize < 0) { *al = SSL_AD_DECODE_ERROR; @@ -563,9 +560,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } /* Read in request_extensions */ + if (size < 2) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } n2s(data,dsize); size -= 2; - if (dsize > size) + if (dsize != size) { *al = SSL_AD_DECODE_ERROR; return 0; @@ -573,6 +575,12 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in sdata = data; if (dsize > 0) { + if (s->tlsext_ocsp_exts) + { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + s->tlsext_ocsp_exts = d2i_X509_EXTENSIONS(NULL, &sdata, dsize); @@ -595,63 +603,50 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in data+=size; } + *p = data; - if (need_ri && !renegotiate_seen) + ri_check: + + /* Need RI if renegotiating */ + + if (!renegotiate_seen && s->new_session && + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { - /* FIXME: Spec currently doesn't give alert to use */ - *al = SSL_AD_ILLEGAL_PARAMETER; + *al = SSL_AD_HANDSHAKE_FAILURE; SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); return 0; } - *p = data; return 1; } int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al) { + unsigned short length; unsigned short type; unsigned short size; - unsigned short len; unsigned char *data = *p; int tlsext_servername = 0; int renegotiate_seen = 0; - int need_ri; - /* Determine if we need to see RI. Strictly speaking if we want to - * avoid an attack we should *always* see RI even on initial server - * hello because the client doesn't see any renegotiation during an - * attack. However this would mean we could not connect to any server - * which doesn't support RI so for the immediate future tolerate RI - * absence on initial connect only. - */ - if (s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION || - !s->new_session) - need_ri = 0; - else - need_ri = 1; if (data >= (d+n-2)) + goto ri_check; + + n2s(data,length); + if (data+length != d+n) { - if (!need_ri) - return 1; - /* We need to see at least one extension: RI */ - /* FIXME: Spec currently doesn't give alert to use */ - *al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + *al = SSL_AD_DECODE_ERROR; return 0; } - n2s(data,len); - while(data <= (d+n-4)) { n2s(data,type); n2s(data,size); if (data+size > (d+n)) - return 1; + goto ri_check; if (s->tlsext_debug_cb) s->tlsext_debug_cb(s, 1, type, data, size, @@ -705,15 +700,6 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in return 0; } - if (!renegotiate_seen && need_ri) - { - /* FIXME: Spec currently doesn't give alert to use */ - *al = SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, - SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); - return 0; - } - if (!s->hit && tlsext_servername == 1) { if (s->tlsext_hostname) @@ -736,6 +722,26 @@ int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } *p = data; + + ri_check: + + /* Determine if we need to see RI. Strictly speaking if we want to + * avoid an attack we should *always* see RI even on initial server + * hello because the client doesn't see any renegotiation during an + * attack. However this would mean we could not connect to any server + * which doesn't support RI so for the immediate future tolerate RI + * absence on initial connect only. + */ + if (!renegotiate_seen + && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) + { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + return 1; }