diff options
author | Jung-uk Kim <jkim@FreeBSD.org> | 2017-05-25 20:52:16 +0000 |
---|---|---|
committer | Jung-uk Kim <jkim@FreeBSD.org> | 2017-05-25 20:52:16 +0000 |
commit | ed7112f094e259f5ad6674b204d52543e831efa2 (patch) | |
tree | ef4498a709580a3a0881f49574a1922b277d9eef /crypto/openssl/ssl | |
parent | 327f2e6c56c975c6f0e5333083e5309192681581 (diff) | |
parent | 12df5ad9af4981f5d3c31a9819d31618c0f1af51 (diff) | |
download | src-test2-ed7112f094e259f5ad6674b204d52543e831efa2.tar.gz src-test2-ed7112f094e259f5ad6674b204d52543e831efa2.zip |
Notes
Diffstat (limited to 'crypto/openssl/ssl')
-rw-r--r-- | crypto/openssl/ssl/d1_both.c | 21 | ||||
-rw-r--r-- | crypto/openssl/ssl/d1_clnt.c | 7 | ||||
-rw-r--r-- | crypto/openssl/ssl/d1_pkt.c | 4 | ||||
-rw-r--r-- | crypto/openssl/ssl/d1_srvr.c | 28 | ||||
-rw-r--r-- | crypto/openssl/ssl/s23_clnt.c | 5 | ||||
-rw-r--r-- | crypto/openssl/ssl/s23_srvr.c | 5 | ||||
-rw-r--r-- | crypto/openssl/ssl/s3_clnt.c | 8 | ||||
-rw-r--r-- | crypto/openssl/ssl/s3_enc.c | 86 | ||||
-rw-r--r-- | crypto/openssl/ssl/s3_lib.c | 2 | ||||
-rw-r--r-- | crypto/openssl/ssl/s3_pkt.c | 3 | ||||
-rw-r--r-- | crypto/openssl/ssl/s3_srvr.c | 56 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_cert.c | 1 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_ciph.c | 3 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_lib.c | 19 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_locl.h | 6 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_rsa.c | 6 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssl_sess.c | 3 | ||||
-rw-r--r-- | crypto/openssl/ssl/ssltest.c | 126 | ||||
-rw-r--r-- | crypto/openssl/ssl/t1_ext.c | 33 | ||||
-rw-r--r-- | crypto/openssl/ssl/t1_lib.c | 21 |
20 files changed, 346 insertions, 97 deletions
diff --git a/crypto/openssl/ssl/d1_both.c b/crypto/openssl/ssl/d1_both.c index 9bc61536101b..e6bc761e8bf2 100644 --- a/crypto/openssl/ssl/d1_both.c +++ b/crypto/openssl/ssl/d1_both.c @@ -517,6 +517,17 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) return i; } + /* + * Don't change the *message* read sequence number while listening. For + * the *record* write sequence we reflect the ClientHello sequence number + * when listening. + */ + if (s->d1->listen) + memcpy(s->s3->write_sequence, s->s3->read_sequence, + sizeof(s->s3->write_sequence)); + else + s->d1->handshake_read_seq++; + if (mt >= 0 && s->s3->tmp.message_type != mt) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); @@ -544,10 +555,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - /* Don't change sequence numbers while listening */ - if (!s->d1->listen) - s->d1->handshake_read_seq++; - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; @@ -1068,7 +1075,9 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) int dtls1_read_failed(SSL *s, int code) { if (code > 0) { +#ifdef TLS_DEBUG fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); +#endif return 1; } @@ -1140,7 +1149,9 @@ int dtls1_retransmit_buffered_messages(SSL *s) (frag->msg_header.seq, frag->msg_header.is_ccs), 0, &found) <= 0 && found) { +#ifdef TLS_DEBUG fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif return -1; } } @@ -1240,7 +1251,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, item = pqueue_find(s->d1->sent_messages, seq64be); if (item == NULL) { +#ifdef TLS_DEBUG fprintf(stderr, "retransmit: message %d non-existant\n", seq); +#endif *found = 0; return 0; } diff --git a/crypto/openssl/ssl/d1_clnt.c b/crypto/openssl/ssl/d1_clnt.c index 7e2f5c2830b5..76451a346d86 100644 --- a/crypto/openssl/ssl/d1_clnt.c +++ b/crypto/openssl/ssl/d1_clnt.c @@ -320,8 +320,13 @@ int dtls1_connect(SSL *s) s->shutdown = 0; /* every DTLS ClientHello resets Finished MAC */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + /* fall thru */ case SSL3_ST_CW_CLNT_HELLO_B: dtls1_start_timer(s); ret = ssl3_client_hello(s); diff --git a/crypto/openssl/ssl/d1_pkt.c b/crypto/openssl/ssl/d1_pkt.c index 7a02459f2b78..10586fee5408 100644 --- a/crypto/openssl/ssl/d1_pkt.c +++ b/crypto/openssl/ssl/d1_pkt.c @@ -1323,9 +1323,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* XDTLS: check that epoch is consistent */ if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - i = SSL_AD_ILLEGAL_PARAMETER; + al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; + goto f_err; } rr->length = 0; diff --git a/crypto/openssl/ssl/d1_srvr.c b/crypto/openssl/ssl/d1_srvr.c index bc875b53c9a0..8502b242e51c 100644 --- a/crypto/openssl/ssl/d1_srvr.c +++ b/crypto/openssl/ssl/d1_srvr.c @@ -282,7 +282,12 @@ int dtls1_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -322,7 +327,11 @@ int dtls1_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -346,15 +355,6 @@ int dtls1_accept(SSL *s) s->init_num = 0; - /* - * Reflect ClientHello sequence to remain stateless while - * listening - */ - if (listen) { - memcpy(s->s3->write_sequence, s->s3->read_sequence, - sizeof(s->s3->write_sequence)); - } - /* If we're just listening, stop here */ if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; @@ -381,7 +381,11 @@ int dtls1_accept(SSL *s) /* HelloVerifyRequest resets Finished MAC */ if (s->version != DTLS1_BAD_VER) - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; #ifndef OPENSSL_NO_SCTP diff --git a/crypto/openssl/ssl/s23_clnt.c b/crypto/openssl/ssl/s23_clnt.c index 6850dc0c6704..b80d1fd8ce6e 100644 --- a/crypto/openssl/ssl/s23_clnt.c +++ b/crypto/openssl/ssl/s23_clnt.c @@ -204,7 +204,10 @@ int ssl23_connect(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; diff --git a/crypto/openssl/ssl/s23_srvr.c b/crypto/openssl/ssl/s23_srvr.c index 470bd3d94f29..d3f6db15ccee 100644 --- a/crypto/openssl/ssl/s23_srvr.c +++ b/crypto/openssl/ssl/s23_srvr.c @@ -195,7 +195,10 @@ int ssl23_accept(SSL *s) s->init_buf = buf; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; diff --git a/crypto/openssl/ssl/s3_clnt.c b/crypto/openssl/ssl/s3_clnt.c index 32f2f1aeed2b..5b8b2da59f54 100644 --- a/crypto/openssl/ssl/s3_clnt.c +++ b/crypto/openssl/ssl/s3_clnt.c @@ -263,6 +263,7 @@ int ssl3_connect(SSL *s) if (!ssl3_setup_buffers(s)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -275,7 +276,11 @@ int ssl3_connect(SSL *s) /* don't push the buffering BIO quite yet */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } s->state = SSL3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; @@ -1864,6 +1869,7 @@ int ssl3_get_key_exchange(SSL *s) goto err; } if (EC_KEY_set_group(ecdh, ngroup) == 0) { + EC_GROUP_free(ngroup); SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } diff --git a/crypto/openssl/ssl/s3_enc.c b/crypto/openssl/ssl/s3_enc.c index fbc954d43c70..1eee9d9b21cf 100644 --- a/crypto/openssl/ssl/s3_enc.c +++ b/crypto/openssl/ssl/s3_enc.c @@ -177,32 +177,34 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_init(&s1); for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { k++; - if (k > sizeof buf) { + if (k > sizeof(buf)) /* bug: 'buf' is too small for this ciphersuite */ - SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); - return 0; - } + goto err; for (j = 0; j < k; j++) buf[j] = c; c++; - EVP_DigestInit_ex(&s1, EVP_sha1(), NULL); - EVP_DigestUpdate(&s1, buf, k); - EVP_DigestUpdate(&s1, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&s1, smd, NULL); - - EVP_DigestInit_ex(&m5, EVP_md5(), NULL); - EVP_DigestUpdate(&m5, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH); + if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || + !EVP_DigestUpdate(&s1, buf, k) || + !EVP_DigestUpdate(&s1, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&s1, smd, NULL)) + goto err2; + + if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || + !EVP_DigestUpdate(&m5, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) + goto err2; if ((int)(i + MD5_DIGEST_LENGTH) > num) { - EVP_DigestFinal_ex(&m5, smd, NULL); + if (!EVP_DigestFinal_ex(&m5, smd, NULL)) + goto err2; memcpy(km, smd, (num - i)); } else - EVP_DigestFinal_ex(&m5, km, NULL); + if (!EVP_DigestFinal_ex(&m5, km, NULL)) + goto err2; km += MD5_DIGEST_LENGTH; } @@ -210,6 +212,12 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_cleanup(&m5); EVP_MD_CTX_cleanup(&s1); return 1; + err: + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + err2: + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 0; } int ssl3_change_cipher_state(SSL *s, int which) @@ -360,25 +368,33 @@ int ssl3_change_cipher_state(SSL *s, int which) * In here I set both the read and write key/iv to the same value * since only the correct one will be used :-). */ - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, key, j); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, key, j) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } key = &(exp_key[0]); if (k > 0) { - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } iv = &(exp_iv[0]); } } + EVP_MD_CTX_cleanup(&md); s->session->key_arg_length = 0; - EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) + goto err2; #ifdef OPENSSL_SSL_TRACE_CRYPTO if (s->msg_callback) { @@ -399,7 +415,6 @@ int ssl3_change_cipher_state(SSL *s, int which) OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); - EVP_MD_CTX_cleanup(&md); return (1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); @@ -555,17 +570,20 @@ int ssl3_enc(SSL *s, int send) if ((bs != 1) && !send) return ssl3_cbc_remove_padding(s, rec, bs, mac_size); } - return (1); + return 1; } -void ssl3_init_finished_mac(SSL *s) +int ssl3_init_finished_mac(SSL *s) { if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer); if (s->s3->handshake_dgst) ssl3_free_digest_list(s); s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + if (s->s3->handshake_buffer == NULL) + return 0; (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + return 1; } void ssl3_free_digest_list(SSL *s) @@ -622,6 +640,10 @@ int ssl3_digest_cached_records(SSL *s) for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { if ((mask & ssl_get_algorithm2(s)) && md) { s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); + if (s->s3->handshake_dgst[i] == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } #ifdef OPENSSL_FIPS if (EVP_MD_nid(md) == NID_md5) { EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], @@ -903,7 +925,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, s, s->msg_callback_arg); } #endif - OPENSSL_cleanse(buf, sizeof buf); + OPENSSL_cleanse(buf, sizeof(buf)); return (ret); } diff --git a/crypto/openssl/ssl/s3_lib.c b/crypto/openssl/ssl/s3_lib.c index 0385e039c8d4..1014a3fce16f 100644 --- a/crypto/openssl/ssl/s3_lib.c +++ b/crypto/openssl/ssl/s3_lib.c @@ -4237,7 +4237,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) return (int)s->cert->ctype_num; } /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, &sig); + siglen = tls12_get_psigalgs(s, 1, &sig); if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) nostrict = 0; for (i = 0; i < siglen; i += 2, sig += 2) { diff --git a/crypto/openssl/ssl/s3_pkt.c b/crypto/openssl/ssl/s3_pkt.c index 6ece87d0628c..0290c991d810 100644 --- a/crypto/openssl/ssl/s3_pkt.c +++ b/crypto/openssl/ssl/s3_pkt.c @@ -670,7 +670,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * promptly send beyond the end of the users buffer ... so we trap and * report the error in a way the user will notice */ - if (len < tot) { + if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); return (-1); } @@ -699,6 +699,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && s->compress == NULL && s->msg_callback == NULL && SSL_USE_EXPLICIT_IV(s) && + s->enc_write_ctx != NULL && EVP_CIPHER_flags(s->enc_write_ctx->cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { unsigned char aad[13]; diff --git a/crypto/openssl/ssl/s3_srvr.c b/crypto/openssl/ssl/s3_srvr.c index ea56f9ca8150..ba17f1b56281 100644 --- a/crypto/openssl/ssl/s3_srvr.c +++ b/crypto/openssl/ssl/s3_srvr.c @@ -311,7 +311,12 @@ int ssl3_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -348,7 +353,11 @@ int ssl3_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -1704,6 +1713,12 @@ int ssl3_send_server_key_exchange(SSL *s) if (type & SSL_kEECDH) { const EC_GROUP *group; + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + ecdhp = cert->ecdh_tmp; if (s->cert->ecdh_tmp_auto) { /* Get NID of appropriate shared curve */ @@ -1724,17 +1739,7 @@ int ssl3_send_server_key_exchange(SSL *s) goto f_err; } - if (s->s3->tmp.ecdh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - /* Duplicate the ECDH structure. */ - if (ecdhp == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } if (s->cert->ecdh_tmp_auto) ecdh = ecdhp; else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { @@ -2084,7 +2089,7 @@ int ssl3_send_certificate_request(SSL *s) if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; - nl = tls12_get_psigalgs(s, &psigs); + nl = tls12_get_psigalgs(s, 1, &psigs); s2n(nl, p); memcpy(p, psigs, nl); p += nl; @@ -3018,6 +3023,11 @@ int ssl3_get_cert_verify(SSL *s) peer = s->session->peer; pkey = X509_get_pubkey(peer); + if (pkey == NULL) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + type = X509_certificate_type(peer, pkey); if (!(type & EVP_PKT_SIGN)) { @@ -3154,7 +3164,9 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } if (i != 64) { +#ifdef SSL_DEBUG fprintf(stderr, "GOST signature length is %d", i); +#endif } for (idx = 0; idx < 64; idx++) { signature[63 - idx] = p[idx]; @@ -3463,8 +3475,22 @@ int ssl3_send_newsession_ticket(SSL *s) * 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) + /* if 0 is returned, write en empty ticket */ + int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1); + + if (ret == 0) { + l2n(0, p); /* timeout */ + s2n(0, p); /* length */ + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, + p - ssl_handshake_start(s)); + s->state = SSL3_ST_SW_SESSION_TICKET_B; + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return ssl_do_write(s); + } + if (ret < 0) goto err; } else { if (RAND_bytes(iv, 16) <= 0) diff --git a/crypto/openssl/ssl/ssl_cert.c b/crypto/openssl/ssl/ssl_cert.c index 1be6fb0032e2..155728d03772 100644 --- a/crypto/openssl/ssl/ssl_cert.c +++ b/crypto/openssl/ssl/ssl_cert.c @@ -412,6 +412,7 @@ CERT *ssl_cert_dup(CERT *cert) #endif ssl_cert_clear_certs(ret); + OPENSSL_free(ret); return NULL; } diff --git a/crypto/openssl/ssl/ssl_ciph.c b/crypto/openssl/ssl/ssl_ciph.c index 2ad8f4392236..40021329a936 100644 --- a/crypto/openssl/ssl/ssl_ciph.c +++ b/crypto/openssl/ssl/ssl_ciph.c @@ -2001,7 +2001,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) if (id < 193 || id > 255) { SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); - return 0; + return 1; } MemCheck_off(); @@ -2013,6 +2013,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) } comp->id = id; comp->method = cm; + comp->name = cm->name; load_builtin_compressions(); if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { OPENSSL_free(comp); diff --git a/crypto/openssl/ssl/ssl_lib.c b/crypto/openssl/ssl/ssl_lib.c index f8054dae6b6b..24be376c9fdf 100644 --- a/crypto/openssl/ssl/ssl_lib.c +++ b/crypto/openssl/ssl/ssl_lib.c @@ -1838,13 +1838,21 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, static unsigned long ssl_session_hash(const SSL_SESSION *a) { + const unsigned char *session_id = a->session_id; unsigned long l; + unsigned char tmp_storage[4]; + + if (a->session_id_length < sizeof(tmp_storage)) { + memset(tmp_storage, 0, sizeof(tmp_storage)); + memcpy(tmp_storage, a->session_id, a->session_id_length); + session_id = tmp_storage; + } l = (unsigned long) - ((unsigned int)a->session_id[0]) | - ((unsigned int)a->session_id[1] << 8L) | - ((unsigned long)a->session_id[2] << 16L) | - ((unsigned long)a->session_id[3] << 24L); + ((unsigned long)session_id[0]) | + ((unsigned long)session_id[1] << 8L) | + ((unsigned long)session_id[2] << 16L) | + ((unsigned long)session_id[3] << 24L); return (l); } @@ -3186,6 +3194,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; ocert->alpn_proposed = NULL; ssl->cert->alpn_sent = ocert->alpn_sent; + + if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) + return NULL; #endif ssl_cert_free(ocert); } diff --git a/crypto/openssl/ssl/ssl_locl.h b/crypto/openssl/ssl/ssl_locl.h index d50edd18c916..aeffc0063471 100644 --- a/crypto/openssl/ssl/ssl_locl.h +++ b/crypto/openssl/ssl/ssl_locl.h @@ -1158,7 +1158,7 @@ long ssl2_default_timeout(void); const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -void ssl3_init_finished_mac(SSL *s); +int ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); int ssl3_send_newsession_ticket(SSL *s); int ssl3_send_cert_status(SSL *s); @@ -1430,7 +1430,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, long ssl_get_algorithm2(SSL *s); int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); int tls1_process_sigalgs(SSL *s); -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs); +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, const unsigned char *sig, EVP_PKEY *pkey); void ssl_set_client_disabled(SSL *s); @@ -1482,6 +1482,8 @@ int custom_ext_add(SSL *s, int server, unsigned char **pret, unsigned char *limit, int *al); int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src); void custom_exts_free(custom_ext_methods *exts); # else diff --git a/crypto/openssl/ssl/ssl_rsa.c b/crypto/openssl/ssl/ssl_rsa.c index f679801a297c..af03d45c2e9a 100644 --- a/crypto/openssl/ssl/ssl_rsa.c +++ b/crypto/openssl/ssl/ssl_rsa.c @@ -964,6 +964,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) int ret = 0; BIO *bin = NULL; size_t num_extensions = 0; + unsigned char *new_serverinfo; if (ctx == NULL || file == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, @@ -1014,12 +1015,13 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) goto end; } /* Append the decoded extension to the serverinfo buffer */ - serverinfo = + new_serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); - if (serverinfo == NULL) { + if (new_serverinfo == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); goto end; } + serverinfo = new_serverinfo; memcpy(serverinfo + serverinfo_length, extension, extension_length); serverinfo_length += extension_length; diff --git a/crypto/openssl/ssl/ssl_sess.c b/crypto/openssl/ssl/ssl_sess.c index c3369a44aea7..f50f5142126f 100644 --- a/crypto/openssl/ssl/ssl_sess.c +++ b/crypto/openssl/ssl/ssl_sess.c @@ -1006,7 +1006,8 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, return 0; } s->sid_ctx_length = sid_ctx_len; - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + if (s->sid_ctx != sid_ctx) + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); return 1; } diff --git a/crypto/openssl/ssl/ssltest.c b/crypto/openssl/ssl/ssltest.c index 890e47685350..b75cac61fbdc 100644 --- a/crypto/openssl/ssl/ssltest.c +++ b/crypto/openssl/ssl/ssltest.c @@ -311,6 +311,10 @@ static const char *sn_client; static const char *sn_server1; static const char *sn_server2; static int sn_expect = 0; +static int s_ticket1 = 0; +static int s_ticket2 = 0; +static int c_ticket = 0; +static int ticket_expect = -1; static int servername_cb(SSL *s, int *ad, void *arg) { @@ -325,6 +329,9 @@ static int servername_cb(SSL *s, int *ad, void *arg) !strcasecmp(servername, sn_server2)) { BIO_printf(bio_stdout, "Switching server context.\n"); SSL_set_SSL_CTX(s, s_ctx2); + /* Copy over all the SSL_CTX options */ + SSL_clear_options(s, 0xFFFFFFFFL); + SSL_set_options(s, SSL_CTX_get_options(s_ctx2)); } } return SSL_TLSEXT_ERR_OK; @@ -349,6 +356,21 @@ static int verify_servername(SSL *client, SSL *server) return -1; } +static int verify_ticket(SSL* ssl) +{ + if (ticket_expect == -1) + return 0; + if (ticket_expect == 0 && + (ssl->session->tlsext_tick == NULL || + ssl->session->tlsext_ticklen == 0)) + return 1; + if (ticket_expect == 1 && + (ssl->session->tlsext_tick != NULL && + ssl->session->tlsext_ticklen != 0)) + return 1; + return -1; +} + /*- * next_protos_parse parses a comma separated list of strings into a string * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. @@ -477,6 +499,42 @@ static int verify_alpn(SSL *client, SSL *server) return -1; } +#ifndef OPENSSL_NO_TLSEXT + +static int cb_ticket0(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + return 0; +} + +static int cb_ticket1(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + static unsigned char key[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + static char name[] = "ticket11ticket11"; + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + if (enc) { + RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH); + EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + HMAC_Init_ex(hctx, key, sizeof(key), EVP_sha1(), NULL); + memcpy(key_name, name, 16); + return 1; + } else { + if (memcmp(key_name, name, 16) == 0) { + EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + HMAC_Init_ex(hctx, key, sizeof(key), EVP_sha1(), NULL); + return 1; + } + } + return 0; +} + +static int cb_ticket2(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + fprintf(stderr, "ticket callback for SNI context should never be called\n"); + EXIT(1); +} +#endif + #define SCT_EXT_TYPE 18 /* @@ -820,6 +878,12 @@ static void sv_usage(void) fprintf(stderr, " -sn_server2 <string> - have server context 2 respond to this servername\n"); fprintf(stderr, " -sn_expect1 - expected server 1\n"); fprintf(stderr, " -sn_expect2 - expected server 2\n"); +#ifndef OPENSSL_NO_TLSEXT + fprintf(stderr, " -s_ticket1 <yes|no|broken> - enable/disable session tickets on context 1\n"); + fprintf(stderr, " -s_ticket2 <yes|no> - enable/disable session tickets on context 2\n"); + fprintf(stderr, " -c_ticket <yes|no> - enable/disable session tickets on the client\n"); + fprintf(stderr, " -ticket_expect <yes|no> - indicate that the client should (or should not) have a ticket\n"); +#endif } static void print_details(SSL *c_ssl, const char *prefix) @@ -1175,13 +1239,21 @@ int main(int argc, char *argv[]) } else if (strcmp(*argv, "-time") == 0) { print_time = 1; } -#ifndef OPENSSL_NO_COMP else if (strcmp(*argv, "-zlib") == 0) { +#ifndef OPENSSL_NO_COMP comp = COMP_ZLIB; +#else + fprintf(stderr, + "ignoring -zlib, since I'm compiled without COMP\n"); +#endif } else if (strcmp(*argv, "-rle") == 0) { +#ifndef OPENSSL_NO_COMP comp = COMP_RLE; - } +#else + fprintf(stderr, + "ignoring -rle, since I'm compiled without COMP\n"); #endif + } else if (strcmp(*argv, "-named_curve") == 0) { if (--argc < 1) goto bad; @@ -1241,6 +1313,36 @@ int main(int argc, char *argv[]) sn_expect = 1; } else if (strcmp(*argv, "-sn_expect2") == 0) { sn_expect = 2; +#ifndef OPENSSL_NO_TLSEXT + } else if (strcmp(*argv, "-s_ticket1") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + s_ticket1 = 1; + if (strcmp(*argv, "broken") == 0) + s_ticket1 = 2; + } else if (strcmp(*argv, "-s_ticket2") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + s_ticket2 = 1; + } else if (strcmp(*argv, "-c_ticket") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + c_ticket = 1; + } else if (strcmp(*argv, "-ticket_expect") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + ticket_expect = 1; + else if (strcmp(*argv, "no") == 0) + ticket_expect = 0; +#endif } else { fprintf(stderr, "unknown option %s\n", *argv); badop = 1; @@ -1679,6 +1781,24 @@ int main(int argc, char *argv[]) if (sn_server1 || sn_server2) SSL_CTX_set_tlsext_servername_callback(s_ctx, servername_cb); +#ifndef OPENSSL_NO_TLSEXT + if (s_ticket1 == 0) + SSL_CTX_set_options(s_ctx, SSL_OP_NO_TICKET); + /* always set the callback */ + if (s_ticket1 == 2) + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx, cb_ticket0); + else + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx, cb_ticket1); + + if (!s_ticket2) + SSL_CTX_set_options(s_ctx2, SSL_OP_NO_TICKET); + /* always set the callback - this should never be called */ + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx2, cb_ticket2); + + if (!c_ticket) + SSL_CTX_set_options(c_ctx, SSL_OP_NO_TICKET); +#endif + c_ssl = SSL_new(c_ctx); s_ssl = SSL_new(s_ctx); @@ -1742,6 +1862,8 @@ int main(int argc, char *argv[]) ret = 1; if (verify_servername(c_ssl, s_ssl) < 0) ret = 1; + if (verify_ticket(c_ssl) < 0) + ret = 1; SSL_free(s_ssl); SSL_free(c_ssl); diff --git a/crypto/openssl/ssl/t1_ext.c b/crypto/openssl/ssl/t1_ext.c index 79ed946a5142..0f4aba0226b4 100644 --- a/crypto/openssl/ssl/t1_ext.c +++ b/crypto/openssl/ssl/t1_ext.c @@ -179,6 +179,25 @@ int custom_ext_add(SSL *s, int server, return 1; } +/* Copy the flags from src to dst for any extensions that exist in both */ +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src) +{ + size_t i; + custom_ext_method *methsrc = src->meths; + + for (i = 0; i < src->meths_count; i++, methsrc++) { + custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); + + if (methdst == NULL) + continue; + + methdst->ext_flags = methsrc->ext_flags; + } + + return 1; +} + /* Copy table of custom extensions */ int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) { @@ -223,16 +242,14 @@ static int custom_ext_meth_add(custom_ext_methods *exts, /* Search for duplicate */ if (custom_ext_find(exts, ext_type)) return 0; - exts->meths = OPENSSL_realloc(exts->meths, - (exts->meths_count + - 1) * sizeof(custom_ext_method)); - - if (!exts->meths) { - exts->meths_count = 0; + meth = OPENSSL_realloc(exts->meths, + (exts->meths_count + 1) + * sizeof(custom_ext_method)); + if (meth == NULL) return 0; - } - meth = exts->meths + exts->meths_count; + exts->meths = meth; + meth += exts->meths_count; memset(meth, 0, sizeof(custom_ext_method)); meth->parse_cb = parse_cb; meth->add_cb = add_cb; diff --git a/crypto/openssl/ssl/t1_lib.c b/crypto/openssl/ssl/t1_lib.c index e60c88bd5b27..6587e8bb685c 100644 --- a/crypto/openssl/ssl/t1_lib.c +++ b/crypto/openssl/ssl/t1_lib.c @@ -1035,7 +1035,7 @@ static unsigned char suiteb_sigalgs[] = { tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) }; # endif -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other @@ -1057,7 +1057,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) } # endif /* If server use client authentication sigalgs if not NULL */ - if (s->server && s->cert->client_sigalgs) { + if (s->server == sent && s->cert->client_sigalgs) { *psigs = s->cert->client_sigalgs; return s->cert->client_sigalgslen; } else if (s->cert->conf_sigalgs) { @@ -1121,7 +1121,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, # endif /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); + sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) break; @@ -1169,7 +1169,7 @@ void ssl_set_client_disabled(SSL *s) * Now go through all signature algorithms seeing if we support any for * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. */ - sigalgslen = tls12_get_psigalgs(s, &sigalgs); + sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { switch (sigalgs[1]) { # ifndef OPENSSL_NO_RSA @@ -1440,7 +1440,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (SSL_CLIENT_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; - salglen = tls12_get_psigalgs(s, &salg); + salglen = tls12_get_psigalgs(s, 1, &salg); /*- * check for enough space. @@ -1769,6 +1769,9 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, return NULL; s2n(TLSEXT_TYPE_session_ticket, ret); s2n(0, ret); + } else { + /* if we don't add the above TLSEXT, we can't add a session ticket later */ + s->tlsext_ticket_expected = 0; } if (s->tlsext_status_expected) { @@ -3574,8 +3577,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, p = sdec; sess = d2i_SSL_SESSION(NULL, &p, slen); + slen -= p - sdec; OPENSSL_free(sdec); if (sess) { + /* Some additional consistency checks */ + if (slen != 0 || sess->session_id_length != 0) { + SSL_SESSION_free(sess); + return 2; + } /* * The session ID, if non-empty, is used by some clients to detect * that the ticket has been accepted. So we copy it to the session @@ -3803,7 +3812,7 @@ static int tls1_set_shared_sigalgs(SSL *s) conf = c->conf_sigalgs; conflen = c->conf_sigalgslen; } else - conflen = tls12_get_psigalgs(s, &conf); + conflen = tls12_get_psigalgs(s, 0, &conf); if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; |