Modify TLS support for new X25519 API.
When handling ECDH check to see if the curve is "custom" (X25519 is currently the only curve of this type) and instead of setting a curve NID just allocate a key of appropriate type. Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
parent
3bca6c2731
commit
ec24630ae2
5 changed files with 66 additions and 43 deletions
21
ssl/s3_lib.c
21
ssl/s3_lib.c
|
@ -3090,7 +3090,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
|
|||
unsigned int cid, nid;
|
||||
for (i = 0; i < clistlen; i++) {
|
||||
n2s(clist, cid);
|
||||
nid = tls1_ec_curve_id2nid(cid);
|
||||
nid = tls1_ec_curve_id2nid(cid, NULL);
|
||||
if (nid != 0)
|
||||
cptr[i] = nid;
|
||||
else
|
||||
|
@ -3982,27 +3982,38 @@ int ssl_generate_master_secret(SSL *s, unsigned char *pms, size_t pmslen,
|
|||
return s->session->master_key_length >= 0;
|
||||
}
|
||||
|
||||
/* Generate a private key from parameters or a curve NID */
|
||||
EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int nid)
|
||||
/* Generate a private key from parameters or a curve ID */
|
||||
EVP_PKEY *ssl_generate_pkey(EVP_PKEY *pm, int id)
|
||||
{
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int nid;
|
||||
if (pm != NULL) {
|
||||
pctx = EVP_PKEY_CTX_new(pm, NULL);
|
||||
nid = 0;
|
||||
} else {
|
||||
unsigned int curve_flags;
|
||||
nid = tls1_ec_curve_id2nid(id, &curve_flags);
|
||||
if (nid == 0)
|
||||
goto err;
|
||||
/*
|
||||
* Generate a new key for this curve.
|
||||
* Should not be called if EC is disabled: if it is it will
|
||||
* fail with an unknown algorithm error.
|
||||
*/
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
||||
if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
|
||||
pctx = EVP_PKEY_CTX_new_id(nid, NULL);
|
||||
nid = 0;
|
||||
} else {
|
||||
pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL);
|
||||
}
|
||||
}
|
||||
if (pctx == NULL)
|
||||
goto err;
|
||||
if (EVP_PKEY_keygen_init(pctx) <= 0)
|
||||
goto err;
|
||||
#ifndef OPENSSL_NO_EC
|
||||
if (pm == NULL && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
|
||||
if (nid != 0 && EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, nid) <= 0)
|
||||
goto err;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1987,7 +1987,13 @@ __owur int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
|
|||
SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
|
||||
|
||||
# ifndef OPENSSL_NO_EC
|
||||
__owur int tls1_ec_curve_id2nid(int curve_id);
|
||||
/* Flags values from tls1_ec_curve_id2nid() */
|
||||
/* Mask for curve type */
|
||||
# define TLS_CURVE_TYPE 0x3
|
||||
# define TLS_CURVE_PRIME 0x0
|
||||
# define TLS_CURVE_CHAR2 0x1
|
||||
# define TLS_CURVE_CUSTOM 0x2
|
||||
__owur int tls1_ec_curve_id2nid(int curve_id, unsigned int *pflags);
|
||||
__owur int tls1_ec_nid2curve_id(int nid);
|
||||
__owur int tls1_check_curve(SSL *s, const unsigned char *p, size_t len);
|
||||
__owur int tls1_shared_curve(SSL *s, int nmatch);
|
||||
|
|
|
@ -1497,6 +1497,7 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
|
|||
PACKET encoded_pt;
|
||||
const unsigned char *ecparams;
|
||||
int curve_nid;
|
||||
unsigned int curve_flags;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
|
||||
/*
|
||||
|
@ -1519,7 +1520,8 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
|
|||
return 0;
|
||||
}
|
||||
|
||||
curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2));
|
||||
curve_nid = tls1_ec_curve_id2nid(*(ecparams + 2), &curve_flags);
|
||||
|
||||
if (curve_nid == 0) {
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE,
|
||||
|
@ -1527,19 +1529,31 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* 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_SKE_ECDHE, ERR_R_EVP_LIB);
|
||||
if ((curve_flags & TLS_CURVE_TYPE) == TLS_CURVE_CUSTOM) {
|
||||
EVP_PKEY *key = EVP_PKEY_new();
|
||||
|
||||
if (key == NULL || !EVP_PKEY_set_type(key, curve_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, curve_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);
|
||||
return 0;
|
||||
pctx = NULL;
|
||||
}
|
||||
EVP_PKEY_CTX_free(pctx);
|
||||
pctx = NULL;
|
||||
|
||||
if (!PACKET_get_length_prefixed_1(pkt, &encoded_pt)) {
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
|
@ -1547,9 +1561,9 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey, int *al)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(s->s3->peer_tmp),
|
||||
PACKET_data(&encoded_pt),
|
||||
PACKET_remaining(&encoded_pt), NULL) == 0) {
|
||||
if (!EVP_PKEY_set1_tls_encodedpoint(s->s3->peer_tmp,
|
||||
PACKET_data(&encoded_pt),
|
||||
PACKET_remaining(&encoded_pt))) {
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_TLS_PROCESS_SKE_ECDHE, SSL_R_BAD_ECPOINT);
|
||||
return 0;
|
||||
|
@ -2269,7 +2283,7 @@ static int tls_construct_cke_ecdhe(SSL *s, unsigned char **p, int *len, int *al)
|
|||
EVP_PKEY *ckey = NULL, *skey = NULL;
|
||||
|
||||
skey = s->s3->peer_tmp;
|
||||
if ((skey == NULL) || EVP_PKEY_get0_EC_KEY(skey) == NULL) {
|
||||
if (skey == NULL) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2282,9 +2296,7 @@ static int tls_construct_cke_ecdhe(SSL *s, unsigned char **p, int *len, int *al)
|
|||
}
|
||||
|
||||
/* Generate encoding of client key */
|
||||
encoded_pt_len = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(ckey),
|
||||
POINT_CONVERSION_UNCOMPRESSED,
|
||||
&encodedPoint, NULL);
|
||||
encoded_pt_len = EVP_PKEY_get1_tls_encodedpoint(ckey, &encodedPoint);
|
||||
|
||||
if (encoded_pt_len == 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EC_LIB);
|
||||
|
|
|
@ -1737,7 +1737,7 @@ int tls_construct_server_key_exchange(SSL *s)
|
|||
SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
|
||||
goto err;
|
||||
}
|
||||
s->s3->tmp.pkey = ssl_generate_pkey(NULL, nid);
|
||||
s->s3->tmp.pkey = ssl_generate_pkey(NULL, curve_id);
|
||||
/* Generate a new key for this curve */
|
||||
if (s->s3->tmp.pkey == NULL) {
|
||||
al = SSL_AD_INTERNAL_ERROR;
|
||||
|
@ -1746,10 +1746,8 @@ int tls_construct_server_key_exchange(SSL *s)
|
|||
}
|
||||
|
||||
/* Encode the public key. */
|
||||
encodedlen = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(s->s3->tmp.pkey),
|
||||
POINT_CONVERSION_UNCOMPRESSED,
|
||||
&encodedPoint, NULL);
|
||||
|
||||
encodedlen = EVP_PKEY_get1_tls_encodedpoint(s->s3->tmp.pkey,
|
||||
&encodedPoint);
|
||||
if (encodedlen == 0) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
|
@ -2386,8 +2384,7 @@ static int tls_process_cke_ecdhe(SSL *s, PACKET *pkt, int *al)
|
|||
SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (EC_KEY_oct2key(EVP_PKEY_get0_EC_KEY(ckey), data, i,
|
||||
NULL) == 0) {
|
||||
if (EVP_PKEY_set1_tls_encodedpoint(ckey, data, i) == 0) {
|
||||
*al = SSL_AD_HANDSHAKE_FAILURE;
|
||||
SSLerr(SSL_F_TLS_PROCESS_CKE_ECDHE, ERR_R_EC_LIB);
|
||||
goto err;
|
||||
|
|
19
ssl/t1_lib.c
19
ssl/t1_lib.c
|
@ -121,12 +121,6 @@ typedef struct {
|
|||
unsigned int flags; /* Flags: currently just field type */
|
||||
} tls_curve_info;
|
||||
|
||||
/* Mask for curve type */
|
||||
# define TLS_CURVE_TYPE 0x3
|
||||
# define TLS_CURVE_PRIME 0x0
|
||||
# define TLS_CURVE_CHAR2 0x1
|
||||
# define TLS_CURVE_CUSTOM 0x2
|
||||
|
||||
/*
|
||||
* Table of curve information.
|
||||
* Do not delete entries or reorder this array! It is used as a lookup
|
||||
|
@ -161,8 +155,7 @@ static const tls_curve_info nid_list[] = {
|
|||
{NID_brainpoolP256r1, 128, TLS_CURVE_PRIME}, /* brainpoolP256r1 (26) */
|
||||
{NID_brainpoolP384r1, 192, TLS_CURVE_PRIME}, /* brainpoolP384r1 (27) */
|
||||
{NID_brainpoolP512r1, 256, TLS_CURVE_PRIME}, /* brainpool512r1 (28) */
|
||||
/* X25519 (29) */
|
||||
{NID_X25519, 128, TLS_CURVE_CUSTOM},
|
||||
{NID_X25519, 128, TLS_CURVE_CUSTOM}, /* X25519 (29) */
|
||||
};
|
||||
|
||||
static const unsigned char ecformats_default[] = {
|
||||
|
@ -222,12 +215,16 @@ static const unsigned char suiteb_curves[] = {
|
|||
0, TLSEXT_curve_P_384
|
||||
};
|
||||
|
||||
int tls1_ec_curve_id2nid(int curve_id)
|
||||
int tls1_ec_curve_id2nid(int curve_id, unsigned int *pflags)
|
||||
{
|
||||
const tls_curve_info *cinfo;
|
||||
/* ECC curves from RFC 4492 and RFC 7027 */
|
||||
if ((curve_id < 1) || ((unsigned int)curve_id > OSSL_NELEM(nid_list)))
|
||||
return 0;
|
||||
return nid_list[curve_id - 1].nid;
|
||||
cinfo = nid_list + curve_id - 1;
|
||||
if (pflags)
|
||||
*pflags = cinfo->flags;
|
||||
return cinfo->nid;
|
||||
}
|
||||
|
||||
int tls1_ec_nid2curve_id(int nid)
|
||||
|
@ -413,7 +410,7 @@ int tls1_shared_curve(SSL *s, int nmatch)
|
|||
continue;
|
||||
if (nmatch == k) {
|
||||
int id = (pref[0] << 8) | pref[1];
|
||||
return tls1_ec_curve_id2nid(id);
|
||||
return tls1_ec_curve_id2nid(id, NULL);
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue