mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(wpa_supplicant): (PEAP client) Update Phase 2 auth requirements
The previous PEAP client behavior allowed the server to skip Phase 2 authentication with the expectation that the server was authenticated during Phase 1 through TLS server certificate validation. Various PEAP specifications are not exactly clear on what the behavior on this front is supposed to be and as such, this ended up being more flexible than the TTLS/FAST/TEAP cases. However, this is not really ideal when unfortunately common misconfiguration of PEAP is used in deployed devices where the server trust root (ca_cert) is not configured or the user has an easy option for allowing this validation step to be skipped. Change the default PEAP client behavior to be to require Phase 2 authentication to be successfully completed for cases where TLS session resumption is not used and the client certificate has not been configured. Those two exceptions are the main cases where a deployed authentication server might skip Phase 2 and as such, where a more strict default behavior could result in undesired interoperability issues. Requiring Phase 2 authentication will end up disabling TLS session resumption automatically to avoid interoperability issues. Allow Phase 2 authentication behavior to be configured with a new phase1 configuration parameter option: 'phase2_auth' option can be used to control Phase 2 (i.e., within TLS tunnel) behavior for PEAP: * 0 = do not require Phase 2 authentication * 1 = require Phase 2 authentication when client certificate (private_key/client_cert) is no used and TLS session resumption was not used (default) * 2 = require Phase 2 authentication in all cases
This commit is contained in:
parent
8643854656
commit
4db2ef0f33
@ -66,6 +66,7 @@ struct eap_peap_data {
|
||||
u8 cmk[20];
|
||||
int soh; /* Whether IF-TNCCS-SOH (Statement of Health; Microsoft NAP)
|
||||
* is enabled. */
|
||||
enum { NO_AUTH, FOR_INITIAL, ALWAYS } phase2_auth;
|
||||
};
|
||||
|
||||
|
||||
@ -114,6 +115,19 @@ eap_peap_parse_phase1(struct eap_peap_data *data,
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Require cryptobinding");
|
||||
}
|
||||
|
||||
if (os_strstr(phase1, "phase2_auth=0")) {
|
||||
data->phase2_auth = NO_AUTH;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PEAP: Do not require Phase 2 authentication");
|
||||
} else if (os_strstr(phase1, "phase2_auth=1")) {
|
||||
data->phase2_auth = FOR_INITIAL;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PEAP: Require Phase 2 authentication for initial connection");
|
||||
} else if (os_strstr(phase1, "phase2_auth=2")) {
|
||||
data->phase2_auth = ALWAYS;
|
||||
wpa_printf(MSG_DEBUG,
|
||||
"EAP-PEAP: Require Phase 2 authentication for all cases");
|
||||
}
|
||||
#ifdef EAP_TNC
|
||||
if (os_strstr(phase1, "tnc=soh2")) {
|
||||
data->soh = 2;
|
||||
@ -145,6 +159,7 @@ eap_peap_init(struct eap_sm *sm)
|
||||
data->force_peap_version = -1;
|
||||
data->peap_outer_success = 2;
|
||||
data->crypto_binding = OPTIONAL_BINDING;
|
||||
data->phase2_auth = FOR_INITIAL;
|
||||
|
||||
if (config && config->phase1 &&
|
||||
eap_peap_parse_phase1(data, config->phase1) < 0) {
|
||||
@ -449,6 +464,19 @@ eap_tlv_validate_cryptobinding(struct eap_sm *sm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool peap_phase2_sufficient(struct eap_sm *sm,
|
||||
struct eap_peap_data *data)
|
||||
{
|
||||
if ((data->phase2_auth == ALWAYS ||
|
||||
(data->phase2_auth == FOR_INITIAL &&
|
||||
!tls_connection_resumed(sm->ssl_ctx, data->ssl.conn) &&
|
||||
!data->ssl.client_cert_conf) ||
|
||||
data->phase2_eap_started) &&
|
||||
!data->phase2_eap_success)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* eap_tlv_process - Process a received EAP-TLV message and generate a response
|
||||
@ -565,6 +593,11 @@ eap_tlv_process(struct eap_sm *sm, struct eap_peap_data *data,
|
||||
" - force failed Phase 2");
|
||||
resp_status = EAP_TLV_RESULT_FAILURE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
} else if (!peap_phase2_sufficient(sm, data)) {
|
||||
wpa_printf(MSG_INFO,
|
||||
"EAP-PEAP: Server indicated Phase 2 success, but sufficient Phase 2 authentication has not been completed");
|
||||
resp_status = EAP_TLV_RESULT_FAILURE;
|
||||
ret->decision = DECISION_FAIL;
|
||||
} else {
|
||||
resp_status = EAP_TLV_RESULT_SUCCESS;
|
||||
ret->decision = DECISION_UNCOND_SUCC;
|
||||
@ -939,8 +972,7 @@ continue_req:
|
||||
/* EAP-Success within TLS tunnel is used to indicate
|
||||
* shutdown of the TLS channel. The authentication has
|
||||
* been completed. */
|
||||
if (data->phase2_eap_started &&
|
||||
!data->phase2_eap_success) {
|
||||
if (!peap_phase2_sufficient(sm, data)) {
|
||||
wpa_printf(MSG_DEBUG, "EAP-PEAP: Phase 2 "
|
||||
"Success used to indicate success, "
|
||||
"but Phase 2 EAP was not yet "
|
||||
@ -1200,8 +1232,9 @@ static bool
|
||||
eap_peap_has_reauth_data(struct eap_sm *sm, void *priv)
|
||||
{
|
||||
struct eap_peap_data *data = priv;
|
||||
|
||||
return tls_connection_established(sm->ssl_ctx, data->ssl.conn) &&
|
||||
data->phase2_success;
|
||||
data->phase2_success && data->phase2_auth != ALWAYS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -89,7 +89,7 @@ static void eap_tls_params_from_conf1(struct tls_connection_params *params,
|
||||
static int eap_tls_params_from_conf(struct eap_sm *sm,
|
||||
struct eap_ssl_data *data,
|
||||
struct tls_connection_params *params,
|
||||
struct eap_peer_config *config)
|
||||
struct eap_peer_config *config, int phase2)
|
||||
{
|
||||
os_memset(params, 0, sizeof(*params));
|
||||
if (sm->workaround && data->eap_type != EAP_TYPE_FAST) {
|
||||
@ -128,6 +128,12 @@ static int eap_tls_params_from_conf(struct eap_sm *sm,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!phase2)
|
||||
data->client_cert_conf = params->client_cert ||
|
||||
params->client_cert_blob ||
|
||||
params->private_key ||
|
||||
params->private_key_blob;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -205,7 +211,7 @@ int eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data,
|
||||
data->eap = sm;
|
||||
data->eap_type = eap_type;
|
||||
data->ssl_ctx = sm->ssl_ctx;
|
||||
if (eap_tls_params_from_conf(sm, data, ¶ms, config) < 0) /* no phase2 */
|
||||
if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) < 0) /* no phase2 */
|
||||
return -1;
|
||||
|
||||
if (eap_tls_init_connection(sm, data, config, ¶ms) < 0)
|
||||
|
@ -73,6 +73,11 @@ struct eap_ssl_data {
|
||||
* eap_type - EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST)
|
||||
*/
|
||||
u8 eap_type;
|
||||
|
||||
/**
|
||||
* client_cert_conf: Whether client certificate has been configured
|
||||
*/
|
||||
bool client_cert_conf;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user