aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2016-08-11 15:41:49 +0100
committerDr. Stephen Henson <steve@openssl.org>2016-08-13 14:11:05 +0100
commitec24630ae2b714d6e22fbfa4695aa8f8adef1828 (patch)
treed011ddd52b33c5bb4d58cdede78c9d4ea690199a
parent3bca6c27317958f30f8bbfe67814a7ab9a07f4a3 (diff)
downloadopenssl-ec24630ae2b714d6e22fbfa4695aa8f8adef1828.tar.gz
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>
-rw-r--r--ssl/s3_lib.c21
-rw-r--r--ssl/ssl_locl.h8
-rw-r--r--ssl/statem/statem_clnt.c50
-rw-r--r--ssl/statem/statem_srvr.c11
-rw-r--r--ssl/t1_lib.c19
5 files changed, 66 insertions, 43 deletions
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index e14b448609..f1363ca3b6 100644
--- a/ssl/s3_lib.c
+++ b/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
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index f502cadb1d..3c230d14d6 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -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);
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index df19211b55..6f4c8ff2bf 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -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);
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index 602336acd9..a5fe75216b 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -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;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index 2418c65862..ca4e7d6956 100644
--- a/ssl/t1_lib.c
+++ b/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++;
}