[PATCH 05/21] dpp: factorize conversion to ASN.1 ECPrivateKey
Cedric Izoard
cedric.izoard at ceva-dsp.com
Mon Jun 28 09:25:22 PDT 2021
From: Cedric Izoard <cedric.izoard at laposte.net>
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 at ceva-dsp.com>
---
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
More information about the Hostap
mailing list