DPP: Allow a list of supported curves to be used in bootstrapping URI
The new DPP_BOOTSTRAP_GEN command parameter supported_curves can be used to specify a colon separated list of supported curves. Information from a parsed URI shows this information with a new supp_curves line in the DPP_BOOTSTRAP_INFO output. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
73b41762d0
commit
b0769ce61c
4 changed files with 133 additions and 6 deletions
126
src/common/dpp.c
126
src/common/dpp.c
|
@ -345,12 +345,36 @@ static int dpp_parse_uri_pk(struct dpp_bootstrap_info *bi, const char *info)
|
|||
}
|
||||
|
||||
|
||||
static int dpp_parse_uri_supported_curves(struct dpp_bootstrap_info *bi,
|
||||
const char *txt)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (!txt)
|
||||
return 0;
|
||||
|
||||
val = hex2num(txt[0]);
|
||||
if (val < 0)
|
||||
return -1;
|
||||
bi->supported_curves = val;
|
||||
|
||||
val = hex2num(txt[1]);
|
||||
if (val > 0)
|
||||
bi->supported_curves |= val << 4;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: URI supported curves: 0x%x",
|
||||
bi->supported_curves);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri)
|
||||
{
|
||||
const char *pos = uri;
|
||||
const char *end;
|
||||
const char *chan_list = NULL, *mac = NULL, *info = NULL, *pk = NULL;
|
||||
const char *version = NULL;
|
||||
const char *version = NULL, *supported_curves = NULL;
|
||||
struct dpp_bootstrap_info *bi;
|
||||
|
||||
wpa_hexdump_ascii(MSG_DEBUG, "DPP: URI", uri, os_strlen(uri));
|
||||
|
@ -383,6 +407,8 @@ static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri)
|
|||
pk = pos + 2;
|
||||
else if (pos[0] == 'V' && pos[1] == ':' && !version)
|
||||
version = pos + 2;
|
||||
else if (pos[0] == 'B' && pos[1] == ':' && !supported_curves)
|
||||
supported_curves = pos + 2;
|
||||
else
|
||||
wpa_hexdump_ascii(MSG_DEBUG,
|
||||
"DPP: Ignore unrecognized URI parameter",
|
||||
|
@ -404,6 +430,7 @@ static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri)
|
|||
dpp_parse_uri_mac(bi, mac) < 0 ||
|
||||
dpp_parse_uri_info(bi, info) < 0 ||
|
||||
dpp_parse_uri_version(bi, version) < 0 ||
|
||||
dpp_parse_uri_supported_curves(bi, supported_curves) < 0 ||
|
||||
dpp_parse_uri_pk(bi, pk) < 0) {
|
||||
dpp_bootstrap_info_free(bi);
|
||||
bi = NULL;
|
||||
|
@ -604,6 +631,7 @@ int dpp_gen_uri(struct dpp_bootstrap_info *bi)
|
|||
{
|
||||
char macstr[ETH_ALEN * 2 + 10];
|
||||
size_t len;
|
||||
char supp_curves[10];
|
||||
|
||||
len = 4; /* "DPP:" */
|
||||
if (bi->chan)
|
||||
|
@ -621,11 +649,26 @@ int dpp_gen_uri(struct dpp_bootstrap_info *bi)
|
|||
#endif /* CONFIG_DPP2 */
|
||||
len += 4 + os_strlen(bi->pk); /* K:...;; */
|
||||
|
||||
if (bi->supported_curves) {
|
||||
u8 val = bi->supported_curves;
|
||||
|
||||
if (val & 0xf0) {
|
||||
val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
|
||||
len += os_snprintf(supp_curves, sizeof(supp_curves),
|
||||
"B:%02x;", val);
|
||||
} else {
|
||||
len += os_snprintf(supp_curves, sizeof(supp_curves),
|
||||
"B:%x;", val);
|
||||
}
|
||||
} else {
|
||||
supp_curves[0] = '\0';
|
||||
}
|
||||
|
||||
os_free(bi->uri);
|
||||
bi->uri = os_malloc(len + 1);
|
||||
if (!bi->uri)
|
||||
return -1;
|
||||
os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%sK:%s;;",
|
||||
os_snprintf(bi->uri, len + 1, "DPP:%s%s%s%s%s%s%s%s%sK:%s;;",
|
||||
bi->chan ? "C:" : "", bi->chan ? bi->chan : "",
|
||||
bi->chan ? ";" : "",
|
||||
macstr,
|
||||
|
@ -633,6 +676,7 @@ int dpp_gen_uri(struct dpp_bootstrap_info *bi)
|
|||
bi->info ? ";" : "",
|
||||
DPP_VERSION == 3 ? "V:3;" :
|
||||
(DPP_VERSION == 2 ? "V:2;" : ""),
|
||||
supp_curves,
|
||||
bi->pk);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4144,10 +4188,47 @@ struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp,
|
|||
}
|
||||
|
||||
|
||||
static int dpp_parse_supported_curves_list(struct dpp_bootstrap_info *bi,
|
||||
char *txt)
|
||||
{
|
||||
char *token, *context = NULL;
|
||||
u8 curves = 0;
|
||||
|
||||
if (!txt)
|
||||
return 0;
|
||||
|
||||
while ((token = str_token(txt, ":", &context))) {
|
||||
if (os_strcmp(token, "P-256") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_P_256);
|
||||
} else if (os_strcmp(token, "P-384") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_P_384);
|
||||
} else if (os_strcmp(token, "P-521") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_P_521);
|
||||
} else if (os_strcmp(token, "BP-256") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_BP_256);
|
||||
} else if (os_strcmp(token, "BP-384") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_BP_384);
|
||||
} else if (os_strcmp(token, "BP-512") == 0) {
|
||||
curves |= BIT(DPP_BOOTSTRAP_CURVE_BP_512);
|
||||
} else {
|
||||
wpa_printf(MSG_DEBUG, "DPP: Unsupported curve '%s'",
|
||||
token);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
bi->supported_curves = curves;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "DPP: URI supported curves: 0x%x",
|
||||
bi->supported_curves);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd)
|
||||
{
|
||||
char *mac = NULL, *info = NULL, *curve = NULL;
|
||||
char *key = NULL;
|
||||
char *key = NULL, *supported_curves = NULL;
|
||||
u8 *privkey = NULL;
|
||||
size_t privkey_len = 0;
|
||||
int ret = -1;
|
||||
|
@ -4174,6 +4255,7 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd)
|
|||
info = get_param(cmd, " info=");
|
||||
curve = get_param(cmd, " curve=");
|
||||
key = get_param(cmd, " key=");
|
||||
supported_curves = get_param(cmd, " supported_curves=");
|
||||
|
||||
if (key) {
|
||||
privkey_len = os_strlen(key) / 2;
|
||||
|
@ -4187,6 +4269,7 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd)
|
|||
dpp_parse_uri_chan_list(bi, bi->chan) < 0 ||
|
||||
dpp_parse_uri_mac(bi, mac) < 0 ||
|
||||
dpp_parse_uri_info(bi, info) < 0 ||
|
||||
dpp_parse_supported_curves_list(bi, supported_curves) < 0 ||
|
||||
dpp_gen_uri(bi) < 0)
|
||||
goto fail;
|
||||
|
||||
|
@ -4199,6 +4282,7 @@ fail:
|
|||
os_free(mac);
|
||||
os_free(info);
|
||||
str_clear_free(key);
|
||||
os_free(supported_curves);
|
||||
bin_clear_free(privkey, privkey_len);
|
||||
dpp_bootstrap_info_free(bi);
|
||||
return ret;
|
||||
|
@ -4253,12 +4337,43 @@ int dpp_bootstrap_info(struct dpp_global *dpp, int id,
|
|||
{
|
||||
struct dpp_bootstrap_info *bi;
|
||||
char pkhash[2 * SHA256_MAC_LEN + 1];
|
||||
char supp_curves[100];
|
||||
|
||||
bi = dpp_bootstrap_get_id(dpp, id);
|
||||
if (!bi)
|
||||
return -1;
|
||||
wpa_snprintf_hex(pkhash, sizeof(pkhash), bi->pubkey_hash,
|
||||
SHA256_MAC_LEN);
|
||||
|
||||
supp_curves[0] = '\0';
|
||||
if (bi->supported_curves) {
|
||||
int ret;
|
||||
size_t i;
|
||||
char *pos = supp_curves;
|
||||
char *end = &supp_curves[sizeof(supp_curves)];
|
||||
const char *curve[6] = { "P-256", "P-384", "P-521",
|
||||
"BP-256", "BP-384", "BP-512" };
|
||||
|
||||
ret = os_snprintf(pos, end - pos, "supp_curves=");
|
||||
if (os_snprintf_error(end - pos, ret))
|
||||
return -1;
|
||||
pos += ret;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(curve); i++) {
|
||||
if (!(bi->supported_curves & BIT(i)))
|
||||
continue;
|
||||
ret = os_snprintf(pos, end - pos, "%s:", curve[i]);
|
||||
if (os_snprintf_error(end - pos, ret))
|
||||
return -1;
|
||||
pos += ret;
|
||||
}
|
||||
|
||||
if (pos[-1] == ':')
|
||||
pos[-1] = '\n';
|
||||
else
|
||||
supp_curves[0] = '\0';
|
||||
}
|
||||
|
||||
return os_snprintf(reply, reply_size, "type=%s\n"
|
||||
"mac_addr=" MACSTR "\n"
|
||||
"info=%s\n"
|
||||
|
@ -4266,7 +4381,7 @@ int dpp_bootstrap_info(struct dpp_global *dpp, int id,
|
|||
"use_freq=%u\n"
|
||||
"curve=%s\n"
|
||||
"pkhash=%s\n"
|
||||
"version=%d\n",
|
||||
"version=%d\n%s",
|
||||
dpp_bootstrap_type_txt(bi->type),
|
||||
MAC2STR(bi->mac_addr),
|
||||
bi->info ? bi->info : "",
|
||||
|
@ -4274,7 +4389,8 @@ int dpp_bootstrap_info(struct dpp_global *dpp, int id,
|
|||
bi->num_freq == 1 ? bi->freq[0] : 0,
|
||||
bi->curve->name,
|
||||
pkhash,
|
||||
bi->version);
|
||||
bi->version,
|
||||
supp_curves);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -146,6 +146,15 @@ enum dpp_bootstrap_type {
|
|||
DPP_BOOTSTRAP_NFC_URI,
|
||||
};
|
||||
|
||||
enum dpp_bootstrap_supported_curves {
|
||||
DPP_BOOTSTRAP_CURVE_P_256 = 0,
|
||||
DPP_BOOTSTRAP_CURVE_P_384 = 1,
|
||||
DPP_BOOTSTRAP_CURVE_P_521 = 2,
|
||||
DPP_BOOTSTRAP_CURVE_BP_256 = 3,
|
||||
DPP_BOOTSTRAP_CURVE_BP_384 = 4,
|
||||
DPP_BOOTSTRAP_CURVE_BP_512 = 5,
|
||||
};
|
||||
|
||||
struct dpp_bootstrap_info {
|
||||
struct dl_list list;
|
||||
unsigned int id;
|
||||
|
@ -159,6 +168,7 @@ struct dpp_bootstrap_info {
|
|||
unsigned int num_freq;
|
||||
bool channels_listed;
|
||||
u8 version;
|
||||
u8 supported_curves; /* enum dpp_bootstrap_supported_curves bitmap */
|
||||
int own;
|
||||
struct crypto_ec_key *pubkey;
|
||||
u8 pubkey_hash[SHA256_MAC_LEN];
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "common.h"
|
||||
|
||||
|
||||
static int hex2num(char c)
|
||||
int hex2num(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
|
|
|
@ -477,6 +477,7 @@ int hwaddr_aton(const char *txt, u8 *addr);
|
|||
int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable);
|
||||
int hwaddr_compact_aton(const char *txt, u8 *addr);
|
||||
int hwaddr_aton2(const char *txt, u8 *addr);
|
||||
int hex2num(char c);
|
||||
int hex2byte(const char *hex);
|
||||
int hexstr2bin(const char *hex, u8 *buf, size_t len);
|
||||
void inc_byte_array(u8 *counter, size_t len);
|
||||
|
|
Loading…
Reference in a new issue