EAP server: Add getSessionId
This extends EAP server implementation to derive Session-Id similarly to the existing EAP peer implementation. Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
d68f74c5ff
commit
d1f89dd732
16 changed files with 306 additions and 0 deletions
|
@ -58,6 +58,8 @@ struct eap_eapol_interface {
|
||||||
struct wpabuf *eapReqData;
|
struct wpabuf *eapReqData;
|
||||||
u8 *eapKeyData;
|
u8 *eapKeyData;
|
||||||
size_t eapKeyDataLen;
|
size_t eapKeyDataLen;
|
||||||
|
u8 *eapSessionId;
|
||||||
|
size_t eapSessionIdLen;
|
||||||
Boolean eapKeyAvailable; /* called keyAvailable in IEEE 802.1X-2004 */
|
Boolean eapKeyAvailable; /* called keyAvailable in IEEE 802.1X-2004 */
|
||||||
|
|
||||||
/* AAA interface to full authenticator variables */
|
/* AAA interface to full authenticator variables */
|
||||||
|
|
|
@ -88,6 +88,19 @@ struct eap_method {
|
||||||
* private data or this function may derive the key.
|
* private data or this function may derive the key.
|
||||||
*/
|
*/
|
||||||
u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len);
|
u8 * (*get_emsk)(struct eap_sm *sm, void *priv, size_t *len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getSessionId - Get EAP method specific Session-Id
|
||||||
|
* @sm: Pointer to EAP state machine allocated with eap_server_sm_init()
|
||||||
|
* @priv: Pointer to private EAP method data from eap_method::init()
|
||||||
|
* @len: Pointer to a variable to store Session-Id length
|
||||||
|
* Returns: Session-Id or %NULL if not available
|
||||||
|
*
|
||||||
|
* This function can be used to get the Session-Id from the EAP method.
|
||||||
|
* The Session-Id may already be stored in the method-specific private
|
||||||
|
* data or this function may derive the Session-Id.
|
||||||
|
*/
|
||||||
|
u8 * (*getSessionId)(struct eap_sm *sm, void *priv, size_t *len);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -171,6 +171,9 @@ SM_STATE(EAP, INITIALIZE)
|
||||||
bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
|
bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
|
||||||
sm->eap_if.eapKeyData = NULL;
|
sm->eap_if.eapKeyData = NULL;
|
||||||
sm->eap_if.eapKeyDataLen = 0;
|
sm->eap_if.eapKeyDataLen = 0;
|
||||||
|
os_free(sm->eap_if.eapSessionId);
|
||||||
|
sm->eap_if.eapSessionId = NULL;
|
||||||
|
sm->eap_if.eapSessionIdLen = 0;
|
||||||
sm->eap_if.eapKeyAvailable = FALSE;
|
sm->eap_if.eapKeyAvailable = FALSE;
|
||||||
sm->eap_if.eapRestart = FALSE;
|
sm->eap_if.eapRestart = FALSE;
|
||||||
|
|
||||||
|
@ -355,6 +358,16 @@ SM_STATE(EAP, METHOD_RESPONSE)
|
||||||
sm->eap_if.eapKeyData = NULL;
|
sm->eap_if.eapKeyData = NULL;
|
||||||
sm->eap_if.eapKeyDataLen = 0;
|
sm->eap_if.eapKeyDataLen = 0;
|
||||||
}
|
}
|
||||||
|
os_free(sm->eap_if.eapSessionId);
|
||||||
|
sm->eap_if.eapSessionId = NULL;
|
||||||
|
if (sm->m->getSessionId) {
|
||||||
|
sm->eap_if.eapSessionId = sm->m->getSessionId(
|
||||||
|
sm, sm->eap_method_priv,
|
||||||
|
&sm->eap_if.eapSessionIdLen);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP: Session-Id",
|
||||||
|
sm->eap_if.eapSessionId,
|
||||||
|
sm->eap_if.eapSessionIdLen);
|
||||||
|
}
|
||||||
sm->methodState = METHOD_END;
|
sm->methodState = METHOD_END;
|
||||||
} else {
|
} else {
|
||||||
sm->methodState = METHOD_CONTINUE;
|
sm->methodState = METHOD_CONTINUE;
|
||||||
|
@ -1353,6 +1366,7 @@ void eap_server_sm_deinit(struct eap_sm *sm)
|
||||||
sm->m->reset(sm, sm->eap_method_priv);
|
sm->m->reset(sm, sm->eap_method_priv);
|
||||||
wpabuf_free(sm->eap_if.eapReqData);
|
wpabuf_free(sm->eap_if.eapReqData);
|
||||||
bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
|
bin_clear_free(sm->eap_if.eapKeyData, sm->eap_if.eapKeyDataLen);
|
||||||
|
os_free(sm->eap_if.eapSessionId);
|
||||||
wpabuf_free(sm->lastReqData);
|
wpabuf_free(sm->lastReqData);
|
||||||
wpabuf_free(sm->eap_if.eapRespData);
|
wpabuf_free(sm->eap_if.eapRespData);
|
||||||
os_free(sm->identity);
|
os_free(sm->identity);
|
||||||
|
|
|
@ -1294,6 +1294,28 @@ static Boolean eap_aka_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_aka_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_aka_data *data = priv;
|
||||||
|
u8 *id;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 1 + EAP_AKA_RAND_LEN + EAP_AKA_AUTN_LEN;
|
||||||
|
id = os_malloc(*len);
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
id[0] = data->eap_method;
|
||||||
|
os_memcpy(id + 1, data->rand, EAP_AKA_RAND_LEN);
|
||||||
|
os_memcpy(id + 1 + EAP_AKA_RAND_LEN, data->autn, EAP_AKA_AUTN_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP-AKA: Derived Session-Id", id, *len);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_aka_register(void)
|
int eap_server_aka_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -1313,6 +1335,7 @@ int eap_server_aka_register(void)
|
||||||
eap->getKey = eap_aka_getKey;
|
eap->getKey = eap_aka_getKey;
|
||||||
eap->isSuccess = eap_aka_isSuccess;
|
eap->isSuccess = eap_aka_isSuccess;
|
||||||
eap->get_emsk = eap_aka_get_emsk;
|
eap->get_emsk = eap_aka_get_emsk;
|
||||||
|
eap->getSessionId = eap_aka_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -1342,6 +1365,7 @@ int eap_server_aka_prime_register(void)
|
||||||
eap->getKey = eap_aka_getKey;
|
eap->getKey = eap_aka_getKey;
|
||||||
eap->isSuccess = eap_aka_isSuccess;
|
eap->isSuccess = eap_aka_isSuccess;
|
||||||
eap->get_emsk = eap_aka_get_emsk;
|
eap->get_emsk = eap_aka_get_emsk;
|
||||||
|
eap->getSessionId = eap_aka_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -1589,6 +1589,18 @@ static Boolean eap_fast_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_fast_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_fast_data *data = priv;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_FAST,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_fast_register(void)
|
int eap_server_fast_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -1608,6 +1620,7 @@ int eap_server_fast_register(void)
|
||||||
eap->getKey = eap_fast_getKey;
|
eap->getKey = eap_fast_getKey;
|
||||||
eap->get_emsk = eap_fast_get_emsk;
|
eap->get_emsk = eap_fast_get_emsk;
|
||||||
eap->isSuccess = eap_fast_isSuccess;
|
eap->isSuccess = eap_fast_isSuccess;
|
||||||
|
eap->getSessionId = eap_fast_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -24,6 +24,8 @@ struct eap_gpsk_data {
|
||||||
size_t sk_len;
|
size_t sk_len;
|
||||||
u8 pk[EAP_GPSK_MAX_PK_LEN];
|
u8 pk[EAP_GPSK_MAX_PK_LEN];
|
||||||
size_t pk_len;
|
size_t pk_len;
|
||||||
|
u8 session_id[128];
|
||||||
|
size_t id_len;
|
||||||
u8 *id_peer;
|
u8 *id_peer;
|
||||||
size_t id_peer_len;
|
size_t id_peer_len;
|
||||||
#define MAX_NUM_CSUITES 2
|
#define MAX_NUM_CSUITES 2
|
||||||
|
@ -417,6 +419,21 @@ static void eap_gpsk_process_gpsk_2(struct eap_sm *sm,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (eap_gpsk_derive_session_id(sm->user->password,
|
||||||
|
sm->user->password_len,
|
||||||
|
data->vendor, data->specifier,
|
||||||
|
data->rand_peer, data->rand_server,
|
||||||
|
data->id_peer, data->id_peer_len,
|
||||||
|
sm->server_id, sm->server_id_len,
|
||||||
|
EAP_TYPE_GPSK,
|
||||||
|
data->session_id, &data->id_len) < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "EAP-GPSK: Failed to derive Session-Id");
|
||||||
|
eap_gpsk_state(data, FAILURE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP-GPSK: Derived Session-Id",
|
||||||
|
data->session_id, data->id_len);
|
||||||
|
|
||||||
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
|
miclen = eap_gpsk_mic_len(data->vendor, data->specifier);
|
||||||
if (end - pos < (int) miclen) {
|
if (end - pos < (int) miclen) {
|
||||||
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
|
wpa_printf(MSG_DEBUG, "EAP-GPSK: Message too short for MIC "
|
||||||
|
@ -593,6 +610,24 @@ static Boolean eap_gpsk_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_gpsk_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_gpsk_data *data = priv;
|
||||||
|
u8 *sid;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
sid = os_malloc(data->id_len);
|
||||||
|
if (sid == NULL)
|
||||||
|
return NULL;
|
||||||
|
os_memcpy(sid, data->session_id, data->id_len);
|
||||||
|
*len = data->id_len;
|
||||||
|
|
||||||
|
return sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_gpsk_register(void)
|
int eap_server_gpsk_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -612,6 +647,7 @@ int eap_server_gpsk_register(void)
|
||||||
eap->getKey = eap_gpsk_getKey;
|
eap->getKey = eap_gpsk_getKey;
|
||||||
eap->isSuccess = eap_gpsk_isSuccess;
|
eap->isSuccess = eap_gpsk_isSuccess;
|
||||||
eap->get_emsk = eap_gpsk_get_emsk;
|
eap->get_emsk = eap_gpsk_get_emsk;
|
||||||
|
eap->getSessionId = eap_gpsk_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -511,6 +511,36 @@ static u8 * eap_ikev2_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
int eap_server_ikev2_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -531,6 +561,7 @@ int eap_server_ikev2_register(void)
|
||||||
eap->getKey = eap_ikev2_getKey;
|
eap->getKey = eap_ikev2_getKey;
|
||||||
eap->isSuccess = eap_ikev2_isSuccess;
|
eap->isSuccess = eap_ikev2_isSuccess;
|
||||||
eap->get_emsk = eap_ikev2_get_emsk;
|
eap->get_emsk = eap_ikev2_get_emsk;
|
||||||
|
eap->getSessionId = eap_ikev2_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -1229,6 +1229,18 @@ static Boolean eap_peap_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_peap_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_peap_data *data = priv;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_PEAP,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_peap_register(void)
|
int eap_server_peap_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -1247,6 +1259,7 @@ int eap_server_peap_register(void)
|
||||||
eap->isDone = eap_peap_isDone;
|
eap->isDone = eap_peap_isDone;
|
||||||
eap->getKey = eap_peap_getKey;
|
eap->getKey = eap_peap_getKey;
|
||||||
eap->isSuccess = eap_peap_isSuccess;
|
eap->isSuccess = eap_peap_isSuccess;
|
||||||
|
eap->getSessionId = eap_peap_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -485,6 +485,28 @@ static Boolean eap_psk_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_psk_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_psk_data *data = priv;
|
||||||
|
u8 *id;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 1 + 2 * EAP_PSK_RAND_LEN;
|
||||||
|
id = os_malloc(*len);
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
id[0] = EAP_TYPE_PSK;
|
||||||
|
os_memcpy(id + 1, data->rand_p, EAP_PSK_RAND_LEN);
|
||||||
|
os_memcpy(id + 1 + EAP_PSK_RAND_LEN, data->rand_s, EAP_PSK_RAND_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP-PSK: Derived Session-Id", id, *len);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_psk_register(void)
|
int eap_server_psk_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -504,6 +526,7 @@ int eap_server_psk_register(void)
|
||||||
eap->getKey = eap_psk_getKey;
|
eap->getKey = eap_psk_getKey;
|
||||||
eap->isSuccess = eap_psk_isSuccess;
|
eap->isSuccess = eap_psk_isSuccess;
|
||||||
eap->get_emsk = eap_psk_get_emsk;
|
eap->get_emsk = eap_psk_get_emsk;
|
||||||
|
eap->getSessionId = eap_psk_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -1020,6 +1020,25 @@ static Boolean eap_pwd_is_done(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_pwd_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_pwd_data *data = priv;
|
||||||
|
u8 *id;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
id = os_malloc(1 + SHA256_MAC_LEN);
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
os_memcpy(id, data->session_id, 1 + SHA256_MAC_LEN);
|
||||||
|
*len = 1 + SHA256_MAC_LEN;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_pwd_register(void)
|
int eap_server_pwd_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -1048,6 +1067,7 @@ int eap_server_pwd_register(void)
|
||||||
eap->getKey = eap_pwd_getkey;
|
eap->getKey = eap_pwd_getkey;
|
||||||
eap->get_emsk = eap_pwd_get_emsk;
|
eap->get_emsk = eap_pwd_get_emsk;
|
||||||
eap->isSuccess = eap_pwd_is_success;
|
eap->isSuccess = eap_pwd_is_success;
|
||||||
|
eap->getSessionId = eap_pwd_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -495,6 +495,28 @@ static Boolean eap_sake_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_sake_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_sake_data *data = priv;
|
||||||
|
u8 *id;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 1 + 2 * EAP_SAKE_RAND_LEN;
|
||||||
|
id = os_malloc(*len);
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
id[0] = EAP_TYPE_SAKE;
|
||||||
|
os_memcpy(id + 1, data->rand_s, EAP_SAKE_RAND_LEN);
|
||||||
|
os_memcpy(id + 1 + EAP_SAKE_RAND_LEN, data->rand_s, EAP_SAKE_RAND_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP-SAKE: Derived Session-Id", id, *len);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_sake_register(void)
|
int eap_server_sake_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -514,6 +536,7 @@ int eap_server_sake_register(void)
|
||||||
eap->getKey = eap_sake_getKey;
|
eap->getKey = eap_sake_getKey;
|
||||||
eap->isSuccess = eap_sake_isSuccess;
|
eap->isSuccess = eap_sake_isSuccess;
|
||||||
eap->get_emsk = eap_sake_get_emsk;
|
eap->get_emsk = eap_sake_get_emsk;
|
||||||
|
eap->getSessionId = eap_sake_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -820,6 +820,29 @@ static Boolean eap_sim_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_sim_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_sim_data *data = priv;
|
||||||
|
u8 *id;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 1 + data->num_chal * GSM_RAND_LEN + EAP_SIM_NONCE_MT_LEN;
|
||||||
|
id = os_malloc(*len);
|
||||||
|
if (id == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
id[0] = EAP_TYPE_SIM;
|
||||||
|
os_memcpy(id + 1, data->rand, data->num_chal * GSM_RAND_LEN);
|
||||||
|
os_memcpy(id + 1 + data->num_chal * GSM_RAND_LEN, data->nonce_mt,
|
||||||
|
EAP_SIM_NONCE_MT_LEN);
|
||||||
|
wpa_hexdump(MSG_DEBUG, "EAP-SIM: Derived Session-Id", id, *len);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_sim_register(void)
|
int eap_server_sim_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -839,6 +862,7 @@ int eap_server_sim_register(void)
|
||||||
eap->getKey = eap_sim_getKey;
|
eap->getKey = eap_sim_getKey;
|
||||||
eap->isSuccess = eap_sim_isSuccess;
|
eap->isSuccess = eap_sim_isSuccess;
|
||||||
eap->get_emsk = eap_sim_get_emsk;
|
eap->get_emsk = eap_sim_get_emsk;
|
||||||
|
eap->getSessionId = eap_sim_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -310,6 +310,18 @@ static Boolean eap_tls_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_tls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_tls_data *data = priv;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TLS,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_tls_register(void)
|
int eap_server_tls_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -329,6 +341,7 @@ int eap_server_tls_register(void)
|
||||||
eap->getKey = eap_tls_getKey;
|
eap->getKey = eap_tls_getKey;
|
||||||
eap->isSuccess = eap_tls_isSuccess;
|
eap->isSuccess = eap_tls_isSuccess;
|
||||||
eap->get_emsk = eap_tls_get_emsk;
|
eap->get_emsk = eap_tls_get_emsk;
|
||||||
|
eap->getSessionId = eap_tls_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -140,6 +140,47 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data
|
||||||
|
* @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
|
||||||
|
* @data: Data for TLS processing
|
||||||
|
* @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST)
|
||||||
|
* @len: Pointer to length of the session ID generated
|
||||||
|
* Returns: Pointer to allocated Session-Id on success or %NULL on failure
|
||||||
|
*
|
||||||
|
* This function derive the Session-Id based on the TLS session data
|
||||||
|
* (client/server random and method type).
|
||||||
|
*
|
||||||
|
* The caller is responsible for freeing the returned buffer.
|
||||||
|
*/
|
||||||
|
u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
|
||||||
|
struct eap_ssl_data *data, u8 eap_type,
|
||||||
|
size_t *len)
|
||||||
|
{
|
||||||
|
struct tls_keys keys;
|
||||||
|
u8 *out;
|
||||||
|
|
||||||
|
if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (keys.client_random == NULL || keys.server_random == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 1 + keys.client_random_len + keys.server_random_len;
|
||||||
|
out = os_malloc(*len);
|
||||||
|
if (out == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* Session-Id = EAP type || client.random || server.random */
|
||||||
|
out[0] = eap_type;
|
||||||
|
os_memcpy(out + 1, keys.client_random, keys.client_random_len);
|
||||||
|
os_memcpy(out + 1 + keys.client_random_len, keys.server_random,
|
||||||
|
keys.server_random_len);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data,
|
struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data,
|
||||||
int eap_type, int version, u8 id)
|
int eap_type, int version, u8 id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1181,6 +1181,18 @@ static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
|
||||||
|
{
|
||||||
|
struct eap_ttls_data *data = priv;
|
||||||
|
|
||||||
|
if (data->state != SUCCESS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS,
|
||||||
|
len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int eap_server_ttls_register(void)
|
int eap_server_ttls_register(void)
|
||||||
{
|
{
|
||||||
struct eap_method *eap;
|
struct eap_method *eap;
|
||||||
|
@ -1199,6 +1211,7 @@ int eap_server_ttls_register(void)
|
||||||
eap->isDone = eap_ttls_isDone;
|
eap->isDone = eap_ttls_isDone;
|
||||||
eap->getKey = eap_ttls_getKey;
|
eap->getKey = eap_ttls_getKey;
|
||||||
eap->isSuccess = eap_ttls_isSuccess;
|
eap->isSuccess = eap_ttls_isSuccess;
|
||||||
|
eap->getSessionId = eap_ttls_get_session_id;
|
||||||
|
|
||||||
ret = eap_server_method_register(eap);
|
ret = eap_server_method_register(eap);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -74,6 +74,9 @@ int eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||||
void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
|
void eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data);
|
||||||
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
|
u8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||||
char *label, size_t len);
|
char *label, size_t len);
|
||||||
|
u8 * eap_server_tls_derive_session_id(struct eap_sm *sm,
|
||||||
|
struct eap_ssl_data *data, u8 eap_type,
|
||||||
|
size_t *len);
|
||||||
struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data,
|
struct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data,
|
||||||
int eap_type, int version, u8 id);
|
int eap_type, int version, u8 id);
|
||||||
struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version);
|
struct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version);
|
||||||
|
|
Loading…
Reference in a new issue