EAP-TEAP server: Allow tunneled EAP method sequence to be optimized
Include the start of the next EAP method in an EAP Payload TLV in the same message with the Crypto-Binding TLV for the previous EAP method to get rid of one roundtrip when using more than a single EAP authentication method within the tunnel. The previous, not optimized, sequence can still be used with eap_teap_method_sequence=1 for more complete testing coverage. Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
parent
f791b5bbc7
commit
1a800a9400
6 changed files with 40 additions and 3 deletions
|
@ -2585,6 +2585,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
|
||||||
bss->eap_teap_separate_result = atoi(pos);
|
bss->eap_teap_separate_result = atoi(pos);
|
||||||
} else if (os_strcmp(buf, "eap_teap_id") == 0) {
|
} else if (os_strcmp(buf, "eap_teap_id") == 0) {
|
||||||
bss->eap_teap_id = atoi(pos);
|
bss->eap_teap_id = atoi(pos);
|
||||||
|
} else if (os_strcmp(buf, "eap_teap_method_sequence") == 0) {
|
||||||
|
bss->eap_teap_method_sequence = atoi(pos);
|
||||||
#endif /* EAP_SERVER_TEAP */
|
#endif /* EAP_SERVER_TEAP */
|
||||||
#ifdef EAP_SERVER_SIM
|
#ifdef EAP_SERVER_SIM
|
||||||
} else if (os_strcmp(buf, "eap_sim_db") == 0) {
|
} else if (os_strcmp(buf, "eap_sim_db") == 0) {
|
||||||
|
|
|
@ -1412,6 +1412,12 @@ eap_server=0
|
||||||
# 5 = require both user and machine identity
|
# 5 = require both user and machine identity
|
||||||
#eap_teap_id=0
|
#eap_teap_id=0
|
||||||
|
|
||||||
|
# EAP-TEAP tunneled EAP method behavior
|
||||||
|
# 0 = minimize roundtrips by merging start of the next EAP method with the
|
||||||
|
# crypto-binding of the previous one.
|
||||||
|
# 1 = complete crypto-binding before starting the next EAP method
|
||||||
|
#eap_teap_method_sequence=0
|
||||||
|
|
||||||
# EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
|
# EAP-SIM and EAP-AKA protected success/failure indication using AT_RESULT_IND
|
||||||
# (default: 0 = disabled).
|
# (default: 0 = disabled).
|
||||||
#eap_sim_aka_result_ind=1
|
#eap_sim_aka_result_ind=1
|
||||||
|
|
|
@ -443,6 +443,7 @@ struct hostapd_bss_config {
|
||||||
int eap_teap_pac_no_inner;
|
int eap_teap_pac_no_inner;
|
||||||
int eap_teap_separate_result;
|
int eap_teap_separate_result;
|
||||||
int eap_teap_id;
|
int eap_teap_id;
|
||||||
|
int eap_teap_method_sequence;
|
||||||
int eap_sim_aka_result_ind;
|
int eap_sim_aka_result_ind;
|
||||||
int eap_sim_id;
|
int eap_sim_id;
|
||||||
char *imsi_privacy_key;
|
char *imsi_privacy_key;
|
||||||
|
|
|
@ -211,6 +211,7 @@ static struct eap_config * authsrv_eap_config(struct hostapd_data *hapd)
|
||||||
cfg->eap_teap_pac_no_inner = hapd->conf->eap_teap_pac_no_inner;
|
cfg->eap_teap_pac_no_inner = hapd->conf->eap_teap_pac_no_inner;
|
||||||
cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result;
|
cfg->eap_teap_separate_result = hapd->conf->eap_teap_separate_result;
|
||||||
cfg->eap_teap_id = hapd->conf->eap_teap_id;
|
cfg->eap_teap_id = hapd->conf->eap_teap_id;
|
||||||
|
cfg->eap_teap_method_sequence = hapd->conf->eap_teap_method_sequence;
|
||||||
cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
|
cfg->eap_sim_aka_result_ind = hapd->conf->eap_sim_aka_result_ind;
|
||||||
cfg->eap_sim_id = hapd->conf->eap_sim_id;
|
cfg->eap_sim_id = hapd->conf->eap_sim_id;
|
||||||
cfg->imsi_privacy_key = hapd->imsi_privacy_key;
|
cfg->imsi_privacy_key = hapd->imsi_privacy_key;
|
||||||
|
|
|
@ -209,6 +209,7 @@ struct eap_config {
|
||||||
EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER = 4,
|
EAP_TEAP_ID_REQUEST_MACHINE_ACCEPT_USER = 4,
|
||||||
EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE = 5,
|
EAP_TEAP_ID_REQUIRE_USER_AND_MACHINE = 5,
|
||||||
} eap_teap_id;
|
} eap_teap_id;
|
||||||
|
int eap_teap_method_sequence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
|
* eap_sim_aka_result_ind - EAP-SIM/AKA protected success indication
|
||||||
|
|
|
@ -74,11 +74,15 @@ struct eap_teap_data {
|
||||||
|
|
||||||
enum teap_error_codes error_code;
|
enum teap_error_codes error_code;
|
||||||
enum teap_identity_types cur_id_type;
|
enum teap_identity_types cur_id_type;
|
||||||
|
|
||||||
|
bool check_crypto_binding;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
static int eap_teap_process_phase2_start(struct eap_sm *sm,
|
||||||
struct eap_teap_data *data);
|
struct eap_teap_data *data);
|
||||||
|
static int eap_teap_phase2_init(struct eap_sm *sm, struct eap_teap_data *data,
|
||||||
|
int vendor, enum eap_type eap_type);
|
||||||
|
|
||||||
|
|
||||||
static const char * eap_teap_state_txt(int state)
|
static const char * eap_teap_state_txt(int state)
|
||||||
|
@ -704,6 +708,8 @@ static struct wpabuf * eap_teap_build_crypto_binding(
|
||||||
wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
|
wpa_hexdump(MSG_MSGDUMP, "EAP-TEAP: MSK Compound MAC",
|
||||||
cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
|
cb->msk_compound_mac, sizeof(cb->msk_compound_mac));
|
||||||
|
|
||||||
|
data->check_crypto_binding = true;
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -889,6 +895,7 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
|
||||||
struct eap_teap_data *data = priv;
|
struct eap_teap_data *data = priv;
|
||||||
struct wpabuf *req = NULL;
|
struct wpabuf *req = NULL;
|
||||||
int piggyback = 0;
|
int piggyback = 0;
|
||||||
|
bool move_to_method = true;
|
||||||
|
|
||||||
if (data->ssl.state == FRAG_ACK) {
|
if (data->ssl.state == FRAG_ACK) {
|
||||||
return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
|
return eap_server_tls_build_ack(id, EAP_TYPE_TEAP,
|
||||||
|
@ -940,6 +947,21 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
|
||||||
break;
|
break;
|
||||||
case CRYPTO_BINDING:
|
case CRYPTO_BINDING:
|
||||||
req = eap_teap_build_crypto_binding(sm, data);
|
req = eap_teap_build_crypto_binding(sm, data);
|
||||||
|
if (req && sm->cfg->eap_teap_auth == 0 &&
|
||||||
|
data->inner_eap_not_done &&
|
||||||
|
!data->phase2_method &&
|
||||||
|
sm->cfg->eap_teap_method_sequence == 0) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"EAP-TEAP: Continue with inner EAP authentication for second credential (optimized)");
|
||||||
|
eap_teap_state(data, PHASE2_ID);
|
||||||
|
if (eap_teap_phase2_init(sm, data, EAP_VENDOR_IETF,
|
||||||
|
EAP_TYPE_IDENTITY) < 0) {
|
||||||
|
eap_teap_state(data, FAILURE);
|
||||||
|
wpabuf_free(req);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
move_to_method = false;
|
||||||
|
}
|
||||||
if (data->phase2_method) {
|
if (data->phase2_method) {
|
||||||
/*
|
/*
|
||||||
* Include the start of the next EAP method in the
|
* Include the start of the next EAP method in the
|
||||||
|
@ -950,6 +972,7 @@ static struct wpabuf * eap_teap_buildReq(struct eap_sm *sm, void *priv, u8 id)
|
||||||
|
|
||||||
eap = eap_teap_build_phase2_req(sm, data, id);
|
eap = eap_teap_build_phase2_req(sm, data, id);
|
||||||
req = wpabuf_concat(req, eap);
|
req = wpabuf_concat(req, eap);
|
||||||
|
if (move_to_method)
|
||||||
eap_teap_state(data, PHASE2_METHOD);
|
eap_teap_state(data, PHASE2_METHOD);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1510,7 +1533,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
|
||||||
struct wpabuf *in_data)
|
struct wpabuf *in_data)
|
||||||
{
|
{
|
||||||
struct eap_teap_tlv_parse tlv;
|
struct eap_teap_tlv_parse tlv;
|
||||||
int check_crypto_binding = data->state == CRYPTO_BINDING;
|
bool check_crypto_binding = data->state == CRYPTO_BINDING ||
|
||||||
|
data->check_crypto_binding;
|
||||||
|
|
||||||
if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
|
if (eap_teap_parse_tlvs(in_data, &tlv) < 0) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
|
@ -1593,6 +1617,7 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Valid Crypto-Binding TLV received");
|
"EAP-TEAP: Valid Crypto-Binding TLV received");
|
||||||
|
data->check_crypto_binding = false;
|
||||||
if (data->final_result) {
|
if (data->final_result) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Authentication completed successfully");
|
"EAP-TEAP: Authentication completed successfully");
|
||||||
|
@ -1671,7 +1696,8 @@ static void eap_teap_process_phase2_tlvs(struct eap_sm *sm,
|
||||||
"EAP-TEAP: Continue with basic password authentication for second credential");
|
"EAP-TEAP: Continue with basic password authentication for second credential");
|
||||||
eap_teap_state(data, PHASE2_BASIC_AUTH);
|
eap_teap_state(data, PHASE2_BASIC_AUTH);
|
||||||
} else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
|
} else if (check_crypto_binding && data->state == CRYPTO_BINDING &&
|
||||||
sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done) {
|
sm->cfg->eap_teap_auth == 0 && data->inner_eap_not_done &&
|
||||||
|
sm->cfg->eap_teap_method_sequence == 1) {
|
||||||
wpa_printf(MSG_DEBUG,
|
wpa_printf(MSG_DEBUG,
|
||||||
"EAP-TEAP: Continue with inner EAP authentication for second credential");
|
"EAP-TEAP: Continue with inner EAP authentication for second credential");
|
||||||
eap_teap_state(data, PHASE2_ID);
|
eap_teap_state(data, PHASE2_ID);
|
||||||
|
|
Loading…
Reference in a new issue