WPS: Moved Credential building to use struct wps_credential
authorJouni Malinen <j@w1.fi>
Thu, 27 Nov 2008 19:14:39 +0000 (21:14 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 27 Nov 2008 19:14:39 +0000 (21:14 +0200)
This makes it easier to store old AP settings into wps->cred (and allow
them to modified and taken into use in the future). Separation between
Credential and AP Settings building is also cleaner in this design.

src/wps/wps_registrar.c

index 8f0be20..be5b73f 100644 (file)
@@ -758,7 +758,8 @@ static int wps_build_r_snonce2(struct wps_data *wps, struct wpabuf *msg)
 }
 
 
-static int wps_build_cred_network_idx(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_network_idx(struct wpabuf *msg,
+                                     struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * Network Index");
        wpabuf_put_be16(msg, ATTR_NETWORK_INDEX);
@@ -768,96 +769,73 @@ static int wps_build_cred_network_idx(struct wps_data *wps, struct wpabuf *msg)
 }
 
 
-static int wps_build_cred_ssid(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_ssid(struct wpabuf *msg,
+                              struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * SSID");
        wpabuf_put_be16(msg, ATTR_SSID);
-       wpabuf_put_be16(msg, wps->wps->ssid_len);
-       wpabuf_put_data(msg, wps->wps->ssid, wps->wps->ssid_len);
+       wpabuf_put_be16(msg, cred->ssid_len);
+       wpabuf_put_data(msg, cred->ssid, cred->ssid_len);
        return 0;
 }
 
 
-static int wps_build_cred_auth_type(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_auth_type(struct wpabuf *msg,
+                                   struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * Authentication Type (0x%x)",
-                  wps->auth_type);
+                  cred->auth_type);
        wpabuf_put_be16(msg, ATTR_AUTH_TYPE);
        wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, wps->auth_type);
+       wpabuf_put_be16(msg, cred->auth_type);
        return 0;
 }
 
 
-static int wps_build_cred_encr_type(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_encr_type(struct wpabuf *msg,
+                                   struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * Encryption Type (0x%x)",
-                  wps->encr_type);
+                  cred->encr_type);
        wpabuf_put_be16(msg, ATTR_ENCR_TYPE);
        wpabuf_put_be16(msg, 2);
-       wpabuf_put_be16(msg, wps->encr_type);
+       wpabuf_put_be16(msg, cred->encr_type);
        return 0;
 }
 
 
-static int wps_build_cred_network_key(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_network_key(struct wpabuf *msg,
+                                     struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * Network Key");
        wpabuf_put_be16(msg, ATTR_NETWORK_KEY);
-       if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap) {
-               u8 r[16];
-               /* Generate a random passphrase */
-               if (os_get_random(r, sizeof(r)) < 0)
-                       return -1;
-               os_free(wps->new_psk);
-               wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
-               if (wps->new_psk == NULL)
-                       return -1;
-               wps->new_psk_len--; /* remove newline */
-               while (wps->new_psk_len &&
-                      wps->new_psk[wps->new_psk_len - 1] == '=')
-                       wps->new_psk_len--;
-               wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
-                                     wps->new_psk, wps->new_psk_len);
-               wpabuf_put_be16(msg, wps->new_psk_len);
-               wpabuf_put_data(msg, wps->new_psk, wps->new_psk_len);
-       } else if (wps->wps->network_key) {
-               wpabuf_put_be16(msg, wps->wps->network_key_len);
-               wpabuf_put_data(msg, wps->wps->network_key,
-                               wps->wps->network_key_len);
-       } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
-               char hex[65];
-               /* Generate a random per-device PSK */
-               os_free(wps->new_psk);
-               wps->new_psk_len = 32;
-               wps->new_psk = os_malloc(wps->new_psk_len);
-               if (wps->new_psk == NULL)
-                       return -1;
-               if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
-                       os_free(wps->new_psk);
-                       wps->new_psk = NULL;
-                       return -1;
-               }
-               wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
-                               wps->new_psk, wps->new_psk_len);
-               wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
-                                wps->new_psk_len);
-               wpabuf_put_be16(msg, wps->new_psk_len * 2);
-               wpabuf_put_data(msg, hex, wps->new_psk_len * 2);
-       } else {
-               /* No Network Key */
-               wpabuf_put_be16(msg, 0);
-       }
+       wpabuf_put_be16(msg, cred->key_len);
+       wpabuf_put_data(msg, cred->key, cred->key_len);
        return 0;
 }
 
 
-static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
+static int wps_build_cred_mac_addr(struct wpabuf *msg,
+                                  struct wps_credential *cred)
 {
        wpa_printf(MSG_DEBUG, "WPS:  * MAC Address");
        wpabuf_put_be16(msg, ATTR_MAC_ADDR);
        wpabuf_put_be16(msg, ETH_ALEN);
-       wpabuf_put_data(msg, wps->mac_addr_e, ETH_ALEN);
+       wpabuf_put_data(msg, cred->mac_addr, ETH_ALEN);
+       return 0;
+}
+
+
+static int wps_build_credential(struct wpabuf *msg,
+                               struct wps_credential *cred)
+{
+       if (wps_build_cred_network_idx(msg, cred) ||
+           wps_build_cred_ssid(msg, cred) ||
+           wps_build_cred_auth_type(msg, cred) ||
+           wps_build_cred_encr_type(msg, cred) ||
+           wps_build_cred_network_key(msg, cred) ||
+           wps_build_cred_mac_addr(msg, cred))
+               return -1;
        return 0;
 }
 
@@ -865,14 +843,12 @@ static int wps_build_cred_mac_addr(struct wps_data *wps, struct wpabuf *msg)
 static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
 {
        struct wpabuf *cred;
-       int ap_settings;
 
-       ap_settings = !wps->wps->ap;
+       wpa_printf(MSG_DEBUG, "WPS:  * Credential");
+       os_memset(&wps->cred, 0, sizeof(wps->cred));
 
-       if (ap_settings)
-               wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
-       else
-               wpa_printf(MSG_DEBUG, "WPS:  * Credential");
+       os_memcpy(wps->cred.ssid, wps->wps->ssid, wps->wps->ssid_len);
+       wps->cred.ssid_len = wps->wps->ssid_len;
 
        /* Select the best authentication and encryption type */
        if (wps->auth_type & WPS_AUTH_WPA2PSK)
@@ -888,6 +864,7 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
                           wps->auth_type);
                return -1;
        }
+       wps->cred.auth_type = wps->auth_type;
 
        if (wps->auth_type == WPS_AUTH_WPA2PSK ||
            wps->auth_type == WPS_AUTH_WPAPSK) {
@@ -911,30 +888,75 @@ static int wps_build_cred(struct wps_data *wps, struct wpabuf *msg)
                        return -1;
                }
        }
+       wps->cred.encr_type = wps->encr_type;
+       os_memcpy(wps->cred.mac_addr, wps->mac_addr_e, ETH_ALEN);
+
+       if (wps->wps->wps_state == WPS_STATE_NOT_CONFIGURED && wps->wps->ap) {
+               u8 r[16];
+               /* Generate a random passphrase */
+               if (os_get_random(r, sizeof(r)) < 0)
+                       return -1;
+               os_free(wps->new_psk);
+               wps->new_psk = base64_encode(r, sizeof(r), &wps->new_psk_len);
+               if (wps->new_psk == NULL)
+                       return -1;
+               wps->new_psk_len--; /* remove newline */
+               while (wps->new_psk_len &&
+                      wps->new_psk[wps->new_psk_len - 1] == '=')
+                       wps->new_psk_len--;
+               wpa_hexdump_ascii_key(MSG_DEBUG, "WPS: Generated passphrase",
+                                     wps->new_psk, wps->new_psk_len);
+               os_memcpy(wps->cred.key, wps->new_psk, wps->new_psk_len);
+               wps->cred.key_len = wps->new_psk_len;
+       } else if (wps->wps->network_key) {
+               os_memcpy(wps->cred.key, wps->wps->network_key,
+                         wps->wps->network_key_len);
+               wps->cred.key_len = wps->wps->network_key_len;
+       } else if (wps->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK)) {
+               char hex[65];
+               /* Generate a random per-device PSK */
+               os_free(wps->new_psk);
+               wps->new_psk_len = 32;
+               wps->new_psk = os_malloc(wps->new_psk_len);
+               if (wps->new_psk == NULL)
+                       return -1;
+               if (os_get_random(wps->new_psk, wps->new_psk_len) < 0) {
+                       os_free(wps->new_psk);
+                       wps->new_psk = NULL;
+                       return -1;
+               }
+               wpa_hexdump_key(MSG_DEBUG, "WPS: Generated per-device PSK",
+                               wps->new_psk, wps->new_psk_len);
+               wpa_snprintf_hex(hex, sizeof(hex), wps->new_psk,
+                                wps->new_psk_len);
+               os_memcpy(wps->cred.key, hex, wps->new_psk_len * 2);
+               wps->cred.key_len = wps->new_psk_len * 2;
+       }
 
        cred = wpabuf_alloc(200);
        if (cred == NULL)
                return -1;
 
-       if (wps_build_cred_network_idx(wps, cred) ||
-           wps_build_cred_ssid(wps, cred) ||
-           wps_build_cred_auth_type(wps, cred) ||
-           wps_build_cred_encr_type(wps, cred) ||
-           wps_build_cred_network_key(wps, cred) ||
-           wps_build_cred_mac_addr(wps, cred)) {
+       if (wps_build_credential(cred, &wps->cred)) {
                wpabuf_free(cred);
                return -1;
        }
 
-       if (ap_settings) {
-               wpabuf_put_buf(msg, cred);
-               wpabuf_free(cred);
-       } else {
-               wpabuf_put_be16(msg, ATTR_CRED);
-               wpabuf_put_be16(msg, wpabuf_len(cred));
-               wpabuf_put_buf(msg, cred);
-               wpabuf_free(cred);
-       }
+       wpabuf_put_be16(msg, ATTR_CRED);
+       wpabuf_put_be16(msg, wpabuf_len(cred));
+       wpabuf_put_buf(msg, cred);
+       wpabuf_free(cred);
+
+       return 0;
+}
+
+
+static int wps_build_ap_settings(struct wps_data *wps, struct wpabuf *msg)
+{
+       wpa_printf(MSG_DEBUG, "WPS:  * AP Settings");
+
+       if (wps_build_credential(msg, &wps->cred))
+               return -1;
 
        return 0;
 }
@@ -1106,7 +1128,8 @@ static struct wpabuf * wps_build_m8(struct wps_data *wps)
        if (wps_build_version(msg) ||
            wps_build_msg_type(msg, WPS_M8) ||
            wps_build_enrollee_nonce(wps, msg) ||
-           wps_build_cred(wps, plain) ||
+           (wps->wps->ap && wps_build_cred(wps, plain)) ||
+           (!wps->wps->ap && wps_build_ap_settings(wps, plain)) ||
            wps_build_key_wrap_auth(wps, plain) ||
            wps_build_encr_settings(wps, msg, plain) ||
            wps_build_authenticator(wps, msg)) {
@@ -1659,13 +1682,11 @@ static enum wps_process_res wps_process_m5(struct wps_data *wps,
 static int wps_process_ap_settings_r(struct wps_data *wps,
                                     struct wps_parse_attr *attr)
 {
-       struct wps_credential cred;
-
        if (wps->wps->ap)
                return 0;
 
        /* AP Settings Attributes in M7 when Enrollee is an AP */
-       if (wps_process_ap_settings(attr, &cred) < 0)
+       if (wps_process_ap_settings(attr, &wps->cred) < 0)
                return -1;
 
        wpa_printf(MSG_INFO, "WPS: Received old AP configuration from AP");
@@ -1674,17 +1695,6 @@ static int wps_process_ap_settings_r(struct wps_data *wps,
         * TODO: Provide access to AP settings and allow changes before sending
         * out M8. For now, just copy the settings unchanged into M8.
         */
-       wps->auth_type = cred.auth_type;
-       wps->encr_type = cred.encr_type;
-       os_memcpy(wps->wps->ssid, cred.ssid, cred.ssid_len);
-       wps->wps->ssid_len = cred.ssid_len;
-       os_memcpy(wps->mac_addr_e, cred.mac_addr, ETH_ALEN);
-       os_free(wps->wps->network_key);
-       wps->wps->network_key = os_malloc(cred.key_len);
-       if (wps->wps->network_key) {
-               os_memcpy(wps->wps->network_key, cred.key, cred.key_len);
-               wps->wps->network_key_len = cred.key_len;
-       }
 
        return 0;
 }