From c2b78c31d631f45cd43c2d04c5ae490b8e9f21ab Mon Sep 17 00:00:00 2001 From: Ben Laurie Date: Sun, 8 Nov 2009 14:51:54 +0000 Subject: First cut of renegotiation extension. --- ssl/t1_lib.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 3 deletions(-) (limited to 'ssl/t1_lib.c') diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 247854e124..6c2085d6aa 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -173,7 +173,32 @@ 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; + } + + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { int ticklen; @@ -269,6 +294,30 @@ 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_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_serverhello_renegotiate_ext(s, ret, &el, el)) + { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) @@ -298,11 +347,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)) @@ -414,6 +475,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) @@ -515,11 +582,19 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in else s->tlsext_status_type = -1; } + /* 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; } @@ -530,11 +605,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); @@ -582,7 +668,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; } @@ -592,6 +683,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) -- cgit v1.2.3