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,
|
static void dpp_copy_netaccesskey(struct dpp_authentication *auth,
|
||||||
struct dpp_config_obj *conf)
|
struct dpp_config_obj *conf)
|
||||||
{
|
{
|
||||||
unsigned char *der = NULL;
|
struct wpabuf *net_access_key;
|
||||||
int der_len;
|
|
||||||
EC_KEY *eckey;
|
|
||||||
struct crypto_ec_key *own_key;
|
struct crypto_ec_key *own_key;
|
||||||
|
|
||||||
own_key = auth->own_protocol_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)
|
auth->reconfig_old_protocol_key)
|
||||||
own_key = auth->reconfig_old_protocol_key;
|
own_key = auth->reconfig_old_protocol_key;
|
||||||
#endif /* CONFIG_DPP2 */
|
#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;
|
return;
|
||||||
|
|
||||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
|
||||||
if (der_len <= 0) {
|
|
||||||
EC_KEY_free(eckey);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wpabuf_free(auth->net_access_key);
|
wpabuf_free(auth->net_access_key);
|
||||||
auth->net_access_key = wpabuf_alloc_copy(der, der_len);
|
auth->net_access_key = net_access_key;
|
||||||
OPENSSL_free(der);
|
|
||||||
EC_KEY_free(eckey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3410,23 +3402,19 @@ void dpp_configurator_free(struct dpp_configurator *conf)
|
||||||
int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
|
int dpp_configurator_get_key(const struct dpp_configurator *conf, char *buf,
|
||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
EC_KEY *eckey;
|
struct wpabuf *key;
|
||||||
int key_len, ret = -1;
|
int ret = -1;
|
||||||
unsigned char *key = NULL;
|
|
||||||
|
|
||||||
if (!conf->csign)
|
if (!conf->csign)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *) conf->csign);
|
key = crypto_ec_key_get_ecprivate_key(conf->csign, true);
|
||||||
if (!eckey)
|
if (!key)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
key_len = i2d_ECPrivateKey(eckey, &key);
|
ret = wpa_snprintf_hex(buf, buflen, wpabuf_head(key), wpabuf_len(key));
|
||||||
if (key_len > 0)
|
|
||||||
ret = wpa_snprintf_hex(buf, buflen, key, key_len);
|
|
||||||
|
|
||||||
EC_KEY_free(eckey);
|
wpabuf_clear_free(key);
|
||||||
OPENSSL_free(key);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,21 +19,6 @@
|
||||||
|
|
||||||
#ifdef CONFIG_DPP2
|
#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)
|
void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
|
||||||
{
|
{
|
||||||
while (key) {
|
while (key) {
|
||||||
|
@ -56,23 +41,13 @@ static struct wpabuf * dpp_build_conf_params(struct dpp_configurator *conf)
|
||||||
/* TODO: proper template values */
|
/* TODO: proper template values */
|
||||||
const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}";
|
const char *conf_template = "{\"wi-fi_tech\":\"infra\",\"discovery\":{\"ssid\":\"test\"},\"cred\":{\"akm\":\"dpp\"}}";
|
||||||
const char *connector_template = NULL;
|
const char *connector_template = NULL;
|
||||||
EC_KEY *eckey;
|
|
||||||
unsigned char *der = NULL;
|
|
||||||
int der_len;
|
|
||||||
|
|
||||||
if (!conf->pp_key)
|
if (!conf->pp_key)
|
||||||
return NULL;
|
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);
|
priv_key = crypto_ec_key_get_ecprivate_key(conf->pp_key, false);
|
||||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
|
||||||
if (der_len > 0)
|
|
||||||
priv_key = wpabuf_alloc_copy(der, der_len);
|
|
||||||
OPENSSL_free(der);
|
|
||||||
if (!priv_key)
|
if (!priv_key)
|
||||||
goto fail;
|
return NULL;
|
||||||
|
|
||||||
len = 100 + os_strlen(conf_template);
|
len = 100 + os_strlen(conf_template);
|
||||||
if (connector_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)
|
static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth)
|
||||||
{
|
{
|
||||||
struct wpabuf *key = NULL, *attr, *alg, *priv_key = NULL;
|
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);
|
priv_key = crypto_ec_key_get_ecprivate_key(auth->conf->csign, false);
|
||||||
if (!eckey)
|
if (!priv_key)
|
||||||
return NULL;
|
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);
|
alg = dpp_build_key_alg(auth->conf->curve);
|
||||||
|
|
||||||
/* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */
|
/* 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;
|
size_t rlen;
|
||||||
char *txt;
|
char *txt;
|
||||||
int res;
|
int res;
|
||||||
unsigned char *der = NULL;
|
struct wpabuf *der = NULL;
|
||||||
int der_len;
|
|
||||||
const EC_GROUP *group;
|
const EC_GROUP *group;
|
||||||
const EC_POINT *point;
|
const EC_POINT *point;
|
||||||
|
|
||||||
|
@ -214,19 +213,17 @@ void dpp_debug_print_key(const char *title, struct crypto_ec_key *key)
|
||||||
if (group && point)
|
if (group && point)
|
||||||
dpp_debug_print_point(title, group, point);
|
dpp_debug_print_point(title, group, point);
|
||||||
|
|
||||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
der = crypto_ec_key_get_ecprivate_key(key, true);
|
||||||
if (der_len > 0)
|
if (der) {
|
||||||
wpa_hexdump_key(MSG_DEBUG, "DPP: ECPrivateKey", der, der_len);
|
wpa_hexdump_buf_key(MSG_DEBUG, "DPP: ECPrivateKey", der);
|
||||||
OPENSSL_free(der);
|
} else {
|
||||||
if (der_len <= 0) {
|
der = crypto_ec_key_get_subject_public_key(key);
|
||||||
der = NULL;
|
if (der)
|
||||||
der_len = i2d_EC_PUBKEY(eckey, &der);
|
wpa_hexdump_buf_key(MSG_DEBUG, "DPP: EC_PUBKEY", der);
|
||||||
if (der_len > 0)
|
|
||||||
wpa_hexdump(MSG_DEBUG, "DPP: EC_PUBKEY", der, der_len);
|
|
||||||
OPENSSL_free(der);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EC_KEY_free(eckey);
|
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;
|
struct crypto_ec_key *key;
|
||||||
const EVP_MD *sign_md;
|
const EVP_MD *sign_md;
|
||||||
unsigned int hash_len = auth->curve->hash_len;
|
unsigned int hash_len = auth->curve->hash_len;
|
||||||
EC_KEY *eckey;
|
struct wpabuf *priv_key;
|
||||||
BIO *out = NULL;
|
BIO *out = NULL;
|
||||||
u8 cp[DPP_CP_LEN];
|
u8 cp[DPP_CP_LEN];
|
||||||
char *password;
|
char *password;
|
||||||
|
@ -2689,18 +2686,11 @@ struct wpabuf * dpp_build_csr(struct dpp_authentication *auth, const char *name)
|
||||||
* a specific group to be used */
|
* a specific group to be used */
|
||||||
key = auth->own_protocol_key;
|
key = auth->own_protocol_key;
|
||||||
|
|
||||||
eckey = EVP_PKEY_get1_EC_KEY((EVP_PKEY *) key);
|
priv_key = crypto_ec_key_get_ecprivate_key(key, true);
|
||||||
if (!eckey)
|
if (!priv_key)
|
||||||
goto fail;
|
|
||||||
der = NULL;
|
|
||||||
der_len = i2d_ECPrivateKey(eckey, &der);
|
|
||||||
if (der_len <= 0)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
wpabuf_free(auth->priv_key);
|
wpabuf_free(auth->priv_key);
|
||||||
auth->priv_key = wpabuf_alloc_copy(der, der_len);
|
auth->priv_key = priv_key;
|
||||||
OPENSSL_free(der);
|
|
||||||
if (!auth->priv_key)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
req = X509_REQ_new();
|
req = X509_REQ_new();
|
||||||
if (!req || !X509_REQ_set_pubkey(req, (EVP_PKEY *) key))
|
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);
|
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
|
* 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()
|
* @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,
|
struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue