diff options
Diffstat (limited to 'src/eap_server/eap_server_fast.c')
| -rw-r--r-- | src/eap_server/eap_server_fast.c | 56 |
1 files changed, 32 insertions, 24 deletions
diff --git a/src/eap_server/eap_server_fast.c b/src/eap_server/eap_server_fast.c index bd9018e78b56..20491726880e 100644 --- a/src/eap_server/eap_server_fast.c +++ b/src/eap_server/eap_server_fast.c @@ -180,42 +180,47 @@ static int eap_fast_session_ticket_cb(void *ctx, const u8 *ticket, size_t len, buf, end - buf); pos = buf; - while (pos + 1 < end) { - if (pos + 2 + pos[1] > end) + while (end - pos > 1) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + if (elen > end - pos) break; - switch (*pos) { + switch (id) { case PAC_OPAQUE_TYPE_PAD: goto done; case PAC_OPAQUE_TYPE_KEY: - if (pos[1] != EAP_FAST_PAC_KEY_LEN) { - wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid " - "PAC-Key length %d", pos[1]); + if (elen != EAP_FAST_PAC_KEY_LEN) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: Invalid PAC-Key length %d", + elen); os_free(buf); return -1; } - pac_key = pos + 2; + pac_key = pos; wpa_hexdump_key(MSG_DEBUG, "EAP-FAST: PAC-Key from " "decrypted PAC-Opaque", pac_key, EAP_FAST_PAC_KEY_LEN); break; case PAC_OPAQUE_TYPE_LIFETIME: - if (pos[1] != 4) { + if (elen != 4) { wpa_printf(MSG_DEBUG, "EAP-FAST: Invalid " "PAC-Key lifetime length %d", - pos[1]); + elen); os_free(buf); return -1; } - lifetime = WPA_GET_BE32(pos + 2); + lifetime = WPA_GET_BE32(pos); break; case PAC_OPAQUE_TYPE_IDENTITY: - identity = pos + 2; - identity_len = pos[1]; + identity = pos; + identity_len = elen; break; } - pos += 2 + pos[1]; + pos += elen; } done: @@ -273,7 +278,7 @@ static void eap_fast_derive_key_auth(struct eap_sm *sm, * Extra key material after TLS key_block: session_key_seed[40] */ - sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, "key expansion", + sks = eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, EAP_FAST_SKS_LEN); if (sks == NULL) { wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive " @@ -300,7 +305,6 @@ static void eap_fast_derive_key_provisioning(struct eap_sm *sm, os_free(data->key_block_p); data->key_block_p = (struct eap_fast_key_block_provisioning *) eap_fast_derive_key(sm->ssl_ctx, data->ssl.conn, - "key expansion", sizeof(*data->key_block_p)); if (data->key_block_p == NULL) { wpa_printf(MSG_DEBUG, "EAP-FAST: Failed to derive key block"); @@ -407,11 +411,13 @@ static int eap_fast_update_icmk(struct eap_sm *sm, struct eap_fast_data *data) static void * eap_fast_init(struct eap_sm *sm) { struct eap_fast_data *data; - u8 ciphers[5] = { + u8 ciphers[7] = { TLS_CIPHER_ANON_DH_AES128_SHA, TLS_CIPHER_AES128_SHA, TLS_CIPHER_RSA_DHE_AES128_SHA, TLS_CIPHER_RC4_SHA, + TLS_CIPHER_RSA_DHE_AES256_SHA, + TLS_CIPHER_AES256_SHA, TLS_CIPHER_NONE }; @@ -1134,7 +1140,7 @@ static int eap_fast_parse_tlvs(struct wpabuf *data, pos = wpabuf_mhead(data); end = pos + wpabuf_len(data); - while (pos + 4 < end) { + while (end - pos > 4) { mandatory = pos[0] & 0x80; tlv_type = WPA_GET_BE16(pos) & 0x3fff; pos += 2; @@ -1559,7 +1565,10 @@ static u8 * eap_fast_getKey(struct eap_sm *sm, void *priv, size_t *len) if (eapKeyData == NULL) return NULL; - eap_fast_derive_eap_msk(data->simck, eapKeyData); + if (eap_fast_derive_eap_msk(data->simck, eapKeyData) < 0) { + os_free(eapKeyData); + return NULL; + } *len = EAP_FAST_KEY_LEN; return eapKeyData; @@ -1578,7 +1587,10 @@ static u8 * eap_fast_get_emsk(struct eap_sm *sm, void *priv, size_t *len) if (eapKeyData == NULL) return NULL; - eap_fast_derive_eap_emsk(data->simck, eapKeyData); + if (eap_fast_derive_eap_emsk(data->simck, eapKeyData) < 0) { + os_free(eapKeyData); + return NULL; + } *len = EAP_EMSK_LEN; return eapKeyData; @@ -1607,7 +1619,6 @@ static u8 * eap_fast_get_session_id(struct eap_sm *sm, void *priv, size_t *len) int eap_server_fast_register(void) { struct eap_method *eap; - int ret; eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION, EAP_VENDOR_IETF, EAP_TYPE_FAST, "FAST"); @@ -1625,8 +1636,5 @@ int eap_server_fast_register(void) eap->isSuccess = eap_fast_isSuccess; eap->getSessionId = eap_fast_get_session_id; - ret = eap_server_method_register(eap); - if (ret) - eap_server_method_free(eap); - return ret; + return eap_server_method_register(eap); } |
