* EAP-IKEv2 server (RFC 5106)
* Copyright (c) 2007, Jouni Malinen <j@w1.fi>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
*/
#include "includes.h"
data->ikev2.proposal.encr = ENCR_AES_CBC;
data->ikev2.proposal.dh = DH_GROUP2_1024BIT_MODP;
- data->ikev2.IDi = (u8 *) os_strdup("hostapd");
- data->ikev2.IDi_len = 7;
+ data->ikev2.IDi = os_malloc(sm->server_id_len);
+ if (data->ikev2.IDi == NULL)
+ goto failed;
+ os_memcpy(data->ikev2.IDi, sm->server_id, sm->server_id_len);
+ data->ikev2.IDi_len = sm->server_id_len;
data->ikev2.get_shared_secret = eap_ikev2_get_shared_secret;
data->ikev2.cb_ctx = sm;
wpabuf_free(data->in_buf);
wpabuf_free(data->out_buf);
ikev2_initiator_deinit(&data->ikev2);
- os_free(data);
+ bin_clear_free(data, sizeof(*data));
}
static int eap_ikev2_process_icv(struct eap_ikev2_data *data,
const struct wpabuf *respData,
- u8 flags, const u8 *pos, const u8 **end)
+ u8 flags, const u8 *pos, const u8 **end,
+ int frag_ack)
{
if (flags & IKEV2_FLAGS_ICV_INCLUDED) {
int icv_len = eap_ikev2_validate_icv(
return -1;
/* Hide Integrity Checksum Data from further processing */
*end -= icv_len;
- } else if (data->keys_ready) {
+ } else if (data->keys_ready && !frag_ack) {
wpa_printf(MSG_INFO, "EAP-IKEV2: The message should have "
"included integrity checksum");
return -1;
if (data->in_buf == NULL) {
/* First fragment of the message */
+ if (message_length > 50000) {
+ /* Limit maximum memory allocation */
+ wpa_printf(MSG_DEBUG,
+ "EAP-IKEV2: Ignore too long message");
+ return -1;
+ }
data->in_buf = wpabuf_alloc(message_length);
if (data->in_buf == NULL) {
wpa_printf(MSG_DEBUG, "EAP-IKEV2: No memory for "
} else
flags = *pos++;
- if (eap_ikev2_process_icv(data, respData, flags, pos, &end) < 0) {
+ if (eap_ikev2_process_icv(data, respData, flags, pos, &end,
+ data->state == WAIT_FRAG_ACK && len == 0) < 0)
+ {
eap_ikev2_state(data, FAIL);
return;
}
}
+static u8 * eap_ikev2_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
+{
+ struct eap_ikev2_data *data = priv;
+ u8 *sid;
+ size_t sid_len;
+ size_t offset;
+
+ if (data->state != DONE || !data->keymat_ok)
+ return NULL;
+
+ sid_len = 1 + data->ikev2.i_nonce_len + data->ikev2.r_nonce_len;
+ sid = os_malloc(sid_len);
+ if (sid) {
+ offset = 0;
+ sid[offset] = EAP_TYPE_IKEV2;
+ offset++;
+ os_memcpy(sid + offset, data->ikev2.i_nonce,
+ data->ikev2.i_nonce_len);
+ offset += data->ikev2.i_nonce_len;
+ os_memcpy(sid + offset, data->ikev2.r_nonce,
+ data->ikev2.r_nonce_len);
+ *len = sid_len;
+ wpa_hexdump(MSG_DEBUG, "EAP-IKEV2: Derived Session-Id",
+ sid, sid_len);
+ }
+
+ return sid;
+}
+
+
int eap_server_ikev2_register(void)
{
struct eap_method *eap;
eap->getKey = eap_ikev2_getKey;
eap->isSuccess = eap_ikev2_isSuccess;
eap->get_emsk = eap_ikev2_get_emsk;
+ eap->getSessionId = eap_ikev2_get_session_id;
ret = eap_server_method_register(eap);
if (ret)