1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.wifi;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.hardware.wifi.supplicant.AuthAlgMask;
22 import android.hardware.wifi.supplicant.DppConnectionKeys;
23 import android.hardware.wifi.supplicant.EapMethod;
24 import android.hardware.wifi.supplicant.EapPhase2Method;
25 import android.hardware.wifi.supplicant.GroupCipherMask;
26 import android.hardware.wifi.supplicant.GroupMgmtCipherMask;
27 import android.hardware.wifi.supplicant.ISupplicantStaNetwork;
28 import android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback;
29 import android.hardware.wifi.supplicant.KeyMgmtMask;
30 import android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams;
31 import android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams;
32 import android.hardware.wifi.supplicant.OcspType;
33 import android.hardware.wifi.supplicant.PairwiseCipherMask;
34 import android.hardware.wifi.supplicant.ProtoMask;
35 import android.hardware.wifi.supplicant.SaeH2eMode;
36 import android.hardware.wifi.supplicant.TlsVersion;
37 import android.net.wifi.OuiKeyedData;
38 import android.net.wifi.SecurityParams;
39 import android.net.wifi.WifiConfiguration;
40 import android.net.wifi.WifiEnterpriseConfig;
41 import android.net.wifi.WifiManager;
42 import android.net.wifi.WifiSsid;
43 import android.os.RemoteException;
44 import android.os.ServiceSpecificException;
45 import android.text.TextUtils;
46 import android.util.Log;
47 
48 import com.android.internal.annotations.VisibleForTesting;
49 import com.android.modules.utils.build.SdkLevel;
50 import com.android.server.wifi.util.ArrayUtils;
51 import com.android.server.wifi.util.HalAidlUtil;
52 import com.android.server.wifi.util.NativeUtil;
53 import com.android.wifi.resources.R;
54 
55 import org.json.JSONException;
56 import org.json.JSONObject;
57 
58 import java.io.UnsupportedEncodingException;
59 import java.net.URLDecoder;
60 import java.net.URLEncoder;
61 import java.util.ArrayList;
62 import java.util.BitSet;
63 import java.util.HashMap;
64 import java.util.Iterator;
65 import java.util.List;
66 import java.util.Map;
67 import java.util.regex.Matcher;
68 import java.util.regex.Pattern;
69 
70 import javax.annotation.concurrent.ThreadSafe;
71 
72 /**
73  * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables
74  * and interacts with networks.
75  * Public fields should be treated as invalid until their 'get' method is called, which will set the
76  * value if it returns true
77  * To maintain thread-safety, the locking protocol is that every non-static method (regardless of
78  * access level) acquires mLock.
79  */
80 @ThreadSafe
81 public class SupplicantStaNetworkHalAidlImpl {
82     private static final String TAG = "SupplicantStaNetworkHalAidlImpl";
83     @VisibleForTesting
84     public static final String ID_STRING_KEY_FQDN = "fqdn";
85     @VisibleForTesting
86     public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid";
87     @VisibleForTesting
88     public static final String ID_STRING_KEY_CONFIG_KEY = "configKey";
89 
90     /**
91      * Regex pattern for extracting the GSM sim authentication response params from a string.
92      * Matches a strings like the following: "[:<kc_value>:<sres_value>]";
93      */
94     private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN =
95             Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)");
96     /**
97      * Regex pattern for extracting the UMTS sim authentication response params from a string.
98      * Matches a strings like the following: ":<ik_value>:<ck_value>:<res_value>";
99      */
100     private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN =
101             Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$");
102     /**
103      * Regex pattern for extracting the UMTS sim auts response params from a string.
104      * Matches a strings like the following: ":<auts_value>";
105      */
106     private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN =
107             Pattern.compile("^:([0-9a-fA-F]+)$");
108 
109     private final Object mLock = new Object();
110     private final Context mContext;
111     private final String mIfaceName;
112     private final WifiMonitor mWifiMonitor;
113     private final WifiGlobals mWifiGlobals;
114     private ISupplicantStaNetwork mISupplicantStaNetwork;
115     private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback;
116     private int mServiceVersion;
117 
118     private boolean mVerboseLoggingEnabled = false;
119     // Network variables read from wpa_supplicant.
120     private int mNetworkId;
121     private byte[] mSsid;
122     private byte[/* 6 */] mBssid;
123     private boolean mScanSsid;
124     private int mKeyMgmtMask;
125     private int mProtoMask;
126     private int mAuthAlgMask;
127     private int mGroupCipherMask;
128     private int mPairwiseCipherMask;
129     private int mGroupMgmtCipherMask;
130     private String mPskPassphrase;
131     private String mSaePassword;
132     private String mSaePasswordId;
133     private byte[] mPsk;
134     private byte[] mWepKey;
135     private int mWepTxKeyIdx;
136     private boolean mRequirePmf;
137     private String mIdStr;
138     private int mEapMethod;
139     private int mEapPhase2Method;
140     private byte[] mEapIdentity;
141     private byte[] mEapAnonymousIdentity;
142     private byte[] mEapPassword;
143     private String mEapCACert;
144     private String mEapCAPath;
145     private String mEapClientCert;
146     private String mEapPrivateKeyId;
147     private String mEapSubjectMatch;
148     private String mEapAltSubjectMatch;
149     private boolean mEapEngine;
150     private String mEapEngineID;
151     private String mEapDomainSuffixMatch;
152     private @WifiEnterpriseConfig.Ocsp int mOcsp;
153     private String mWapiCertSuite;
154     private long mAdvanceKeyMgmtFeatures;
155     private long mWpaDriverFeatures;
156 
SupplicantStaNetworkHalAidlImpl(int serviceVersion, ISupplicantStaNetwork staNetwork, String ifaceName, Context context, WifiMonitor monitor, WifiGlobals wifiGlobals, long advanceKeyMgmtFeature, long wpaDriverFeatures)157     SupplicantStaNetworkHalAidlImpl(int serviceVersion,
158             ISupplicantStaNetwork staNetwork, String ifaceName,
159             Context context, WifiMonitor monitor, WifiGlobals wifiGlobals,
160             long advanceKeyMgmtFeature, long wpaDriverFeatures) {
161         mServiceVersion = serviceVersion;
162         mISupplicantStaNetwork = staNetwork;
163         mContext = context;
164         mIfaceName = ifaceName;
165         mWifiMonitor = monitor;
166         mWifiGlobals = wifiGlobals;
167         mAdvanceKeyMgmtFeatures = advanceKeyMgmtFeature;
168         mWpaDriverFeatures = wpaDriverFeatures;
169     }
170 
171     /**
172      * Check that the service is running at least the expected version.
173      * Use to avoid the case where the framework is using a newer
174      * interface version than the service.
175      */
isServiceVersionIsAtLeast(int expectedVersion)176     private boolean isServiceVersionIsAtLeast(int expectedVersion) {
177         return expectedVersion <= mServiceVersion;
178     }
179 
180     /**
181      * Enable/Disable verbose logging.
182      *
183      */
enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled)184     void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) {
185         synchronized (mLock) {
186             mVerboseLoggingEnabled = verboseEnabled;
187         }
188     }
189 
190     /**
191      * Read network variables from wpa_supplicant into the provided WifiConfiguration object.
192      *
193      * @param config WifiConfiguration object to be populated.
194      * @param networkExtras Map of network extras parsed from wpa_supplicant.
195      * @return true if succeeds, false otherwise.
196      * @throws IllegalArgumentException on malformed configuration params.
197      */
198     @VisibleForTesting
loadWifiConfiguration(WifiConfiguration config, Map<String, String> networkExtras)199     public boolean loadWifiConfiguration(WifiConfiguration config,
200             Map<String, String> networkExtras) throws IllegalArgumentException {
201         synchronized (mLock) {
202             if (config == null) {
203                 return false;
204             }
205             /** SSID */
206             config.SSID = null;
207             if (getSsid() && !ArrayUtils.isEmpty(mSsid)) {
208                 config.SSID = WifiSsid.fromBytes(mSsid).toString();
209             } else {
210                 Log.e(TAG, "failed to read ssid");
211                 return false;
212             }
213             /** Network Id */
214             config.networkId = -1;
215             if (getId()) {
216                 config.networkId = mNetworkId;
217             } else {
218                 Log.e(TAG, "getId failed");
219                 return false;
220             }
221             /** BSSID */
222             config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null);
223             if (getBssid() && !ArrayUtils.isEmpty(mBssid)) {
224                 config.getNetworkSelectionStatus().setNetworkSelectionBSSID(
225                         NativeUtil.macAddressFromByteArray(mBssid));
226             }
227             /** Scan SSID (Is Hidden Network?) */
228             config.hiddenSSID = false;
229             if (getScanSsid()) {
230                 config.hiddenSSID = mScanSsid;
231             }
232             /** Require PMF*/
233             config.requirePmf = false;
234             if (getRequirePmf()) {
235                 config.requirePmf = mRequirePmf;
236             }
237             /** WEP keys **/
238             config.wepTxKeyIndex = -1;
239             if (getWepTxKeyIdx()) {
240                 config.wepTxKeyIndex = mWepTxKeyIdx;
241             }
242             for (int i = 0; i < 4; i++) {
243                 config.wepKeys[i] = null;
244                 if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) {
245                     config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString(
246                             NativeUtil.byteArrayToArrayList(mWepKey));
247                 }
248             }
249 
250             /** allowedKeyManagement */
251             if (getKeyMgmt()) {
252                 BitSet keyMgmtMask = HalAidlUtil.supplicantToWifiConfigurationKeyMgmtMask(
253                         mKeyMgmtMask);
254                 keyMgmtMask = removeFastTransitionFlags(keyMgmtMask);
255                 keyMgmtMask = removeSha256KeyMgmtFlags(keyMgmtMask);
256                 keyMgmtMask = removePskSaeUpgradableTypeFlags(keyMgmtMask);
257                 config.setSecurityParams(keyMgmtMask);
258                 config.enableFils(
259                         keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA256),
260                         keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA384));
261             }
262 
263             // supplicant only have one valid security type, it won't be a disbled params.
264             SecurityParams securityParams = config.getDefaultSecurityParams();
265 
266             /** PSK passphrase */
267             config.preSharedKey = null;
268             if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) {
269                 if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) {
270                     config.preSharedKey = mPskPassphrase;
271                 } else {
272                     config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase);
273                 }
274             } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) {
275                 config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk);
276             } /* Do not read SAE password */
277 
278             /** metadata: idstr */
279             if (getIdStr() && !TextUtils.isEmpty(mIdStr)) {
280                 Map<String, String> metadata = parseNetworkExtra(mIdStr);
281                 networkExtras.putAll(metadata);
282             } else {
283                 Log.w(TAG, "getIdStr failed or empty");
284             }
285 
286             /** WAPI Cert Suite */
287             if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT)) {
288                 if (config.enterpriseConfig == null) {
289                     return false;
290                 }
291                 config.enterpriseConfig.setEapMethod(
292                         WifiEnterpriseConfig.Eap.WAPI_CERT);
293                 /** WAPI Certificate Suite. */
294                 if (getWapiCertSuite() && !TextUtils.isEmpty(mWapiCertSuite)) {
295                     config.enterpriseConfig.setWapiCertSuite(mWapiCertSuite);
296                 }
297                 return true;
298             }
299             return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig);
300         }
301     }
302 
303     /**
304      * Read network variables from the provided WifiConfiguration object into wpa_supplicant.
305      *
306      * @param config WifiConfiguration object to be saved. Note that the SSID will already by the
307      *               raw, untranslated SSID to pass to supplicant directly.
308      * @return true if succeeds, false otherwise.
309      * @throws IllegalArgumentException on malformed configuration params.
310      */
saveWifiConfiguration(WifiConfiguration config)311     public boolean saveWifiConfiguration(WifiConfiguration config) throws IllegalArgumentException {
312         synchronized (mLock) {
313             if (config == null) {
314                 return false;
315             }
316             // ieee80211be
317             if (!config.isWifi7Enabled() && isServiceVersionIsAtLeast(3)) {
318                 if (!disableEht()) {
319                     Log.e(TAG, "failed to disable EHT (Wi-Fi 7)");
320                     return false;
321                 }
322             }
323             // SSID
324             if (config.SSID != null) {
325                 WifiSsid wifiSsid = WifiSsid.fromString(config.SSID);
326                 if (!setSsid(wifiSsid.getBytes())) {
327                     Log.e(TAG, "failed to set SSID: " + wifiSsid);
328                     return false;
329                 }
330             }
331             // BSSID
332             String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID();
333             if (bssidStr != null) {
334                 byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr);
335                 if (!setBssid(bssid)) {
336                     Log.e(TAG, "failed to set BSSID: " + bssidStr);
337                     return false;
338                 }
339             }
340             // HiddenSSID
341             if (!setScanSsid(config.hiddenSSID)) {
342                 Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID);
343                 return false;
344             }
345 
346             SecurityParams securityParams = config.getNetworkSelectionStatus()
347                     .getCandidateSecurityParams();
348             if (securityParams == null) {
349                 Log.wtf(TAG, "No available security params.");
350                 return false;
351             }
352             Log.d(TAG, "The target security params: " + securityParams);
353 
354             boolean isRequirePmf = NativeUtil.getOptimalPmfSettingForConfig(config,
355                     securityParams.isRequirePmf(), mWifiGlobals);
356             // RequirePMF
357             if (!setRequirePmf(isRequirePmf)) {
358                 Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf);
359                 return false;
360             }
361             // Key Management Scheme
362             BitSet allowedKeyManagement = securityParams.getAllowedKeyManagement();
363             if (allowedKeyManagement.cardinality() != 0) {
364                 // Add upgradable type key management flags for PSK/SAE.
365                 allowedKeyManagement = addPskSaeUpgradableTypeFlagsIfSupported(config,
366                         allowedKeyManagement);
367                 // Add FT flags if supported.
368                 allowedKeyManagement = addFastTransitionFlags(allowedKeyManagement);
369                 // Add SHA256 key management flags.
370                 allowedKeyManagement = addSha256KeyMgmtFlags(allowedKeyManagement);
371                 if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(allowedKeyManagement))) {
372                     Log.e(TAG, "failed to set Key Management");
373                     return false;
374                 }
375                 // Check and set SuiteB configurations.
376                 if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SUITE_B_192)
377                         && !saveSuiteBConfig(config)) {
378                     Log.e(TAG, "failed to set Suite-B-192 configuration");
379                     return false;
380                 }
381                 // Check and set DPP Connection keys
382                 if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.DPP)
383                         && !saveDppConnectionConfig(config)) {
384                     Log.e(TAG, "failed to set DPP connection params");
385                     return false;
386                 }
387             }
388             // Security Protocol
389             BitSet allowedProtocols = securityParams.getAllowedProtocols();
390             if (allowedProtocols.cardinality() != 0 && !setProto(
391                     wifiConfigurationToSupplicantProtoMask(allowedProtocols, mWifiGlobals,
392                             WifiConfigurationUtil.isConfigForEnterpriseNetwork(config)))) {
393                 Log.e(TAG, "failed to set Security Protocol");
394                 return false;
395             }
396             // Auth Algorithm
397             BitSet allowedAuthAlgorithms = securityParams.getAllowedAuthAlgorithms();
398             if (allowedAuthAlgorithms.cardinality() != 0
399                     && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask(
400                     allowedAuthAlgorithms))) {
401                 Log.e(TAG, "failed to set AuthAlgorithm");
402                 return false;
403             }
404             // Group Cipher
405             BitSet allowedGroupCiphers = NativeUtil.getOptimalGroupCiphersForConfig(
406                     config, securityParams.getAllowedGroupCiphers(), mWifiGlobals);
407             if (allowedGroupCiphers.cardinality() != 0
408                     && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
409                     allowedGroupCiphers)))) {
410                 Log.e(TAG, "failed to set Group Cipher");
411                 return false;
412             }
413             // Pairwise Cipher
414             BitSet allowedPairwiseCiphers = NativeUtil.getOptimalPairwiseCiphersForConfig(
415                     config, securityParams.getAllowedPairwiseCiphers(), mWifiGlobals);
416             if (allowedPairwiseCiphers.cardinality() != 0
417                     && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
418                     allowedPairwiseCiphers))) {
419                 Log.e(TAG, "failed to set PairwiseCipher");
420                 return false;
421             }
422             // Pre Shared Key
423             // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk.
424             // For SAE, password must be a quoted ASCII string
425             if (config.preSharedKey != null) {
426                 if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) {
427                     if (!setPskPassphrase(config.preSharedKey)) {
428                         Log.e(TAG, "failed to set wapi psk passphrase");
429                         return false;
430                     }
431                 } else if (config.preSharedKey.startsWith("\"")) {
432                     if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
433                         // WPA3 case, field is SAE Password
434                         if (!setSaePassword(
435                                 NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
436                             Log.e(TAG, "failed to set sae password");
437                             return false;
438                         }
439                     }
440                     if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
441                         if (!setPskPassphrase(
442                                 NativeUtil.removeEnclosingQuotes(config.preSharedKey))) {
443                             Log.e(TAG, "failed to set psk passphrase");
444                             return false;
445                         }
446                     }
447                 } else {
448                     if (!allowedKeyManagement.get(WifiConfiguration.KeyMgmt.WPA_PSK)
449                             && allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
450                         return false;
451                     }
452                     if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) {
453                         Log.e(TAG, "failed to set psk");
454                         return false;
455                     }
456                 }
457             }
458             // Wep Keys
459             boolean hasSetKey = false;
460             if (config.wepKeys != null) {
461                 for (int i = 0; i < config.wepKeys.length; i++) {
462                     if (config.wepKeys[i] != null) {
463                         if (!setWepKey(i, NativeUtil.byteArrayFromArrayList(
464                                 NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i])))) {
465                             Log.e(TAG, "failed to set wep_key " + i);
466                             return false;
467                         }
468                         hasSetKey = true;
469                     }
470                 }
471             }
472             // Wep Tx Key Idx
473             if (hasSetKey) {
474                 if (!setWepTxKeyIdx(config.wepTxKeyIndex)) {
475                     Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex);
476                     return false;
477                 }
478             }
479             // metadata: FQDN + ConfigKey + CreatorUid
480             final Map<String, String> metadata = new HashMap<String, String>();
481             if (config.isPasspoint()) {
482                 metadata.put(ID_STRING_KEY_FQDN, config.FQDN);
483                 // Selected RCOI
484                 if (!setSelectedRcoi(config.enterpriseConfig.getSelectedRcoi())) {
485                     Log.e(TAG, "failed to set selected RCOI");
486                     return false;
487                 }
488             }
489             metadata.put(ID_STRING_KEY_CONFIG_KEY, config.getProfileKey());
490             metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid));
491             if (!setIdStr(createNetworkExtra(metadata))) {
492                 Log.e(TAG, "failed to set id string");
493                 return false;
494             }
495             // UpdateIdentifier
496             if (config.updateIdentifier != null
497                     && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) {
498                 Log.e(TAG, "failed to set update identifier");
499                 return false;
500             }
501             // SAE configuration
502             if (allowedKeyManagement.get(WifiConfiguration.KeyMgmt.SAE)) {
503                 /**
504                  * Hash-to-Element preference.
505                  * For devices that don't support H2E, H2E mode will be permanently disabled.
506                  * Devices that support H2E will enable both legacy and H2E mode by default,
507                  * and will connect to SAE networks with H2E if possible, unless H2E only
508                  * mode is enabled, and then the device will not connect to SAE networks in
509                  * legacy mode.
510                  */
511                 if (!mWifiGlobals.isWpa3SaeH2eSupported() && securityParams.isSaeH2eOnlyMode()) {
512                     Log.e(TAG, "This device does not support SAE H2E.");
513                     return false;
514                 }
515                 byte mode = mWifiGlobals.isWpa3SaeH2eSupported()
516                         ? SaeH2eMode.H2E_OPTIONAL
517                         : SaeH2eMode.DISABLED;
518                 if (securityParams.isSaeH2eOnlyMode()) {
519                     mode = SaeH2eMode.H2E_MANDATORY;
520                 }
521                 if (!setSaeH2eMode(mode)) {
522                     Log.e(TAG, "failed to set H2E preference.");
523                     return false;
524                 }
525             }
526             // Vendor data
527             if (SdkLevel.isAtLeastV() && isServiceVersionIsAtLeast(3)
528                     && config.getVendorData() != null
529                     && !config.getVendorData().isEmpty()
530                     && !setVendorData(config.getVendorData())) {
531                 Log.e(TAG, "Failed to set vendor data.");
532                 return false;
533             }
534             // Finish here if no EAP config to set
535             if (config.enterpriseConfig != null
536                     && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) {
537                 if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) {
538                     // WAPI certificate suite name
539                     String param = config.enterpriseConfig
540                             .getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY);
541                     if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) {
542                         Log.e(TAG, config.SSID + ": failed to set WAPI certificate suite: "
543                                 + param);
544                         return false;
545                     }
546                     return true;
547                 } else if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) {
548                     return false;
549                 }
550             }
551 
552             // Now that the network is configured fully, start listening for callback events.
553             return registerNewCallback(config.networkId, config.SSID);
554         }
555     }
556 
557     /**
558      * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object.
559      *
560      * @param ssid      SSID of the network. (Used for logging purposes only)
561      * @param eapConfig WifiEnterpriseConfig object to be populated.
562      * @return true if succeeds, false otherwise.
563      */
loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig)564     private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
565         synchronized (mLock) {
566             if (eapConfig == null) {
567                 return false;
568             }
569             /** EAP method */
570             if (getEapMethod()) {
571                 eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod));
572             } else {
573                 // Invalid eap method could be because it's not an enterprise config.
574                 Log.e(TAG, "Failed to get eap method. Assuming not an enterprise network");
575                 return true;
576             }
577             /** EAP Phase 2 method */
578             if (getEapPhase2Method()) {
579                 eapConfig.setPhase2Method(
580                         supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method));
581             } else {
582                 // We cannot have an invalid eap phase 2 method. Return failure.
583                 Log.e(TAG, "Failed to get eap phase2 method");
584                 return false;
585             }
586             /** EAP Identity */
587             if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) {
588                 eapConfig.setFieldValue(
589                         WifiEnterpriseConfig.IDENTITY_KEY,
590                         NativeUtil.stringFromByteArray(mEapIdentity));
591             }
592             /** EAP Anonymous Identity */
593             if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) {
594                 eapConfig.setFieldValue(
595                         WifiEnterpriseConfig.ANON_IDENTITY_KEY,
596                         NativeUtil.stringFromByteArray(mEapAnonymousIdentity));
597             }
598             /** EAP Password */
599             if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) {
600                 eapConfig.setFieldValue(
601                         WifiEnterpriseConfig.PASSWORD_KEY,
602                         NativeUtil.stringFromByteArray(mEapPassword));
603             }
604             /** EAP Client Cert */
605             if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) {
606                 eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert);
607             }
608             /** EAP CA Cert */
609             if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) {
610                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert);
611             }
612             /** EAP OCSP type */
613             if (getOcsp()) {
614                 eapConfig.setOcsp(mOcsp);
615             }
616             /** EAP Subject Match */
617             if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) {
618                 eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch);
619             }
620             /** EAP Engine ID */
621             if (getEapEngineId() && !TextUtils.isEmpty(mEapEngineID)) {
622                 eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID);
623             }
624             /** EAP Engine. Set this only if the engine id is non null. */
625             if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) {
626                 eapConfig.setFieldValue(
627                         WifiEnterpriseConfig.ENGINE_KEY,
628                         mEapEngine
629                                 ? WifiEnterpriseConfig.ENGINE_ENABLE
630                                 : WifiEnterpriseConfig.ENGINE_DISABLE);
631             }
632             /** EAP Private Key */
633             if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) {
634                 eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId);
635             }
636             /** EAP Alt Subject Match */
637             if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) {
638                 eapConfig.setFieldValue(
639                         WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch);
640             }
641             /** EAP Domain Suffix Match */
642             if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) {
643                 eapConfig.setFieldValue(
644                         WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch);
645             }
646             /** EAP CA Path*/
647             if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) {
648                 eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath);
649             }
650             return true;
651         }
652     }
653 
654     /**
655      * save network variables from the provided dpp configuration to wpa_supplicant.
656      *
657      * @param config wificonfiguration object to be saved
658      * @return true if succeeds, false otherwise.
659      */
saveDppConnectionConfig(WifiConfiguration config)660     private boolean saveDppConnectionConfig(WifiConfiguration config) {
661         synchronized (mLock) {
662             final String methodStr = "setDppKeys";
663             if (!checkStaNetworkAndLogFailure(methodStr)) {
664                 return false;
665             }
666             try {
667                 DppConnectionKeys keys = new DppConnectionKeys();
668                 keys.connector = config.getDppConnector();
669                 keys.cSign = config.getDppCSignKey();
670                 keys.netAccessKey = config.getDppNetAccessKey();
671                 mISupplicantStaNetwork.setDppKeys(keys);
672                 return true;
673             } catch (RemoteException e) {
674                 handleRemoteException(e, methodStr);
675             } catch (ServiceSpecificException e) {
676                 handleServiceSpecificException(e, methodStr);
677             }
678             return false;
679         }
680     }
681 
682     /**
683      * Save network variables from the provided SuiteB configuration to wpa_supplicant.
684      *
685      * @param config WifiConfiguration object to be saved
686      * @return true if succeeds, false otherwise.
687      */
saveSuiteBConfig(WifiConfiguration config)688     private boolean saveSuiteBConfig(WifiConfiguration config) {
689         synchronized (mLock) {
690             SecurityParams securityParams = config.getNetworkSelectionStatus()
691                     .getCandidateSecurityParams();
692             if (securityParams == null) {
693                 Log.wtf(TAG, "No available security params.");
694                 return false;
695             }
696 
697             /** Group Cipher **/
698             BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers();
699             if (allowedGroupCiphers.cardinality() != 0
700                     && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask(
701                     allowedGroupCiphers))) {
702                 Log.e(TAG, "Failed to set Group Cipher");
703                 return false;
704             }
705             /** Pairwise Cipher*/
706             BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers();
707             if (allowedPairwiseCiphers.cardinality() != 0
708                     && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask(
709                     allowedPairwiseCiphers))) {
710                 Log.e(TAG, "Failed to set PairwiseCipher");
711                 return false;
712             }
713             /** GroupMgmt Cipher */
714             BitSet allowedGroupManagementCiphers =
715                     securityParams.getAllowedGroupManagementCiphers();
716             if (allowedGroupManagementCiphers.cardinality() != 0
717                     && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask(
718                     allowedGroupManagementCiphers))) {
719                 Log.e(TAG, "Failed to set GroupMgmtCipher");
720                 return false;
721             }
722 
723             BitSet allowedSuiteBCiphers = securityParams.getAllowedSuiteBCiphers();
724             if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) {
725                 if (!enableTlsSuiteBEapPhase1Param(true)) {
726                     Log.e(TAG, "Failed to set TLSSuiteB");
727                     return false;
728                 }
729             } else if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) {
730                 if (!enableSuiteBEapOpenSslCiphers()) {
731                     Log.e(TAG, "Failed to set OpensslCipher");
732                     return false;
733                 }
734             }
735 
736             return true;
737         }
738     }
739 
740     /**
741      * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant.
742      *
743      * @param ssid SSID of the network. (Used for logging purposes only)
744      * @param eapConfig WifiEnterpriseConfig object to be saved.
745      * @return true if succeeds, false otherwise.
746      */
saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig)747     private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) {
748         synchronized (mLock) {
749             if (eapConfig == null) {
750                 return false;
751             }
752             /** EAP method */
753             if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) {
754                 Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod());
755                 return false;
756             }
757             /** EAP Phase 2 method */
758             if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method(
759                     eapConfig.getPhase2Method()))) {
760                 Log.e(TAG, ssid + ": failed to set eap phase 2 method: "
761                         + eapConfig.getPhase2Method());
762                 return false;
763             }
764             if (eapConfig.isAuthenticationSimBased()
765                     && eapConfig.getEapMethod() != WifiEnterpriseConfig.Eap.PEAP
766                     && eapConfig.getStrictConservativePeerMode()) {
767                 if (!enableStrictConservativePeerMode()) {
768                     Log.w(TAG, "failed or not support to set strict conservative peer mode.");
769                 }
770                 // don't return false, as the mode is optional.
771             }
772             String eapParam = null;
773             /** EAP Identity */
774             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY);
775             if (!TextUtils.isEmpty(eapParam)
776                     && !setEapIdentity(NativeUtil.stringToByteArray(eapParam))) {
777                 Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam);
778                 return false;
779             }
780             /** EAP Anonymous Identity */
781             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY);
782             if (!TextUtils.isEmpty(eapParam)) {
783                 String decoratedUsernamePrefix =
784                         eapConfig.getFieldValue(WifiEnterpriseConfig.DECORATED_IDENTITY_PREFIX_KEY);
785                 if (!TextUtils.isEmpty(decoratedUsernamePrefix)) {
786                     eapParam = decoratedUsernamePrefix + eapParam;
787                 }
788                 if (!setEapAnonymousIdentity(NativeUtil.stringToByteArray(eapParam))) {
789                     Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam);
790                     return false;
791                 }
792             }
793             /** EAP Password */
794             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY);
795             if (!TextUtils.isEmpty(eapParam)
796                     && !setEapPassword(NativeUtil.stringToByteArray(eapParam))) {
797                 Log.e(TAG, ssid + ": failed to set eap password");
798                 return false;
799             }
800             /** EAP Client Cert */
801             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY);
802             if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) {
803                 Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam);
804                 return false;
805             }
806             /** EAP CA Cert */
807             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
808             if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) {
809                 Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam);
810                 return false;
811             }
812             /** EAP Subject Match */
813             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY);
814             if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) {
815                 Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam);
816                 return false;
817             }
818             /** EAP Engine ID */
819             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY);
820             if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) {
821                 Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam);
822                 return false;
823             }
824             /** EAP Engine */
825             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY);
826             if (!TextUtils.isEmpty(eapParam) && !setEapEngine(
827                     eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) {
828                 Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam);
829                 return false;
830             }
831             /** EAP Private Key */
832             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY);
833             if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) {
834                 Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam);
835                 return false;
836             }
837             /** EAP Alt Subject Match */
838             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY);
839             if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) {
840                 Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam);
841                 return false;
842             }
843             /** EAP Domain Suffix Match */
844             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY);
845             if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) {
846                 Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam);
847                 return false;
848             }
849             /** EAP CA Path*/
850             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY);
851             if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) {
852                 Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam);
853                 return false;
854             }
855             /** EAP Proactive Key Caching */
856             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING);
857             if (!TextUtils.isEmpty(eapParam)
858                     && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) {
859                 Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam);
860                 return false;
861             }
862             /** OCSP (Online Certificate Status Protocol) */
863             if (!setOcsp(eapConfig.getOcsp())) {
864                 Log.e(TAG, "failed to set ocsp");
865                 return false;
866             }
867             /** EAP ERP */
868             eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP);
869             if (!TextUtils.isEmpty(eapParam) && eapParam.equals("1")) {
870                 if (!setEapErp(true)) {
871                     Log.e(TAG, ssid + ": failed to set eap erp");
872                     return false;
873                 }
874             }
875             if (isServiceVersionIsAtLeast(2)) {
876                 if (!setMinimumTlsVersionEapPhase1Param(getOptimalMinimumTlsVersion(eapConfig))) {
877                     Log.e(TAG, "Failed to set the minimum TLS version");
878                     return false;
879                 }
880             }
881             return true;
882         }
883     }
884 
getOptimalMinimumTlsVersion(WifiEnterpriseConfig enterpriseConfig)885     private int getOptimalMinimumTlsVersion(WifiEnterpriseConfig enterpriseConfig) {
886         int maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_2;
887         if ((mWpaDriverFeatures & WifiManager.WIFI_FEATURE_TLS_V1_3) != 0) {
888             maxTlsVersionSupported = WifiEnterpriseConfig.TLS_V1_3;
889         }
890 
891         int requiredMinimumTlsVersion = enterpriseConfig.getMinimumTlsVersion();
892         if (requiredMinimumTlsVersion > maxTlsVersionSupported) {
893             Log.w(TAG, "The required minimum TLS version " + requiredMinimumTlsVersion
894                     + " exceeds the maximum supported TLS version " + maxTlsVersionSupported
895                     + ", fallback to the maximum supported TLS version.");
896             return maxTlsVersionSupported;
897         }
898         return requiredMinimumTlsVersion;
899     }
900 
901     /**
902      * Maps WifiConfiguration Key Management BitSet to Supplicant AIDL bitmask int
903      *
904      * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant
905      * AIDL hal
906      */
wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt)907     private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) {
908         int mask = 0;
909         for (int bit = keyMgmt.nextSetBit(0); bit != -1;
910                 bit = keyMgmt.nextSetBit(bit + 1)) {
911             switch (bit) {
912                 case WifiConfiguration.KeyMgmt.NONE:
913                     mask |= KeyMgmtMask.NONE;
914                     break;
915                 case WifiConfiguration.KeyMgmt.WPA_PSK:
916                     mask |= KeyMgmtMask.WPA_PSK;
917                     break;
918                 case WifiConfiguration.KeyMgmt.WPA_EAP:
919                     mask |= KeyMgmtMask.WPA_EAP;
920                     break;
921                 case WifiConfiguration.KeyMgmt.IEEE8021X:
922                     mask |= KeyMgmtMask.IEEE8021X;
923                     break;
924                 case WifiConfiguration.KeyMgmt.OSEN:
925                     mask |= KeyMgmtMask.OSEN;
926                     break;
927                 case WifiConfiguration.KeyMgmt.FT_PSK:
928                     mask |= KeyMgmtMask.FT_PSK;
929                     break;
930                 case WifiConfiguration.KeyMgmt.FT_EAP:
931                     mask |= KeyMgmtMask.FT_EAP;
932                     break;
933                 case WifiConfiguration.KeyMgmt.OWE:
934                     mask |= KeyMgmtMask.OWE;
935                     break;
936                 case WifiConfiguration.KeyMgmt.SAE:
937                     mask |= KeyMgmtMask.SAE;
938                     break;
939                 case WifiConfiguration.KeyMgmt.SUITE_B_192:
940                     mask |= KeyMgmtMask.SUITE_B_192;
941                     break;
942                 case WifiConfiguration.KeyMgmt.WPA_PSK_SHA256:
943                     mask |= KeyMgmtMask.WPA_PSK_SHA256;
944                     break;
945                 case WifiConfiguration.KeyMgmt.WPA_EAP_SHA256:
946                     mask |= KeyMgmtMask.WPA_EAP_SHA256;
947                     break;
948                 case WifiConfiguration.KeyMgmt.WAPI_PSK:
949                     mask |= KeyMgmtMask.WAPI_PSK;
950                     break;
951                 case WifiConfiguration.KeyMgmt.WAPI_CERT:
952                     mask |= KeyMgmtMask.WAPI_CERT;
953                     break;
954                 case WifiConfiguration.KeyMgmt.FILS_SHA256:
955                     mask |= KeyMgmtMask.FILS_SHA256;
956                     break;
957                 case WifiConfiguration.KeyMgmt.FILS_SHA384:
958                     mask |= KeyMgmtMask.FILS_SHA384;
959                     break;
960                 case WifiConfiguration.KeyMgmt.DPP:
961                     mask |= KeyMgmtMask.DPP;
962                     break;
963                 case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen
964                 default:
965                     throw new IllegalArgumentException(
966                             "Invalid protoMask bit in keyMgmt: " + bit);
967             }
968         }
969         return mask;
970     }
971 
wifiConfigurationToSupplicantProtoMask(BitSet protoMask, WifiGlobals wifiGlobals, boolean isEnterprise)972     private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask,
973             WifiGlobals wifiGlobals, boolean isEnterprise) {
974         int mask = 0;
975         for (int bit = protoMask.nextSetBit(0); bit != -1;
976                 bit = protoMask.nextSetBit(bit + 1)) {
977             switch (bit) {
978                 case WifiConfiguration.Protocol.WPA:
979                     if (isEnterprise || !wifiGlobals.isWpaPersonalDeprecated()) {
980                         mask |= ProtoMask.WPA;
981                     }
982                     break;
983                 case WifiConfiguration.Protocol.RSN:
984                     mask |= ProtoMask.RSN;
985                     break;
986                 case WifiConfiguration.Protocol.OSEN:
987                     mask |= ProtoMask.OSEN;
988                     break;
989                 case WifiConfiguration.Protocol.WAPI:
990                     mask |= ProtoMask.WAPI;
991                     break;
992                 default:
993                     throw new IllegalArgumentException(
994                             "Invalid protoMask bit in wificonfig: " + bit);
995             }
996         }
997         return mask;
998     }
999 
wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask)1000     private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) {
1001         int mask = 0;
1002         for (int bit = authAlgMask.nextSetBit(0); bit != -1;
1003                 bit = authAlgMask.nextSetBit(bit + 1)) {
1004             switch (bit) {
1005                 case WifiConfiguration.AuthAlgorithm.OPEN:
1006                     mask |= AuthAlgMask.OPEN;
1007                     break;
1008                 case WifiConfiguration.AuthAlgorithm.SHARED:
1009                     mask |= AuthAlgMask.SHARED;
1010                     break;
1011                 case WifiConfiguration.AuthAlgorithm.LEAP:
1012                     mask |= AuthAlgMask.LEAP;
1013                     break;
1014                 case WifiConfiguration.AuthAlgorithm.SAE:
1015                     mask |= AuthAlgMask.SAE;
1016                     break;
1017                 default:
1018                     throw new IllegalArgumentException(
1019                             "Invalid authAlgMask bit in wificonfig: " + bit);
1020             }
1021         }
1022         return mask;
1023     }
1024 
wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask)1025     private int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) {
1026         synchronized (mLock) {
1027             int mask = 0;
1028             for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit =
1029                     groupCipherMask.nextSetBit(bit + 1)) {
1030                 switch (bit) {
1031                     case WifiConfiguration.GroupCipher.WEP40:
1032                         mask |= GroupCipherMask.WEP40;
1033                         break;
1034                     case WifiConfiguration.GroupCipher.WEP104:
1035                         mask |= GroupCipherMask.WEP104;
1036                         break;
1037                     case WifiConfiguration.GroupCipher.TKIP:
1038                         mask |= GroupCipherMask.TKIP;
1039                         break;
1040                     case WifiConfiguration.GroupCipher.CCMP:
1041                         mask |= GroupCipherMask.CCMP;
1042                         break;
1043                     case WifiConfiguration.GroupCipher.GTK_NOT_USED:
1044                         mask |= GroupCipherMask.GTK_NOT_USED;
1045                         break;
1046                     case WifiConfiguration.GroupCipher.GCMP_256:
1047                         if (0 == (mAdvanceKeyMgmtFeatures
1048                                 & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
1049                             Log.d(TAG, "Ignore unsupported GCMP_256 cipher.");
1050                             break;
1051                         }
1052                         mask |= GroupCipherMask.GCMP_256;
1053                         break;
1054                     case WifiConfiguration.GroupCipher.SMS4:
1055                         mask |= GroupCipherMask.SMS4;
1056                         break;
1057                     case WifiConfiguration.GroupCipher.GCMP_128:
1058                         mask |= GroupCipherMask.GCMP_128;
1059                         break;
1060                     default:
1061                         throw new IllegalArgumentException(
1062                                 "Invalid GroupCipherMask bit in wificonfig: " + bit);
1063                 }
1064             }
1065             return mask;
1066         }
1067     }
1068 
wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet groupMgmtCipherMask)1069     private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet
1070             groupMgmtCipherMask) {
1071         int mask = 0;
1072 
1073         for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit =
1074                 groupMgmtCipherMask.nextSetBit(bit + 1)) {
1075             switch (bit) {
1076                 case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256:
1077                     mask |= GroupMgmtCipherMask.BIP_CMAC_256;
1078                     break;
1079                 case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128:
1080                     mask |= GroupMgmtCipherMask.BIP_GMAC_128;
1081                     break;
1082                 case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256:
1083                     mask |= GroupMgmtCipherMask.BIP_GMAC_256;
1084                     break;
1085                 default:
1086                     throw new IllegalArgumentException(
1087                             "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit);
1088             }
1089         }
1090         return mask;
1091     }
1092 
wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask)1093     private int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) {
1094         synchronized (mLock) {
1095             int mask = 0;
1096             for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1;
1097                     bit = pairwiseCipherMask.nextSetBit(bit + 1)) {
1098                 switch (bit) {
1099                     case WifiConfiguration.PairwiseCipher.NONE:
1100                         mask |= PairwiseCipherMask.NONE;
1101                         break;
1102                     case WifiConfiguration.PairwiseCipher.TKIP:
1103                         mask |= PairwiseCipherMask.TKIP;
1104                         break;
1105                     case WifiConfiguration.PairwiseCipher.CCMP:
1106                         mask |= PairwiseCipherMask.CCMP;
1107                         break;
1108                     case WifiConfiguration.PairwiseCipher.GCMP_256:
1109                         if (0 == (mAdvanceKeyMgmtFeatures
1110                                 & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) {
1111                             Log.d(TAG, "Ignore unsupporting GCMP_256 cipher.");
1112                             break;
1113                         }
1114                         mask |= PairwiseCipherMask.GCMP_256;
1115                         break;
1116                     case WifiConfiguration.PairwiseCipher.SMS4:
1117                         mask |= PairwiseCipherMask.SMS4;
1118                         break;
1119                     case WifiConfiguration.PairwiseCipher.GCMP_128:
1120                         mask |= PairwiseCipherMask.GCMP_128;
1121                         break;
1122                     default:
1123                         throw new IllegalArgumentException(
1124                                 "Invalid pairwiseCipherMask bit in wificonfig: " + bit);
1125                 }
1126             }
1127             return mask;
1128         }
1129     }
1130 
supplicantToWifiConfigurationEapMethod(int value)1131     private static int supplicantToWifiConfigurationEapMethod(int value) {
1132         switch (value) {
1133             case EapMethod.PEAP:
1134                 return WifiEnterpriseConfig.Eap.PEAP;
1135             case EapMethod.TLS:
1136                 return WifiEnterpriseConfig.Eap.TLS;
1137             case EapMethod.TTLS:
1138                 return WifiEnterpriseConfig.Eap.TTLS;
1139             case EapMethod.PWD:
1140                 return WifiEnterpriseConfig.Eap.PWD;
1141             case EapMethod.SIM:
1142                 return WifiEnterpriseConfig.Eap.SIM;
1143             case EapMethod.AKA:
1144                 return WifiEnterpriseConfig.Eap.AKA;
1145             case EapMethod.AKA_PRIME:
1146                 return WifiEnterpriseConfig.Eap.AKA_PRIME;
1147             case EapMethod.WFA_UNAUTH_TLS:
1148                 return WifiEnterpriseConfig.Eap.UNAUTH_TLS;
1149             // WifiEnterpriseConfig.Eap.NONE:
1150             default:
1151                 Log.e(TAG, "invalid eap method value from supplicant: " + value);
1152                 return -1;
1153         }
1154     }
1155 
supplicantToWifiConfigurationEapPhase2Method(int value)1156     private static int supplicantToWifiConfigurationEapPhase2Method(int value) {
1157         switch (value) {
1158             case EapPhase2Method.NONE:
1159                 return WifiEnterpriseConfig.Phase2.NONE;
1160             case EapPhase2Method.PAP:
1161                 return WifiEnterpriseConfig.Phase2.PAP;
1162             case EapPhase2Method.MSPAP:
1163                 return WifiEnterpriseConfig.Phase2.MSCHAP;
1164             case EapPhase2Method.MSPAPV2:
1165                 return WifiEnterpriseConfig.Phase2.MSCHAPV2;
1166             case EapPhase2Method.GTC:
1167                 return WifiEnterpriseConfig.Phase2.GTC;
1168             case EapPhase2Method.SIM:
1169                 return WifiEnterpriseConfig.Phase2.SIM;
1170             case EapPhase2Method.AKA:
1171                 return WifiEnterpriseConfig.Phase2.AKA;
1172             case EapPhase2Method.AKA_PRIME:
1173                 return WifiEnterpriseConfig.Phase2.AKA_PRIME;
1174             default:
1175                 Log.e(TAG, "Invalid eap phase2 method value from supplicant: " + value);
1176                 return -1;
1177         }
1178     }
1179 
wifiConfigurationToSupplicantEapMethod(int value)1180     private static int wifiConfigurationToSupplicantEapMethod(int value) {
1181         switch (value) {
1182             case WifiEnterpriseConfig.Eap.PEAP:
1183                 return EapMethod.PEAP;
1184             case WifiEnterpriseConfig.Eap.TLS:
1185                 return EapMethod.TLS;
1186             case WifiEnterpriseConfig.Eap.TTLS:
1187                 return EapMethod.TTLS;
1188             case WifiEnterpriseConfig.Eap.PWD:
1189                 return EapMethod.PWD;
1190             case WifiEnterpriseConfig.Eap.SIM:
1191                 return EapMethod.SIM;
1192             case WifiEnterpriseConfig.Eap.AKA:
1193                 return EapMethod.AKA;
1194             case WifiEnterpriseConfig.Eap.AKA_PRIME:
1195                 return EapMethod.AKA_PRIME;
1196             case WifiEnterpriseConfig.Eap.UNAUTH_TLS:
1197                 return EapMethod.WFA_UNAUTH_TLS;
1198             // WifiEnterpriseConfig.Eap.NONE:
1199             default:
1200                 Log.e(TAG, "Invalid eap method value from WifiConfiguration: " + value);
1201                 return -1;
1202         }
1203     }
1204 
wifiConfigurationToSupplicantEapPhase2Method(int value)1205     private static int wifiConfigurationToSupplicantEapPhase2Method(int value) {
1206         switch (value) {
1207             case WifiEnterpriseConfig.Phase2.NONE:
1208                 return EapPhase2Method.NONE;
1209             case WifiEnterpriseConfig.Phase2.PAP:
1210                 return EapPhase2Method.PAP;
1211             case WifiEnterpriseConfig.Phase2.MSCHAP:
1212                 return EapPhase2Method.MSPAP;
1213             case WifiEnterpriseConfig.Phase2.MSCHAPV2:
1214                 return EapPhase2Method.MSPAPV2;
1215             case WifiEnterpriseConfig.Phase2.GTC:
1216                 return EapPhase2Method.GTC;
1217             case WifiEnterpriseConfig.Phase2.SIM:
1218                 return EapPhase2Method.SIM;
1219             case WifiEnterpriseConfig.Phase2.AKA:
1220                 return EapPhase2Method.AKA;
1221             case WifiEnterpriseConfig.Phase2.AKA_PRIME:
1222                 return EapPhase2Method.AKA_PRIME;
1223             default:
1224                 Log.e(TAG, "Invalid eap phase2 method value from WifiConfiguration: " + value);
1225                 return -1;
1226         }
1227     }
1228 
1229     /**
1230      * Retrieves the ID allocated to this network by the supplicant.
1231      * Result is stored in mNetworkId.
1232      *
1233      * This is not the |SSID| of the network, but an internal identifier for
1234      * this network used by the supplicant.
1235      *
1236      * @return true if ID was retrieved, false otherwise
1237      */
getId()1238     private boolean getId() {
1239         synchronized (mLock) {
1240             final String methodStr = "getId";
1241             if (!checkStaNetworkAndLogFailure(methodStr)) {
1242                 return false;
1243             }
1244             try {
1245                 mNetworkId = mISupplicantStaNetwork.getId();
1246                 return true;
1247             } catch (RemoteException e) {
1248                 handleRemoteException(e, methodStr);
1249             } catch (ServiceSpecificException e) {
1250                 handleServiceSpecificException(e, methodStr);
1251             }
1252             return false;
1253         }
1254     }
1255 
1256     /** Get current network id */
getNetworkId()1257     public int getNetworkId() {
1258         synchronized (mLock) {
1259             if (!getId()) {
1260                 return -1;
1261             }
1262             return mNetworkId;
1263         }
1264     }
1265 
registerCallback(ISupplicantStaNetworkCallback callback)1266     private boolean registerCallback(ISupplicantStaNetworkCallback callback) {
1267         synchronized (mLock) {
1268             final String methodStr = "registerCallback";
1269             if (!checkStaNetworkAndLogFailure(methodStr)) {
1270                 return false;
1271             }
1272             try {
1273                 mISupplicantStaNetwork.registerCallback(callback);
1274                 return true;
1275             } catch (RemoteException e) {
1276                 handleRemoteException(e, methodStr);
1277             } catch (ServiceSpecificException e) {
1278                 handleServiceSpecificException(e, methodStr);
1279             }
1280             return false;
1281         }
1282     }
1283 
registerNewCallback(int networkId, String ssid)1284     private boolean registerNewCallback(int networkId, String ssid) {
1285         synchronized (mLock) {
1286             ISupplicantStaNetworkCallback callback =
1287                     new SupplicantStaNetworkCallbackAidlImpl(
1288                             SupplicantStaNetworkHalAidlImpl.this,
1289                             networkId, ssid, mIfaceName, mLock, mWifiMonitor);
1290             if (!registerCallback(callback)) {
1291                 Log.e(TAG, "Failed to register callback.");
1292                 return false;
1293             }
1294             mISupplicantStaNetworkCallback = callback;
1295             return true;
1296         }
1297     }
1298 
1299     /**
1300      * Set SSID for this network.
1301      *
1302      * @param ssid Value to set.
1303      *        Max length of |ParamSizeLimits.SSID_MAX_LEN_IN_BYTES|.
1304      * @return true if successful, false otherwise
1305      */
setSsid(byte[] ssid)1306     private boolean setSsid(byte[] ssid) {
1307         synchronized (mLock) {
1308             final String methodStr = "setSsid";
1309             if (!checkStaNetworkAndLogFailure(methodStr)) {
1310                 return false;
1311             }
1312             try {
1313                 mISupplicantStaNetwork.setSsid(ssid);
1314                 Log.i(TAG, "Successfully set SSID");
1315                 return true;
1316             } catch (RemoteException e) {
1317                 handleRemoteException(e, methodStr);
1318             } catch (ServiceSpecificException e) {
1319                 handleServiceSpecificException(e, methodStr);
1320             }
1321             return false;
1322         }
1323     }
1324 
1325     /**
1326      * Disable EHT for this network.
1327      *
1328      * @return true if successful, false otherwise
1329      */
disableEht()1330     private boolean disableEht() {
1331         synchronized (mLock) {
1332             final String methodStr = "disableEht";
1333             if (!checkStaNetworkAndLogFailure(methodStr)) {
1334                 return false;
1335             }
1336             try {
1337                 if (!isServiceVersionIsAtLeast(3)) {
1338                     return false;
1339                 }
1340                 mISupplicantStaNetwork.disableEht();
1341                 Log.i(TAG, "Successfully disabled EHT");
1342                 return true;
1343             } catch (RemoteException e) {
1344                 handleRemoteException(e, methodStr);
1345             } catch (ServiceSpecificException e) {
1346                 handleServiceSpecificException(e, methodStr);
1347             }
1348             return false;
1349         }
1350     }
1351 
1352     /**
1353      * Set the BSSID for this network.
1354      *
1355      * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address.
1356      * @return true if it succeeds, false otherwise.
1357      */
setBssid(String bssidStr)1358     public boolean setBssid(String bssidStr) {
1359         synchronized (mLock) {
1360             try {
1361                 return setBssid(NativeUtil.macAddressToByteArray(bssidStr));
1362             } catch (IllegalArgumentException e) {
1363                 Log.e(TAG, "Illegal argument " + bssidStr, e);
1364                 return false;
1365             }
1366         }
1367     }
1368 
setBssid(byte[ ] bssid)1369     private boolean setBssid(byte[/* 6 */] bssid) {
1370         synchronized (mLock) {
1371             final String methodStr = "setBssid";
1372             if (!checkStaNetworkAndLogFailure(methodStr)) {
1373                 return false;
1374             }
1375             try {
1376                 mISupplicantStaNetwork.setBssid(bssid);
1377                 return true;
1378             } catch (RemoteException e) {
1379                 handleRemoteException(e, methodStr);
1380             } catch (ServiceSpecificException e) {
1381                 handleServiceSpecificException(e, methodStr);
1382             }
1383             return false;
1384         }
1385     }
1386 
1387     /**
1388      * Set whether to send probe requests for this network (hidden).
1389      *
1390      * @param enable true to set, false otherwise.
1391      * @return true if successful, false otherwise
1392      */
setScanSsid(boolean enable)1393     private boolean setScanSsid(boolean enable) {
1394         synchronized (mLock) {
1395             final String methodStr = "setScanSsid";
1396             if (!checkStaNetworkAndLogFailure(methodStr)) {
1397                 return false;
1398             }
1399             try {
1400                 mISupplicantStaNetwork.setScanSsid(enable);
1401                 return true;
1402             } catch (RemoteException e) {
1403                 handleRemoteException(e, methodStr);
1404             } catch (ServiceSpecificException e) {
1405                 handleServiceSpecificException(e, methodStr);
1406             }
1407             return false;
1408         }
1409     }
1410 
1411     /**
1412      * Set key management mask for the network.
1413      *
1414      * @param keyMgmtMask value to set.
1415      *        Combination of |KeyMgmtMask| values.
1416      * @return true if successful, false otherwise
1417      */
setKeyMgmt(int keyMgmtMask)1418     private boolean setKeyMgmt(int keyMgmtMask) {
1419         synchronized (mLock) {
1420             final String methodStr = "setKeyMgmt";
1421             if (!checkStaNetworkAndLogFailure(methodStr)) {
1422                 return false;
1423             }
1424             try {
1425                 mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask);
1426                 return true;
1427             } catch (RemoteException e) {
1428                 handleRemoteException(e, methodStr);
1429             } catch (ServiceSpecificException e) {
1430                 handleServiceSpecificException(e, methodStr);
1431             }
1432             return false;
1433         }
1434     }
1435 
1436     /**
1437      * Set proto mask for the network.
1438      *
1439      * @param protoMask value to set.
1440      *        Combination of |ProtoMask| values.
1441      * @return true if successful, false otherwise
1442      */
setProto(int protoMask)1443     private boolean setProto(int protoMask) {
1444         synchronized (mLock) {
1445             final String methodStr = "setProto";
1446             if (!checkStaNetworkAndLogFailure(methodStr)) {
1447                 return false;
1448             }
1449             try {
1450                 mISupplicantStaNetwork.setProto(protoMask);
1451                 return true;
1452             } catch (RemoteException e) {
1453                 handleRemoteException(e, methodStr);
1454             } catch (ServiceSpecificException e) {
1455                 handleServiceSpecificException(e, methodStr);
1456             }
1457             return false;
1458         }
1459     }
1460 
1461     /**
1462      * Set auth alg mask for the network.
1463      *
1464      * @param authAlgMask value to set.
1465      *        Combination of |ProtoMask| values.
1466      * @return true if successful, false otherwise
1467      */
setAuthAlg(int authAlgMask)1468     private boolean setAuthAlg(int authAlgMask) {
1469         synchronized (mLock) {
1470             final String methodStr = "setAuthAlg";
1471             if (!checkStaNetworkAndLogFailure(methodStr)) {
1472                 return false;
1473             }
1474             try {
1475                 mISupplicantStaNetwork.setAuthAlg(authAlgMask);
1476                 return true;
1477             } catch (RemoteException e) {
1478                 handleRemoteException(e, methodStr);
1479             } catch (ServiceSpecificException e) {
1480                 handleServiceSpecificException(e, methodStr);
1481             }
1482             return false;
1483         }
1484     }
1485 
1486     /**
1487      * Set group cipher mask for the network.
1488      *
1489      * @param groupCipherMask value to set.
1490      *        Combination of |ProtoMask| values.
1491      * @return true if successful, false otherwise
1492      */
setGroupCipher(int groupCipherMask)1493     private boolean setGroupCipher(int groupCipherMask) {
1494         synchronized (mLock) {
1495             final String methodStr = "setGroupCipher";
1496             if (!checkStaNetworkAndLogFailure(methodStr)) {
1497                 return false;
1498             }
1499             if (mVerboseLoggingEnabled) {
1500                 Log.d(TAG, String.format("setGroupCipher: 0x%x", groupCipherMask));
1501             }
1502             try {
1503                 mISupplicantStaNetwork.setGroupCipher(groupCipherMask);
1504                 return true;
1505             } catch (RemoteException e) {
1506                 handleRemoteException(e, methodStr);
1507             } catch (ServiceSpecificException e) {
1508                 handleServiceSpecificException(e, methodStr);
1509             }
1510             return false;
1511         }
1512     }
1513 
1514     /**
1515      * Enable TLS Suite-B in EAP Phase1
1516      *
1517      * @param enable Set to true to enable TLS Suite-B in EAP phase1
1518      * @return true if successful, false otherwise
1519      */
enableTlsSuiteBEapPhase1Param(boolean enable)1520     private boolean enableTlsSuiteBEapPhase1Param(boolean enable) {
1521         synchronized (mLock) {
1522             final String methodStr = "setEapPhase1Params";
1523             if (!checkStaNetworkAndLogFailure(methodStr)) {
1524                 return false;
1525             }
1526             try {
1527                 mISupplicantStaNetwork.enableTlsSuiteBEapPhase1Param(enable);
1528                 return true;
1529             } catch (RemoteException e) {
1530                 handleRemoteException(e, methodStr);
1531             } catch (ServiceSpecificException e) {
1532                 handleServiceSpecificException(e, methodStr);
1533             }
1534             return false;
1535         }
1536     }
1537 
1538     /**
1539      * Set EAP OpenSSL Suite-B-192 ciphers for WPA3-Enterprise
1540      *
1541      * @return true if successful, false otherwise
1542      */
enableSuiteBEapOpenSslCiphers()1543     private boolean enableSuiteBEapOpenSslCiphers() {
1544         synchronized (mLock) {
1545             final String methodStr = "setEapOpenSslCiphers";
1546             if (!checkStaNetworkAndLogFailure(methodStr)) {
1547                 return false;
1548             }
1549             try {
1550                 mISupplicantStaNetwork.enableSuiteBEapOpenSslCiphers();
1551                 return true;
1552             } catch (RemoteException e) {
1553                 handleRemoteException(e, methodStr);
1554             } catch (ServiceSpecificException e) {
1555                 handleServiceSpecificException(e, methodStr);
1556             }
1557             return false;
1558         }
1559     }
1560 
1561     /**
1562      * Set pairwise cipher mask for the network.
1563      *
1564      * @param pairwiseCipherMask value to set.
1565      *        Combination of |ProtoMask| values.
1566      * @return true if successful, false otherwise
1567      */
setPairwiseCipher(int pairwiseCipherMask)1568     private boolean setPairwiseCipher(int pairwiseCipherMask) {
1569         synchronized (mLock) {
1570             final String methodStr = "setPairwiseCipher";
1571             if (!checkStaNetworkAndLogFailure(methodStr)) {
1572                 return false;
1573             }
1574             if (mVerboseLoggingEnabled) {
1575                 Log.d(TAG, String.format("setPairwiseCipher: 0x%x", pairwiseCipherMask));
1576             }
1577             try {
1578                 mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask);
1579                 return true;
1580             } catch (RemoteException e) {
1581                 handleRemoteException(e, methodStr);
1582             } catch (ServiceSpecificException e) {
1583                 handleServiceSpecificException(e, methodStr);
1584             }
1585             return false;
1586         }
1587     }
1588 
1589     /**
1590      * Set group management cipher mask for the network.
1591      *
1592      * @param groupMgmtCipherMask value to set.
1593      *        Combination of |GroupMgmtCipherMask| values.
1594      * @return true if successful, false otherwise
1595      */
setGroupMgmtCipher(int groupMgmtCipherMask)1596     private boolean setGroupMgmtCipher(int groupMgmtCipherMask) {
1597         synchronized (mLock) {
1598             final String methodStr = "setGroupMgmtCipher";
1599             if (!checkStaNetworkAndLogFailure(methodStr)) {
1600                 return false;
1601             }
1602             try {
1603                 mISupplicantStaNetwork.setGroupMgmtCipher(groupMgmtCipherMask);
1604                 return true;
1605             } catch (RemoteException e) {
1606                 handleRemoteException(e, methodStr);
1607             } catch (ServiceSpecificException e) {
1608                 handleServiceSpecificException(e, methodStr);
1609             }
1610             return false;
1611         }
1612     }
1613 
1614     /**
1615      * Set passphrase for WPA_PSK network.
1616      *
1617      * @param psk value to set.
1618      *        Length of value must be between
1619      *        |ParamSizeLimits.PSK_PASSPHRASE_MIN_LEN_IN_BYTES| and
1620      *        |ParamSizeLimits.PSK_PASSPHRASE_MAX_LEN_IN_BYTES|.
1621      * @return true if successful, false otherwise
1622      */
setPskPassphrase(String psk)1623     private boolean setPskPassphrase(String psk) {
1624         synchronized (mLock) {
1625             final String methodStr = "setPskPassphrase";
1626             if (!checkStaNetworkAndLogFailure(methodStr)) {
1627                 return false;
1628             }
1629             try {
1630                 mISupplicantStaNetwork.setPskPassphrase(psk);
1631                 return true;
1632             } catch (RemoteException e) {
1633                 handleRemoteException(e, methodStr);
1634             } catch (ServiceSpecificException e) {
1635                 handleServiceSpecificException(e, methodStr);
1636             }
1637             return false;
1638         }
1639     }
1640 
1641     /**
1642      * Set raw psk for WPA_PSK network.
1643      *
1644      * @param psk value to set as specified in IEEE 802.11i-2004 standard.
1645      *        This is the calculated using 'wpa_passphrase <ssid> [passphrase]'
1646      * @return true if successful, false otherwise
1647      */
setPsk(byte[] psk)1648     private boolean setPsk(byte[] psk) {
1649         synchronized (mLock) {
1650             final String methodStr = "setPsk";
1651             if (!checkStaNetworkAndLogFailure(methodStr)) {
1652                 return false;
1653             }
1654             try {
1655                 mISupplicantStaNetwork.setPsk(psk);
1656                 return true;
1657             } catch (RemoteException e) {
1658                 handleRemoteException(e, methodStr);
1659             } catch (ArrayIndexOutOfBoundsException e) {
1660                 Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e);
1661             } catch (ServiceSpecificException e) {
1662                 handleServiceSpecificException(e, methodStr);
1663             }
1664             return false;
1665         }
1666     }
1667 
1668     /**
1669      * Set WEP key for WEP network.
1670      *
1671      * @param keyIdx Index of wep key to set.
1672      *        Max of |ParamSizeLimits.WEP_KEYS_MAX_NUM|.
1673      * @param wepKey value to set.
1674      *        Length of each key must be either
1675      *        |ParamSizeLimits.WEP40_KEY_LEN_IN_BYTES| or
1676      *        |ParamSizeLimits.WEP104_KEY_LEN_IN_BYTES|.
1677      * @return true if successful, false otherwise
1678      */
setWepKey(int keyIdx, byte[] wepKey)1679     private boolean setWepKey(int keyIdx, byte[] wepKey) {
1680         synchronized (mLock) {
1681             final String methodStr = "setWepKey";
1682             if (!checkStaNetworkAndLogFailure(methodStr)) {
1683                 return false;
1684             }
1685             try {
1686                 mISupplicantStaNetwork.setWepKey(keyIdx, wepKey);
1687                 return true;
1688             } catch (RemoteException e) {
1689                 handleRemoteException(e, methodStr);
1690             } catch (ServiceSpecificException e) {
1691                 handleServiceSpecificException(e, methodStr);
1692             }
1693             return false;
1694         }
1695     }
1696 
1697     /**
1698      * Set default Tx key index for WEP network.
1699      *
1700      * @param keyIdx value to set.
1701      *        Max of |ParamSizeLimits.WEP_KEYS_MAX_NUM|.
1702      * @return true if successful, false otherwise
1703      */
setWepTxKeyIdx(int keyIdx)1704     private boolean setWepTxKeyIdx(int keyIdx) {
1705         synchronized (mLock) {
1706             final String methodStr = "setWepTxKeyIdx";
1707             if (!checkStaNetworkAndLogFailure(methodStr)) {
1708                 return false;
1709             }
1710             try {
1711                 mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx);
1712                 return true;
1713             } catch (RemoteException e) {
1714                 handleRemoteException(e, methodStr);
1715             } catch (ServiceSpecificException e) {
1716                 handleServiceSpecificException(e, methodStr);
1717             }
1718             return false;
1719         }
1720     }
1721 
1722     /**
1723      * Set whether RequirePmf is enabled for this network.
1724      *
1725      * @param enable true to set, false otherwise.
1726      * @return true if successful, false otherwise
1727      */
setRequirePmf(boolean enable)1728     private boolean setRequirePmf(boolean enable) {
1729         synchronized (mLock) {
1730             final String methodStr = "setRequirePmf";
1731             if (!checkStaNetworkAndLogFailure(methodStr)) {
1732                 return false;
1733             }
1734             if (mVerboseLoggingEnabled) {
1735                 Log.d(TAG, "setRequirePmf: " + enable);
1736             }
1737             try {
1738                 mISupplicantStaNetwork.setRequirePmf(enable);
1739                 return true;
1740             } catch (RemoteException e) {
1741                 handleRemoteException(e, methodStr);
1742             } catch (ServiceSpecificException e) {
1743                 handleServiceSpecificException(e, methodStr);
1744             }
1745             return false;
1746         }
1747     }
1748 
1749     /**
1750      * Set PPS MO ID for this network.
1751      * (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier)
1752      *
1753      * @param identifier ID value to set.
1754      * @return true if successful, false otherwise
1755      */
setUpdateIdentifier(int identifier)1756     private boolean setUpdateIdentifier(int identifier) {
1757         synchronized (mLock) {
1758             final String methodStr = "setUpdateIdentifier";
1759             if (!checkStaNetworkAndLogFailure(methodStr)) {
1760                 return false;
1761             }
1762             try {
1763                 mISupplicantStaNetwork.setUpdateIdentifier(identifier);
1764                 return true;
1765             } catch (RemoteException e) {
1766                 handleRemoteException(e, methodStr);
1767             } catch (ServiceSpecificException e) {
1768                 handleServiceSpecificException(e, methodStr);
1769             }
1770             return false;
1771         }
1772     }
1773 
1774     /**
1775      * Set WAPI certificate suite name for this network.
1776      *
1777      * @param certSuite value to set.
1778      * @return true if successful, false otherwise
1779      */
setWapiCertSuite(String certSuite)1780     private boolean setWapiCertSuite(String certSuite) {
1781         synchronized (mLock) {
1782             final String methodStr = "setWapiCertSuite";
1783             if (!checkStaNetworkAndLogFailure(methodStr)) {
1784                 return false;
1785             }
1786             try {
1787                 mISupplicantStaNetwork.setWapiCertSuite(certSuite);
1788                 return true;
1789             } catch (RemoteException e) {
1790                 handleRemoteException(e, methodStr);
1791             } catch (ServiceSpecificException e) {
1792                 handleServiceSpecificException(e, methodStr);
1793             }
1794             return false;
1795         }
1796     }
1797 
1798     /**
1799      * Set EAP Method for this network.
1800      *
1801      * @param method value to be set.
1802      *        Must be one of |EapMethod| values.
1803      * @return true if successful, false otherwise
1804      */
setEapMethod(int method)1805     private boolean setEapMethod(int method) {
1806         synchronized (mLock) {
1807             final String methodStr = "setEapMethod";
1808             if (!checkStaNetworkAndLogFailure(methodStr)) {
1809                 return false;
1810             }
1811             try {
1812                 mISupplicantStaNetwork.setEapMethod(method);
1813                 return true;
1814             } catch (RemoteException e) {
1815                 handleRemoteException(e, methodStr);
1816             } catch (ServiceSpecificException e) {
1817                 handleServiceSpecificException(e, methodStr);
1818             }
1819             return false;
1820         }
1821     }
1822 
1823     /**
1824      * Set EAP Phase2 Method for this network.
1825      *
1826      * EAP method needs to be set for this to work.
1827      *
1828      * @param method value to set.
1829      *        Must be one of |EapPhase2Method| values.
1830      * @return true if successful, false otherwise
1831      */
setEapPhase2Method(int method)1832     private boolean setEapPhase2Method(int method) {
1833         synchronized (mLock) {
1834             final String methodStr = "setEapPhase2Method";
1835             if (!checkStaNetworkAndLogFailure(methodStr)) {
1836                 return false;
1837             }
1838             try {
1839                 mISupplicantStaNetwork.setEapPhase2Method(method);
1840                 return true;
1841             } catch (RemoteException e) {
1842                 handleRemoteException(e, methodStr);
1843             } catch (ServiceSpecificException e) {
1844                 handleServiceSpecificException(e, methodStr);
1845             }
1846             return false;
1847         }
1848     }
1849 
1850     /**
1851      * Set EAP Identity for this network.
1852      *
1853      * @param identity value to set.
1854      * @return true if successful, false otherwise
1855      */
setEapIdentity(byte[] identity)1856     private boolean setEapIdentity(byte[] identity) {
1857         synchronized (mLock) {
1858             final String methodStr = "setEapIdentity";
1859             if (!checkStaNetworkAndLogFailure(methodStr)) {
1860                 return false;
1861             }
1862             try {
1863                 mISupplicantStaNetwork.setEapIdentity(identity);
1864                 return true;
1865             } catch (RemoteException e) {
1866                 handleRemoteException(e, methodStr);
1867             } catch (ServiceSpecificException e) {
1868                 handleServiceSpecificException(e, methodStr);
1869             }
1870             return false;
1871         }
1872     }
1873 
1874     /**
1875      * Set EAP Anonymous Identity for this network.
1876      *
1877      * @param identity value to set.
1878      * @return true if successful, false otherwise
1879      */
setEapAnonymousIdentity(byte[] identity)1880     public boolean setEapAnonymousIdentity(byte[] identity) {
1881         synchronized (mLock) {
1882             final String methodStr = "setEapAnonymousIdentity";
1883             if (!checkStaNetworkAndLogFailure(methodStr)) {
1884                 return false;
1885             }
1886             try {
1887                 mISupplicantStaNetwork.setEapAnonymousIdentity(identity);
1888                 return true;
1889             } catch (RemoteException e) {
1890                 handleRemoteException(e, methodStr);
1891             } catch (ServiceSpecificException e) {
1892                 handleServiceSpecificException(e, methodStr);
1893             }
1894             return false;
1895         }
1896     }
1897 
1898     /**
1899      * Set EAP Password for this network.
1900      *
1901      * @param password value to set.
1902      * @return true if successful, false otherwise
1903      */
setEapPassword(byte[] password)1904     private boolean setEapPassword(byte[] password) {
1905         synchronized (mLock) {
1906             final String methodStr = "setEapPassword";
1907             if (!checkStaNetworkAndLogFailure(methodStr)) {
1908                 return false;
1909             }
1910             try {
1911                 mISupplicantStaNetwork.setEapPassword(password);
1912                 return true;
1913             } catch (RemoteException e) {
1914                 handleRemoteException(e, methodStr);
1915             } catch (ServiceSpecificException e) {
1916                 handleServiceSpecificException(e, methodStr);
1917             }
1918             return false;
1919         }
1920     }
1921 
1922     /**
1923      * Set EAP CA certificate file path for this network.
1924      *
1925      * @param path value to set.
1926      * @return true if successful, false otherwise
1927      */
setEapCACert(String path)1928     private boolean setEapCACert(String path) {
1929         synchronized (mLock) {
1930             final String methodStr = "setEapCACert";
1931             if (!checkStaNetworkAndLogFailure(methodStr)) {
1932                 return false;
1933             }
1934             try {
1935                 mISupplicantStaNetwork.setEapCACert(path);
1936                 return true;
1937             } catch (RemoteException e) {
1938                 handleRemoteException(e, methodStr);
1939             } catch (ServiceSpecificException e) {
1940                 handleServiceSpecificException(e, methodStr);
1941             }
1942             return false;
1943         }
1944     }
1945 
1946     /**
1947      * Set EAP CA certificate directory path for this network.
1948      *
1949      * @param path value to set.
1950      * @return true if successful, false otherwise
1951      */
setEapCAPath(String path)1952     private boolean setEapCAPath(String path) {
1953         synchronized (mLock) {
1954             final String methodStr = "setEapCAPath";
1955             if (!checkStaNetworkAndLogFailure(methodStr)) {
1956                 return false;
1957             }
1958             try {
1959                 mISupplicantStaNetwork.setEapCAPath(path);
1960                 return true;
1961             } catch (RemoteException e) {
1962                 handleRemoteException(e, methodStr);
1963             } catch (ServiceSpecificException e) {
1964                 handleServiceSpecificException(e, methodStr);
1965             }
1966             return false;
1967         }
1968     }
1969 
1970     /**
1971      * Set EAP Client certificate file path for this network.
1972      *
1973      * @param path value to set.
1974      * @return true if successful, false otherwise
1975      */
setEapClientCert(String path)1976     private boolean setEapClientCert(String path) {
1977         synchronized (mLock) {
1978             final String methodStr = "setEapClientCert";
1979             if (!checkStaNetworkAndLogFailure(methodStr)) {
1980                 return false;
1981             }
1982             try {
1983                 mISupplicantStaNetwork.setEapClientCert(path);
1984                 return true;
1985             } catch (RemoteException e) {
1986                 handleRemoteException(e, methodStr);
1987             } catch (ServiceSpecificException e) {
1988                 handleServiceSpecificException(e, methodStr);
1989             }
1990             return false;
1991         }
1992     }
1993 
1994     /**
1995      * Set EAP private key Id for this network.
1996      * This is used if private key operations for EAP-TLS are performed
1997      * using a smartcard.
1998      *
1999      * @param id value to set.
2000      * @return true if successful, false otherwise
2001      */
setEapPrivateKeyId(String id)2002     private boolean setEapPrivateKeyId(String id) {
2003         synchronized (mLock) {
2004             final String methodStr = "setEapPrivateKeyId";
2005             if (!checkStaNetworkAndLogFailure(methodStr)) {
2006                 return false;
2007             }
2008             try {
2009                 mISupplicantStaNetwork.setEapPrivateKeyId(id);
2010                 return true;
2011             } catch (RemoteException e) {
2012                 handleRemoteException(e, methodStr);
2013             } catch (ServiceSpecificException e) {
2014                 handleServiceSpecificException(e, methodStr);
2015             }
2016             return false;
2017         }
2018     }
2019 
2020     /**
2021      * Set EAP subject match for this network.
2022      *
2023      * @param match value to set.
2024      * @return true if successful, false otherwise
2025      */
setEapSubjectMatch(String match)2026     private boolean setEapSubjectMatch(String match) {
2027         synchronized (mLock) {
2028             final String methodStr = "setEapSubjectMatch";
2029             if (!checkStaNetworkAndLogFailure(methodStr)) {
2030                 return false;
2031             }
2032             try {
2033                 mISupplicantStaNetwork.setEapSubjectMatch(match);
2034                 return true;
2035             } catch (RemoteException e) {
2036                 handleRemoteException(e, methodStr);
2037             } catch (ServiceSpecificException e) {
2038                 handleServiceSpecificException(e, methodStr);
2039             }
2040             return false;
2041         }
2042     }
2043 
2044     /**
2045      * Set EAP Alt subject match for this network.
2046      *
2047      * @param match value to set.
2048      * @return true if successful, false otherwise
2049      */
setEapAltSubjectMatch(String match)2050     private boolean setEapAltSubjectMatch(String match) {
2051         synchronized (mLock) {
2052             final String methodStr = "setEapAltSubjectMatch";
2053             if (!checkStaNetworkAndLogFailure(methodStr)) {
2054                 return false;
2055             }
2056             try {
2057                 mISupplicantStaNetwork.setEapAltSubjectMatch(match);
2058                 return true;
2059             } catch (RemoteException e) {
2060                 handleRemoteException(e, methodStr);
2061             } catch (ServiceSpecificException e) {
2062                 handleServiceSpecificException(e, methodStr);
2063             }
2064             return false;
2065         }
2066     }
2067 
2068     /**
2069      * Enable EAP Open SSL Engine for this network.
2070      *
2071      * @param enable true to set, false otherwise.
2072      * @return true if successful, false otherwise
2073      */
setEapEngine(boolean enable)2074     private boolean setEapEngine(boolean enable) {
2075         synchronized (mLock) {
2076             final String methodStr = "setEapEngine";
2077             if (!checkStaNetworkAndLogFailure(methodStr)) {
2078                 return false;
2079             }
2080             try {
2081                 mISupplicantStaNetwork.setEapEngine(enable);
2082                 return true;
2083             } catch (RemoteException e) {
2084                 handleRemoteException(e, methodStr);
2085             } catch (ServiceSpecificException e) {
2086                 handleServiceSpecificException(e, methodStr);
2087             }
2088             return false;
2089         }
2090     }
2091 
2092     /**
2093      * Set EAP Open SSL Engine ID for this network.
2094      *
2095      * @param id value to set.
2096      * @return true if successful, false otherwise
2097      */
setEapEngineID(String id)2098     private boolean setEapEngineID(String id) {
2099         synchronized (mLock) {
2100             final String methodStr = "setEapEngineID";
2101             if (!checkStaNetworkAndLogFailure(methodStr)) {
2102                 return false;
2103             }
2104             try {
2105                 mISupplicantStaNetwork.setEapEngineID(id);
2106                 return true;
2107             } catch (RemoteException e) {
2108                 handleRemoteException(e, methodStr);
2109             } catch (ServiceSpecificException e) {
2110                 handleServiceSpecificException(e, methodStr);
2111             }
2112             return false;
2113         }
2114     }
2115 
2116     /**
2117      * Set EAP Domain suffix match for this network.
2118      *
2119      * @param match value to set.
2120      * @return true if successful, false otherwise
2121      */
setEapDomainSuffixMatch(String match)2122     private boolean setEapDomainSuffixMatch(String match) {
2123         synchronized (mLock) {
2124             final String methodStr = "setEapDomainSuffixMatch";
2125             if (!checkStaNetworkAndLogFailure(methodStr)) {
2126                 return false;
2127             }
2128             try {
2129                 mISupplicantStaNetwork.setEapDomainSuffixMatch(match);
2130                 return true;
2131             } catch (RemoteException e) {
2132                 handleRemoteException(e, methodStr);
2133             } catch (ServiceSpecificException e) {
2134                 handleServiceSpecificException(e, methodStr);
2135             }
2136             return false;
2137         }
2138     }
2139 
2140     /**
2141      * This field can be used to enable proactive key caching which is also
2142      * known as opportunistic PMKSA caching for WPA2. This is disabled (0)
2143      * by default unless default value is changed with the global okc=1
2144      * parameter.
2145      *
2146      * Proactive key caching is used to make supplicant assume that the APs
2147      * are using the same PMK and generate PMKSA cache entries without
2148      * doing RSN pre-authentication. This requires support from the AP side
2149      * and is normally used with wireless switches that co-locate the
2150      * authenticator.
2151      *
2152      * @param enable true to set, false otherwise.
2153      * @return true if successful, false otherwise
2154      */
setEapProactiveKeyCaching(boolean enable)2155     private boolean setEapProactiveKeyCaching(boolean enable) {
2156         synchronized (mLock) {
2157             final String methodStr = "setEapProactiveKeyCaching";
2158             if (!checkStaNetworkAndLogFailure(methodStr)) {
2159                 return false;
2160             }
2161             try {
2162                 mISupplicantStaNetwork.setProactiveKeyCaching(enable);
2163                 return true;
2164             } catch (RemoteException e) {
2165                 handleRemoteException(e, methodStr);
2166             } catch (ServiceSpecificException e) {
2167                 handleServiceSpecificException(e, methodStr);
2168             }
2169             return false;
2170         }
2171     }
2172 
2173     /**
2174      * Set ID string for this network.
2175      * Network identifier string for external scripts.
2176      *
2177      * @param idString ID string value to set.
2178      * @return true if successful, false otherwise
2179      */
setIdStr(String idString)2180     private boolean setIdStr(String idString) {
2181         synchronized (mLock) {
2182             final String methodStr = "setIdStr";
2183             if (!checkStaNetworkAndLogFailure(methodStr)) {
2184                 return false;
2185             }
2186             try {
2187                 mISupplicantStaNetwork.setIdStr(idString);
2188                 return true;
2189             } catch (RemoteException e) {
2190                 handleRemoteException(e, methodStr);
2191             } catch (ServiceSpecificException e) {
2192                 handleServiceSpecificException(e, methodStr);
2193             }
2194             return false;
2195         }
2196     }
2197 
2198     /**
2199      * Set SAE password for WPA3-Personal
2200      *
2201      * @param saePassword string with the above option
2202      * @return true if successful, false otherwise
2203      */
setSaePassword(String saePassword)2204     private boolean setSaePassword(String saePassword) {
2205         synchronized (mLock) {
2206             final String methodStr = "setSaePassword";
2207             if (!checkStaNetworkAndLogFailure(methodStr)) {
2208                 return false;
2209             }
2210             try {
2211                 mISupplicantStaNetwork.setSaePassword(saePassword);
2212                 return true;
2213             } catch (RemoteException e) {
2214                 handleRemoteException(e, methodStr);
2215             } catch (ServiceSpecificException e) {
2216                 handleServiceSpecificException(e, methodStr);
2217             }
2218             return false;
2219         }
2220     }
2221 
2222     /**
2223      * Enable Extensible Authentication (EAP) - Re-authentication Protocol (ERP) for this network.
2224      *
2225      * @param enable true to set, false otherwise.
2226      * @return true if successful, false otherwise
2227      */
setEapErp(boolean enable)2228     private boolean setEapErp(boolean enable) {
2229         synchronized (mLock) {
2230             final String methodStr = "setEapErp";
2231             if (!checkStaNetworkAndLogFailure(methodStr)) {
2232                 return false;
2233             }
2234             try {
2235                 mISupplicantStaNetwork.setEapErp(enable);
2236                 return true;
2237             } catch (RemoteException e) {
2238                 handleRemoteException(e, methodStr);
2239             } catch (ServiceSpecificException e) {
2240                 handleServiceSpecificException(e, methodStr);
2241             }
2242             return false;
2243         }
2244     }
2245 
2246     /**
2247      * Get SSID for this network. Result is stored in mSsid.
2248      *
2249      * @return true if successful, false otherwise
2250      */
getSsid()2251     private boolean getSsid() {
2252         synchronized (mLock) {
2253             final String methodStr = "getSsid";
2254             if (!checkStaNetworkAndLogFailure(methodStr)) {
2255                 return false;
2256             }
2257             try {
2258                 mSsid = mISupplicantStaNetwork.getSsid();
2259                 return true;
2260             } catch (RemoteException e) {
2261                 handleRemoteException(e, methodStr);
2262             } catch (ServiceSpecificException e) {
2263                 handleServiceSpecificException(e, methodStr);
2264             }
2265             return false;
2266         }
2267     }
2268 
2269     /**
2270      * Get the BSSID set for this network. Result is stored in mBssid.
2271      *
2272      * @return true if successful, false otherwise
2273      */
getBssid()2274     private boolean getBssid() {
2275         synchronized (mLock) {
2276             final String methodStr = "getBssid";
2277             if (!checkStaNetworkAndLogFailure(methodStr)) {
2278                 return false;
2279             }
2280             try {
2281                 mBssid = mISupplicantStaNetwork.getBssid();
2282                 return true;
2283             } catch (RemoteException e) {
2284                 handleRemoteException(e, methodStr);
2285             } catch (ServiceSpecificException e) {
2286                 handleServiceSpecificException(e, methodStr);
2287             }
2288             return false;
2289         }
2290     }
2291 
2292     /**
2293      * Get whether Probe Requests are being sent for this network (hidden).
2294      * Result is stored in mScanSsid.
2295      *
2296      * @return true if successful, false otherwise
2297      */
getScanSsid()2298     private boolean getScanSsid() {
2299         synchronized (mLock) {
2300             final String methodStr = "getScanSsid";
2301             if (!checkStaNetworkAndLogFailure(methodStr)) {
2302                 return false;
2303             }
2304             try {
2305                 mScanSsid = mISupplicantStaNetwork.getScanSsid();
2306                 return true;
2307             } catch (RemoteException e) {
2308                 handleRemoteException(e, methodStr);
2309             } catch (ServiceSpecificException e) {
2310                 handleServiceSpecificException(e, methodStr);
2311             }
2312             return false;
2313         }
2314     }
2315 
2316     /**
2317      * Get the key mgmt mask set for the network. Result is stored in mKeyMgmtMask.
2318      *
2319      * @return true if successful, false otherwise
2320      */
getKeyMgmt()2321     private boolean getKeyMgmt() {
2322         synchronized (mLock) {
2323             final String methodStr = "getKeyMgmt";
2324             if (!checkStaNetworkAndLogFailure(methodStr)) {
2325                 return false;
2326             }
2327             try {
2328                 mKeyMgmtMask = mISupplicantStaNetwork.getKeyMgmt();
2329                 return true;
2330             } catch (RemoteException e) {
2331                 handleRemoteException(e, methodStr);
2332             } catch (ServiceSpecificException e) {
2333                 handleServiceSpecificException(e, methodStr);
2334             }
2335             return false;
2336         }
2337     }
2338 
2339     /**
2340      * Get the proto mask set for the network. Result is stored in mProtoMask.
2341      *
2342      * @return true if successful, false otherwise
2343      */
getProto()2344     private boolean getProto() {
2345         synchronized (mLock) {
2346             final String methodStr = "getProto";
2347             if (!checkStaNetworkAndLogFailure(methodStr)) {
2348                 return false;
2349             }
2350             try {
2351                 mProtoMask = mISupplicantStaNetwork.getProto();
2352                 return true;
2353             } catch (RemoteException e) {
2354                 handleRemoteException(e, methodStr);
2355             } catch (ServiceSpecificException e) {
2356                 handleServiceSpecificException(e, methodStr);
2357             }
2358             return false;
2359         }
2360     }
2361 
2362     /**
2363      * Get the auth alg mask set for the network. Result is stored in mAuthAlgMask.
2364      *
2365      * @return true if successful, false otherwise
2366      */
getAuthAlg()2367     private boolean getAuthAlg() {
2368         synchronized (mLock) {
2369             final String methodStr = "getAuthAlg";
2370             if (!checkStaNetworkAndLogFailure(methodStr)) {
2371                 return false;
2372             }
2373             try {
2374                 mAuthAlgMask = mISupplicantStaNetwork.getAuthAlg();
2375                 return true;
2376             } catch (RemoteException e) {
2377                 handleRemoteException(e, methodStr);
2378             } catch (ServiceSpecificException e) {
2379                 handleServiceSpecificException(e, methodStr);
2380             }
2381             return false;
2382         }
2383     }
2384 
2385     /**
2386      * Get the group cipher mask set for the network. Result is stored in mGroupCipherMask.
2387      *
2388      * @return true if successful, false otherwise
2389      */
getGroupCipher()2390     private boolean getGroupCipher() {
2391         synchronized (mLock) {
2392             final String methodStr = "getGroupCipher";
2393             if (!checkStaNetworkAndLogFailure(methodStr)) {
2394                 return false;
2395             }
2396             try {
2397                 mGroupCipherMask = mISupplicantStaNetwork.getGroupCipher();
2398                 return true;
2399             } catch (RemoteException e) {
2400                 handleRemoteException(e, methodStr);
2401             } catch (ServiceSpecificException e) {
2402                 handleServiceSpecificException(e, methodStr);
2403             }
2404             return false;
2405         }
2406     }
2407 
2408     /**
2409      * Get the pairwise cipher mask set for the network. Result is stored in mPairwiseCipherMask.
2410      *
2411      * @return true if successful, false otherwise
2412      */
getPairwiseCipher()2413     private boolean getPairwiseCipher() {
2414         synchronized (mLock) {
2415             final String methodStr = "getPairwiseCipher";
2416             if (!checkStaNetworkAndLogFailure(methodStr)) {
2417                 return false;
2418             }
2419             try {
2420                 mPairwiseCipherMask = mISupplicantStaNetwork.getPairwiseCipher();
2421                 return true;
2422             } catch (RemoteException e) {
2423                 handleRemoteException(e, methodStr);
2424             } catch (ServiceSpecificException e) {
2425                 handleServiceSpecificException(e, methodStr);
2426             }
2427             return false;
2428         }
2429 
2430     }
2431 
2432     /**
2433      * Get the group management cipher mask set for the network. Result is stored in
2434      * mGroupMgmtCipherMask.
2435      *
2436      * @return true if successful, false otherwise
2437      */
getGroupMgmtCipher()2438     private boolean getGroupMgmtCipher() {
2439         synchronized (mLock) {
2440             final String methodStr = "getGroupMgmtCipher";
2441             if (!checkStaNetworkAndLogFailure(methodStr)) {
2442                 return false;
2443             }
2444             try {
2445                 mGroupMgmtCipherMask = mISupplicantStaNetwork.getGroupMgmtCipher();
2446                 return true;
2447             } catch (RemoteException e) {
2448                 handleRemoteException(e, methodStr);
2449             } catch (ServiceSpecificException e) {
2450                 handleServiceSpecificException(e, methodStr);
2451             }
2452             return false;
2453         }
2454     }
2455 
2456     /**
2457      * Get passphrase for WPA_PSK network. Result is stored in mPskPassphrase if retrieved.
2458      * Must return a failure if network has no passphrase set (use |getPsk| if
2459      * network was configured with raw psk instead).
2460      *
2461      * @return true if successful, false otherwise
2462      */
getPskPassphrase()2463     private boolean getPskPassphrase() {
2464         synchronized (mLock) {
2465             final String methodStr = "getPskPassphrase";
2466             if (!checkStaNetworkAndLogFailure(methodStr)) {
2467                 return false;
2468             }
2469             try {
2470                 mPskPassphrase = mISupplicantStaNetwork.getPskPassphrase();
2471                 return true;
2472             } catch (RemoteException e) {
2473                 handleRemoteException(e, methodStr);
2474             } catch (ServiceSpecificException e) {
2475                 handleServiceSpecificException(e, methodStr);
2476             }
2477             return false;
2478         }
2479     }
2480 
2481     /**
2482      * Get SAE password for WPA3-Personal. Result is stored in mSaePassword.
2483      *
2484      * @return true if successful, false otherwise
2485      */
getSaePassword()2486     private boolean getSaePassword() {
2487         synchronized (mLock) {
2488             final String methodStr = "getSaePassword";
2489             if (!checkStaNetworkAndLogFailure(methodStr)) {
2490                 return false;
2491             }
2492             try {
2493                 mSaePassword = mISupplicantStaNetwork.getSaePassword();
2494                 return true;
2495             } catch (RemoteException e) {
2496                 handleRemoteException(e, methodStr);
2497             } catch (ServiceSpecificException e) {
2498                 handleServiceSpecificException(e, methodStr);
2499             }
2500             return false;
2501         }
2502     }
2503 
2504     /**
2505      * Get raw psk for WPA_PSK network. Result is stored in mPsk.
2506      *
2507      * @return true if successful, false otherwise
2508      */
getPsk()2509     private boolean getPsk() {
2510         synchronized (mLock) {
2511             final String methodStr = "getPsk";
2512             if (!checkStaNetworkAndLogFailure(methodStr)) {
2513                 return false;
2514             }
2515             try {
2516                 mPsk = mISupplicantStaNetwork.getPsk();
2517                 return true;
2518             } catch (RemoteException e) {
2519                 handleRemoteException(e, methodStr);
2520             } catch (ServiceSpecificException e) {
2521                 handleServiceSpecificException(e, methodStr);
2522             }
2523             return false;
2524         }
2525     }
2526 
2527     /**
2528      * Get WEP key for WEP network. Result is stored in mWepKey.
2529      *
2530      * @param keyIdx Index of wep key to be fetched.
2531      *        Max of |WEP_KEYS_MAX_NUM|.
2532      * @return true if successful, false otherwise
2533      */
getWepKey(int keyIdx)2534     private boolean getWepKey(int keyIdx) {
2535         synchronized (mLock) {
2536             final String methodStr = "keyIdx";
2537             if (!checkStaNetworkAndLogFailure(methodStr)) {
2538                 return false;
2539             }
2540             try {
2541                 mWepKey = mISupplicantStaNetwork.getWepKey(keyIdx);
2542                 return true;
2543             } catch (RemoteException e) {
2544                 handleRemoteException(e, methodStr);
2545             } catch (ServiceSpecificException e) {
2546                 handleServiceSpecificException(e, methodStr);
2547             }
2548             return false;
2549         }
2550     }
2551 
2552     /**
2553      * Get default Tx key index for WEP network. Result is stored in mWepTxKeyIdx.
2554      *
2555      * @return true if successful, false otherwise
2556      */
getWepTxKeyIdx()2557     private boolean getWepTxKeyIdx() {
2558         synchronized (mLock) {
2559             final String methodStr = "getWepTxKeyIdx";
2560             if (!checkStaNetworkAndLogFailure(methodStr)) {
2561                 return false;
2562             }
2563             try {
2564                 mWepTxKeyIdx = mISupplicantStaNetwork.getWepTxKeyIdx();
2565                 return true;
2566             } catch (RemoteException e) {
2567                 handleRemoteException(e, methodStr);
2568             } catch (ServiceSpecificException e) {
2569                 handleServiceSpecificException(e, methodStr);
2570             }
2571             return false;
2572         }
2573     }
2574 
2575     /**
2576      * Get whether RequirePmf is enabled for this network. Result is stored in mWepTxKeyIdx.
2577      *
2578      * @return true if successful, false otherwise
2579      */
getRequirePmf()2580     private boolean getRequirePmf() {
2581         synchronized (mLock) {
2582             final String methodStr = "getRequirePmf";
2583             if (!checkStaNetworkAndLogFailure(methodStr)) {
2584                 return false;
2585             }
2586             try {
2587                 mRequirePmf = mISupplicantStaNetwork.getRequirePmf();
2588                 return true;
2589             } catch (RemoteException e) {
2590                 handleRemoteException(e, methodStr);
2591             } catch (ServiceSpecificException e) {
2592                 handleServiceSpecificException(e, methodStr);
2593             }
2594             return false;
2595         }
2596     }
2597 
2598     /**
2599      * Get WAPI certificate suite name set for this network. Result is stored in mWapiCertSuite.
2600      *
2601      * @return true if successful, false otherwise
2602      */
getWapiCertSuite()2603     private boolean getWapiCertSuite() {
2604         synchronized (mLock) {
2605             final String methodStr = "getWapiCertSuite";
2606             if (!checkStaNetworkAndLogFailure(methodStr)) {
2607                 return false;
2608             }
2609             try {
2610                 mWapiCertSuite = mISupplicantStaNetwork.getWapiCertSuite();
2611                 return true;
2612             } catch (RemoteException e) {
2613                 handleRemoteException(e, methodStr);
2614             } catch (ServiceSpecificException e) {
2615                 handleServiceSpecificException(e, methodStr);
2616             }
2617             return false;
2618         }
2619     }
2620 
2621     /**
2622      * Get EAP Method set for this network. Result is stored in mEapMethod.
2623      *
2624      * @return true if successful, false otherwise
2625      */
getEapMethod()2626     private boolean getEapMethod() {
2627         synchronized (mLock) {
2628             final String methodStr = "getEapMethod";
2629             if (!checkStaNetworkAndLogFailure(methodStr)) {
2630                 return false;
2631             }
2632             try {
2633                 mEapMethod = mISupplicantStaNetwork.getEapMethod();
2634                 return true;
2635             } catch (RemoteException e) {
2636                 handleRemoteException(e, methodStr);
2637             } catch (ServiceSpecificException e) {
2638                 handleServiceSpecificException(e, methodStr);
2639             }
2640             return false;
2641         }
2642     }
2643 
2644     /**
2645      * Get EAP Phase2 Method set for this network. Result is stored in mEapPhase2Method.
2646      *
2647      * @return true if successful, false otherwise
2648      */
getEapPhase2Method()2649     private boolean getEapPhase2Method() {
2650         synchronized (mLock) {
2651             final String methodStr = "getEapPhase2Method";
2652             if (!checkStaNetworkAndLogFailure(methodStr)) {
2653                 return false;
2654             }
2655             try {
2656                 mEapPhase2Method = mISupplicantStaNetwork.getEapPhase2Method();
2657                 return true;
2658             } catch (RemoteException e) {
2659                 handleRemoteException(e, methodStr);
2660             } catch (ServiceSpecificException e) {
2661                 handleServiceSpecificException(e, methodStr);
2662             }
2663             return false;
2664         }
2665     }
2666 
2667     /**
2668      * Get EAP Identity set for this network. Result is stored in mEapIdentity.
2669      *
2670      * @return true if successful, false otherwise
2671      */
getEapIdentity()2672     private boolean getEapIdentity() {
2673         synchronized (mLock) {
2674             final String methodStr = "getEapIdentity";
2675             if (!checkStaNetworkAndLogFailure(methodStr)) {
2676                 return false;
2677             }
2678             try {
2679                 mEapIdentity = mISupplicantStaNetwork.getEapIdentity();
2680                 return true;
2681             } catch (RemoteException e) {
2682                 handleRemoteException(e, methodStr);
2683             } catch (ServiceSpecificException e) {
2684                 handleServiceSpecificException(e, methodStr);
2685             }
2686             return false;
2687         }
2688     }
2689 
2690     /**
2691      * Get EAP Anonymous Identity set for this network. Result is stored in mEapAnonymousIdentity.
2692      *
2693      * @return true if successful, false otherwise
2694      */
getEapAnonymousIdentity()2695     private boolean getEapAnonymousIdentity() {
2696         synchronized (mLock) {
2697             final String methodStr = "getEapAnonymousIdentity";
2698             if (!checkStaNetworkAndLogFailure(methodStr)) {
2699                 return false;
2700             }
2701             try {
2702                 mEapAnonymousIdentity = mISupplicantStaNetwork.getEapAnonymousIdentity();
2703                 return true;
2704             } catch (RemoteException e) {
2705                 handleRemoteException(e, methodStr);
2706             } catch (ServiceSpecificException e) {
2707                 handleServiceSpecificException(e, methodStr);
2708             }
2709             return false;
2710         }
2711     }
2712 
2713     /**
2714      * Wrapper method for getEapAnonymousIdentity(). Gets the anonymous identity
2715      * from supplicant and returns it as a string.
2716      *
2717      * @return anonymous identity string if successful, null otherwise.
2718      */
fetchEapAnonymousIdentity()2719     public String fetchEapAnonymousIdentity() {
2720         synchronized (mLock) {
2721             if (!getEapAnonymousIdentity()) {
2722                 return null;
2723             }
2724             return NativeUtil.stringFromByteArray(mEapAnonymousIdentity);
2725         }
2726     }
2727 
2728     /**
2729      * Get EAP Password set for this network. Result is stored in mEapPassword.
2730      *
2731      * @return true if successful, false otherwise
2732      */
getEapPassword()2733     private boolean getEapPassword() {
2734         synchronized (mLock) {
2735             final String methodStr = "getEapPassword";
2736             if (!checkStaNetworkAndLogFailure(methodStr)) {
2737                 return false;
2738             }
2739             try {
2740                 mEapPassword = mISupplicantStaNetwork.getEapPassword();
2741                 return true;
2742             } catch (RemoteException e) {
2743                 handleRemoteException(e, methodStr);
2744             } catch (ServiceSpecificException e) {
2745                 handleServiceSpecificException(e, methodStr);
2746             }
2747             return false;
2748         }
2749     }
2750 
2751     /**
2752      * Get EAP CA certificate file path set for this network. Result is stored in mEapCACert.
2753      *
2754      * @return true if successful, false otherwise
2755      */
getEapCACert()2756     private boolean getEapCACert() {
2757         synchronized (mLock) {
2758             final String methodStr = "getEapCACert";
2759             if (!checkStaNetworkAndLogFailure(methodStr)) {
2760                 return false;
2761             }
2762             try {
2763                 mEapCACert = mISupplicantStaNetwork.getEapCACert();
2764                 return true;
2765             } catch (RemoteException e) {
2766                 handleRemoteException(e, methodStr);
2767             } catch (ServiceSpecificException e) {
2768                 handleServiceSpecificException(e, methodStr);
2769             }
2770             return false;
2771         }
2772     }
2773 
2774     /**
2775      * Get EAP CA certificate directory path set for this network. Result is stored in mEapCAPath.
2776      *
2777      * @return true if successful, false otherwise
2778      */
getEapCAPath()2779     private boolean getEapCAPath() {
2780         synchronized (mLock) {
2781             final String methodStr = "getEapCAPath";
2782             if (!checkStaNetworkAndLogFailure(methodStr)) {
2783                 return false;
2784             }
2785             try {
2786                 mEapCAPath = mISupplicantStaNetwork.getEapCAPath();
2787                 return true;
2788             } catch (RemoteException e) {
2789                 handleRemoteException(e, methodStr);
2790             } catch (ServiceSpecificException e) {
2791                 handleServiceSpecificException(e, methodStr);
2792             }
2793             return false;
2794         }
2795     }
2796 
2797     /**
2798      * Get EAP Client certificate file path set for this network.
2799      * Result is stored in mEapClientCert.
2800      *
2801      * @return true if successful, false otherwise
2802      */
getEapClientCert()2803     private boolean getEapClientCert() {
2804         synchronized (mLock) {
2805             final String methodStr = "getEapClientCert";
2806             if (!checkStaNetworkAndLogFailure(methodStr)) {
2807                 return false;
2808             }
2809             try {
2810                 mEapClientCert = mISupplicantStaNetwork.getEapClientCert();
2811                 return true;
2812             } catch (RemoteException e) {
2813                 handleRemoteException(e, methodStr);
2814             } catch (ServiceSpecificException e) {
2815                 handleServiceSpecificException(e, methodStr);
2816             }
2817             return false;
2818         }
2819     }
2820 
2821     /**
2822      * Get EAP private key Id set for this network. Result is stored in mEapPrivateKeyId.
2823      *
2824      * @return true if successful, false otherwise
2825      */
getEapPrivateKeyId()2826     private boolean getEapPrivateKeyId() {
2827         synchronized (mLock) {
2828             final String methodStr = "getEapPrivateKeyId";
2829             if (!checkStaNetworkAndLogFailure(methodStr)) {
2830                 return false;
2831             }
2832             try {
2833                 mEapPrivateKeyId = mISupplicantStaNetwork.getEapPrivateKeyId();
2834                 return true;
2835             } catch (RemoteException e) {
2836                 handleRemoteException(e, methodStr);
2837             } catch (ServiceSpecificException e) {
2838                 handleServiceSpecificException(e, methodStr);
2839             }
2840             return false;
2841         }
2842     }
2843 
2844     /**
2845      * Get EAP subject match set for this network. Result is stored in mEapSubjectMatch.
2846      *
2847      * @return true if successful, false otherwise
2848      */
getEapSubjectMatch()2849     private boolean getEapSubjectMatch() {
2850         synchronized (mLock) {
2851             final String methodStr = "getEapSubjectMatch";
2852             if (!checkStaNetworkAndLogFailure(methodStr)) {
2853                 return false;
2854             }
2855             try {
2856                 mEapSubjectMatch = mISupplicantStaNetwork.getEapSubjectMatch();
2857                 return true;
2858             } catch (RemoteException e) {
2859                 handleRemoteException(e, methodStr);
2860             } catch (ServiceSpecificException e) {
2861                 handleServiceSpecificException(e, methodStr);
2862             }
2863             return false;
2864         }
2865     }
2866 
2867     /**
2868      * Get EAP Alt subject match set for this network. Result is stored in mEapAltSubjectMatch.
2869      *
2870      * @return true if successful, false otherwise
2871      */
getEapAltSubjectMatch()2872     private boolean getEapAltSubjectMatch() {
2873         synchronized (mLock) {
2874             final String methodStr = "getEapAltSubjectMatch";
2875             if (!checkStaNetworkAndLogFailure(methodStr)) {
2876                 return false;
2877             }
2878             try {
2879                 mEapAltSubjectMatch = mISupplicantStaNetwork.getEapAltSubjectMatch();
2880                 return true;
2881             } catch (RemoteException e) {
2882                 handleRemoteException(e, methodStr);
2883             } catch (ServiceSpecificException e) {
2884                 handleServiceSpecificException(e, methodStr);
2885             }
2886             return false;
2887         }
2888     }
2889 
2890     /**
2891      * Get whether EAP Open SSL Engine is enabled for this network. Result is stored in mEapEngine.
2892      *
2893      * @return true if successful, false otherwise
2894      */
getEapEngine()2895     private boolean getEapEngine() {
2896         synchronized (mLock) {
2897             final String methodStr = "getEapEngine";
2898             if (!checkStaNetworkAndLogFailure(methodStr)) {
2899                 return false;
2900             }
2901             try {
2902                 mEapEngine = mISupplicantStaNetwork.getEapEngine();
2903                 return true;
2904             } catch (RemoteException e) {
2905                 handleRemoteException(e, methodStr);
2906             } catch (ServiceSpecificException e) {
2907                 handleServiceSpecificException(e, methodStr);
2908             }
2909             return false;
2910         }
2911     }
2912 
2913     /**
2914      * Get EAP Open SSL Engine ID set for this network. Result is stored in mEapEngineID.
2915      *
2916      * @return true if successful, false otherwise
2917      */
getEapEngineId()2918     private boolean getEapEngineId() {
2919         synchronized (mLock) {
2920             final String methodStr = "getEapEngineId";
2921             if (!checkStaNetworkAndLogFailure(methodStr)) {
2922                 return false;
2923             }
2924             try {
2925                 mEapEngineID = mISupplicantStaNetwork.getEapEngineId();
2926                 return true;
2927             } catch (RemoteException e) {
2928                 handleRemoteException(e, methodStr);
2929             } catch (ServiceSpecificException e) {
2930                 handleServiceSpecificException(e, methodStr);
2931             }
2932             return false;
2933         }
2934     }
2935 
2936     /**
2937      * Get EAP Domain suffix match set for this network. Result is stored in mEapDomainSuffixMatch.
2938      *
2939      * @return true if successful, false otherwise
2940      */
getEapDomainSuffixMatch()2941     private boolean getEapDomainSuffixMatch() {
2942         synchronized (mLock) {
2943             final String methodStr = "getEapDomainSuffixMatch";
2944             if (!checkStaNetworkAndLogFailure(methodStr)) {
2945                 return false;
2946             }
2947             try {
2948                 mEapDomainSuffixMatch = mISupplicantStaNetwork.getEapDomainSuffixMatch();
2949                 return true;
2950             } catch (RemoteException e) {
2951                 handleRemoteException(e, methodStr);
2952             } catch (ServiceSpecificException e) {
2953                 handleServiceSpecificException(e, methodStr);
2954             }
2955             return false;
2956         }
2957     }
2958 
2959     /**
2960      * Get ID string set for this network. Network identifier string for external scripts.
2961      * Result is stored in mIdStr.
2962      *
2963      * @return true if successful, false otherwise
2964      */
getIdStr()2965     private boolean getIdStr() {
2966         synchronized (mLock) {
2967             final String methodStr = "getIdStr";
2968             if (!checkStaNetworkAndLogFailure(methodStr)) {
2969                 return false;
2970             }
2971             try {
2972                 mIdStr = mISupplicantStaNetwork.getIdStr();
2973                 return true;
2974             } catch (RemoteException e) {
2975                 handleRemoteException(e, methodStr);
2976             } catch (ServiceSpecificException e) {
2977                 handleServiceSpecificException(e, methodStr);
2978             }
2979             return false;
2980         }
2981     }
2982 
2983     /**
2984      * Enable the network for connection purposes.
2985      *
2986      * This must trigger a connection to the network if:
2987      * a) |noConnect| is false, and
2988      * b) This is the only network configured, and
2989      * c) Is visible in the current scan results.
2990      *
2991      * @param noConnect Only enable the network, don't trigger a connect.
2992      * @return true if successful, false otherwise
2993      */
enable(boolean noConnect)2994     public boolean enable(boolean noConnect) {
2995         synchronized (mLock) {
2996             final String methodStr = "enable";
2997             if (!checkStaNetworkAndLogFailure(methodStr)) {
2998                 return false;
2999             }
3000             try {
3001                 mISupplicantStaNetwork.enable(noConnect);
3002                 return true;
3003             } catch (RemoteException e) {
3004                 handleRemoteException(e, methodStr);
3005             } catch (ServiceSpecificException e) {
3006                 handleServiceSpecificException(e, methodStr);
3007             }
3008             return false;
3009         }
3010     }
3011 
3012     /**
3013      * Disable the network for connection purposes.
3014      * This must trigger a disconnection from the network, if currently
3015      * connected to this one.
3016      *
3017      * @return true if successful, false otherwise
3018      */
disable()3019     public boolean disable() {
3020         synchronized (mLock) {
3021             final String methodStr = "disable";
3022             if (!checkStaNetworkAndLogFailure(methodStr)) {
3023                 return false;
3024             }
3025             try {
3026                 mISupplicantStaNetwork.disable();
3027                 return true;
3028             } catch (RemoteException e) {
3029                 handleRemoteException(e, methodStr);
3030             } catch (ServiceSpecificException e) {
3031                 handleServiceSpecificException(e, methodStr);
3032             }
3033             return false;
3034         }
3035     }
3036 
3037     /**
3038      * Trigger a connection to this network.
3039      *
3040      * @return true if it succeeds, false otherwise.
3041      */
select()3042     public boolean select() {
3043         synchronized (mLock) {
3044             final String methodStr = "select";
3045             if (!checkStaNetworkAndLogFailure(methodStr)) {
3046                 return false;
3047             }
3048             try {
3049                 mISupplicantStaNetwork.select();
3050                 return true;
3051             } catch (RemoteException e) {
3052                 handleRemoteException(e, methodStr);
3053             } catch (ServiceSpecificException e) {
3054                 handleServiceSpecificException(e, methodStr);
3055             }
3056             return false;
3057         }
3058     }
3059 
3060     /**
3061      * Send GSM auth response.
3062      *
3063      * @param paramsStr Response params as a string.
3064      * @return true if succeeds, false otherwise.
3065      */
sendNetworkEapSimGsmAuthResponse(String paramsStr)3066     public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) {
3067         synchronized (mLock) {
3068             try {
3069                 Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
3070                 ArrayList<NetworkResponseEapSimGsmAuthParams> params = new ArrayList<>();
3071                 while (match.find()) {
3072                     if (match.groupCount() != 2) {
3073                         Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
3074                         return false;
3075                     }
3076                     NetworkResponseEapSimGsmAuthParams param =
3077                             new NetworkResponseEapSimGsmAuthParams();
3078                     param.kc = new byte[8];
3079                     param.sres = new byte[4];
3080                     byte[] kc = NativeUtil.hexStringToByteArray(match.group(1));
3081                     if (kc == null || kc.length != param.kc.length) {
3082                         Log.e(TAG, "Invalid kc value: " + match.group(1));
3083                         return false;
3084                     }
3085                     byte[] sres = NativeUtil.hexStringToByteArray(match.group(2));
3086                     if (sres == null || sres.length != param.sres.length) {
3087                         Log.e(TAG, "Invalid sres value: " + match.group(2));
3088                         return false;
3089                     }
3090                     System.arraycopy(kc, 0, param.kc, 0, param.kc.length);
3091                     System.arraycopy(sres, 0, param.sres, 0, param.sres.length);
3092                     params.add(param);
3093                 }
3094                 // The number of kc/sres pairs can either be 2 or 3 depending on the request.
3095                 if (params.size() > 3 || params.size() < 2) {
3096                     Log.e(TAG, "Malformed gsm auth response params: " + paramsStr);
3097                     return false;
3098                 }
3099                 NetworkResponseEapSimGsmAuthParams[] paramsArr =
3100                         new NetworkResponseEapSimGsmAuthParams[params.size()];
3101                 for (int i = 0; i < params.size(); i++) {
3102                     paramsArr[i] = params.get(i);
3103                 }
3104                 return sendNetworkEapSimGsmAuthResponse(paramsArr);
3105             } catch (IllegalArgumentException e) {
3106                 Log.e(TAG, "Illegal argument " + paramsStr, e);
3107                 return false;
3108             }
3109         }
3110     }
3111 
sendNetworkEapSimGsmAuthResponse( NetworkResponseEapSimGsmAuthParams[] params)3112     private boolean sendNetworkEapSimGsmAuthResponse(
3113             NetworkResponseEapSimGsmAuthParams[] params) {
3114         synchronized (mLock) {
3115             final String methodStr = "sendNetworkEapSimGsmAuthResponse";
3116             if (!checkStaNetworkAndLogFailure(methodStr)) {
3117                 return false;
3118             }
3119             try {
3120                 mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params);
3121                 return true;
3122             } catch (RemoteException e) {
3123                 handleRemoteException(e, methodStr);
3124             } catch (ServiceSpecificException e) {
3125                 handleServiceSpecificException(e, methodStr);
3126             }
3127             return false;
3128         }
3129     }
3130 
3131     /**
3132      * Send GSM auth failure.
3133      *
3134      * @return true if successful, false otherwise
3135      */
sendNetworkEapSimGsmAuthFailure()3136     public boolean sendNetworkEapSimGsmAuthFailure() {
3137         synchronized (mLock) {
3138             final String methodStr = "sendNetworkEapSimGsmAuthFailure";
3139             if (!checkStaNetworkAndLogFailure(methodStr)) {
3140                 return false;
3141             }
3142             try {
3143                 mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure();
3144                 return true;
3145             } catch (RemoteException e) {
3146                 handleRemoteException(e, methodStr);
3147             } catch (ServiceSpecificException e) {
3148                 handleServiceSpecificException(e, methodStr);
3149             }
3150             return false;
3151         }
3152     }
3153 
3154     /**
3155      * Send UMTS auth response.
3156      *
3157      * @param paramsStr Response params as a string.
3158      * @return true if succeeds, false otherwise.
3159      */
sendNetworkEapSimUmtsAuthResponse(String paramsStr)3160     public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) {
3161         synchronized (mLock) {
3162             try {
3163                 Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
3164                 if (!match.find() || match.groupCount() != 3) {
3165                     Log.e(TAG, "Malformed umts auth response params: " + paramsStr);
3166                     return false;
3167                 }
3168                 NetworkResponseEapSimUmtsAuthParams params =
3169                         new NetworkResponseEapSimUmtsAuthParams();
3170                 params.ik = new byte[16];
3171                 params.ck = new byte[16];
3172                 byte[] ik = NativeUtil.hexStringToByteArray(match.group(1));
3173                 if (ik == null || ik.length != params.ik.length) {
3174                     Log.e(TAG, "Invalid ik value: " + match.group(1));
3175                     return false;
3176                 }
3177                 byte[] ck = NativeUtil.hexStringToByteArray(match.group(2));
3178                 if (ck == null || ck.length != params.ck.length) {
3179                     Log.e(TAG, "Invalid ck value: " + match.group(2));
3180                     return false;
3181                 }
3182                 byte[] res = NativeUtil.hexStringToByteArray(match.group(3));
3183                 if (res == null || res.length == 0) {
3184                     Log.e(TAG, "Invalid res value: " + match.group(3));
3185                     return false;
3186                 }
3187                 params.res = new byte[res.length];
3188                 System.arraycopy(ik, 0, params.ik, 0, params.ik.length);
3189                 System.arraycopy(ck, 0, params.ck, 0, params.ck.length);
3190                 System.arraycopy(res, 0, params.res, 0, params.res.length);
3191                 return sendNetworkEapSimUmtsAuthResponse(params);
3192             } catch (IllegalArgumentException e) {
3193                 Log.e(TAG, "Illegal argument " + paramsStr, e);
3194                 return false;
3195             }
3196         }
3197     }
3198 
sendNetworkEapSimUmtsAuthResponse( NetworkResponseEapSimUmtsAuthParams params)3199     private boolean sendNetworkEapSimUmtsAuthResponse(
3200             NetworkResponseEapSimUmtsAuthParams params) {
3201         synchronized (mLock) {
3202             final String methodStr = "sendNetworkEapSimUmtsAuthResponse";
3203             if (!checkStaNetworkAndLogFailure(methodStr)) {
3204                 return false;
3205             }
3206             try {
3207                 mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params);
3208                 return true;
3209             } catch (RemoteException e) {
3210                 handleRemoteException(e, methodStr);
3211             } catch (ServiceSpecificException e) {
3212                 handleServiceSpecificException(e, methodStr);
3213             }
3214             return false;
3215         }
3216     }
3217 
3218     /**
3219      * Send UMTS auts response.
3220      *
3221      * @param paramsStr Response params as a string.
3222      * @return true if succeeds, false otherwise.
3223      */
sendNetworkEapSimUmtsAutsResponse(String paramsStr)3224     public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) {
3225         synchronized (mLock) {
3226             try {
3227                 Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr);
3228                 if (!match.find() || match.groupCount() != 1) {
3229                     Log.e(TAG, "Malformed umts auts response params: " + paramsStr);
3230                     return false;
3231                 }
3232                 byte[] auts = NativeUtil.hexStringToByteArray(match.group(1));
3233                 if (auts == null || auts.length != 14) {
3234                     Log.e(TAG, "Invalid auts value: " + match.group(1));
3235                     return false;
3236                 }
3237                 return sendNetworkEapSimUmtsAutsResponse(auts);
3238             } catch (IllegalArgumentException e) {
3239                 Log.e(TAG, "Illegal argument " + paramsStr, e);
3240                 return false;
3241             }
3242         }
3243     }
3244 
sendNetworkEapSimUmtsAutsResponse(byte[ ] auts)3245     private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) {
3246         synchronized (mLock) {
3247             final String methodStr = "sendNetworkEapSimUmtsAutsResponse";
3248             if (!checkStaNetworkAndLogFailure(methodStr)) {
3249                 return false;
3250             }
3251             try {
3252                 mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts);
3253                 return true;
3254             } catch (RemoteException e) {
3255                 handleRemoteException(e, methodStr);
3256             } catch (ServiceSpecificException e) {
3257                 handleServiceSpecificException(e, methodStr);
3258             }
3259             return false;
3260         }
3261     }
3262 
3263     /**
3264      * Send UMTS auth failure.
3265      *
3266      * @return true if successful, false otherwise
3267      */
sendNetworkEapSimUmtsAuthFailure()3268     public boolean sendNetworkEapSimUmtsAuthFailure() {
3269         synchronized (mLock) {
3270             final String methodStr = "sendNetworkEapSimUmtsAuthFailure";
3271             if (!checkStaNetworkAndLogFailure(methodStr)) {
3272                 return false;
3273             }
3274             try {
3275                 mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure();
3276                 return true;
3277             } catch (RemoteException e) {
3278                 handleRemoteException(e, methodStr);
3279             } catch (ServiceSpecificException e) {
3280                 handleServiceSpecificException(e, methodStr);
3281             }
3282             return false;
3283         }
3284     }
3285 
3286     /**
3287      * Send eap identity response.
3288      *
3289      * @param identityStr identity used for EAP-Identity
3290      * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM
3291      * @return true if succeeds, false otherwise.
3292      */
sendNetworkEapIdentityResponse(String identityStr, String encryptedIdentityStr)3293     public boolean sendNetworkEapIdentityResponse(String identityStr,
3294             String encryptedIdentityStr) {
3295         synchronized (mLock) {
3296             try {
3297                 byte[] unencryptedIdentity = NativeUtil.stringToByteArray(identityStr);
3298                 byte[] encryptedIdentity = new byte[0];
3299                 if (!TextUtils.isEmpty(encryptedIdentityStr)) {
3300                     encryptedIdentity = NativeUtil.stringToByteArray(encryptedIdentityStr);
3301                 }
3302                 return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity);
3303             } catch (IllegalArgumentException e) {
3304                 Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e);
3305                 return false;
3306             }
3307         }
3308     }
3309 
sendNetworkEapIdentityResponse(byte[] unencryptedIdentity, byte[] encryptedIdentity)3310     private boolean sendNetworkEapIdentityResponse(byte[] unencryptedIdentity,
3311             byte[] encryptedIdentity) {
3312         synchronized (mLock) {
3313             final String methodStr = "sendNetworkEapIdentityResponse";
3314             if (!checkStaNetworkAndLogFailure(methodStr)) {
3315                 return false;
3316             }
3317             try {
3318                 mISupplicantStaNetwork.sendNetworkEapIdentityResponse(
3319                         unencryptedIdentity, encryptedIdentity);
3320                 return true;
3321             } catch (RemoteException e) {
3322                 handleRemoteException(e, methodStr);
3323             } catch (ServiceSpecificException e) {
3324                 handleServiceSpecificException(e, methodStr);
3325             }
3326             return false;
3327         }
3328     }
3329 
3330     /**
3331      * Set OCSP (Online Certificate Status Protocol) type for this network.
3332      *
3333      * @param ocsp value to set.
3334      * @return true if successful, false otherwise
3335      */
setOcsp(@ifiEnterpriseConfig.Ocsp int ocsp)3336     private boolean setOcsp(@WifiEnterpriseConfig.Ocsp int ocsp) {
3337         synchronized (mLock) {
3338             final String methodStr = "setOcsp";
3339             if (!checkStaNetworkAndLogFailure(methodStr)) {
3340                 return false;
3341             }
3342 
3343             int halOcspValue = OcspType.NONE;
3344             switch (ocsp) {
3345                 case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS:
3346                     halOcspValue = OcspType.REQUEST_CERT_STATUS;
3347                     break;
3348                 case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS:
3349                     halOcspValue = OcspType.REQUIRE_CERT_STATUS;
3350                     break;
3351                 case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS:
3352                     halOcspValue = OcspType.REQUIRE_ALL_CERTS_STATUS;
3353                     break;
3354             }
3355 
3356             try {
3357                 mISupplicantStaNetwork.setOcsp(halOcspValue);
3358                 return true;
3359             } catch (RemoteException e) {
3360                 handleRemoteException(e, methodStr);
3361             } catch (ServiceSpecificException e) {
3362                 handleServiceSpecificException(e, methodStr);
3363             }
3364             return false;
3365         }
3366     }
3367 
3368     /**
3369      * Get OCSP (Online Certificate Status Protocol) type for this network. Value stored in mOcsp.
3370      *
3371      * @return true if successful, false otherwise
3372      */
getOcsp()3373     private boolean getOcsp() {
3374         synchronized (mLock) {
3375             final String methodStr = "getOcsp";
3376             if (!checkStaNetworkAndLogFailure(methodStr)) {
3377                 return false;
3378             }
3379 
3380             try {
3381                 int halOcspValue = mISupplicantStaNetwork.getOcsp();
3382                 mOcsp = WifiEnterpriseConfig.OCSP_NONE;
3383                 switch (halOcspValue) {
3384                     case OcspType.REQUEST_CERT_STATUS:
3385                         mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS;
3386                         break;
3387                     case OcspType.REQUIRE_CERT_STATUS:
3388                         mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS;
3389                         break;
3390                     case OcspType.REQUIRE_ALL_CERTS_STATUS:
3391                         mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS;
3392                         break;
3393                     default:
3394                         Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue);
3395                         break;
3396                 }
3397                 return true;
3398             } catch (RemoteException e) {
3399                 handleRemoteException(e, methodStr);
3400             } catch (ServiceSpecificException e) {
3401                 handleServiceSpecificException(e, methodStr);
3402             }
3403             return false;
3404         }
3405     }
3406 
3407     /**
3408      * Add a pairwise master key (PMK) into supplicant PMK cache.
3409      *
3410      * @param serializedEntry is serialized PMK cache entry, the content is
3411      *              opaque for the framework and depends on the native implementation.
3412      * @return true if successful, false otherwise
3413      */
setPmkCache(byte[] serializedEntry)3414     public boolean setPmkCache(byte[] serializedEntry) {
3415         synchronized (mLock) {
3416             final String methodStr = "setPmkCache";
3417             if (!checkStaNetworkAndLogFailure(methodStr)) {
3418                 return false;
3419             }
3420             try {
3421                 mISupplicantStaNetwork.setPmkCache(serializedEntry);
3422                 return true;
3423             } catch (RemoteException e) {
3424                 handleRemoteException(e, methodStr);
3425             } catch (ServiceSpecificException e) {
3426                 handleServiceSpecificException(e, methodStr);
3427             }
3428             return false;
3429         }
3430     }
3431 
3432     /**
3433      * Set SAE H2E (Hash-to-Element) mode.
3434      *
3435      * @param mode SAE H2E supporting mode.
3436      * @return true if successful, false otherwise
3437      */
setSaeH2eMode(byte mode)3438     private boolean setSaeH2eMode(byte mode) {
3439         synchronized (mLock) {
3440             final String methodStr = "setSaeH2eMode";
3441             if (!checkStaNetworkAndLogFailure(methodStr)) {
3442                 return false;
3443             }
3444             try {
3445                 mISupplicantStaNetwork.setSaeH2eMode(mode);
3446                 return true;
3447             } catch (RemoteException e) {
3448                 handleRemoteException(e, methodStr);
3449             } catch (ServiceSpecificException e) {
3450                 handleServiceSpecificException(e, methodStr);
3451             }
3452             return false;
3453         }
3454     }
3455 
3456     /**
3457      * Retrieve the NFC token for this network.
3458      *
3459      * @return Hex string corresponding to the NFC token or null for failure.
3460      */
getWpsNfcConfigurationToken()3461     public String getWpsNfcConfigurationToken() {
3462         synchronized (mLock) {
3463             byte[] token = getWpsNfcConfigurationTokenInternal();
3464             if (token == null) {
3465                 return null;
3466             }
3467             return NativeUtil.hexStringFromByteArray(token);
3468         }
3469     }
3470 
getWpsNfcConfigurationTokenInternal()3471     private byte[] getWpsNfcConfigurationTokenInternal() {
3472         synchronized (mLock) {
3473             final String methodStr = "getWpsNfcConfigurationToken";
3474             if (!checkStaNetworkAndLogFailure(methodStr)) {
3475                 return null;
3476             }
3477             try {
3478                 return mISupplicantStaNetwork.getWpsNfcConfigurationToken();
3479             } catch (RemoteException e) {
3480                 handleRemoteException(e, methodStr);
3481             } catch (ServiceSpecificException e) {
3482                 handleServiceSpecificException(e, methodStr);
3483             }
3484             return null;
3485         }
3486     }
3487 
getTag()3488     private String getTag() {
3489         synchronized (mLock) {
3490             return TAG + "[" + mIfaceName + "]";
3491         }
3492     }
3493 
3494     /**
3495      * Helper function to log callbacks.
3496      */
logCallback(final String methodStr)3497     protected void logCallback(final String methodStr) {
3498         synchronized (mLock) {
3499             if (mVerboseLoggingEnabled) {
3500                 Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received");
3501             }
3502         }
3503     }
3504 
3505     /**
3506      * Returns false if mISupplicantStaNetwork is null, and logs failure containing methodStr
3507      */
checkStaNetworkAndLogFailure(final String methodStr)3508     private boolean checkStaNetworkAndLogFailure(final String methodStr) {
3509         synchronized (mLock) {
3510             if (mISupplicantStaNetwork == null) {
3511                 Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null");
3512                 return false;
3513             }
3514             return true;
3515         }
3516     }
3517 
handleRemoteException(RemoteException e, String methodStr)3518     private void handleRemoteException(RemoteException e, String methodStr) {
3519         synchronized (mLock) {
3520             mISupplicantStaNetwork = null;
3521             Log.e(TAG,
3522                     "ISupplicantStaNetwork." + methodStr + " failed with remote exception: ", e);
3523         }
3524     }
3525 
handleServiceSpecificException(ServiceSpecificException e, String methodStr)3526     private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) {
3527         synchronized (mLock) {
3528             Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with "
3529                     + "service specific exception: ", e);
3530         }
3531     }
3532 
3533     /**
3534      * Adds FT flags for networks if the device supports it.
3535      */
addFastTransitionFlags(BitSet keyManagementFlags)3536     private BitSet addFastTransitionFlags(BitSet keyManagementFlags) {
3537         synchronized (mLock) {
3538             if (!mContext.getResources().getBoolean(
3539                     R.bool.config_wifi_fast_bss_transition_enabled)) {
3540                 return keyManagementFlags;
3541             }
3542             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3543             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
3544                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK);
3545             }
3546             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
3547                 modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP);
3548             }
3549             return modifiedFlags;
3550         }
3551     }
3552 
3553     /**
3554      * Removes FT flags for networks if the device supports it.
3555      */
removeFastTransitionFlags(BitSet keyManagementFlags)3556     private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) {
3557         synchronized (mLock) {
3558             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3559             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK);
3560             modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP);
3561             return modifiedFlags;
3562         }
3563     }
3564 
3565     /**
3566      * Adds SHA256 key management flags for networks.
3567      */
addSha256KeyMgmtFlags(BitSet keyManagementFlags)3568     private BitSet addSha256KeyMgmtFlags(BitSet keyManagementFlags) {
3569         synchronized (mLock) {
3570             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3571             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) {
3572                 modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
3573             }
3574             if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) {
3575                 modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
3576             }
3577             return modifiedFlags;
3578         }
3579     }
3580 
3581     /**
3582      * Removes SHA256 key management flags for networks.
3583      */
removeSha256KeyMgmtFlags(BitSet keyManagementFlags)3584     private BitSet removeSha256KeyMgmtFlags(BitSet keyManagementFlags) {
3585         synchronized (mLock) {
3586             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3587             modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256);
3588             modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256);
3589             return modifiedFlags;
3590         }
3591     }
3592 
3593     /**
3594      * Adds both PSK and SAE AKM if auto-upgrade offload is supported.
3595      */
addPskSaeUpgradableTypeFlagsIfSupported( WifiConfiguration config, BitSet keyManagementFlags)3596     private BitSet addPskSaeUpgradableTypeFlagsIfSupported(
3597             WifiConfiguration config, BitSet keyManagementFlags) {
3598         synchronized (mLock) {
3599             if (!config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK)
3600                     || !config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled()
3601                     || !mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) {
3602                 return keyManagementFlags;
3603             }
3604 
3605             BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3606             modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK);
3607             modifiedFlags.set(WifiConfiguration.KeyMgmt.SAE);
3608             return modifiedFlags;
3609         }
3610     }
3611 
3612     /**
3613      * Removes SAE AKM when PSK and SAE AKM are both set, it only happens when
3614      * auto-upgrade offload is supported.
3615      */
removePskSaeUpgradableTypeFlags(BitSet keyManagementFlags)3616     private BitSet removePskSaeUpgradableTypeFlags(BitSet keyManagementFlags) {
3617         if (!keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)
3618                 || !keyManagementFlags.get(WifiConfiguration.KeyMgmt.SAE)) {
3619             return keyManagementFlags;
3620         }
3621         BitSet modifiedFlags = (BitSet) keyManagementFlags.clone();
3622         modifiedFlags.clear(WifiConfiguration.KeyMgmt.SAE);
3623         return modifiedFlags;
3624     }
3625 
3626     /**
3627      * Creates the JSON encoded network extra using the map of string key, value pairs.
3628      */
createNetworkExtra(Map<String, String> values)3629     public static String createNetworkExtra(Map<String, String> values) {
3630         final String encoded;
3631         try {
3632             encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8");
3633         } catch (NullPointerException e) {
3634             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
3635             return null;
3636         } catch (UnsupportedEncodingException e) {
3637             Log.e(TAG, "Unable to serialize networkExtra: " + e.toString());
3638             return null;
3639         }
3640         return encoded;
3641     }
3642 
3643     /**
3644      * Parse the network extra JSON encoded string to a map of string key, value pairs.
3645      */
parseNetworkExtra(String encoded)3646     public static Map<String, String> parseNetworkExtra(String encoded) {
3647         if (TextUtils.isEmpty(encoded)) {
3648             return null;
3649         }
3650         try {
3651             // This method reads a JSON dictionary that was written by setNetworkExtra(). However,
3652             // on devices that upgraded from Marshmallow, it may encounter a legacy value instead -
3653             // an FQDN stored as a plain string. If such a value is encountered, the JSONObject
3654             // constructor will thrown a JSONException and the method will return null.
3655             final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8"));
3656             final Map<String, String> values = new HashMap<>();
3657             final Iterator<?> it = json.keys();
3658             while (it.hasNext()) {
3659                 final String key = (String) it.next();
3660                 final Object value = json.get(key);
3661                 if (value instanceof String) {
3662                     values.put(key, (String) value);
3663                 }
3664             }
3665             return values;
3666         } catch (UnsupportedEncodingException e) {
3667             Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString());
3668             return null;
3669         } catch (JSONException e) {
3670             // This is not necessarily an error. This exception will also occur if we encounter a
3671             // legacy FQDN stored as a plain string. We want to return null in this case as no JSON
3672             // dictionary of extras was found.
3673             return null;
3674         }
3675     }
3676 
3677     /**
3678      * Returns a big-endian representation of {@code rcoi} in an 3 or 5-element byte array.
3679      */
rcoiToByteArray(long rcoi)3680     private static byte[] rcoiToByteArray(long rcoi) {
3681         // An RCOI is either 3- or 5-octet array, IEEE Std 802.11, section 9.4.1.31: Organization
3682         // Identifier field
3683         int arraySize = 3;
3684         rcoi &= 0xffffffffffL;
3685         if ((rcoi & 0xffff000000L) != 0) {
3686             // This is a 5-octet RCOI
3687             arraySize = 5;
3688         }
3689 
3690         byte[] result = new byte[arraySize];
3691         for (int i = arraySize - 1; i >= 0; i--) {
3692             result[i] = (byte) (rcoi & 0xffL);
3693             rcoi >>= 8;
3694         }
3695         return result;
3696     }
3697 
3698     /**
3699      * Set the selected RCOI for this Passpoint network.
3700      *
3701      * @param selectedRcoi value to set.
3702      * @return true if successful, false otherwise
3703      */
setSelectedRcoi(long selectedRcoi)3704     private boolean setSelectedRcoi(long selectedRcoi) {
3705         if (selectedRcoi == 0) {
3706             // Nothing to set
3707             return true;
3708         }
3709         synchronized (mLock) {
3710             final String methodStr = "setSelectedRcoi";
3711             if (!checkStaNetworkAndLogFailure(methodStr)) {
3712                 return false;
3713             }
3714 
3715             try {
3716                 mISupplicantStaNetwork
3717                         .setRoamingConsortiumSelection(rcoiToByteArray(selectedRcoi));
3718                 return true;
3719             } catch (RemoteException e) {
3720                 handleRemoteException(e, methodStr);
3721             } catch (ServiceSpecificException e) {
3722                 handleServiceSpecificException(e, methodStr);
3723             }
3724             return false;
3725         }
3726     }
3727 
frameworkToAidlTlsVersion(@ifiEnterpriseConfig.TlsVersion int tlsVersion)3728     private int frameworkToAidlTlsVersion(@WifiEnterpriseConfig.TlsVersion int tlsVersion) {
3729         switch (tlsVersion) {
3730             case WifiEnterpriseConfig.TLS_V1_3:
3731                 return TlsVersion.TLS_V1_3;
3732             case WifiEnterpriseConfig.TLS_V1_2:
3733                 return TlsVersion.TLS_V1_2;
3734             case WifiEnterpriseConfig.TLS_V1_1:
3735                 return TlsVersion.TLS_V1_1;
3736             case WifiEnterpriseConfig.TLS_V1_0:
3737                 return TlsVersion.TLS_V1_0;
3738             default:
3739                 Log.e(TAG, "Invalid TLS version: " + tlsVersion);
3740                 return -1;
3741         }
3742     }
3743 
3744     /**
3745      * Enable TLS V1.3 in EAP Phase1
3746      *
3747      * @param tlsVersion the TLS version
3748      * @return true if successful, false otherwise
3749      */
setMinimumTlsVersionEapPhase1Param( @ifiEnterpriseConfig.TlsVersion int tlsVersion)3750     private boolean setMinimumTlsVersionEapPhase1Param(
3751             @WifiEnterpriseConfig.TlsVersion int tlsVersion) {
3752         synchronized (mLock) {
3753             final String methodStr = "setMinimumTlsVersionEapPhase1Param";
3754             if (!checkStaNetworkAndLogFailure(methodStr)) {
3755                 return false;
3756             }
3757             int aidlTlsVersion = frameworkToAidlTlsVersion(tlsVersion);
3758             if (aidlTlsVersion < 0) {
3759                 return false;
3760             }
3761             try {
3762                 mISupplicantStaNetwork.setMinimumTlsVersionEapPhase1Param(aidlTlsVersion);
3763                 return true;
3764             } catch (RemoteException e) {
3765                 handleRemoteException(e, methodStr);
3766             } catch (ServiceSpecificException e) {
3767                 handleServiceSpecificException(e, methodStr);
3768             }
3769             return false;
3770         }
3771     }
3772 
enableStrictConservativePeerMode()3773     private boolean enableStrictConservativePeerMode() {
3774         synchronized (mLock) {
3775             final String methodStr = "setStrictConservativePeerMode";
3776             if (!checkStaNetworkAndLogFailure(methodStr)) {
3777                 return false;
3778             }
3779             // check AIDL version
3780             try {
3781                 if (mISupplicantStaNetwork.getInterfaceVersion() < 2) {
3782                     return false;
3783                 }
3784                 mISupplicantStaNetwork.setStrictConservativePeerMode(true);
3785                 return true;
3786             } catch (RemoteException e) {
3787                 handleRemoteException(e, methodStr);
3788             } catch (ServiceSpecificException e) {
3789                 handleServiceSpecificException(e, methodStr);
3790             }
3791             return false;
3792         }
3793     }
3794 
setVendorData(@onNull List<OuiKeyedData> vendorData)3795     private boolean setVendorData(@NonNull List<OuiKeyedData> vendorData) {
3796         synchronized (mLock) {
3797             final String methodStr = "setVendorData";
3798             if (!checkStaNetworkAndLogFailure(methodStr)) {
3799                 return false;
3800             }
3801             try {
3802                 if (!isServiceVersionIsAtLeast(3)) {
3803                     return false;
3804                 }
3805                 if (vendorData == null || vendorData.isEmpty()) {
3806                     return false;
3807                 }
3808                 mISupplicantStaNetwork.setVendorData(
3809                         HalAidlUtil.frameworkToHalOuiKeyedDataList(vendorData));
3810                 return true;
3811             } catch (RemoteException e) {
3812                 handleRemoteException(e, methodStr);
3813             } catch (ServiceSpecificException e) {
3814                 handleServiceSpecificException(e, methodStr);
3815             }
3816             return false;
3817         }
3818     }
3819 }
3820