From d7c42d71ba407a4b3c26ed58263ae225976bbac3 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Tue, 1 Nov 2016 14:09:19 +0000 Subject: [PATCH] Add processing of the key_share received in the ServerHello Reviewed-by: Rich Salz --- include/openssl/ssl.h | 1 + ssl/ssl_err.c | 1 + ssl/t1_lib.c | 56 +++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index dab0c4ee38..fdef8c54e3 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2313,6 +2313,7 @@ int ERR_load_SSL_strings(void); # define SSL_R_BAD_ECPOINT 306 # define SSL_R_BAD_HANDSHAKE_LENGTH 332 # define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_KEY_SHARE 108 # define SSL_R_BAD_LENGTH 271 # define SSL_R_BAD_PACKET_LENGTH 115 # define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 7523f1c76f..fcd4375c24 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -342,6 +342,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = { {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"}, {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"}, {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"}, + {ERR_REASON(SSL_R_BAD_KEY_SHARE), "bad key share"}, {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"}, {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"}, {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 11c8399a28..f87b7ef1ea 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -2637,12 +2637,64 @@ static int ssl_scan_serverhello_tlsext(SSL *s, PACKET *pkt, int *al) s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS; if (!s->hit) s->session->flags |= SSL_SESS_FLAG_EXTMS; - } + } else if (type == TLSEXT_TYPE_key_share + && s->version == TLS1_3_VERSION) { + unsigned int group_id; + PACKET encoded_pt; + EVP_PKEY *ckey = s->s3->tmp.pkey, *skey = NULL; + + /* Sanity check */ + if (ckey == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!PACKET_get_net_2(&spkt, &group_id)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, + SSL_R_LENGTH_MISMATCH); + return 0; + } + + if (group_id != s->s3->group_id) { + /* + * This isn't for the group that we sent in the original + * key_share! + */ + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, + SSL_R_BAD_KEY_SHARE); + return 0; + } + + /* TODO(TLS1.3): Create skey from ckey */ + skey = ssl_generate_pkey(ckey); + + if (!PACKET_as_length_prefixed_2(&spkt, &encoded_pt)) { + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, + SSL_R_LENGTH_MISMATCH); + return 0; + } + + if (!EVP_PKEY_set1_tls_encodedpoint(skey, PACKET_data(&encoded_pt), + PACKET_remaining(&encoded_pt))) { + *al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL_SCAN_SERVERHELLO_TLSEXT, SSL_R_BAD_ECPOINT); + return 0; + } + + /* + * TODO(TLS1.3): Throw it all away for now, later we will use the + * two keys. + */ + EVP_PKEY_free(skey); /* * If this extension type was not otherwise handled, but matches a * custom_cli_ext_record, then send it to the c callback */ - else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) + } else if (custom_ext_parse(s, 0, type, data, size, al) <= 0) return 0; } -- 2.25.1