DPP2: Add privacyProtectionKey into Configurator backup/restore

This allows the privacyProtectionKey to be transferred to a new
Configurator similarly to the way c-sign-key is transferred.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
This commit is contained in:
Jouni Malinen 2020-10-13 23:11:40 +03:00 committed by Jouni Malinen
parent a0ccc4017f
commit 0f07230eb9
3 changed files with 84 additions and 9 deletions

View file

@ -4275,12 +4275,12 @@ int dpp_configurator_from_backup(struct dpp_global *dpp,
struct dpp_asymmetric_key *key)
{
struct dpp_configurator *conf;
const EC_KEY *eckey;
const EC_GROUP *group;
const EC_KEY *eckey, *eckey_pp;
const EC_GROUP *group, *group_pp;
int nid;
const struct dpp_curve_params *curve;
if (!key->csign)
if (!key->csign || !key->pp_key)
return -1;
eckey = EVP_PKEY_get0_EC_KEY(key->csign);
if (!eckey)
@ -4294,6 +4294,18 @@ int dpp_configurator_from_backup(struct dpp_global *dpp,
wpa_printf(MSG_INFO, "DPP: Unsupported group in c-sign-key");
return -1;
}
eckey_pp = EVP_PKEY_get0_EC_KEY(key->pp_key);
if (!eckey_pp)
return -1;
group_pp = EC_KEY_get0_group(eckey_pp);
if (!group_pp)
return -1;
if (EC_GROUP_get_curve_name(group) !=
EC_GROUP_get_curve_name(group_pp)) {
wpa_printf(MSG_INFO,
"DPP: Mismatch in c-sign-key and ppKey groups");
return -1;
}
conf = os_zalloc(sizeof(*conf));
if (!conf)
@ -4301,6 +4313,8 @@ int dpp_configurator_from_backup(struct dpp_global *dpp,
conf->curve = curve;
conf->csign = key->csign;
key->csign = NULL;
conf->pp_key = key->pp_key;
key->pp_key = NULL;
conf->own = 1;
if (dpp_configurator_gen_kid(conf) < 0) {
dpp_configurator_free(conf);

View file

@ -235,6 +235,7 @@ struct dpp_configuration {
struct dpp_asymmetric_key {
struct dpp_asymmetric_key *next;
EVP_PKEY *csign;
EVP_PKEY *pp_key;
char *config_template;
char *connector_template;
};

View file

@ -40,6 +40,7 @@ void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
struct dpp_asymmetric_key *next = key->next;
EVP_PKEY_free(key->csign);
EVP_PKEY_free(key->pp_key);
str_clear_free(key->config_template);
str_clear_free(key->connector_template);
os_free(key);
@ -48,35 +49,62 @@ void dpp_free_asymmetric_key(struct dpp_asymmetric_key *key)
}
static struct wpabuf * dpp_build_conf_params(void)
static struct wpabuf * dpp_build_conf_params(struct dpp_configurator *conf)
{
struct wpabuf *buf;
struct wpabuf *buf, *priv_key = NULL;
size_t len;
/* 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(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);
if (!priv_key)
goto fail;
len = 100 + os_strlen(conf_template);
if (connector_template)
len += os_strlen(connector_template);
if (priv_key)
len += wpabuf_len(priv_key);
buf = wpabuf_alloc(len);
if (!buf)
return NULL;
goto fail;
/*
* DPPConfigurationParameters ::= SEQUENCE {
* privacyProtectionKey PrivateKey,
* configurationTemplate UTF8String,
* connectorTemplate UTF8String OPTIONAL}
*/
/* PrivateKey ::= OCTET STRING */
asn1_put_octet_string(buf, priv_key);
asn1_put_utf8string(buf, conf_template);
if (connector_template)
asn1_put_utf8string(buf, connector_template);
wpabuf_clear_free(priv_key);
return asn1_encaps(buf, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SEQUENCE);
fail:
wpabuf_clear_free(priv_key);
return NULL;
}
static struct wpabuf * dpp_build_attribute(void)
static struct wpabuf * dpp_build_attribute(struct dpp_configurator *conf)
{
struct wpabuf *conf_params, *attr;
@ -88,7 +116,7 @@ static struct wpabuf * dpp_build_attribute(void)
* type OBJECT IDENTIFIER,
* values SET SIZE(1..MAX) OF Type
*/
conf_params = dpp_build_conf_params();
conf_params = dpp_build_conf_params(conf);
conf_params = asn1_encaps(conf_params, ASN1_CLASS_UNIVERSAL,
ASN1_TAG_SET);
if (!conf_params)
@ -167,7 +195,7 @@ static struct wpabuf * dpp_build_key_pkg(struct dpp_authentication *auth)
alg = dpp_build_key_alg(auth->conf->curve);
/* Attributes ::= SET OF Attribute { { OneAsymmetricKeyAttributes } } */
attr = dpp_build_attribute();
attr = dpp_build_attribute(auth->conf);
attr = asn1_encaps(attr, ASN1_CLASS_UNIVERSAL, ASN1_TAG_SET);
if (!priv_key || !attr || !alg)
goto fail;
@ -1059,6 +1087,7 @@ dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
/*
* DPPConfigurationParameters ::= SEQUENCE {
* privacyProtectionKey PrivateKey,
* configurationTemplate UTF8String,
* connectorTemplate UTF8String OPTIONAL}
*/
@ -1075,6 +1104,37 @@ dpp_parse_one_asymmetric_key(const u8 *buf, size_t len)
end = pos;
pos = hdr.payload;
/*
* PrivateKey ::= OCTET STRING
* (Contains DER encoding of ECPrivateKey)
*/
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_OCTETSTRING) {
wpa_printf(MSG_DEBUG,
"DPP: Expected OCTETSTRING (PrivateKey) - found class %d tag 0x%x",
hdr.class, hdr.tag);
goto fail;
}
wpa_hexdump_key(MSG_MSGDUMP, "DPP: privacyProtectionKey",
hdr.payload, hdr.length);
pos = hdr.payload + hdr.length;
eckey = d2i_ECPrivateKey(NULL, &hdr.payload, hdr.length);
if (!eckey) {
wpa_printf(MSG_INFO,
"DPP: OpenSSL: d2i_ECPrivateKey() failed: %s",
ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
key->pp_key = EVP_PKEY_new();
if (!key->pp_key || EVP_PKEY_assign_EC_KEY(key->pp_key, eckey) != 1) {
EC_KEY_free(eckey);
goto fail;
}
if (wpa_debug_show_keys)
dpp_debug_print_key("DPP: Received privacyProtectionKey",
key->pp_key);
if (asn1_get_next(pos, end - pos, &hdr) < 0 ||
hdr.class != ASN1_CLASS_UNIVERSAL ||
hdr.tag != ASN1_TAG_UTF8STRING) {