aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHai Shalom <haishalom@google.com>2023-04-19 15:42:17 -0700
committerHai Shalom <haishalom@google.com>2023-04-24 15:42:57 -0700
commitae89c83f5d9a052f639027196075525c833e27bc (patch)
treec7efe7a3c8e760259e0f5eae7118bba8d394e921
parente12166ac483d0a00bbbedcaacf157f28f2212c28 (diff)
downloadwpa_supplicant_8-ae89c83f5d9a052f639027196075525c833e27bc.tar.gz
[wpa_supplicant] Generate more cert notification events
Starting a TOFU connection with the Android trust store is desirable because it would allow authenticating networks that use globally trusted Root CAs and not sending the Root CA during the TLS handshake. 1. Do not drop certificate events if the sytem CA path was set. 2. Generate certificate events for the entire chain if validation againts the trust store fails - this happens when the network has its own private Root CA. The framework needs to do its own validation before accepting a full chain. Bug: 271921032 Test: Connect successfully and securely to WPA-Enterprise networks: * Globally trusted Root CA * Private Root CA with intermediates * Partial / leaf only chain Change-Id: Ia0540ca382f9587d89ec265d76aa9f366bab3303
-rw-r--r--src/crypto/tls_openssl.c38
-rw-r--r--wpa_supplicant/aidl/aidl_manager.cpp10
2 files changed, 25 insertions, 23 deletions
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 01b17b26..23bbe687 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -2587,6 +2587,7 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
u8 hash[32];
const u8 *addr[1];
size_t len[1];
+
addr[0] = wpabuf_head(cert);
len[0] = wpabuf_len(cert);
if (sha256_vector(1, addr, len, hash) < 0 ||
@@ -2608,29 +2609,30 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
}
#endif /* CONFIG_SHA256 */
- openssl_tls_cert_event(conn, err_cert, depth, buf);
-
if (!preverify_ok) {
- if (depth > 0) {
- /* Send cert event for the peer certificate so that
- * the upper layers get information about it even if
- * validation of a CA certificate fails. */
- STACK_OF(X509) *chain;
-
- chain = X509_STORE_CTX_get1_chain(x509_ctx);
- if (chain && sk_X509_num(chain) > 0) {
- char buf2[256];
- X509 *cert;
-
- cert = sk_X509_value(chain, 0);
+ /* Send cert events for the peer certificate chain so that
+ * the upper layers get information about it even if
+ * validation of a CA certificate fails. */
+ STACK_OF(X509) *chain;
+ int num_of_certs;
+
+ chain = X509_STORE_CTX_get1_chain(x509_ctx);
+ num_of_certs = sk_X509_num(chain);
+ if (chain && num_of_certs > 0) {
+ char buf2[256];
+ X509 *cert;
+ int cur_depth;
+
+ for (cur_depth = num_of_certs - 1; cur_depth >= 0; cur_depth--) {
+ cert = sk_X509_value(chain, cur_depth);
X509_NAME_oneline(X509_get_subject_name(cert),
buf2, sizeof(buf2));
- openssl_tls_cert_event(conn, cert, 0, buf2);
+ openssl_tls_cert_event(conn, cert, cur_depth, buf2);
}
- if (chain)
- sk_X509_pop_free(chain, X509_free);
}
+ if (chain)
+ sk_X509_pop_free(chain, X509_free);
wpa_printf(MSG_WARNING, "TLS: Certificate verification failed,"
" error %d (%s) depth %d for '%s'", err, err_str,
@@ -2640,6 +2642,8 @@ static int tls_verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
return preverify_ok;
}
+ openssl_tls_cert_event(conn, err_cert, depth, buf);
+
wpa_printf(MSG_DEBUG, "TLS: tls_verify_cb - preverify_ok=%d "
"err=%d (%s) ca_cert_verify=%d depth=%d buf='%s'",
preverify_ok, err, err_str,
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index d7987e62..89b5432b 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -2058,17 +2058,15 @@ void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
return;
}
struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+ if (!wpa_key_mgmt_wpa_ieee8021x(current_ssid->key_mgmt)) {
+ return;
+ }
if (NULL == subject || NULL == cert_hash || NULL == cert) {
wpa_printf(MSG_ERROR,
"Incomplete certificate information. Drop Certification event!");
return;
}
- if (!wpa_key_mgmt_wpa_ieee8021x(current_ssid->key_mgmt)) {
- wpa_printf(MSG_ERROR, "Not 802.1x configuration, Drop Certification event!");
- return;
- }
- if (current_ssid->eap.cert.ca_path || current_ssid->eap.cert.ca_cert) {
- wpa_printf(MSG_DEBUG, "Already has CA certificate. Drop Certification event!");
+ if (current_ssid->eap.cert.ca_cert) {
return;
}