EXT PW: Add support for psk parameter from external storage
This allows wpa_supplicant configuration file to be created without the PSK/passphrase value included in the file when a backend for external password storage is available. Following example can be used for developer testing: ext_password_backend=test:psk1=12345678 network={ ssid="test-psk" key_mgmt=WPA-PSK psk=ext:psk1 } Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
306ae22556
commit
9173b16fd1
3 changed files with 88 additions and 2 deletions
|
@ -324,6 +324,21 @@ static int wpa_config_parse_psk(const struct parse_data *data,
|
|||
struct wpa_ssid *ssid, int line,
|
||||
const char *value)
|
||||
{
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
if (os_strncmp(value, "ext:", 4) == 0) {
|
||||
os_free(ssid->passphrase);
|
||||
ssid->passphrase = NULL;
|
||||
ssid->psk_set = 0;
|
||||
os_free(ssid->ext_psk);
|
||||
ssid->ext_psk = os_strdup(value + 4);
|
||||
if (ssid->ext_psk == NULL)
|
||||
return -1;
|
||||
wpa_printf(MSG_DEBUG, "PSK: External password '%s'",
|
||||
ssid->ext_psk);
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
||||
|
||||
if (*value == '"') {
|
||||
#ifndef CONFIG_NO_PBKDF2
|
||||
const char *pos;
|
||||
|
@ -381,6 +396,17 @@ static int wpa_config_parse_psk(const struct parse_data *data,
|
|||
static char * wpa_config_write_psk(const struct parse_data *data,
|
||||
struct wpa_ssid *ssid)
|
||||
{
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
if (ssid->ext_psk) {
|
||||
size_t len = 4 + os_strlen(ssid->ext_psk) + 1;
|
||||
char *buf = os_malloc(len);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
os_snprintf(buf, len, "ext:%s", ssid->ext_psk);
|
||||
return buf;
|
||||
}
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
||||
|
||||
if (ssid->passphrase)
|
||||
return wpa_config_write_string_ascii(
|
||||
(const u8 *) ssid->passphrase,
|
||||
|
@ -1771,6 +1797,7 @@ void wpa_config_free_ssid(struct wpa_ssid *ssid)
|
|||
{
|
||||
os_free(ssid->ssid);
|
||||
os_free(ssid->passphrase);
|
||||
os_free(ssid->ext_psk);
|
||||
#ifdef IEEE8021X_EAPOL
|
||||
eap_peer_config_free(&ssid->eap);
|
||||
#endif /* IEEE8021X_EAPOL */
|
||||
|
|
|
@ -1104,6 +1104,63 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
|||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
|
||||
}
|
||||
#endif /* CONFIG_NO_PBKDF2 */
|
||||
#ifdef CONFIG_EXT_PASSWORD
|
||||
if (ssid->ext_psk) {
|
||||
struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
|
||||
ssid->ext_psk);
|
||||
char pw_str[64 + 1];
|
||||
u8 psk[PMK_LEN];
|
||||
|
||||
if (pw == NULL) {
|
||||
wpa_msg(wpa_s, MSG_INFO, "EXT PW: No PSK "
|
||||
"found from external storage");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wpabuf_len(pw) < 8 || wpabuf_len(pw) > 64) {
|
||||
wpa_msg(wpa_s, MSG_INFO, "EXT PW: Unexpected "
|
||||
"PSK length %d in external storage",
|
||||
(int) wpabuf_len(pw));
|
||||
ext_password_free(pw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(pw_str, wpabuf_head(pw), wpabuf_len(pw));
|
||||
pw_str[wpabuf_len(pw)] = '\0';
|
||||
|
||||
#ifndef CONFIG_NO_PBKDF2
|
||||
if (wpabuf_len(pw) >= 8 && wpabuf_len(pw) < 64 && bss)
|
||||
{
|
||||
pbkdf2_sha1(pw_str, (char *) bss->ssid,
|
||||
bss->ssid_len, 4096, psk, PMK_LEN);
|
||||
os_memset(pw_str, 0, sizeof(pw_str));
|
||||
wpa_hexdump_key(MSG_MSGDUMP, "PSK (from "
|
||||
"external passphrase)",
|
||||
psk, PMK_LEN);
|
||||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
|
||||
} else
|
||||
#endif /* CONFIG_NO_PBKDF2 */
|
||||
if (wpabuf_len(pw) == 2 * PMK_LEN) {
|
||||
if (hexstr2bin(pw_str, psk, PMK_LEN) < 0) {
|
||||
wpa_msg(wpa_s, MSG_INFO, "EXT PW: "
|
||||
"Invalid PSK hex string");
|
||||
os_memset(pw_str, 0, sizeof(pw_str));
|
||||
ext_password_free(pw);
|
||||
return -1;
|
||||
}
|
||||
wpa_sm_set_pmk(wpa_s->wpa, psk, PMK_LEN);
|
||||
} else {
|
||||
wpa_msg(wpa_s, MSG_INFO, "EXT PW: No suitable "
|
||||
"PSK available");
|
||||
os_memset(pw_str, 0, sizeof(pw_str));
|
||||
ext_password_free(pw);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memset(pw_str, 0, sizeof(pw_str));
|
||||
ext_password_free(pw);
|
||||
}
|
||||
#endif /* CONFIG_EXT_PASSWORD */
|
||||
} else
|
||||
wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
|
||||
|
||||
|
@ -3430,7 +3487,8 @@ int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
|
|||
return 1; /* invalid WEP key */
|
||||
}
|
||||
|
||||
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set)
|
||||
if (wpa_key_mgmt_wpa_psk(ssid->key_mgmt) && !ssid->psk_set &&
|
||||
!ssid->ext_psk)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -508,7 +508,8 @@ fast_reauth=1
|
|||
# The key used in WPA-PSK mode can be entered either as 64 hex-digits, i.e.,
|
||||
# 32 bytes or as an ASCII passphrase (in which case, the real PSK will be
|
||||
# generated using the passphrase and SSID). ASCII passphrase must be between
|
||||
# 8 and 63 characters (inclusive).
|
||||
# 8 and 63 characters (inclusive). ext:<name of external PSK field> format can
|
||||
# be used to indicate that the PSK/passphrase is stored in external storage.
|
||||
# This field is not needed, if WPA-EAP is used.
|
||||
# Note: Separate tool, wpa_passphrase, can be used to generate 256-bit keys
|
||||
# from ASCII passphrase. This process uses lot of CPU and wpa_supplicant
|
||||
|
|
Loading…
Reference in a new issue