DPP: Factorize conversion to ASN.1 ECPrivateKey
Add crypto_ec_key_get_ecprivate_key() function in crypto.h and use it when possible in DPP code. This function converts a struct crypto_ec_key into a DER encoded ASN.1 ECPrivateKey. Signed-off-by: Cedric Izoard <cedric.izoard@ceva-dsp.com>
This commit is contained in:
parent
63bf3d25ab
commit
2d5772e691
5 changed files with 65 additions and 84 deletions
|
@ -2450,9 +2450,7 @@ static void dpp_copy_ppkey(struct dpp_config_obj *conf,
|
|||
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;
|
||||
|
@ -2461,19 +2459,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)
|
||||
|
||||
net_access_key = crypto_ec_key_get_ecprivate_key(own_key, true);
|
||||
if (!net_access_key)
|
||||
return;
|
||||
|
||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
||||
if (der_len <= 0) {
|
||||
EC_KEY_free(eckey);
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3410,23 +3402,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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 } } */
|
||||
|
|
|
@ -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,17 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2676,7 +2673,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;
|
||||
|
@ -2689,18 +2686,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))
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -2318,6 +2318,34 @@ 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;
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue