wifi: implement certificate HAL callback for Trust On First Use support
Bug: 196180536
Test: atest VtsHalWifiSupplicantStaIfaceTargetTest \
VtsHalWifiSupplicantStaNetworkTargetTest \
VtsHalWifiSupplicantP2pIfaceTargetTest
Change-Id: Ifdba307dee9003054f897db57a9f207ebc198cb4
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index c3ee8b6..f078e71 100644
--- a/wpa_supplicant/aidl/aidl.cpp
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -936,3 +936,28 @@
aidl_manager->notifyBssFreqChanged(wpa_s);
}
+
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+ int depth, const char *subject,
+ const char *altsubject[],
+ int num_altsubject,
+ const char *cert_hash,
+ const struct wpabuf *cert)
+{
+ if (!wpa_s)
+ return;
+
+ AidlManager *aidl_manager = AidlManager::getInstance();
+ if (!aidl_manager)
+ return;
+
+ wpa_printf(MSG_DEBUG, "Notify certification");
+
+ aidl_manager->notifyCertification(wpa_s,
+ depth,
+ subject,
+ altsubject,
+ num_altsubject,
+ cert_hash,
+ cert);
+}
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
index 8d2807d..71275e3 100644
--- a/wpa_supplicant/aidl/aidl.h
+++ b/wpa_supplicant/aidl/aidl.h
@@ -127,6 +127,12 @@
struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, u8 bitmap);
void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s);
void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s);
+ void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+ int depth, const char *subject,
+ const char *altsubject[],
+ int num_altsubject,
+ const char *cert_hash,
+ const struct wpabuf *cert);
#else // CONFIG_CTRL_IFACE_AIDL
static inline int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
{
@@ -280,6 +286,13 @@
{}
void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s)
{}
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+ int depth, const char *subject,
+ const char *altsubject[],
+ int num_altsubject,
+ const char *cert_hash,
+ const struct wpabuf *cert)
+{}
#endif // CONFIG_CTRL_IFACE_AIDL
#ifdef _cplusplus
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index b1457b8..780ee92 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -1915,6 +1915,52 @@
callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
}
+void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
+ int depth, const char *subject,
+ const char *altsubject[],
+ int num_altsubject,
+ const char *cert_hash,
+ const struct wpabuf *cert)
+{
+ if (!wpa_s->current_ssid) {
+ wpa_printf(MSG_ERROR, "Current network NULL. Drop Certification event!");
+ return;
+ }
+ struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+ 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!");
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "notifyCertification: depth=%d subject=%s hash=%s cert-size=%zu",
+ depth, subject, cert_hash, cert->used);
+ std::vector<uint8_t> subjectBlob(subject, subject + strlen(subject));
+ std::vector<uint8_t> certHashBlob(cert_hash, cert_hash + strlen(cert_hash));
+ std::vector<uint8_t> certBlob(cert->buf, cert->buf + cert->used);
+
+ const std::function<
+ ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
+ func = std::bind(
+ &ISupplicantStaNetworkCallback::onServerCertificateAvailable,
+ std::placeholders::_1,
+ depth,
+ subjectBlob,
+ certHashBlob,
+ certBlob);
+
+ callWithEachStaNetworkCallback(
+ misc_utils::charBufToString(wpa_s->ifname), current_ssid->id, func);
+}
+
/**
* Retrieve the |ISupplicantP2pIface| aidl object reference using the provided
* ifname.
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
index 912c817..babb2cc 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -144,6 +144,12 @@
u8 bitmap);
void notifyNetworkNotFound(struct wpa_supplicant *wpa_s);
void notifyBssFreqChanged(struct wpa_supplicant *wpa_s);
+ void notifyCertification(struct wpa_supplicant *wpa_s,
+ int depth, const char *subject,
+ const char *altsubject[],
+ int num_altsubject,
+ const char *cert_hash,
+ const struct wpabuf *cert);
// Methods called from aidl objects.
void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index 7238267..abde780 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -1688,6 +1688,8 @@
#endif
mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
+ mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
+
wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
return {static_cast<WpaDriverCapabilitiesMask>(mask),
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index a2bd488..aaa2269 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -906,6 +906,10 @@
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
"depth=%d %s", cert->depth, cert->altsubject[i]);
+ wpas_aidl_notify_ceritification(wpa_s, cert->depth, cert->subject,
+ cert->altsubject, cert->num_altsubject,
+ cert_hash, cert->cert);
+
/* notify the new DBus API */
wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
cert->altsubject, cert->num_altsubject,