Support strict conservative peer mode for EAP-SIM/AKA/AKA'
Bug: 239710602
Test: atest VtsHalWifiSupplicantStaNetworkTargetTest
Change-Id: I23cd42ba749c5c2f9d7651a88e813f3def2488bc
diff --git a/src/eap_peer/eap.c b/src/eap_peer/eap.c
index db46d95..d23556d 100644
--- a/src/eap_peer/eap.c
+++ b/src/eap_peer/eap.c
@@ -1731,6 +1731,9 @@
wpa_hexdump_ascii(MSG_DEBUG,
"EAP: using IMSI privacy anonymous identity",
identity, identity_len);
+ } else if (config->strict_conservative_peer_mode) {
+ wpa_printf(MSG_DEBUG, "EAP: never use real identity in conservative peer mode.");
+ return NULL;
} else {
identity = config->identity;
identity_len = config->identity_len;
@@ -2816,6 +2819,24 @@
return config->identity;
}
+
+/**
+ * eap_get_config_strict_conservative_peer_mode - get the value of
+ * strict conservative peer mode in eap_peer_config.
+ * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init()
+*/
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm)
+{
+ struct eap_peer_config *config;
+ config = eap_get_config(sm);
+ if (config) {
+ return config->strict_conservative_peer_mode;
+ }
+
+ return 0;
+}
+
+
static const u8 * strnchr(const u8 *str, size_t len, u8 needle) {
const u8 *cur = str;
diff --git a/src/eap_peer/eap.h b/src/eap_peer/eap.h
index aae1a41..06654ce 100644
--- a/src/eap_peer/eap.h
+++ b/src/eap_peer/eap.h
@@ -371,6 +371,7 @@
const u8 * eap_get_eapSessionId(struct eap_sm *sm, size_t *len);
const u8 * eap_get_eapKeyData(struct eap_sm *sm, size_t *len);
struct wpabuf * eap_get_eapRespData(struct eap_sm *sm);
+int eap_get_config_strict_conservative_peer_mode(struct eap_sm *sm);
void eap_register_scard_ctx(struct eap_sm *sm, void *ctx);
void eap_invalidate_cached_session(struct eap_sm *sm);
diff --git a/src/eap_peer/eap_aka.c b/src/eap_peer/eap_aka.c
index 7f660e6..fc2b16f 100644
--- a/src/eap_peer/eap_aka.c
+++ b/src/eap_peer/eap_aka.c
@@ -708,6 +708,11 @@
identity_len = data->pseudonym_len;
eap_aka_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO,
+ "EAP-AKA: reject permanent identity in conservative peer mode");
+ return eap_aka_client_error(data, id, EAP_AKA_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/src/eap_peer/eap_config.h b/src/eap_peer/eap_config.h
index 26744ab..e28ebad 100644
--- a/src/eap_peer/eap_config.h
+++ b/src/eap_peer/eap_config.h
@@ -338,6 +338,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in convervative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never send the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* machine_identity - EAP Identity for machine credential
*
* This field is used to set the machine identity or NAI for cases where
diff --git a/src/eap_peer/eap_sim.c b/src/eap_peer/eap_sim.c
index 71e9108..0ccb9a8 100644
--- a/src/eap_peer/eap_sim.c
+++ b/src/eap_peer/eap_sim.c
@@ -576,6 +576,11 @@
identity_len = data->pseudonym_len;
eap_sim_clear_identities(sm, data, CLEAR_REAUTH_ID);
} else if (id_req != NO_ID_REQ) {
+ if (id_req == PERMANENT_ID && eap_get_config_strict_conservative_peer_mode(sm)) {
+ wpa_printf(MSG_INFO,
+ "EAP-SIM: reject permanent identity in conservative peer mode");
+ return eap_sim_client_error(data, id, EAP_SIM_UNABLE_TO_PROCESS_PACKET);
+ }
identity = eap_get_config_identity(sm, &identity_len);
if (identity) {
int ids = CLEAR_PSEUDONYM | CLEAR_REAUTH_ID;
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index f9f980c..0d5d4e6 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -304,6 +304,15 @@
in_identity);
}
+::ndk::ScopedAStatus StaNetwork::setStrictConservativePeerMode(
+ bool in_enable)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+ &StaNetwork::setStrictConservativePeerModeInternal,
+ in_enable);
+}
+
::ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity)
{
@@ -1246,6 +1255,13 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus StaNetwork::setStrictConservativePeerModeInternal(bool enable)
+{
+ struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+ wpa_ssid->eap.strict_conservative_peer_mode = enable ? 1 : 0;
+ return ndk::ScopedAStatus::ok();
+}
+
ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentityInternal(
const std::vector<uint8_t> &identity)
{
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
index 6661130..f794844 100644
--- a/wpa_supplicant/aidl/sta_network.h
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -85,6 +85,8 @@
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapEncryptedImsiIdentity(
const std::vector<uint8_t>& in_identity) override;
+ ::ndk::ScopedAStatus setStrictConservativePeerMode(
+ bool in_enable) override;
::ndk::ScopedAStatus setEapAnonymousIdentity(
const std::vector<uint8_t>& in_identity) override;
::ndk::ScopedAStatus setEapPassword(
@@ -212,6 +214,8 @@
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapEncryptedImsiIdentityInternal(
const std::vector<uint8_t>& identity);
+ ndk::ScopedAStatus setStrictConservativePeerModeInternal(
+ bool enable);
ndk::ScopedAStatus setEapAnonymousIdentityInternal(
const std::vector<uint8_t>& identity);
ndk::ScopedAStatus setEapPasswordInternal(
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 065b6fb..2b1bdeb 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2529,6 +2529,7 @@
{ INTe(sim_num, sim_num) },
{ STRe(imsi_privacy_cert, imsi_privacy_cert) },
{ STRe(imsi_privacy_attr, imsi_privacy_attr) },
+ { INTe(strict_conservative_peer_mode, strict_conservative_peer_mode) },
{ STRe(openssl_ciphers, openssl_ciphers) },
{ INTe(erp, erp) },
#endif /* IEEE8021X_EAPOL */
@@ -3953,6 +3954,11 @@
return 0;
}
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0) {
+ cred->strict_conservative_peer_mode = atoi(val);
+ return 0;
+ }
+
if (line) {
wpa_printf(MSG_ERROR, "Line %d: unknown cred field '%s'.",
line, var);
@@ -4109,6 +4115,9 @@
if (os_strcmp(var, "imsi_privacy_attr") == 0)
return alloc_strdup(cred->imsi_privacy_attr);
+ if (os_strcmp(var, "strict_conservative_peer_mode") == 0)
+ return alloc_int_str(cred->strict_conservative_peer_mode);
+
if (os_strcmp(var, "milenage") == 0) {
if (!(cred->milenage))
return NULL;
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index a81e9eb..0316e9b 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -202,6 +202,18 @@
char *imsi_privacy_attr;
/**
+ * strict_conservative_peer_mode - Whether the strict conservative peer
+ * mode is enabled or not
+ *
+ * This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+ * for EAP-SIM/AKA/AKA', in convervative peer mode, a client error would
+ * be sent to the server, but it allows to send the permanent identity
+ * in some special cases according to 4.6.2 of RFC 4187; With the strict
+ * mode, it never send the permanent identity to server for privacy concern.
+ */
+ int strict_conservative_peer_mode;
+
+ /**
* engine - Use an engine for private key operations
*/
int engine;
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 260df8f..372a57b 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1044,6 +1044,9 @@
if (cred->imsi_privacy_attr)
fprintf(f, "\timsi_privacy_attr=\"%s\"\n",
cred->imsi_privacy_attr);
+ if (cred->strict_conservative_peer_mode)
+ fprintf(f,"\tstrict_conservative_peer_mode=\"%d\"\n",
+ cred->strict_conservative_peer_mode);
}
diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c
index 6198bd7..acd9044 100644
--- a/wpa_supplicant/interworking.c
+++ b/wpa_supplicant/interworking.c
@@ -1077,6 +1077,12 @@
goto fail;
}
+ if (cred->strict_conservative_peer_mode) {
+ if (wpa_config_set_quoted(ssid, "strict_conservative_peer_mode",
+ "1") < 0)
+ goto fail;
+ }
+
wpa_s->next_ssid = ssid;
wpa_config_update_prio_list(wpa_s->conf);
if (!only_add)
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index 8262eef..b6a1a74 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -1175,6 +1175,14 @@
# unencrypted identity with EAP types that support different tunnelled
# identity, e.g., EAP-TTLS). This field can also be used with
# EAP-SIM/AKA/AKA' to store the pseudonym identity.
+# strict_conservative_peer_mode: Whether the strict conservative peer mode
+# is enabled. This field is used to handle the reponse of AT_PERMANENT_ID_REQ
+# for EAP-SIM/AKA/AKA'. In non-strict convervative peer mode, a client
+# error would be sent to the server, but the mode will send the permanent
+# identity in some special cases according to 4.6.2 of RFC 4187; With the
+# strict mode, the permanent identity is never sent to the server.
+# 0 = disabled (default)
+# 1 = enabled
# password: Password string for EAP. This field can include either the
# plaintext password (using ASCII or hex string) or a NtPasswordHash
# (16-byte MD4 hash of password) in hash:<32 hex digits> format.