Merge "Revert "Rename local RC file config variable in Supplicant servi...""
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index da76a01..7874785 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -513,6 +513,18 @@
 		bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
 	}
 
+	// vendor_elements string
+	std::string vendor_elements_as_string;
+	if (nw_params.vendorElements.size() > 0) {
+		std::stringstream ss;
+		ss << std::hex;
+		ss << std::setfill('0');
+		for (uint8_t b : nw_params.vendorElements) {
+			ss << std::setw(2) << static_cast<unsigned int>(b);
+		}
+		vendor_elements_as_string = StringPrintf("vendor_elements=%s", ss.str().c_str());
+	}
+
 	return StringPrintf(
 		"interface=%s\n"
 		"driver=nl80211\n"
@@ -535,6 +547,7 @@
 		"%s\n"
 		"%s\n"
 		"%s\n"
+		"%s\n"
 		"%s\n",
 		iface_params.name.c_str(), ssid_as_string.c_str(),
 		channel_config_as_string.c_str(),
@@ -549,7 +562,8 @@
 		encryption_config_as_string.c_str(),
 		bridge_as_string.c_str(),
 		enable_edmg_as_string.c_str(),
-		edmg_channel_as_string.c_str());
+		edmg_channel_as_string.c_str(),
+		vendor_elements_as_string.c_str());
 }
 
 Generation getGeneration(hostapd_hw_modes *current_mode)
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 086dfb3..4bc5075 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -3066,7 +3066,7 @@
 #ifdef CONFIG_SUITEB
 #ifdef OPENSSL_IS_BORINGSSL
 	/* Start with defaults from BoringSSL */
-	SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, NULL, 0);
+	SSL_set_verify_algorithm_prefs(conn->ssl, NULL, 0);
 #endif /* OPENSSL_IS_BORINGSSL */
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
 	if (flags & TLS_CONN_SUITEB_NO_ECDH) {
@@ -3120,7 +3120,7 @@
 #ifdef OPENSSL_IS_BORINGSSL
 		uint16_t sigalgs[1] = { SSL_SIGN_RSA_PKCS1_SHA384 };
 
-		if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
+		if (SSL_set_verify_algorithm_prefs(conn->ssl, sigalgs,
 						       1) != 1) {
 			wpa_printf(MSG_INFO,
 				   "OpenSSL: Failed to set Suite B sigalgs");
@@ -3158,7 +3158,7 @@
 			return -1;
 		}
 
-		if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
+		if (SSL_set_verify_algorithm_prefs(conn->ssl, sigalgs,
 						       1) != 1) {
 			wpa_printf(MSG_INFO,
 				   "OpenSSL: Failed to set Suite B sigalgs");
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
index f3f04a3..f078e71 100644
--- a/wpa_supplicant/aidl/aidl.cpp
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -921,3 +921,43 @@
 
 	aidl_manager->notifyNetworkNotFound(wpa_s);
 }
+
+void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify %s frequency changed to %d",
+	    wpa_s->ifname, wpa_s->assoc_freq);
+
+	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 899f99cd..71275e3 100644
--- a/wpa_supplicant/aidl/aidl.h
+++ b/wpa_supplicant/aidl/aidl.h
@@ -126,6 +126,13 @@
 	void wpas_aidl_notify_transition_disable(
 		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)
 {
@@ -277,6 +284,15 @@
 {}
 static 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)
+{}
 #endif  // CONFIG_CTRL_IFACE_AIDL
 
 #ifdef _cplusplus
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index 1ce9326..780ee92 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -1892,6 +1892,75 @@
 	callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
 }
 
+void AidlManager::notifyBssFreqChanged(struct wpa_supplicant *wpa_group_s)
+{
+	if (!wpa_group_s || !wpa_group_s->parent)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s) {
+		wpa_printf(MSG_INFO, "Drop BSS frequency changed event");
+		return;
+	}
+
+	uint32_t aidl_freq = wpa_group_s->current_bss
+				? wpa_group_s->current_bss->freq
+				: wpa_group_s->assoc_freq;
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+		func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_freq);
+	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 b538e36..babb2cc 100644
--- a/wpa_supplicant/aidl/aidl_manager.h
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -143,6 +143,13 @@
 			struct wpa_ssid *ssid,
 			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/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index b6294da..b59d103 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -2071,6 +2071,15 @@
 	ss.write((char *) serializedEntry.data(), std::streamsize(serializedEntry.size()));
 	misc_utils::deserializePmkCacheEntry(ss, new_entry);
 	new_entry->network_ctx = wpa_ssid;
+
+	// If there is an entry has a later expiration, ignore this one.
+	struct rsn_pmksa_cache_entry *existing_entry = wpa_sm_pmksa_cache_get(
+		wpa_s->wpa, new_entry->aa, NULL, NULL, new_entry->akmp);
+	if (NULL != existing_entry &&
+		existing_entry->expiration >= new_entry->expiration) {
+		return ndk::ScopedAStatus::ok();
+	}
+
 	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, new_entry);
 
 	return ndk::ScopedAStatus::ok();
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index b3cb287..aaa2269 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -467,6 +467,8 @@
 		return;
 
 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
+
+	wpas_aidl_notify_bss_freq_changed(wpa_s);
 }
 
 
@@ -904,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,