提交 ec24630a 编写于 作者: D Dr. Stephen Henson

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: NRich Salz <rsalz@openssl.org>
上级 3bca6c27
......@@ -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;
......
......@@ -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++;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册