Loading ssl/d1_clnt.c +60 −1 Original line number Diff line number Diff line Loading @@ -286,16 +286,44 @@ int dtls1_connect(SSL *s) 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; #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; s->state=SSL3_ST_CR_KEY_EXCH_A; #endif s->init_num=0; break; Loading Loading @@ -437,11 +465,36 @@ int dtls1_connect(SSL *s) } 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; #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; Loading Loading @@ -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) { SSL_SESSION *sess = s->session; 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)) Loading Loading @@ -637,7 +696,7 @@ int dtls1_client_hello(SSL *s) *(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; Loading ssl/d1_lib.c +0 −191 Original line number Diff line number Diff line Loading @@ -382,194 +382,3 @@ int dtls1_listen(SSL *s, struct sockaddr *client) (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 ssl/d1_srvr.c +160 −2 Original line number Diff line number Diff line Loading @@ -305,8 +305,18 @@ int dtls1_accept(SSL *s) ret=dtls1_send_server_hello(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->hit) { 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; Loading @@ -321,10 +331,24 @@ int dtls1_accept(SSL *s) 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; s->state=SSL3_ST_SW_KEY_EXCH_A; #endif s->init_num=0; break; Loading Loading @@ -519,11 +543,34 @@ int dtls1_accept(SSL *s) 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; #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: Loading Loading @@ -765,7 +812,7 @@ int dtls1_send_server_hello(SSL *s) #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; Loading Loading @@ -1394,3 +1441,114 @@ int dtls1_send_server_certificate(SSL *s) /* 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 ssl/s3_clnt.c +3 −16 Original line number Diff line number Diff line Loading @@ -166,9 +166,6 @@ 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) { Loading Loading @@ -915,7 +912,7 @@ int ssl3_get_server_hello(SSL *s) #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)) { Loading @@ -929,17 +926,6 @@ int ssl3_get_server_hello(SSL *s) 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)) Loading Loading @@ -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; } p=d=(unsigned char *)s->init_msg; n2l(p, s->session->tlsext_tick_lifetime_hint); n2s(p, ticklen); Loading Loading @@ -2996,7 +2983,7 @@ err: */ #ifndef OPENSSL_NO_TLSEXT static int ssl3_check_finished(SSL *s) int ssl3_check_finished(SSL *s) { int ok; long n; Loading ssl/s3_srvr.c +1 −12 Original line number Diff line number Diff line Loading @@ -1015,7 +1015,7 @@ int ssl3_get_client_hello(SSL *s) #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)) { Loading Loading @@ -1081,17 +1081,6 @@ int ssl3_get_client_hello(SSL *s) 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 Loading Loading
ssl/d1_clnt.c +60 −1 Original line number Diff line number Diff line Loading @@ -286,16 +286,44 @@ int dtls1_connect(SSL *s) 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; #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; s->state=SSL3_ST_CR_KEY_EXCH_A; #endif s->init_num=0; break; Loading Loading @@ -437,11 +465,36 @@ int dtls1_connect(SSL *s) } 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; #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; Loading Loading @@ -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) { SSL_SESSION *sess = s->session; 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)) Loading Loading @@ -637,7 +696,7 @@ int dtls1_client_hello(SSL *s) *(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; Loading
ssl/d1_lib.c +0 −191 Original line number Diff line number Diff line Loading @@ -382,194 +382,3 @@ int dtls1_listen(SSL *s, struct sockaddr *client) (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
ssl/d1_srvr.c +160 −2 Original line number Diff line number Diff line Loading @@ -305,8 +305,18 @@ int dtls1_accept(SSL *s) ret=dtls1_send_server_hello(s); if (ret <= 0) goto end; #ifndef OPENSSL_NO_TLSEXT if (s->hit) { 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; Loading @@ -321,10 +331,24 @@ int dtls1_accept(SSL *s) 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; s->state=SSL3_ST_SW_KEY_EXCH_A; #endif s->init_num=0; break; Loading Loading @@ -519,11 +543,34 @@ int dtls1_accept(SSL *s) 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; #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: Loading Loading @@ -765,7 +812,7 @@ int dtls1_send_server_hello(SSL *s) #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; Loading Loading @@ -1394,3 +1441,114 @@ int dtls1_send_server_certificate(SSL *s) /* 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
ssl/s3_clnt.c +3 −16 Original line number Diff line number Diff line Loading @@ -166,9 +166,6 @@ 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) { Loading Loading @@ -915,7 +912,7 @@ int ssl3_get_server_hello(SSL *s) #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)) { Loading @@ -929,17 +926,6 @@ int ssl3_get_server_hello(SSL *s) 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)) Loading Loading @@ -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; } p=d=(unsigned char *)s->init_msg; n2l(p, s->session->tlsext_tick_lifetime_hint); n2s(p, ticklen); Loading Loading @@ -2996,7 +2983,7 @@ err: */ #ifndef OPENSSL_NO_TLSEXT static int ssl3_check_finished(SSL *s) int ssl3_check_finished(SSL *s) { int ok; long n; Loading
ssl/s3_srvr.c +1 −12 Original line number Diff line number Diff line Loading @@ -1015,7 +1015,7 @@ int ssl3_get_client_hello(SSL *s) #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)) { Loading Loading @@ -1081,17 +1081,6 @@ int ssl3_get_client_hello(SSL *s) 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 Loading