From: Cedric Izoard <cedric.izoard@xxxxxxxxxxx> Add crypto_ec_key_get_ecprivate_key function in crypto.h and use it when possible in DPP code. This function convert a struct crypto_ec_key into a DER encoded ASN.1 ECPrivateKey. Signed-off-by: Cedric Izoard <cedric.izoard@xxxxxxxxxxxx> --- src/common/dpp.c | 34 ++++++++++-------------------- src/common/dpp_backup.c | 42 ++++--------------------------------- src/common/dpp_crypto.c | 37 +++++++++++++------------------- src/crypto/crypto.h | 9 ++++++++ src/crypto/crypto_openssl.c | 29 +++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 84 deletions(-) diff --git a/src/common/dpp.c b/src/common/dpp.c index 14783ba74..f85eb2d4d 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -2446,9 +2446,7 @@ static void dpp_copy_ppkey(struct dpp_config_obj *conf, struct crypto_ec_key *pp static void dpp_copy_netaccesskey(struct dpp_authentication *auth, struct dpp_config_obj *conf) { - unsigned char *der = NULL; - int der_len; - EC_KEY *eckey; + struct wpabuf *net_access_key; struct crypto_ec_key *own_key; own_key = auth->own_protocol_key; @@ -2457,19 +2455,13 @@ static void dpp_copy_netaccesskey(struct dpp_authentication *auth, auth->reconfig_old_protocol_key) own_key = auth->reconfig_old_protocol_key; #endif /* CONFIG_DPP2 */ - eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *)own_key); - if (!eckey) - return; - der_len = i2d_ECPrivateKey(eckey, &der); - if (der_len <= 0) { - EC_KEY_free(eckey); + net_access_key = crypto_ec_key_get_ecprivate_key(own_key, true); + if (!net_access_key) return; - } + wpabuf_free(auth->net_access_key); - auth->net_access_key = wpabuf_alloc_copy(der, der_len); - OPENSSL_free(der); - EC_KEY_free(eckey); + auth->net_access_key = net_access_key; } @@ -3406,23 +3398,19 @@ void dpp_configurator_free(struct dpp_configurator *conf) int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf, size_t buflen) { - EC_KEY *eckey; - int key_len, ret = -1; - unsigned char *key = NULL; + struct wpabuf *key; + int ret = -1; if (!conf->csign) return -1; - eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *)conf->csign); - if (!eckey) + key = crypto_ec_key_get_ecprivate_key(conf->csign, true); + if (!key) return -1; - key_len = i2d_ECPrivateKey(eckey, &key); - if (key_len > 0) - ret = wpa_snprintf_hex(buf, buflen, key, key_len); + ret = wpa_snprintf_hex(buf, buflen, wpabuf_head(key), wpabuf_len(key)); - EC_KEY_free(eckey); - OPENSSL_free(key); + wpabuf_clear_free(key); return ret; } diff --git a/src/common/dpp_backup.c b/src/common/dpp_backup.c index 1e03e0fb9..65fe12afc 100644 --- a/src/common/dpp_backup.c +++ b/src/common/dpp_backup.c @@ -19,21 +19,6 @@ #ifdef CONFIG_DPP2 -#if OPENSSL_VERSION_NUMBER < 0x10100000L || \ - (defined(LIBRESSL_VERSION_NUMBER) && \ - LIBRESSL_VERSION_NUMBER < 0x20700000L) -/* Compatibility wrappers for older versions. */ - -static EC_KEY * EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) -{ - if (pkey->type != EVP_PKEY_EC) - return NULL; - return pkey->pkey.ec; -} - -#endif - - void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key) { while (key) { @@ -56,23 +41,13 @@ static struct wpabuf * dpp_build_conf_params(struct dpp_configurator *conf) /* TODO: proper template values */ const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}"; const char *connector_template = NULL; - EC_KEY *eckey; - unsigned char *der = NULL; - int der_len; if (!conf->pp_key) return NULL; - eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)conf->pp_key); - if (!eckey) - return NULL; - EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); - der_len = i2d_ECPrivateKey(eckey, &der); - if (der_len > 0) - priv_key = wpabuf_alloc_copy(der, der_len); - OPENSSL_free(der); + priv_key = crypto_ec_key_get_ecprivate_key(conf->pp_key, false); if (!priv_key) - goto fail; + return NULL; len = 100 + os_strlen(conf_template); if (connector_template) @@ -178,20 +153,11 @@ static struct wpabuf * dpp_build_key_alg(const struct dpp_curve_params *curve) static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth) { struct wpabuf *key = NULL, *attr, *alg, *priv_key = NULL; - EC_KEY *eckey; - unsigned char *der = NULL; - int der_len; - eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)auth->conf->csign); - if (!eckey) + priv_key = crypto_ec_key_get_ecprivate_key(auth->conf->csign, false); + if (!priv_key) return NULL; - EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); - der_len = i2d_ECPrivateKey(eckey, &der); - if (der_len > 0) - priv_key = wpabuf_alloc_copy(der, der_len); - OPENSSL_free(der); - alg = dpp_build_key_alg(auth->conf->curve); /* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */ diff --git a/src/common/dpp_crypto.c b/src/common/dpp_crypto.c index 5e4d213ac..222d15368 100644 --- a/src/common/dpp_crypto.c +++ b/src/common/dpp_crypto.c @@ -183,8 +183,7 @@ void dpp_debug_print_key(const char *title, struct crypto_ec_key *key) size_t rlen; char *txt; int res; - unsigned char *der = NULL; - int der_len; + struct wpabuf *der = NULL; const EC_GROUP *group; const EC_POINT *point; @@ -214,19 +213,18 @@ void dpp_debug_print_key(const char *title, struct crypto_ec_key *key) if (group && point) dpp_debug_print_point(title, group, point); - der_len = i2d_ECPrivateKey(eckey, &der); - if (der_len > 0) - wpa_hexdump_key(MSG_DEBUG, "DPP: ECPrivateKey", der, der_len); - OPENSSL_free(der); - if (der_len <= 0) { - der = NULL; - der_len = i2d_EC_PUBKEY(eckey, &der); - if (der_len > 0) - wpa_hexdump(MSG_DEBUG, "DPP: EC_PUBKEY", der, der_len); - OPENSSL_free(der); + der = crypto_ec_key_get_ecprivate_key(key, true); + if (der) { + wpa_hexdump_buf_key(MSG_DEBUG, "DPP: ECPrivateKey", der); + } else { + der = crypto_ec_key_get_subject_public_key(key); + if (der) { + wpa_hexdump_buf_key(MSG_DEBUG, "DPP: EC_PUBKEY", der); + } } EC_KEY_free(eckey); + wpabuf_clear_free(der); } @@ -2669,7 +2667,7 @@ struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name) struct crypto_ec_key *key; const EVP_MD *sign_md; unsigned int hash_len = auth->curve->hash_len; - EC_KEY *eckey; + struct wpabuf * priv_key; BIO *out = NULL; u8 cp[DPP_CP_LEN]; char *password; @@ -2682,18 +2680,11 @@ struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name) * a specific group to be used */ key = auth->own_protocol_key; - eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *)key); - if (!eckey) - goto fail; - der = NULL; - der_len = i2d_ECPrivateKey(eckey, &der); - if (der_len <= 0) + priv_key = crypto_ec_key_get_ecprivate_key(key, true); + if (!priv_key) goto fail; wpabuf_free(auth->priv_key); - auth->priv_key = wpabuf_alloc_copy(der, der_len); - OPENSSL_free(der); - if (!auth->priv_key) - goto fail; + auth->priv_key = priv_key; req = X509_REQ_new(); if (!req || !X509_REQ_set_pubkey(req, (EVP_PKEY *)key)) diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 382b34622..b4e3ae530 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -1014,6 +1014,15 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key); */ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key); +/** + * crypto_ec_key_get_ecprivate_key - Get ECPrivateKey ASN.1 for a EC key + * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen() + * @include_pub: Whether to include public key in the ASN.1 sequence + * Returns: Buffer with DER encoding of ASN.1 ECPrivateKey or %NULL on failure + */ +struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, + bool include_pub); + /** * crypto_ec_key_sign - Sign a buffer with an EC key * @key: EC key from crypto_ec_key_parse_priv() or crypto_ec_key_gen() diff --git a/src/crypto/crypto_openssl.c b/src/crypto/crypto_openssl.c index 648c1cbf6..a10746f41 100644 --- a/src/crypto/crypto_openssl.c +++ b/src/crypto/crypto_openssl.c @@ -2334,6 +2334,35 @@ struct wpabuf * crypto_ec_key_get_subject_public_key(struct crypto_ec_key *key) } +struct wpabuf * crypto_ec_key_get_ecprivate_key(struct crypto_ec_key *key, + bool include_pub) +{ + EC_KEY *eckey = NULL; + unsigned char *der = NULL; + int der_len; + struct wpabuf *buf; + + eckey = EVP_PKEY_get0_EC_KEY((EVP_PKEY *)key); + if (!eckey) + return NULL; + + if (include_pub) + EC_KEY_clear_flags(eckey, EC_PKEY_NO_PUBKEY); + else + EC_KEY_set_enc_flags(eckey, EC_PKEY_NO_PUBKEY); + + EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED); + + der_len = i2d_ECPrivateKey(eckey, &der); + if (der_len <= 0) { + return NULL; + } + buf = wpabuf_alloc_copy(der, der_len); + OPENSSL_free(der); + return buf; +} + + struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data, size_t len) { -- 2.17.0 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap