diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 46e76e33c8b0aa2c47885b947047d66b3a6a6d42..a8f5637be5a6545376d417e02f8da9e436f68c8a 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -4621,6 +4621,43 @@ EVP_PKEY *ssl_generate_pkey_group(uint16_t id) EVP_PKEY_CTX_free(pctx); return pkey; } + +/* + * Generate parameters from a group ID + */ +EVP_PKEY *ssl_generate_param_group(uint16_t id) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + const TLS_GROUP_INFO *ginf = tls1_group_id_lookup(id); + + if (ginf == NULL) + goto err; + + if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { + pkey = EVP_PKEY_new(); + if (pkey != NULL && EVP_PKEY_set_type(pkey, ginf->nid)) + return pkey; + EVP_PKEY_free(pkey); + return NULL; + } + + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); + if (pctx == NULL) + goto err; + if (EVP_PKEY_paramgen_init(pctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0) + goto err; + if (EVP_PKEY_paramgen(pctx, &pkey) <= 0) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + + err: + EVP_PKEY_CTX_free(pctx); + return pkey; +} #endif /* Derive secrets for ECDH/DH */ diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 029372e41e325caf14674162305a3c578de667e0..dc4a0f4701c94c5cba27d1f23f639cc578ef1009 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -2351,6 +2351,7 @@ void tls1_get_formatlist(SSL *s, const unsigned char **pformats, size_t *num_formats); __owur int tls1_check_ec_tmp_key(SSL *s, unsigned long id); __owur EVP_PKEY *ssl_generate_pkey_group(uint16_t id); +__owur EVP_PKEY *ssl_generate_param_group(uint16_t id); # endif /* OPENSSL_NO_EC */ __owur int tls_curve_allowed(SSL *s, uint16_t curve, int op); diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 5fb0d05a2a1781c7da28d2bc159e838e3949d183..ebae44899a1952ce559fef56d09cfcfde70a60fa 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -502,7 +502,6 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, const uint16_t *clntcurves, *srvrcurves; size_t clnt_num_curves, srvr_num_curves; int found = 0; - const TLS_GROUP_INFO *ginf; if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) return 1; @@ -575,43 +574,13 @@ int tls_parse_ctos_key_share(SSL *s, PACKET *pkt, unsigned int context, X509 *x, continue; } - ginf = tls1_group_id_lookup(group_id); - - if (ginf == NULL) { + if ((s->s3->peer_tmp = ssl_generate_param_group(group_id)) == NULL) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } - if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { - /* Can happen for some curves, e.g. X25519 */ - EVP_PKEY *key = EVP_PKEY_new(); - - if (key == NULL || !EVP_PKEY_set_type(key, ginf->nid)) { - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB); - EVP_PKEY_free(key); - return 0; - } - s->s3->peer_tmp = key; - } else { - /* Set up EVP_PKEY with named curve as parameters */ - EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); - - if (pctx == NULL - || EVP_PKEY_paramgen_init(pctx) <= 0 - || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, - ginf->nid) <= 0 - || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) { - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PARSE_CTOS_KEY_SHARE, ERR_R_EVP_LIB); - EVP_PKEY_CTX_free(pctx); - return 0; - } - EVP_PKEY_CTX_free(pctx); - pctx = NULL; - } s->s3->group_id = group_id; if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp, diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index a20bf005932f0cf38ad22048bd9502a474159a8f..833450babd17607e24b96c3d0545f5d256b165fc 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2041,8 +2041,6 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) #ifndef OPENSSL_NO_EC PACKET encoded_pt; const unsigned char *ecparams; - const TLS_GROUP_INFO *ginf; - EVP_PKEY_CTX *pctx = NULL; /* * Extract elliptic curve parameters and the server's ephemeral ECDH @@ -2064,41 +2062,13 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al) return 0; } - ginf = tls1_group_id_lookup(ecparams[2]); - - if (ginf == NULL) { + if ((s->s3->peer_tmp = ssl_generate_param_group(ecparams[2])) == NULL) { *al = SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); return 0; } - if ((ginf->flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) { - EVP_PKEY *key = EVP_PKEY_new(); - - if (key == NULL || !EVP_PKEY_set_type(key, ginf->nid)) { - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB); - EVP_PKEY_free(key); - return 0; - } - s->s3->peer_tmp = key; - } else { - /* Set up EVP_PKEY with named curve as parameters */ - pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL); - if (pctx == NULL - || EVP_PKEY_paramgen_init(pctx) <= 0 - || EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ginf->nid) <= 0 - || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) { - *al = SSL_AD_INTERNAL_ERROR; - SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, ERR_R_EVP_LIB); - EVP_PKEY_CTX_free(pctx); - return 0; - } - EVP_PKEY_CTX_free(pctx); - pctx = NULL; - } - if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) { *al = SSL_AD_DECODE_ERROR; SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_LENGTH_MISMATCH);