diff --git a/src/common/defs.h b/src/common/defs.h index 6aea3751a..b3ac4e863 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -312,6 +312,7 @@ enum wpa_ctrl_req_type { WPA_CTRL_REQ_EAP_PASSPHRASE, WPA_CTRL_REQ_SIM, WPA_CTRL_REQ_PSK_PASSPHRASE, + WPA_CTRL_REQ_EXT_CERT_CHECK, NUM_WPA_CTRL_REQS }; diff --git a/src/crypto/tls.h b/src/crypto/tls.h index 2e562339c..bca94d67d 100644 --- a/src/crypto/tls.h +++ b/src/crypto/tls.h @@ -95,6 +95,7 @@ struct tls_config { #define TLS_CONN_DISABLE_TLSv1_2 BIT(6) #define TLS_CONN_EAP_FAST BIT(7) #define TLS_CONN_DISABLE_TLSv1_0 BIT(8) +#define TLS_CONN_EXT_CERT_CHECK BIT(9) /** * struct tls_connection_params - Parameters for TLS connection diff --git a/src/crypto/tls_gnutls.c b/src/crypto/tls_gnutls.c index f994379b1..b1bec4a53 100644 --- a/src/crypto/tls_gnutls.c +++ b/src/crypto/tls_gnutls.c @@ -347,6 +347,12 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, if (conn == NULL || params == NULL) return -1; + if (params->flags & TLS_CONN_EXT_CERT_CHECK) { + wpa_printf(MSG_INFO, + "GnuTLS: tls_ext_cert_check=1 not supported"); + return -1; + } + if (params->subject_match) { wpa_printf(MSG_INFO, "GnuTLS: subject_match not supported"); return -1; diff --git a/src/crypto/tls_internal.c b/src/crypto/tls_internal.c index dcbb31d76..8b90d5652 100644 --- a/src/crypto/tls_internal.c +++ b/src/crypto/tls_internal.c @@ -200,6 +200,12 @@ int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, if (conn->client == NULL) return -1; + if (params->flags & TLS_CONN_EXT_CERT_CHECK) { + wpa_printf(MSG_INFO, + "TLS: tls_ext_cert_check=1 not supported"); + return -1; + } + cred = tlsv1_cred_alloc(); if (cred == NULL) return -1; diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c index 471ae2b7c..1d75ba7af 100644 --- a/src/crypto/tls_openssl.c +++ b/src/crypto/tls_openssl.c @@ -1583,7 +1583,8 @@ static void openssl_tls_cert_event(struct tls_connection *conn, return; os_memset(&ev, 0, sizeof(ev)); - if (conn->cert_probe || context->cert_in_cb) { + if (conn->cert_probe || (conn->flags & TLS_CONN_EXT_CERT_CHECK) || + context->cert_in_cb) { cert = get_x509_cert(err_cert); ev.peer_cert.cert = cert; } @@ -1821,7 +1822,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx) } #endif /* OPENSSL_IS_BORINGSSL */ - if (preverify_ok && context->event_cb != NULL) + if (depth == 0 && preverify_ok && context->event_cb != NULL) context->event_cb(context->cb_ctx, TLS_CERT_CHAIN_SUCCESS, NULL); diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c index 28d5116fd..5c1897862 100644 --- a/src/eap_peer/eap.c +++ b/src/eap_peer/eap.c @@ -48,6 +48,8 @@ static void eap_sm_parseEapReq(struct eap_sm *sm, const struct wpabuf *req); static const char * eap_sm_method_state_txt(EapMethodState state); static const char * eap_sm_decision_txt(EapDecision decision); #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ +static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, + const char *msg, size_t msglen); @@ -320,11 +322,14 @@ SM_STATE(EAP, GET_METHOD) wpa_printf(MSG_DEBUG, "EAP: Initialize selected EAP method: " "vendor %u method %u (%s)", sm->reqVendor, method, sm->m->name); - if (reinit) + if (reinit) { sm->eap_method_priv = sm->m->init_for_reauth( sm, sm->eap_method_priv); - else + } else { + sm->waiting_ext_cert_check = 0; + sm->ext_cert_check = 0; sm->eap_method_priv = sm->m->init(sm); + } if (sm->eap_method_priv == NULL) { struct eap_peer_config *config = eap_get_config(sm); @@ -1858,6 +1863,11 @@ static void eap_peer_sm_tls_event(void *ctx, enum tls_event ev, case TLS_CERT_CHAIN_SUCCESS: eap_notify_status(sm, "remote certificate verification", "success"); + if (sm->ext_cert_check) { + sm->waiting_ext_cert_check = 1; + eap_sm_request(sm, WPA_CTRL_REQ_EXT_CERT_CHECK, + NULL, 0); + } break; case TLS_CERT_CHAIN_FAILURE: wpa_msg(sm->msg_ctx, MSG_INFO, WPA_EVENT_EAP_TLS_CERT_ERROR @@ -2180,10 +2190,10 @@ int eap_sm_get_status(struct eap_sm *sm, char *buf, size_t buflen, int verbose) #endif /* CONFIG_CTRL_IFACE */ -#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, const char *msg, size_t msglen) { +#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG) struct eap_peer_config *config; const char *txt = NULL; char *tmp; @@ -2232,16 +2242,17 @@ static void eap_sm_request(struct eap_sm *sm, enum wpa_ctrl_req_type field, case WPA_CTRL_REQ_SIM: txt = msg; break; + case WPA_CTRL_REQ_EXT_CERT_CHECK: + break; default: return; } if (sm->eapol_cb->eap_param_needed) sm->eapol_cb->eap_param_needed(sm->eapol_ctx, field, txt); -} -#else /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ -#define eap_sm_request(sm, type, msg, msglen) do { } while (0) #endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */ +} + const char * eap_sm_get_method_name(struct eap_sm *sm) { diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h index 2b1a1d5e4..39ddcff67 100644 --- a/src/eap_peer/eap_config.h +++ b/src/eap_peer/eap_config.h @@ -739,6 +739,20 @@ struct eap_peer_config { * erp - Whether EAP Re-authentication Protocol (ERP) is enabled */ int erp; + + /** + * pending_ext_cert_check - External server certificate check status + * + * This field should not be set in configuration step. It is only used + * internally when control interface is used to request external + * validation of server certificate chain. + */ + enum { + NO_CHECK = 0, + PENDING_CHECK, + EXT_CERT_CHECK_GOOD, + EXT_CERT_CHECK_BAD, + } pending_ext_cert_check; }; diff --git a/src/eap_peer/eap_fast.c b/src/eap_peer/eap_fast.c index 8b6b7fd92..a7f6befa0 100644 --- a/src/eap_peer/eap_fast.c +++ b/src/eap_peer/eap_fast.c @@ -1,6 +1,6 @@ /* * EAP peer method: EAP-FAST (RFC 4851) - * Copyright (c) 2004-2008, Jouni Malinen + * Copyright (c) 2004-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -67,6 +67,7 @@ struct eap_fast_data { int simck_idx; struct wpabuf *pending_phase2_req; + struct wpabuf *pending_resp; }; @@ -254,6 +255,7 @@ static void eap_fast_deinit(struct eap_sm *sm, void *priv) os_memset(data->emsk, 0, EAP_EMSK_LEN); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); + wpabuf_free(data->pending_resp); os_free(data); } @@ -1568,6 +1570,34 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, res = 1; } } else { + if (sm->waiting_ext_cert_check && data->pending_resp) { + struct eap_peer_config *config = eap_get_config(sm); + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_GOOD) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: External certificate check succeeded - continue handshake"); + resp = data->pending_resp; + data->pending_resp = NULL; + sm->waiting_ext_cert_check = 0; + return resp; + } + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_BAD) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: External certificate check failed - force authentication failure"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->waiting_ext_cert_check = 0; + return NULL; + } + + wpa_printf(MSG_DEBUG, + "EAP-FAST: Continuing to wait external server certificate validation"); + return NULL; + } + /* Continue processing TLS handshake (phase 1). */ res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_FAST, @@ -1581,6 +1611,14 @@ static struct wpabuf * eap_fast_process(struct eap_sm *sm, void *priv, return resp; } + if (sm->waiting_ext_cert_check) { + wpa_printf(MSG_DEBUG, + "EAP-FAST: Waiting external server certificate validation"); + wpabuf_free(data->pending_resp); + data->pending_resp = resp; + return NULL; + } + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char cipher[80]; wpa_printf(MSG_DEBUG, @@ -1645,6 +1683,8 @@ static void eap_fast_deinit_for_reauth(struct eap_sm *sm, void *priv) data->key_block_p = NULL; wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = NULL; + wpabuf_free(data->pending_resp); + data->pending_resp = NULL; } diff --git a/src/eap_peer/eap_i.h b/src/eap_peer/eap_i.h index 99b44dae4..6ab24834d 100644 --- a/src/eap_peer/eap_i.h +++ b/src/eap_peer/eap_i.h @@ -366,6 +366,8 @@ struct eap_sm { int external_sim; unsigned int expected_failure:1; + unsigned int ext_cert_check:1; + unsigned int waiting_ext_cert_check:1; struct dl_list erp_keys; /* struct eap_erp_key */ }; diff --git a/src/eap_peer/eap_peap.c b/src/eap_peer/eap_peap.c index 98a48a6cf..059609899 100644 --- a/src/eap_peer/eap_peap.c +++ b/src/eap_peer/eap_peap.c @@ -1,6 +1,6 @@ /* * EAP peer method: EAP-PEAP (draft-josefsson-pppext-eap-tls-eap-10.txt) - * Copyright (c) 2004-2008, Jouni Malinen + * Copyright (c) 2004-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -59,6 +59,7 @@ struct eap_peap_data { size_t id_len; struct wpabuf *pending_phase2_req; + struct wpabuf *pending_resp; enum { NO_BINDING, OPTIONAL_BINDING, REQUIRE_BINDING } crypto_binding; int crypto_binding_used; u8 binding_nonce[32]; @@ -191,6 +192,7 @@ static void eap_peap_deinit(struct eap_sm *sm, void *priv) eap_peap_free_key(data); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); + wpabuf_free(data->pending_resp); os_free(data); } @@ -1006,6 +1008,34 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, !data->resuming) { res = eap_peap_decrypt(sm, data, ret, req, &msg, &resp); } else { + if (sm->waiting_ext_cert_check && data->pending_resp) { + struct eap_peer_config *config = eap_get_config(sm); + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_GOOD) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: External certificate check succeeded - continue handshake"); + resp = data->pending_resp; + data->pending_resp = NULL; + sm->waiting_ext_cert_check = 0; + return resp; + } + + if (config->pending_ext_cert_check == + EXT_CERT_CHECK_BAD) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: External certificate check failed - force authentication failure"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->waiting_ext_cert_check = 0; + return NULL; + } + + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Continuing to wait external server certificate validation"); + return NULL; + } + res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_PEAP, data->peap_version, id, &msg, @@ -1018,6 +1048,16 @@ static struct wpabuf * eap_peap_process(struct eap_sm *sm, void *priv, ret->decision = DECISION_FAIL; return resp; } + + + if (sm->waiting_ext_cert_check) { + wpa_printf(MSG_DEBUG, + "EAP-PEAP: Waiting external server certificate validation"); + wpabuf_free(data->pending_resp); + data->pending_resp = resp; + return NULL; + } + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { char *label; wpa_printf(MSG_DEBUG, @@ -1123,6 +1163,8 @@ static void eap_peap_deinit_for_reauth(struct eap_sm *sm, void *priv) struct eap_peap_data *data = priv; wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = NULL; + wpabuf_free(data->pending_resp); + data->pending_resp = NULL; data->crypto_binding_used = 0; } diff --git a/src/eap_peer/eap_tls.c b/src/eap_peer/eap_tls.c index 66a027a62..ba8e74b55 100644 --- a/src/eap_peer/eap_tls.c +++ b/src/eap_peer/eap_tls.c @@ -1,6 +1,6 @@ /* * EAP peer method: EAP-TLS (RFC 2716) - * Copyright (c) 2004-2008, 2012, Jouni Malinen + * Copyright (c) 2004-2008, 2012-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -25,6 +25,7 @@ struct eap_tls_data { size_t id_len; void *ssl_ctx; u8 eap_type; + struct wpabuf *pending_resp; }; @@ -142,6 +143,7 @@ static void eap_tls_deinit(struct eap_sm *sm, void *priv) eap_peer_tls_ssl_deinit(sm, &data->ssl); eap_tls_free_key(data); os_free(data->session_id); + wpabuf_free(data->pending_resp); os_free(data); } @@ -216,6 +218,32 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, struct eap_tls_data *data = priv; struct wpabuf msg; + if (sm->waiting_ext_cert_check && data->pending_resp) { + struct eap_peer_config *config = eap_get_config(sm); + + if (config->pending_ext_cert_check == EXT_CERT_CHECK_GOOD) { + wpa_printf(MSG_DEBUG, + "EAP-TLS: External certificate check succeeded - continue handshake"); + resp = data->pending_resp; + data->pending_resp = NULL; + sm->waiting_ext_cert_check = 0; + return resp; + } + + if (config->pending_ext_cert_check == EXT_CERT_CHECK_BAD) { + wpa_printf(MSG_DEBUG, + "EAP-TLS: External certificate check failed - force authentication failure"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->waiting_ext_cert_check = 0; + return NULL; + } + + wpa_printf(MSG_DEBUG, + "EAP-TLS: Continuing to wait external server certificate validation"); + return NULL; + } + pos = eap_peer_tls_process_init(sm, &data->ssl, data->eap_type, ret, reqData, &left, &flags); if (pos == NULL) @@ -237,6 +265,14 @@ static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, return eap_tls_failure(sm, data, ret, res, resp, id); } + if (sm->waiting_ext_cert_check) { + wpa_printf(MSG_DEBUG, + "EAP-TLS: Waiting external server certificate validation"); + wpabuf_free(data->pending_resp); + data->pending_resp = resp; + return NULL; + } + if (tls_connection_established(data->ssl_ctx, data->ssl.conn)) eap_tls_success(sm, data, ret); @@ -258,6 +294,10 @@ static Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv) static void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv) { + struct eap_tls_data *data = priv; + + wpabuf_free(data->pending_resp); + data->pending_resp = NULL; } diff --git a/src/eap_peer/eap_tls_common.c b/src/eap_peer/eap_tls_common.c index af2b7541d..4b994fd3a 100644 --- a/src/eap_peer/eap_tls_common.c +++ b/src/eap_peer/eap_tls_common.c @@ -80,6 +80,10 @@ static void eap_tls_params_flags(struct tls_connection_params *params, params->flags |= TLS_CONN_DISABLE_TLSv1_2; if (os_strstr(txt, "tls_disable_tlsv1_2=0")) params->flags &= ~TLS_CONN_DISABLE_TLSv1_2; + if (os_strstr(txt, "tls_ext_cert_check=1")) + params->flags |= TLS_CONN_EXT_CERT_CHECK; + if (os_strstr(txt, "tls_ext_cert_check=0")) + params->flags &= ~TLS_CONN_EXT_CERT_CHECK; } @@ -177,6 +181,8 @@ static int eap_tls_params_from_conf(struct eap_sm *sm, params->openssl_ciphers = config->openssl_ciphers; + sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK); + return 0; } diff --git a/src/eap_peer/eap_ttls.c b/src/eap_peer/eap_ttls.c index b186c9156..9741dedef 100644 --- a/src/eap_peer/eap_ttls.c +++ b/src/eap_peer/eap_ttls.c @@ -1,6 +1,6 @@ /* * EAP peer method: EAP-TTLS (RFC 5281) - * Copyright (c) 2004-2011, Jouni Malinen + * Copyright (c) 2004-2015, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -58,6 +58,7 @@ struct eap_ttls_data { size_t id_len; struct wpabuf *pending_phase2_req; + struct wpabuf *pending_resp; #ifdef EAP_TNC int ready_for_tnc; @@ -153,6 +154,7 @@ static void eap_ttls_deinit(struct eap_sm *sm, void *priv) eap_ttls_free_key(data); os_free(data->session_id); wpabuf_free(data->pending_phase2_req); + wpabuf_free(data->pending_resp); os_free(data); } @@ -1408,6 +1410,32 @@ static int eap_ttls_process_handshake(struct eap_sm *sm, { int res; + if (sm->waiting_ext_cert_check && data->pending_resp) { + struct eap_peer_config *config = eap_get_config(sm); + + if (config->pending_ext_cert_check == EXT_CERT_CHECK_GOOD) { + wpa_printf(MSG_DEBUG, + "EAP-TTLS: External certificate check succeeded - continue handshake"); + *out_data = data->pending_resp; + data->pending_resp = NULL; + sm->waiting_ext_cert_check = 0; + return 0; + } + + if (config->pending_ext_cert_check == EXT_CERT_CHECK_BAD) { + wpa_printf(MSG_DEBUG, + "EAP-TTLS: External certificate check failed - force authentication failure"); + ret->methodState = METHOD_DONE; + ret->decision = DECISION_FAIL; + sm->waiting_ext_cert_check = 0; + return 0; + } + + wpa_printf(MSG_DEBUG, + "EAP-TTLS: Continuing to wait external server certificate validation"); + return 0; + } + res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TTLS, data->ttls_version, identifier, in_data, out_data); @@ -1418,6 +1446,15 @@ static int eap_ttls_process_handshake(struct eap_sm *sm, return -1; } + if (sm->waiting_ext_cert_check) { + wpa_printf(MSG_DEBUG, + "EAP-TTLS: Waiting external server certificate validation"); + wpabuf_free(data->pending_resp); + data->pending_resp = *out_data; + *out_data = NULL; + return 0; + } + if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) { wpa_printf(MSG_DEBUG, "EAP-TTLS: TLS done, proceed to " "Phase 2"); @@ -1557,6 +1594,8 @@ static void eap_ttls_deinit_for_reauth(struct eap_sm *sm, void *priv) struct eap_ttls_data *data = priv; wpabuf_free(data->pending_phase2_req); data->pending_phase2_req = NULL; + wpabuf_free(data->pending_resp); + data->pending_resp = NULL; #ifdef EAP_TNC data->ready_for_tnc = 0; data->tnc_started = 0; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 580fbe8a1..6e2d18073 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -5556,6 +5556,16 @@ int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s, if (wpa_s->wpa_state == WPA_SCANNING && !wpa_s->scanning) wpa_supplicant_req_scan(wpa_s, 0, 0); break; + case WPA_CTRL_REQ_EXT_CERT_CHECK: + if (eap->pending_ext_cert_check != PENDING_CHECK) + return -1; + if (os_strcmp(value, "good") == 0) + eap->pending_ext_cert_check = EXT_CERT_CHECK_GOOD; + else if (os_strcmp(value, "bad") == 0) + eap->pending_ext_cert_check = EXT_CERT_CHECK_BAD; + else + return -1; + break; default: wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field); return -1; diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf index 2ce1cc4e3..e33b720aa 100644 --- a/wpa_supplicant/wpa_supplicant.conf +++ b/wpa_supplicant/wpa_supplicant.conf @@ -1037,6 +1037,12 @@ fast_reauth=1 # that have issues interoperating with updated TLS version) # tls_disable_tlsv1_2=1 - disable use of TLSv1.2 (a workaround for AAA servers # that have issues interoperating with updated TLS version) +# tls_ext_cert_check=0 - No external server certificate validation (default) +# tls_ext_cert_check=1 - External server certificate validation enabled; this +# requires an external program doing validation of server certificate +# chain when receiving CTRL-RSP-EXT_CERT_CHECK event from the control +# interface and report the result of the validation with +# CTRL-RSP_EXT_CERT_CHECK. # # Following certificate/private key fields are used in inner Phase2 # authentication when using EAP-TTLS or EAP-PEAP. diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 7986695aa..f84c8b90a 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -739,6 +739,8 @@ enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field) return WPA_CTRL_REQ_SIM; else if (os_strcmp(field, "PSK_PASSPHRASE") == 0) return WPA_CTRL_REQ_PSK_PASSPHRASE; + else if (os_strcmp(field, "EXT_CERT_CHECK") == 0) + return WPA_CTRL_REQ_EXT_CERT_CHECK; return WPA_CTRL_REQ_UNKNOWN; } @@ -782,6 +784,10 @@ const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field, *txt = "PSK or passphrase"; ret = "PSK_PASSPHRASE"; break; + case WPA_CTRL_REQ_EXT_CERT_CHECK: + *txt = "External server certificate validation"; + ret = "EXT_CERT_CHECK"; + break; default: break; } @@ -837,6 +843,8 @@ static void wpa_supplicant_eap_param_needed(void *ctx, if (ssid == NULL) return; + if (field == WPA_CTRL_REQ_EXT_CERT_CHECK) + ssid->eap.pending_ext_cert_check = PENDING_CHECK; wpas_notify_network_request(wpa_s, ssid, field, default_txt); field_name = wpa_supplicant_ctrl_req_to_string(field, default_txt,