Add processing of the key_share received in the ServerHello Reviewed-by: Rich Salz <rsalz@openssl.org>
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index 7523f1c..fcd4375 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c
@@ -342,6 +342,7 @@ {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 11c8399..f87b7ef 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c
@@ -2637,12 +2637,64 @@ 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; }