diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2017-06-16 19:23:47 +0100 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2017-06-21 14:11:01 +0100 |
commit | 72ceb6a6923456d9ff036cd81014024cf54280c4 (patch) | |
tree | a9fe2515e748b253980c8631d60344b17ecb99d3 | |
parent | 03327c8bf2af2db937a7d39268ea70ab90819279 (diff) |
Convert key exchange to one shot call
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/3585)
-rw-r--r-- | ssl/statem/statem_clnt.c | 27 | ||||
-rw-r--r-- | ssl/statem/statem_lib.c | 18 | ||||
-rw-r--r-- | ssl/statem/statem_locl.h | 2 | ||||
-rw-r--r-- | ssl/statem/statem_srvr.c | 27 |
4 files changed, 51 insertions, 23 deletions
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 9629c1068a..46439359fb 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2170,6 +2170,9 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) PACKET params; int maxsig; const EVP_MD *md = NULL; + unsigned char *tbs; + size_t tbslen; + int rv; /* * |pkt| now points to the beginning of the signature, so the difference @@ -2185,7 +2188,6 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) if (SSL_USE_SIGALGS(s)) { unsigned int sigalg; - int rv; if (!PACKET_get_net_2(pkt, &sigalg)) { al = SSL_AD_DECODE_ERROR; @@ -2255,19 +2257,22 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; } } - if (EVP_DigestVerifyUpdate(md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestVerifyUpdate(md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestVerifyUpdate(md_ctx, PACKET_data(¶ms), - PACKET_remaining(¶ms)) <= 0) { + tbslen = construct_key_exchange_tbs(s, &tbs, PACKET_data(¶ms), + PACKET_remaining(¶ms)); + if (tbslen == 0) { al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); goto err; } - if (EVP_DigestVerifyFinal(md_ctx, PACKET_data(&signature), - PACKET_remaining(&signature)) <= 0) { - /* bad signature */ + + rv = EVP_DigestVerify(md_ctx, PACKET_data(&signature), + PACKET_remaining(&signature), tbs, tbslen); + OPENSSL_free(tbs); + if (rv < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB); + goto err; + } else if (rv == 0) { al = SSL_AD_DECRYPT_ERROR; SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); goto err; diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 539cc71521..abdeb56a30 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -2132,3 +2132,21 @@ int construct_ca_names(SSL *s, WPACKET *pkt) return 1; } + +/* Create a buffer containing data to be signed for server key exchange */ +size_t construct_key_exchange_tbs(const SSL *s, unsigned char **ptbs, + const void *param, size_t paramlen) +{ + size_t tbslen = 2 * SSL3_RANDOM_SIZE + paramlen; + unsigned char *tbs = OPENSSL_malloc(tbslen); + + if (tbs == NULL) + return 0; + memcpy(tbs, s->s3->client_random, SSL3_RANDOM_SIZE); + memcpy(tbs + SSL3_RANDOM_SIZE, s->s3->server_random, SSL3_RANDOM_SIZE); + + memcpy(tbs + SSL3_RANDOM_SIZE * 2, param, paramlen); + + *ptbs = tbs; + return tbslen; +} diff --git a/ssl/statem/statem_locl.h b/ssl/statem/statem_locl.h index 673822a7c5..b6ce4cc965 100644 --- a/ssl/statem/statem_locl.h +++ b/ssl/statem/statem_locl.h @@ -63,6 +63,8 @@ int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups, int create_synthetic_message_hash(SSL *s); int parse_ca_names(SSL *s, PACKET *pkt, int *al); int construct_ca_names(SSL *s, WPACKET *pkt); +size_t construct_key_exchange_tbs(const SSL *s, unsigned char **ptbs, + const void *param, size_t paramlen); /* * TLS/DTLS client state machine functions diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 1cde8c83d2..6168b98ede 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2410,9 +2410,10 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) /* not anonymous */ if (lu != NULL) { EVP_PKEY *pkey = s->s3->tmp.cert->privatekey; - const EVP_MD *md = ssl_md(lu->hash_idx); - unsigned char *sigbytes1, *sigbytes2; - size_t siglen; + const EVP_MD *md; + unsigned char *sigbytes1, *sigbytes2, *tbs; + size_t siglen, tbslen; + int rv; if (pkey == NULL || md == NULL) { /* Should never happen */ @@ -2456,15 +2457,17 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) goto f_err; } } - if (EVP_DigestSignUpdate(md_ctx, &(s->s3->client_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestSignUpdate(md_ctx, &(s->s3->server_random[0]), - SSL3_RANDOM_SIZE) <= 0 - || EVP_DigestSignUpdate(md_ctx, - s->init_buf->data + paramoffset, - paramlen) <= 0 - || EVP_DigestSignFinal(md_ctx, sigbytes1, &siglen) <= 0 - || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) + tbslen = construct_key_exchange_tbs(s, &tbs, + s->init_buf->data + paramoffset, + paramlen); + if (tbslen == 0) { + SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto f_err; + } + rv = EVP_DigestSign(md_ctx, sigbytes1, &siglen, tbs, tbslen); + OPENSSL_free(tbs); + if (rv <= 0 || !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2) || sigbytes1 != sigbytes2) { SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); |