#ifndef OPENSSL_NO_EC
EVP_PKEY_free(s->s3->tmp.pkey);
s->s3->tmp.pkey = NULL;
- EC_KEY_free(s->s3->peer_ecdh_tmp);
+ EVP_PKEY_free(s->s3->peer_tmp);
+ s->s3->peer_tmp = NULL;
#endif
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
#ifndef OPENSSL_NO_EC
EVP_PKEY_free(s->s3->tmp.pkey);
s->s3->tmp.pkey = NULL;
- EC_KEY_free(s->s3->peer_ecdh_tmp);
- s->s3->peer_ecdh_tmp = NULL;
+ EVP_PKEY_free(s->s3->peer_tmp);
+ s->s3->peer_tmp = NULL;
s->s3->is_probably_safari = 0;
#endif /* !OPENSSL_NO_EC */
EVP_PKEY *ptmp;
int rv = 0;
#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_EC)
- if (!s->s3->peer_dh_tmp && !s->s3->peer_ecdh_tmp)
+ if (s->s3->peer_dh_tmp == NULL && s->s3->peer_tmp == NULL)
return 0;
#endif
ptmp = EVP_PKEY_new();
if (ptmp == NULL)
return 0;
#ifndef OPENSSL_NO_DH
- else if (s->s3->peer_dh_tmp)
+ else if (s->s3->peer_dh_tmp != NULL)
rv = EVP_PKEY_set1_DH(ptmp, s->s3->peer_dh_tmp);
#endif
#ifndef OPENSSL_NO_EC
- else if (s->s3->peer_ecdh_tmp)
- rv = EVP_PKEY_set1_EC_KEY(ptmp, s->s3->peer_ecdh_tmp);
+ else if (s->s3->peer_tmp != NULL)
+ rv = EVP_PKEY_set1_EC_KEY(ptmp,
+ EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp));
#endif
if (rv) {
*(EVP_PKEY **)parg = ptmp;
DH *dh = NULL;
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY *ecdh = NULL;
- int curve_nid = 0;
+ EVP_PKEY_CTX *pctx = NULL;
#endif
PACKET save_param_start, signature;
s->s3->peer_dh_tmp = NULL;
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY_free(s->s3->peer_ecdh_tmp);
- s->s3->peer_ecdh_tmp = NULL;
+ EVP_PKEY_free(s->s3->peer_tmp);
+ s->s3->peer_tmp = NULL;
#endif
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
PACKET encoded_pt;
unsigned char *ecparams;
+ int curve_nid;
/*
* Extract elliptic curve parameters and the server's ephemeral ECDH
goto f_err;
}
- if ((curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2))) == 0) {
+ curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2));
+ if (curve_nid == 0) {
al = SSL_AD_INTERNAL_ERROR;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE,
SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
goto f_err;
}
- ecdh = EC_KEY_new_by_curve_name(curve_nid);
-
- if (ecdh == NULL) {
- SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
+ /* 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, curve_nid) <= 0
+ || EVP_PKEY_paramgen(pctx, &s->s3->peer_tmp) <= 0) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, ERR_R_EVP_LIB);
+ goto f_err;
}
+ EVP_PKEY_CTX_free(pctx);
+ pctx = NULL;
if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
goto f_err;
}
- if (EC_KEY_oct2key(ecdh, PACKET_data(&encoded_pt),
+ if (EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp),
+ PACKET_data(&encoded_pt),
PACKET_remaining(&encoded_pt), NULL) == 0) {
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
goto f_err;
pkey = X509_get_pubkey(s->session->peer);
# endif
/* else anonymous ECDH, so no certificate or pkey. */
- s->s3->peer_ecdh_tmp = ecdh;
- ecdh = NULL;
} else if (alg_k) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_TLS_PROCESS_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
DH_free(dh);
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY_free(ecdh);
+ EVP_PKEY_CTX_free(pctx);
#endif
EVP_MD_CTX_free(md_ctx);
ossl_statem_set_error(s);
EVP_PKEY *pkey = NULL;
#endif
#ifndef OPENSSL_NO_EC
- EC_KEY *clnt_ecdh = NULL;
- const EC_POINT *srvr_ecpoint = NULL;
- EVP_PKEY *srvr_pub_pkey = NULL;
+ EVP_PKEY *ckey = NULL, *skey = NULL;
unsigned char *encodedPoint = NULL;
int encoded_pt_len = 0;
#endif
#ifndef OPENSSL_NO_EC
else if (alg_k & (SSL_kECDHE | SSL_kECDHr | SSL_kECDHe | SSL_kECDHEPSK)) {
- const EC_GROUP *srvr_group = NULL;
- EC_KEY *tkey;
- int field_size = 0;
- if (s->s3->peer_ecdh_tmp != NULL) {
- tkey = s->s3->peer_ecdh_tmp;
+ if (s->s3->peer_tmp != NULL) {
+ skey = s->s3->peer_tmp;
} else {
/* Get the Server Public Key from Cert */
- srvr_pub_pkey = X509_get_pubkey(s->session->peer);
- if ((srvr_pub_pkey == NULL)
- || (srvr_pub_pkey->type != EVP_PKEY_EC)
- || (srvr_pub_pkey->pkey.ec == NULL)) {
+ skey = X509_get0_pubkey(s->session->peer);
+ if ((skey == NULL)
+ || (skey->type != EVP_PKEY_EC)
+ || (skey->pkey.ec == NULL)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
goto err;
}
-
- tkey = srvr_pub_pkey->pkey.ec;
}
- srvr_group = EC_KEY_get0_group(tkey);
- srvr_ecpoint = EC_KEY_get0_public_key(tkey);
-
- if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ ckey = ssl_generate_pkey(skey, NID_undef);
- if ((clnt_ecdh = EC_KEY_new()) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
+ if (ssl_derive(s, ckey, skey) == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EVP_LIB);
goto err;
}
- if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
- }
- /* Generate a new ECDH key pair */
- if (!(EC_KEY_generate_key(clnt_ecdh))) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
-
- /*
- * use the 'p' output buffer for the ECDH key, but make sure to
- * clear it out afterwards
- */
-
- field_size = EC_GROUP_get_degree(srvr_group);
- if (field_size <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
- pmslen = (field_size + 7) / 8;
- pms = OPENSSL_malloc(pmslen);
- if (pms == NULL)
- goto memerr;
- n = ECDH_compute_key(pms, pmslen, srvr_ecpoint, clnt_ecdh, NULL);
- if (n <= 0 || pmslen != (size_t)n) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
-
- /*
- * First check the size of encoding and allocate memory
- * accordingly.
- */
- encoded_pt_len =
- EC_KEY_key2buf(clnt_ecdh, POINT_CONVERSION_UNCOMPRESSED,
- &encodedPoint, NULL);
+ /* Generate encoding of client key */
+ encoded_pt_len = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(ckey),
+ POINT_CONVERSION_UNCOMPRESSED,
+ &encodedPoint, NULL);
if (encoded_pt_len == 0) {
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
goto err;
}
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
+
n = encoded_pt_len;
*p = n; /* length of encoded point */
/* Free allocated memory */
OPENSSL_free(encodedPoint);
- EC_KEY_free(clnt_ecdh);
- EVP_PKEY_free(srvr_pub_pkey);
}
#endif /* !OPENSSL_NO_EC */
#ifndef OPENSSL_NO_GOST
goto err;
}
- s->s3->tmp.pms = pms;
- s->s3->tmp.pmslen = pmslen;
+ if (pms != NULL) {
+ s->s3->tmp.pms = pms;
+ s->s3->tmp.pmslen = pmslen;
+ }
return 1;
memerr:
s->s3->tmp.pms = NULL;
#ifndef OPENSSL_NO_EC
OPENSSL_free(encodedPoint);
- EC_KEY_free(clnt_ecdh);
- EVP_PKEY_free(srvr_pub_pkey);
+ EVP_PKEY_free(ckey);
#endif
#ifndef OPENSSL_NO_PSK
OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);