]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EXT PW: Add support for psk parameter from external storage
authorJouni Malinen <j@w1.fi>
Fri, 3 Aug 2012 18:36:38 +0000 (21:36 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 3 Aug 2012 19:15:42 +0000 (22:15 +0300)
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>

wpa_supplicant/config.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant.conf

index 9d7f38ed11c8396b341b421fb131780457941401..70c28fe858b60baca26cf1c394c28272c0a6d660 100644 (file)
@@ -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 */
index 9247195479b8c501866dabb9744ccd37bd5f0fda..61fbec99cb804cd3424eb0a35f0fa3a64bea47c0 100644 (file)
@@ -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;
index 05a2d0bc2d89373448031723af81d6008312654f..9f1cd00fb1d2651e531182bacd7b1f675f7f0e01 100644 (file)
@@ -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