From e780b4bf2032d1cdea76e515a7ebaffda484e53e Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Dec 2019 18:22:36 +0200 Subject: [PATCH] DPP: Bootstrapping via NFC URI Record This extends hostapd and wpa_supplicant DPP implementation to allow the bootstrapping URI to be generated for and parsed from an NFC Tag with an NFC URI Record. This is similar to the way the bootstrapping URI is used with QR Code for unidirectional authentication. The DPP_BOOTSTRAP_GEN command uses "type=nfc-uri" to request the URI to be assigned for NFC URI Record. In practice, the URI is generated identically to the QR Code case, but the internal entry maintains the NFC-URI type. A new command "DPP_NFC_URI " can now be used to parse the URI read from an NFC Tag with the NFC URI Record. This is similar to the DPP_QR_CODE command. Other commands (mainly, DPP_LISTEN and DPP_AUTH_INIT) are used for NFC URI in the same way as they are used for QR Code. Signed-off-by: Jouni Malinen --- hostapd/ctrl_iface.c | 9 ++++++++ src/ap/dpp_hostapd.c | 19 +++++++++++++++++ src/ap/dpp_hostapd.h | 2 ++ src/common/dpp.c | 37 ++++++++++++++++++++++----------- src/common/dpp.h | 4 +++- wpa_supplicant/ctrl_iface.c | 11 ++++++++++ wpa_supplicant/dpp_supplicant.c | 18 ++++++++++++++++ wpa_supplicant/dpp_supplicant.h | 1 + 8 files changed, 88 insertions(+), 13 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 00febc30f..8692284d1 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3318,6 +3318,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, if (os_snprintf_error(reply_size, reply_len)) reply_len = -1; } + } else if (os_strncmp(buf, "DPP_NFC_URI ", 12) == 0) { + res = hostapd_dpp_nfc_uri(hapd, buf + 12); + if (res < 0) { + reply_len = -1; + } else { + reply_len = os_snprintf(reply, reply_size, "%d", res); + if (os_snprintf_error(reply_size, reply_len)) + reply_len = -1; + } } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) { res = dpp_bootstrap_gen(hapd->iface->interfaces->dpp, buf + 18); if (res < 0) { diff --git a/src/ap/dpp_hostapd.c b/src/ap/dpp_hostapd.c index 085d42325..64158fc7e 100644 --- a/src/ap/dpp_hostapd.c +++ b/src/ap/dpp_hostapd.c @@ -1,6 +1,7 @@ /* * hostapd / DPP integration * Copyright (c) 2017, Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -62,6 +63,24 @@ int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd) } +/** + * hostapd_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI) + * @hapd: Pointer to hostapd_data + * @cmd: DPP URI read from a NFC Tag (URI NDEF message) + * Returns: Identifier of the stored info or -1 on failure + */ +int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd) +{ + struct dpp_bootstrap_info *bi; + + bi = dpp_add_nfc_uri(hapd->iface->interfaces->dpp, cmd); + if (!bi) + return -1; + + return bi->id; +} + + static void hostapd_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx) { diff --git a/src/ap/dpp_hostapd.h b/src/ap/dpp_hostapd.h index c1ec5d70e..e151c2fc6 100644 --- a/src/ap/dpp_hostapd.h +++ b/src/ap/dpp_hostapd.h @@ -1,6 +1,7 @@ /* * hostapd / DPP integration * Copyright (c) 2017, Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -10,6 +11,7 @@ #define DPP_HOSTAPD_H int hostapd_dpp_qr_code(struct hostapd_data *hapd, const char *cmd); +int hostapd_dpp_nfc_uri(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_auth_init(struct hostapd_data *hapd, const char *cmd); int hostapd_dpp_listen(struct hostapd_data *hapd, const char *cmd); void hostapd_dpp_listen_stop(struct hostapd_data *hapd); diff --git a/src/common/dpp.c b/src/common/dpp.c index 6c20fc1e6..834fae0e0 100644 --- a/src/common/dpp.c +++ b/src/common/dpp.c @@ -830,6 +830,8 @@ const char * dpp_bootstrap_type_txt(enum dpp_bootstrap_type type) return "QRCODE"; case DPP_BOOTSTRAP_PKEX: return "PKEX"; + case DPP_BOOTSTRAP_NFC_URI: + return "NFC-URI"; } return "??"; } @@ -1181,17 +1183,6 @@ static struct dpp_bootstrap_info * dpp_parse_uri(const char *uri) } -struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri) -{ - struct dpp_bootstrap_info *bi; - - bi = dpp_parse_uri(uri); - if (bi) - bi->type = DPP_BOOTSTRAP_QR_CODE; - return bi; -} - - static void dpp_debug_print_key(const char *title, EVP_PKEY *key) { EC_KEY *eckey; @@ -8959,10 +8950,30 @@ struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp, if (!dpp) return NULL; - bi = dpp_parse_qr_code(uri); + bi = dpp_parse_uri(uri); if (!bi) return NULL; + bi->type = DPP_BOOTSTRAP_QR_CODE; + bi->id = dpp_next_id(dpp); + dl_list_add(&dpp->bootstrap, &bi->list); + return bi; +} + + +struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp, + const char *uri) +{ + struct dpp_bootstrap_info *bi; + + if (!dpp) + return NULL; + + bi = dpp_parse_uri(uri); + if (!bi) + return NULL; + + bi->type = DPP_BOOTSTRAP_NFC_URI; bi->id = dpp_next_id(dpp); dl_list_add(&dpp->bootstrap, &bi->list); return bi; @@ -8990,6 +9001,8 @@ int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd) bi->type = DPP_BOOTSTRAP_QR_CODE; else if (os_strstr(cmd, "type=pkex")) bi->type = DPP_BOOTSTRAP_PKEX; + else if (os_strstr(cmd, "type=nfc-uri")) + bi->type = DPP_BOOTSTRAP_NFC_URI; else goto fail; diff --git a/src/common/dpp.h b/src/common/dpp.h index 2a558b63c..7d14e76d3 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -106,6 +106,7 @@ struct dpp_curve_params { enum dpp_bootstrap_type { DPP_BOOTSTRAP_QR_CODE, DPP_BOOTSTRAP_PKEX, + DPP_BOOTSTRAP_NFC_URI, }; struct dpp_bootstrap_info { @@ -414,7 +415,6 @@ int dpp_parse_uri_chan_list(struct dpp_bootstrap_info *bi, const char *chan_list); int dpp_parse_uri_mac(struct dpp_bootstrap_info *bi, const char *mac); int dpp_parse_uri_info(struct dpp_bootstrap_info *bi, const char *info); -struct dpp_bootstrap_info * dpp_parse_qr_code(const char *uri); char * dpp_keygen(struct dpp_bootstrap_info *bi, const char *curve, const u8 *privkey, size_t privkey_len); struct hostapd_hw_modes; @@ -534,6 +534,8 @@ void dpp_pfs_free(struct dpp_pfs *pfs); struct dpp_bootstrap_info * dpp_add_qr_code(struct dpp_global *dpp, const char *uri); +struct dpp_bootstrap_info * dpp_add_nfc_uri(struct dpp_global *dpp, + const char *uri); int dpp_bootstrap_gen(struct dpp_global *dpp, const char *cmd); struct dpp_bootstrap_info * dpp_bootstrap_get_id(struct dpp_global *dpp, unsigned int id); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 7f8ec4a6a..f238bc73f 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10678,6 +10678,17 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (os_snprintf_error(reply_size, reply_len)) reply_len = -1; } + } else if (os_strncmp(buf, "DPP_NFC_URI ", 12) == 0) { + int res; + + res = wpas_dpp_nfc_uri(wpa_s, buf + 12); + if (res < 0) { + reply_len = -1; + } else { + reply_len = os_snprintf(reply, reply_size, "%d", res); + if (os_snprintf_error(reply_size, reply_len)) + reply_len = -1; + } } else if (os_strncmp(buf, "DPP_BOOTSTRAP_GEN ", 18) == 0) { int res; diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index 78adab613..80d2c9ce7 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -88,6 +88,24 @@ int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd) } +/** + * wpas_dpp_nfc_uri - Parse and add DPP bootstrapping info from NFC Tag (URI) + * @wpa_s: Pointer to wpa_supplicant data + * @cmd: DPP URI read from a NFC Tag (URI NDEF message) + * Returns: Identifier of the stored info or -1 on failure + */ +int wpas_dpp_nfc_uri(struct wpa_supplicant *wpa_s, const char *cmd) +{ + struct dpp_bootstrap_info *bi; + + bi = dpp_add_nfc_uri(wpa_s->dpp, cmd); + if (!bi) + return -1; + + return bi->id; +} + + static void wpas_dpp_auth_resp_retry_timeout(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; diff --git a/wpa_supplicant/dpp_supplicant.h b/wpa_supplicant/dpp_supplicant.h index b33798265..607036a38 100644 --- a/wpa_supplicant/dpp_supplicant.h +++ b/wpa_supplicant/dpp_supplicant.h @@ -13,6 +13,7 @@ enum dpp_status_error; int wpas_dpp_qr_code(struct wpa_supplicant *wpa_s, const char *cmd); +int wpas_dpp_nfc_uri(struct wpa_supplicant *wpa_s, const char *cmd); int wpas_dpp_auth_init(struct wpa_supplicant *wpa_s, const char *cmd); int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd); void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s);