diff options
author | Matt Caswell <matt@openssl.org> | 2020-05-20 16:20:27 +0100 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2020-06-05 11:04:11 +0100 |
commit | 6a9bd9298bd706e3a4a40ecfa1d89f65f8592c65 (patch) | |
tree | 38fdba8151948162bbaf8df6c073844ee05c1e46 /crypto | |
parent | 0d52ede71685e4176999cc5e52000dcb540747fc (diff) |
Make EVP_PKEY_[get1|set1]_tls_encodedpoint work with provided keys
EVP_PKEY_[get1|set1]_tls_encodedpoint() only worked if an ameth was present
which isn't the case for provided keys. Support has been added to dh,
ec and ecx keys.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11898)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/dh/dh_ameth.c | 2 | ||||
-rw-r--r-- | crypto/dh/dh_key.c | 40 | ||||
-rw-r--r-- | crypto/dh/dh_local.h | 3 | ||||
-rw-r--r-- | crypto/evp/p_lib.c | 39 |
4 files changed, 65 insertions, 19 deletions
diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index d93d519444..d5e5f72517 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -438,7 +438,7 @@ static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: return dh_buf2key(EVP_PKEY_get0_DH(pkey), arg2, arg1); case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: - return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2); + return dh_key2buf(EVP_PKEY_get0_DH(pkey), arg2, 0, 1); default: return -2; } diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 1893b487ca..5d2acca25c 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -351,10 +351,10 @@ err: return 0; } -size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) +size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out, size_t size, int alloc) { const BIGNUM *pubkey; - unsigned char *pbuf; + unsigned char *pbuf = NULL; const BIGNUM *p; int p_size; @@ -366,19 +366,29 @@ size_t dh_key2buf(const DH *dh, unsigned char **pbuf_out) DHerr(DH_F_DH_KEY2BUF, DH_R_INVALID_PUBKEY); return 0; } - if ((pbuf = OPENSSL_malloc(p_size)) == NULL) { - DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE); - return 0; - } - /* - * As per Section 4.2.8.1 of RFC 8446 left pad public - * key with zeros to the size of p - */ - if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) { - OPENSSL_free(pbuf); - DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR); - return 0; + if (pbuf_out != NULL && (alloc || *pbuf_out != NULL)) { + if (!alloc) { + if (size >= (size_t)p_size) + pbuf = *pbuf_out; + } else { + pbuf = OPENSSL_malloc(p_size); + } + + if (pbuf == NULL) { + DHerr(DH_F_DH_KEY2BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * As per Section 4.2.8.1 of RFC 8446 left pad public + * key with zeros to the size of p + */ + if (BN_bn2binpad(pubkey, pbuf, p_size) < 0) { + if (alloc) + OPENSSL_free(pbuf); + DHerr(DH_F_DH_KEY2BUF, DH_R_BN_ERROR); + return 0; + } + *pbuf_out = pbuf; } - *pbuf_out = pbuf; return p_size; } diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index a54d25f487..51c3f974e1 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -58,6 +58,3 @@ struct dh_method { int (*generate_params) (DH *dh, int prime_len, int generator, BN_GENCB *cb); }; - -int dh_buf2key(DH *key, const unsigned char *buf, size_t len); -size_t dh_key2buf(const DH *dh, unsigned char **pbuf); diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 4670912588..1d57a22aee 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -1215,6 +1215,18 @@ int EVP_PKEY_supports_digest_nid(EVP_PKEY *pkey, int nid) int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, const unsigned char *pt, size_t ptlen) { + if (pkey->ameth == NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (pkey->keymgmt == NULL || pkey->keydata == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + (unsigned char *)pt, ptlen); + return evp_keymgmt_set_params(pkey->keymgmt, pkey->keydata, params); + } + if (ptlen > INT_MAX) return 0; if (evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_SET1_TLS_ENCPT, ptlen, @@ -1226,6 +1238,33 @@ int EVP_PKEY_set1_tls_encodedpoint(EVP_PKEY *pkey, size_t EVP_PKEY_get1_tls_encodedpoint(EVP_PKEY *pkey, unsigned char **ppt) { int rv; + + if (pkey->ameth == NULL) { + OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; + + if (pkey->keymgmt == NULL || pkey->keydata == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + NULL, 0); + if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) + return 0; + + *ppt = OPENSSL_malloc(params[0].return_size); + if (*ppt == NULL) + return 0; + + params[0] = + OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, + *ppt, params[0].return_size); + if (!evp_keymgmt_get_params(pkey->keymgmt, pkey->keydata, params)) + return 0; + + return params[0].return_size; + } + + rv = evp_pkey_asn1_ctrl(pkey, ASN1_PKEY_CTRL_GET1_TLS_ENCPT, 0, ppt); if (rv <= 0) return 0; |