summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2017-06-16 19:23:47 +0100
committerDr. Stephen Henson <steve@openssl.org>2017-06-21 14:11:01 +0100
commit72ceb6a6923456d9ff036cd81014024cf54280c4 (patch)
treea9fe2515e748b253980c8631d60344b17ecb99d3
parent03327c8bf2af2db937a7d39268ea70ab90819279 (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.c27
-rw-r--r--ssl/statem/statem_lib.c18
-rw-r--r--ssl/statem/statem_locl.h2
-rw-r--r--ssl/statem/statem_srvr.c27
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(&params),
- PACKET_remaining(&params)) <= 0) {
+ tbslen = construct_key_exchange_tbs(s, &tbs, PACKET_data(&params),
+ PACKET_remaining(&params));
+ 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);