wps_attr_process.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha256.h"
00020 #include "wps_i.h"
00021 
00022 
00023 int wps_process_authenticator(struct wps_data *wps, const u8 *authenticator,
00024                               const struct wpabuf *msg)
00025 {
00026         u8 hash[SHA256_MAC_LEN];
00027         const u8 *addr[2];
00028         size_t len[2];
00029 
00030         if (authenticator == NULL) {
00031                 wpa_printf(MSG_DEBUG, "WPS: No Authenticator attribute "
00032                            "included");
00033                 return -1;
00034         }
00035 
00036         if (wps->last_msg == NULL) {
00037                 wpa_printf(MSG_DEBUG, "WPS: Last message not available for "
00038                            "validating authenticator");
00039                 return -1;
00040         }
00041 
00042         /* Authenticator = HMAC-SHA256_AuthKey(M_prev || M_curr*)
00043          * (M_curr* is M_curr without the Authenticator attribute)
00044          */
00045         addr[0] = wpabuf_head(wps->last_msg);
00046         len[0] = wpabuf_len(wps->last_msg);
00047         addr[1] = wpabuf_head(msg);
00048         len[1] = wpabuf_len(msg) - 4 - WPS_AUTHENTICATOR_LEN;
00049         hmac_sha256_vector(wps->authkey, WPS_AUTHKEY_LEN, 2, addr, len, hash);
00050 
00051         if (os_memcmp(hash, authenticator, WPS_AUTHENTICATOR_LEN) != 0) {
00052                 wpa_printf(MSG_DEBUG, "WPS: Incorrect Authenticator");
00053                 return -1;
00054         }
00055 
00056         return 0;
00057 }
00058 
00059 
00060 int wps_process_key_wrap_auth(struct wps_data *wps, struct wpabuf *msg,
00061                               const u8 *key_wrap_auth)
00062 {
00063         u8 hash[SHA256_MAC_LEN];
00064         const u8 *head;
00065         size_t len;
00066 
00067         if (key_wrap_auth == NULL) {
00068                 wpa_printf(MSG_DEBUG, "WPS: No KWA in decrypted attribute");
00069                 return -1;
00070         }
00071 
00072         head = wpabuf_head(msg);
00073         len = wpabuf_len(msg) - 4 - WPS_KWA_LEN;
00074         if (head + len != key_wrap_auth - 4) {
00075                 wpa_printf(MSG_DEBUG, "WPS: KWA not in the end of the "
00076                            "decrypted attribute");
00077                 return -1;
00078         }
00079 
00080         hmac_sha256(wps->authkey, WPS_AUTHKEY_LEN, head, len, hash);
00081         if (os_memcmp(hash, key_wrap_auth, WPS_KWA_LEN) != 0) {
00082                 wpa_printf(MSG_DEBUG, "WPS: Invalid KWA");
00083                 return -1;
00084         }
00085 
00086         return 0;
00087 }
00088 
00089 
00090 static int wps_process_cred_network_idx(struct wps_credential *cred,
00091                                         const u8 *idx)
00092 {
00093         if (idx == NULL) {
00094                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00095                            "Network Index");
00096                 return -1;
00097         }
00098 
00099         wpa_printf(MSG_DEBUG, "WPS: Network Index: %d", *idx);
00100 
00101         return 0;
00102 }
00103 
00104 
00105 static int wps_process_cred_ssid(struct wps_credential *cred, const u8 *ssid,
00106                                  size_t ssid_len)
00107 {
00108         if (ssid == NULL) {
00109                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include SSID");
00110                 return -1;
00111         }
00112 
00113         /* Remove zero-padding since some Registrar implementations seem to use
00114          * hardcoded 32-octet length for this attribute */
00115         while (ssid_len > 0 && ssid[ssid_len - 1] == 0)
00116                 ssid_len--;
00117 
00118         wpa_hexdump_ascii(MSG_DEBUG, "WPS: SSID", ssid, ssid_len);
00119         if (ssid_len <= sizeof(cred->ssid)) {
00120                 os_memcpy(cred->ssid, ssid, ssid_len);
00121                 cred->ssid_len = ssid_len;
00122         }
00123 
00124         return 0;
00125 }
00126 
00127 
00128 static int wps_process_cred_auth_type(struct wps_credential *cred,
00129                                       const u8 *auth_type)
00130 {
00131         if (auth_type == NULL) {
00132                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00133                            "Authentication Type");
00134                 return -1;
00135         }
00136 
00137         cred->auth_type = WPA_GET_BE16(auth_type);
00138         wpa_printf(MSG_DEBUG, "WPS: Authentication Type: 0x%x",
00139                    cred->auth_type);
00140 
00141         return 0;
00142 }
00143 
00144 
00145 static int wps_process_cred_encr_type(struct wps_credential *cred,
00146                                       const u8 *encr_type)
00147 {
00148         if (encr_type == NULL) {
00149                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00150                            "Encryption Type");
00151                 return -1;
00152         }
00153 
00154         cred->encr_type = WPA_GET_BE16(encr_type);
00155         wpa_printf(MSG_DEBUG, "WPS: Encryption Type: 0x%x",
00156                    cred->encr_type);
00157 
00158         return 0;
00159 }
00160 
00161 
00162 static int wps_process_cred_network_key_idx(struct wps_credential *cred,
00163                                             const u8 *key_idx)
00164 {
00165         if (key_idx == NULL)
00166                 return 0; /* optional attribute */
00167 
00168         wpa_printf(MSG_DEBUG, "WPS: Network Key Index: %d", *key_idx);
00169         cred->key_idx = *key_idx;
00170 
00171         return 0;
00172 }
00173 
00174 
00175 static int wps_process_cred_network_key(struct wps_credential *cred,
00176                                         const u8 *key, size_t key_len)
00177 {
00178         if (key == NULL) {
00179                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00180                            "Network Key");
00181                 return -1;
00182         }
00183 
00184         wpa_hexdump_key(MSG_DEBUG, "WPS: Network Key", key, key_len);
00185         if (key_len <= sizeof(cred->key)) {
00186                 os_memcpy(cred->key, key, key_len);
00187                 cred->key_len = key_len;
00188         }
00189 
00190         return 0;
00191 }
00192 
00193 
00194 static int wps_process_cred_mac_addr(struct wps_credential *cred,
00195                                      const u8 *mac_addr)
00196 {
00197         if (mac_addr == NULL) {
00198                 wpa_printf(MSG_DEBUG, "WPS: Credential did not include "
00199                            "MAC Address");
00200                 return -1;
00201         }
00202 
00203         wpa_printf(MSG_DEBUG, "WPS: MAC Address " MACSTR, MAC2STR(mac_addr));
00204         os_memcpy(cred->mac_addr, mac_addr, ETH_ALEN);
00205 
00206         return 0;
00207 }
00208 
00209 
00210 static int wps_process_cred_eap_type(struct wps_credential *cred,
00211                                      const u8 *eap_type, size_t eap_type_len)
00212 {
00213         if (eap_type == NULL)
00214                 return 0; /* optional attribute */
00215 
00216         wpa_hexdump(MSG_DEBUG, "WPS: EAP Type", eap_type, eap_type_len);
00217 
00218         return 0;
00219 }
00220 
00221 
00222 static int wps_process_cred_eap_identity(struct wps_credential *cred,
00223                                          const u8 *identity,
00224                                          size_t identity_len)
00225 {
00226         if (identity == NULL)
00227                 return 0; /* optional attribute */
00228 
00229         wpa_hexdump_ascii(MSG_DEBUG, "WPS: EAP Identity",
00230                           identity, identity_len);
00231 
00232         return 0;
00233 }
00234 
00235 
00236 static int wps_process_cred_key_prov_auto(struct wps_credential *cred,
00237                                           const u8 *key_prov_auto)
00238 {
00239         if (key_prov_auto == NULL)
00240                 return 0; /* optional attribute */
00241 
00242         wpa_printf(MSG_DEBUG, "WPS: Key Provided Automatically: %d",
00243                    *key_prov_auto);
00244 
00245         return 0;
00246 }
00247 
00248 
00249 static int wps_process_cred_802_1x_enabled(struct wps_credential *cred,
00250                                            const u8 *dot1x_enabled)
00251 {
00252         if (dot1x_enabled == NULL)
00253                 return 0; /* optional attribute */
00254 
00255         wpa_printf(MSG_DEBUG, "WPS: 802.1X Enabled: %d", *dot1x_enabled);
00256 
00257         return 0;
00258 }
00259 
00260 
00261 static void wps_workaround_cred_key(struct wps_credential *cred)
00262 {
00263         if (cred->auth_type & (WPS_AUTH_WPAPSK | WPS_AUTH_WPA2PSK) &&
00264             cred->key_len > 8 && cred->key_len < 64 &&
00265             cred->key[cred->key_len - 1] == 0) {
00266                 /*
00267                  * A deployed external registrar is known to encode ASCII
00268                  * passphrases incorrectly. Remove the extra NULL termination
00269                  * to fix the encoding.
00270                  */
00271                 wpa_printf(MSG_DEBUG, "WPS: Workaround - remove NULL "
00272                            "termination from ASCII passphrase");
00273                 cred->key_len--;
00274         }
00275 }
00276 
00277 
00278 int wps_process_cred(struct wps_parse_attr *attr,
00279                      struct wps_credential *cred)
00280 {
00281         wpa_printf(MSG_DEBUG, "WPS: Process Credential");
00282 
00283         /* TODO: support multiple Network Keys */
00284         if (wps_process_cred_network_idx(cred, attr->network_idx) ||
00285             wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
00286             wps_process_cred_auth_type(cred, attr->auth_type) ||
00287             wps_process_cred_encr_type(cred, attr->encr_type) ||
00288             wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
00289             wps_process_cred_network_key(cred, attr->network_key,
00290                                          attr->network_key_len) ||
00291             wps_process_cred_mac_addr(cred, attr->mac_addr) ||
00292             wps_process_cred_eap_type(cred, attr->eap_type,
00293                                       attr->eap_type_len) ||
00294             wps_process_cred_eap_identity(cred, attr->eap_identity,
00295                                           attr->eap_identity_len) ||
00296             wps_process_cred_key_prov_auto(cred, attr->key_prov_auto) ||
00297             wps_process_cred_802_1x_enabled(cred, attr->dot1x_enabled))
00298                 return -1;
00299 
00300         wps_workaround_cred_key(cred);
00301 
00302         return 0;
00303 }
00304 
00305 
00306 int wps_process_ap_settings(struct wps_parse_attr *attr,
00307                             struct wps_credential *cred)
00308 {
00309         wpa_printf(MSG_DEBUG, "WPS: Processing AP Settings");
00310         os_memset(cred, 0, sizeof(*cred));
00311         /* TODO: optional attributes New Password and Device Password ID */
00312         if (wps_process_cred_ssid(cred, attr->ssid, attr->ssid_len) ||
00313             wps_process_cred_auth_type(cred, attr->auth_type) ||
00314             wps_process_cred_encr_type(cred, attr->encr_type) ||
00315             wps_process_cred_network_key_idx(cred, attr->network_key_idx) ||
00316             wps_process_cred_network_key(cred, attr->network_key,
00317                                          attr->network_key_len) ||
00318             wps_process_cred_mac_addr(cred, attr->mac_addr))
00319                 return -1;
00320 
00321         wps_workaround_cred_key(cred);
00322 
00323         return 0;
00324 }
00325 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:54 2009 for hostapd by  doxygen 1.6.1