| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.server.wifi; |
| |
| import android.content.Context; |
| import android.hardware.wifi.supplicant.AuthAlgMask; |
| import android.hardware.wifi.supplicant.DppConnectionKeys; |
| import android.hardware.wifi.supplicant.EapMethod; |
| import android.hardware.wifi.supplicant.EapPhase2Method; |
| import android.hardware.wifi.supplicant.GroupCipherMask; |
| import android.hardware.wifi.supplicant.GroupMgmtCipherMask; |
| import android.hardware.wifi.supplicant.ISupplicantStaNetwork; |
| import android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback; |
| import android.hardware.wifi.supplicant.KeyMgmtMask; |
| import android.hardware.wifi.supplicant.NetworkResponseEapSimGsmAuthParams; |
| import android.hardware.wifi.supplicant.NetworkResponseEapSimUmtsAuthParams; |
| import android.hardware.wifi.supplicant.OcspType; |
| import android.hardware.wifi.supplicant.PairwiseCipherMask; |
| import android.hardware.wifi.supplicant.ProtoMask; |
| import android.hardware.wifi.supplicant.SaeH2eMode; |
| import android.net.wifi.SecurityParams; |
| import android.net.wifi.WifiConfiguration; |
| import android.net.wifi.WifiEnterpriseConfig; |
| import android.net.wifi.WifiManager; |
| import android.os.RemoteException; |
| import android.os.ServiceSpecificException; |
| import android.text.TextUtils; |
| import android.util.Log; |
| |
| import com.android.internal.annotations.VisibleForTesting; |
| import com.android.server.wifi.util.ArrayUtils; |
| import com.android.server.wifi.util.NativeUtil; |
| import com.android.wifi.resources.R; |
| |
| import org.json.JSONException; |
| import org.json.JSONObject; |
| |
| import java.io.UnsupportedEncodingException; |
| import java.net.URLDecoder; |
| import java.net.URLEncoder; |
| import java.util.ArrayList; |
| import java.util.BitSet; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| import javax.annotation.concurrent.ThreadSafe; |
| |
| /** |
| * Wrapper class for ISupplicantStaNetwork HAL calls. Gets and sets supplicant sta network variables |
| * and interacts with networks. |
| * Public fields should be treated as invalid until their 'get' method is called, which will set the |
| * value if it returns true |
| * To maintain thread-safety, the locking protocol is that every non-static method (regardless of |
| * access level) acquires mLock. |
| */ |
| @ThreadSafe |
| public class SupplicantStaNetworkHalAidlImpl { |
| private static final String TAG = "SupplicantStaNetworkHalAidlImpl"; |
| @VisibleForTesting |
| public static final String ID_STRING_KEY_FQDN = "fqdn"; |
| @VisibleForTesting |
| public static final String ID_STRING_KEY_CREATOR_UID = "creatorUid"; |
| @VisibleForTesting |
| public static final String ID_STRING_KEY_CONFIG_KEY = "configKey"; |
| |
| /** |
| * Regex pattern for extracting the GSM sim authentication response params from a string. |
| * Matches a strings like the following: "[:<kc_value>:<sres_value>]"; |
| */ |
| private static final Pattern GSM_AUTH_RESPONSE_PARAMS_PATTERN = |
| Pattern.compile(":([0-9a-fA-F]+):([0-9a-fA-F]+)"); |
| /** |
| * Regex pattern for extracting the UMTS sim authentication response params from a string. |
| * Matches a strings like the following: ":<ik_value>:<ck_value>:<res_value>"; |
| */ |
| private static final Pattern UMTS_AUTH_RESPONSE_PARAMS_PATTERN = |
| Pattern.compile("^:([0-9a-fA-F]+):([0-9a-fA-F]+):([0-9a-fA-F]+)$"); |
| /** |
| * Regex pattern for extracting the UMTS sim auts response params from a string. |
| * Matches a strings like the following: ":<auts_value>"; |
| */ |
| private static final Pattern UMTS_AUTS_RESPONSE_PARAMS_PATTERN = |
| Pattern.compile("^:([0-9a-fA-F]+)$"); |
| |
| private final Object mLock = new Object(); |
| private final Context mContext; |
| private final String mIfaceName; |
| private final WifiMonitor mWifiMonitor; |
| private final WifiGlobals mWifiGlobals; |
| private ISupplicantStaNetwork mISupplicantStaNetwork; |
| private ISupplicantStaNetworkCallback mISupplicantStaNetworkCallback; |
| |
| private boolean mVerboseLoggingEnabled = false; |
| // Network variables read from wpa_supplicant. |
| private int mNetworkId; |
| private byte[] mSsid; |
| private byte[/* 6 */] mBssid; |
| private boolean mScanSsid; |
| private int mKeyMgmtMask; |
| private int mProtoMask; |
| private int mAuthAlgMask; |
| private int mGroupCipherMask; |
| private int mPairwiseCipherMask; |
| private int mGroupMgmtCipherMask; |
| private String mPskPassphrase; |
| private String mSaePassword; |
| private String mSaePasswordId; |
| private byte[] mPsk; |
| private byte[] mWepKey; |
| private int mWepTxKeyIdx; |
| private boolean mRequirePmf; |
| private String mIdStr; |
| private int mEapMethod; |
| private int mEapPhase2Method; |
| private byte[] mEapIdentity; |
| private byte[] mEapAnonymousIdentity; |
| private byte[] mEapPassword; |
| private String mEapCACert; |
| private String mEapCAPath; |
| private String mEapClientCert; |
| private String mEapPrivateKeyId; |
| private String mEapSubjectMatch; |
| private String mEapAltSubjectMatch; |
| private boolean mEapEngine; |
| private String mEapEngineID; |
| private String mEapDomainSuffixMatch; |
| private @WifiEnterpriseConfig.Ocsp int mOcsp; |
| private String mWapiCertSuite; |
| private long mAdvanceKeyMgmtFeatures; |
| |
| SupplicantStaNetworkHalAidlImpl(ISupplicantStaNetwork staNetwork, String ifaceName, |
| Context context, WifiMonitor monitor, WifiGlobals wifiGlobals, |
| long advanceKeyMgmtFeature) { |
| mISupplicantStaNetwork = staNetwork; |
| mContext = context; |
| mIfaceName = ifaceName; |
| mWifiMonitor = monitor; |
| mWifiGlobals = wifiGlobals; |
| mAdvanceKeyMgmtFeatures = advanceKeyMgmtFeature; |
| } |
| |
| /** |
| * Enable/Disable verbose logging. |
| * |
| * @param enable true to enable, false to disable. |
| */ |
| void enableVerboseLogging(boolean verboseEnabled, boolean halVerboseEnabled) { |
| synchronized (mLock) { |
| mVerboseLoggingEnabled = verboseEnabled; |
| } |
| } |
| |
| /** |
| * Read network variables from wpa_supplicant into the provided WifiConfiguration object. |
| * |
| * @param config WifiConfiguration object to be populated. |
| * @param networkExtras Map of network extras parsed from wpa_supplicant. |
| * @return true if succeeds, false otherwise. |
| * @throws IllegalArgumentException on malformed configuration params. |
| */ |
| @VisibleForTesting |
| public boolean loadWifiConfiguration(WifiConfiguration config, |
| Map<String, String> networkExtras) throws IllegalArgumentException { |
| synchronized (mLock) { |
| if (config == null) { |
| return false; |
| } |
| /** SSID */ |
| config.SSID = null; |
| if (getSsid() && !ArrayUtils.isEmpty(mSsid)) { |
| config.SSID = NativeUtil.encodeSsid(NativeUtil.byteArrayToArrayList(mSsid)); |
| } else { |
| Log.e(TAG, "failed to read ssid"); |
| return false; |
| } |
| /** Network Id */ |
| config.networkId = -1; |
| if (getId()) { |
| config.networkId = mNetworkId; |
| } else { |
| Log.e(TAG, "getId failed"); |
| return false; |
| } |
| /** BSSID */ |
| config.getNetworkSelectionStatus().setNetworkSelectionBSSID(null); |
| if (getBssid() && !ArrayUtils.isEmpty(mBssid)) { |
| config.getNetworkSelectionStatus().setNetworkSelectionBSSID( |
| NativeUtil.macAddressFromByteArray(mBssid)); |
| } |
| /** Scan SSID (Is Hidden Network?) */ |
| config.hiddenSSID = false; |
| if (getScanSsid()) { |
| config.hiddenSSID = mScanSsid; |
| } |
| /** Require PMF*/ |
| config.requirePmf = false; |
| if (getRequirePmf()) { |
| config.requirePmf = mRequirePmf; |
| } |
| /** WEP keys **/ |
| config.wepTxKeyIndex = -1; |
| if (getWepTxKeyIdx()) { |
| config.wepTxKeyIndex = mWepTxKeyIdx; |
| } |
| for (int i = 0; i < 4; i++) { |
| config.wepKeys[i] = null; |
| if (getWepKey(i) && !ArrayUtils.isEmpty(mWepKey)) { |
| config.wepKeys[i] = NativeUtil.bytesToHexOrQuotedString( |
| NativeUtil.byteArrayToArrayList(mWepKey)); |
| } |
| } |
| |
| /** allowedKeyManagement */ |
| if (getKeyMgmt()) { |
| BitSet keyMgmtMask = supplicantToWifiConfigurationKeyMgmtMask(mKeyMgmtMask); |
| keyMgmtMask = removeFastTransitionFlags(keyMgmtMask); |
| keyMgmtMask = removeSha256KeyMgmtFlags(keyMgmtMask); |
| keyMgmtMask = removePskSaeUpgradableTypeFlags(keyMgmtMask); |
| config.setSecurityParams(keyMgmtMask); |
| config.enableFils( |
| keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA256), |
| keyMgmtMask.get(WifiConfiguration.KeyMgmt.FILS_SHA384)); |
| } |
| |
| // supplicant only have one valid security type, it won't be a disbled params. |
| SecurityParams securityParams = config.getDefaultSecurityParams(); |
| |
| /** PSK passphrase */ |
| config.preSharedKey = null; |
| if (getPskPassphrase() && !TextUtils.isEmpty(mPskPassphrase)) { |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) { |
| config.preSharedKey = mPskPassphrase; |
| } else { |
| config.preSharedKey = NativeUtil.addEnclosingQuotes(mPskPassphrase); |
| } |
| } else if (getPsk() && !ArrayUtils.isEmpty(mPsk)) { |
| config.preSharedKey = NativeUtil.hexStringFromByteArray(mPsk); |
| } /* Do not read SAE password */ |
| |
| /** metadata: idstr */ |
| if (getIdStr() && !TextUtils.isEmpty(mIdStr)) { |
| Map<String, String> metadata = parseNetworkExtra(mIdStr); |
| networkExtras.putAll(metadata); |
| } else { |
| Log.w(TAG, "getIdStr failed or empty"); |
| } |
| |
| /** WAPI Cert Suite */ |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_CERT)) { |
| if (config.enterpriseConfig == null) { |
| return false; |
| } |
| config.enterpriseConfig.setEapMethod( |
| WifiEnterpriseConfig.Eap.WAPI_CERT); |
| /** WAPI Certificate Suite. */ |
| if (getWapiCertSuite() && !TextUtils.isEmpty(mWapiCertSuite)) { |
| config.enterpriseConfig.setWapiCertSuite(mWapiCertSuite); |
| } |
| return true; |
| } |
| return loadWifiEnterpriseConfig(config.SSID, config.enterpriseConfig); |
| } |
| } |
| |
| /** |
| * Read network variables from the provided WifiConfiguration object into wpa_supplicant. |
| * |
| * @param config WifiConfiguration object to be saved. |
| * @return true if succeeds, false otherwise. |
| * @throws IllegalArgumentException on malformed configuration params. |
| */ |
| public boolean saveWifiConfiguration(WifiConfiguration config) throws IllegalArgumentException { |
| synchronized (mLock) { |
| if (config == null) { |
| return false; |
| } |
| /** SSID */ |
| if (config.SSID != null) { |
| if (!setSsid(NativeUtil.byteArrayFromArrayList( |
| NativeUtil.decodeSsid(config.SSID)))) { |
| Log.e(TAG, "failed to set SSID: " + config.SSID); |
| return false; |
| } |
| } |
| /** BSSID */ |
| String bssidStr = config.getNetworkSelectionStatus().getNetworkSelectionBSSID(); |
| if (bssidStr != null) { |
| byte[] bssid = NativeUtil.macAddressToByteArray(bssidStr); |
| if (!setBssid(bssid)) { |
| Log.e(TAG, "failed to set BSSID: " + bssidStr); |
| return false; |
| } |
| } |
| /** HiddenSSID */ |
| if (!setScanSsid(config.hiddenSSID)) { |
| Log.e(TAG, config.SSID + ": failed to set hiddenSSID: " + config.hiddenSSID); |
| return false; |
| } |
| |
| SecurityParams securityParams = config.getNetworkSelectionStatus() |
| .getCandidateSecurityParams(); |
| if (securityParams == null) { |
| Log.wtf(TAG, "No available security params."); |
| return false; |
| } |
| Log.d(TAG, "The target security params: " + securityParams); |
| |
| boolean isRequirePmf = getOptimalPmfSettingForConfig(config, |
| securityParams.isRequirePmf()); |
| /** RequirePMF */ |
| if (!setRequirePmf(isRequirePmf)) { |
| Log.e(TAG, config.SSID + ": failed to set requirePMF: " + config.requirePmf); |
| return false; |
| } |
| /** Key Management Scheme */ |
| BitSet allowedKeyManagement = securityParams.getAllowedKeyManagement(); |
| if (allowedKeyManagement.cardinality() != 0) { |
| // Add FT flags if supported. |
| BitSet keyMgmtMask = addFastTransitionFlags(allowedKeyManagement); |
| // Add SHA256 key management flags. |
| keyMgmtMask = addSha256KeyMgmtFlags(keyMgmtMask); |
| // Add upgradable type key management flags for PSK/SAE. |
| keyMgmtMask = addPskSaeUpgradableTypeFlagsIfSupported(config, keyMgmtMask); |
| if (!setKeyMgmt(wifiConfigurationToSupplicantKeyMgmtMask(keyMgmtMask))) { |
| Log.e(TAG, "failed to set Key Management"); |
| return false; |
| } |
| // Check and set SuiteB configurations. |
| if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.SUITE_B_192) |
| && !saveSuiteBConfig(config)) { |
| Log.e(TAG, "failed to set Suite-B-192 configuration"); |
| return false; |
| } |
| // Check and set DPP Connection keys |
| if (keyMgmtMask.get(WifiConfiguration.KeyMgmt.DPP) |
| && !saveDppConnectionConfig(config)) { |
| Log.e(TAG, "failed to set DPP connection params"); |
| return false; |
| } |
| } |
| /** Security Protocol */ |
| BitSet allowedProtocols = securityParams.getAllowedProtocols(); |
| if (allowedProtocols.cardinality() != 0 |
| && !setProto(wifiConfigurationToSupplicantProtoMask(allowedProtocols))) { |
| Log.e(TAG, "failed to set Security Protocol"); |
| return false; |
| } |
| /** Auth Algorithm */ |
| BitSet allowedAuthAlgorithms = securityParams.getAllowedAuthAlgorithms(); |
| if (allowedAuthAlgorithms.cardinality() != 0 |
| && !setAuthAlg(wifiConfigurationToSupplicantAuthAlgMask( |
| allowedAuthAlgorithms))) { |
| Log.e(TAG, "failed to set AuthAlgorithm"); |
| return false; |
| } |
| /** Group Cipher */ |
| BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers(); |
| if (allowedGroupCiphers.cardinality() != 0 |
| && (!setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( |
| allowedGroupCiphers)))) { |
| Log.e(TAG, "failed to set Group Cipher"); |
| return false; |
| } |
| /** Pairwise Cipher*/ |
| BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers(); |
| if (allowedPairwiseCiphers.cardinality() != 0 |
| && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask( |
| allowedPairwiseCiphers))) { |
| Log.e(TAG, "failed to set PairwiseCipher"); |
| return false; |
| } |
| /** Pre Shared Key */ |
| // For PSK, this can either be quoted ASCII passphrase or hex string for raw psk. |
| // For SAE, password must be a quoted ASCII string |
| if (config.preSharedKey != null) { |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_WAPI_PSK)) { |
| if (!setPskPassphrase(config.preSharedKey)) { |
| Log.e(TAG, "failed to set wapi psk passphrase"); |
| return false; |
| } |
| } else if (config.preSharedKey.startsWith("\"")) { |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) { |
| /* WPA3 case, field is SAE Password */ |
| if (!setSaePassword( |
| NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { |
| Log.e(TAG, "failed to set sae password"); |
| return false; |
| } |
| } else { |
| if (!setPskPassphrase( |
| NativeUtil.removeEnclosingQuotes(config.preSharedKey))) { |
| Log.e(TAG, "failed to set psk passphrase"); |
| return false; |
| } |
| } |
| } else { |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) { |
| return false; |
| } |
| if (!setPsk(NativeUtil.hexStringToByteArray(config.preSharedKey))) { |
| Log.e(TAG, "failed to set psk"); |
| return false; |
| } |
| } |
| } |
| /** Wep Keys */ |
| boolean hasSetKey = false; |
| if (config.wepKeys != null) { |
| for (int i = 0; i < config.wepKeys.length; i++) { |
| if (config.wepKeys[i] != null) { |
| if (!setWepKey(i, NativeUtil.byteArrayFromArrayList( |
| NativeUtil.hexOrQuotedStringToBytes(config.wepKeys[i])))) { |
| Log.e(TAG, "failed to set wep_key " + i); |
| return false; |
| } |
| hasSetKey = true; |
| } |
| } |
| } |
| /** Wep Tx Key Idx */ |
| if (hasSetKey) { |
| if (!setWepTxKeyIdx(config.wepTxKeyIndex)) { |
| Log.e(TAG, "failed to set wep_tx_keyidx: " + config.wepTxKeyIndex); |
| return false; |
| } |
| } |
| /** metadata: FQDN + ConfigKey + CreatorUid */ |
| final Map<String, String> metadata = new HashMap<String, String>(); |
| if (config.isPasspoint()) { |
| metadata.put(ID_STRING_KEY_FQDN, config.FQDN); |
| /** Selected RCOI */ |
| if (!setSelectedRcoi(config.enterpriseConfig.getSelectedRcoi())) { |
| Log.e(TAG, "failed to set selected RCOI"); |
| return false; |
| } |
| } |
| metadata.put(ID_STRING_KEY_CONFIG_KEY, config.getProfileKey()); |
| metadata.put(ID_STRING_KEY_CREATOR_UID, Integer.toString(config.creatorUid)); |
| if (!setIdStr(createNetworkExtra(metadata))) { |
| Log.e(TAG, "failed to set id string"); |
| return false; |
| } |
| /** UpdateIdentifier */ |
| if (config.updateIdentifier != null |
| && !setUpdateIdentifier(Integer.parseInt(config.updateIdentifier))) { |
| Log.e(TAG, "failed to set update identifier"); |
| return false; |
| } |
| /** SAE configuration */ |
| if (securityParams.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE)) { |
| /** |
| * Hash-to-Element preference. |
| * For devices that don't support H2E, H2E mode will be permanently disabled. |
| * Devices that support H2E will enable both legacy and H2E mode by default, |
| * and will connect to SAE networks with H2E if possible, unless H2E only |
| * mode is enabled, and then the device will not connect to SAE networks in |
| * legacy mode. |
| */ |
| if (!mWifiGlobals.isWpa3SaeH2eSupported() && securityParams.isSaeH2eOnlyMode()) { |
| Log.e(TAG, "This device does not support SAE H2E."); |
| return false; |
| } |
| byte mode = mWifiGlobals.isWpa3SaeH2eSupported() |
| ? SaeH2eMode.H2E_OPTIONAL |
| : SaeH2eMode.DISABLED; |
| if (securityParams.isSaeH2eOnlyMode()) { |
| mode = SaeH2eMode.H2E_MANDATORY; |
| } |
| if (!setSaeH2eMode(mode)) { |
| Log.e(TAG, "failed to set H2E preference."); |
| return false; |
| } |
| } |
| // Finish here if no EAP config to set |
| if (config.enterpriseConfig != null |
| && config.enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE) { |
| if (config.enterpriseConfig.getEapMethod() == WifiEnterpriseConfig.Eap.WAPI_CERT) { |
| /** WAPI certificate suite name*/ |
| String param = config.enterpriseConfig |
| .getFieldValue(WifiEnterpriseConfig.WAPI_CERT_SUITE_KEY); |
| if (!TextUtils.isEmpty(param) && !setWapiCertSuite(param)) { |
| Log.e(TAG, config.SSID + ": failed to set WAPI certificate suite: " |
| + param); |
| return false; |
| } |
| return true; |
| } else if (!saveWifiEnterpriseConfig(config.SSID, config.enterpriseConfig)) { |
| return false; |
| } |
| } |
| |
| // Now that the network is configured fully, start listening for callback events. |
| return registerNewCallback(config.networkId, config.SSID); |
| } |
| } |
| |
| /** |
| * Read network variables from wpa_supplicant into the provided WifiEnterpriseConfig object. |
| * |
| * @param ssid SSID of the network. (Used for logging purposes only) |
| * @param eapConfig WifiEnterpriseConfig object to be populated. |
| * @return true if succeeds, false otherwise. |
| */ |
| private boolean loadWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) { |
| synchronized (mLock) { |
| if (eapConfig == null) { |
| return false; |
| } |
| /** EAP method */ |
| if (getEapMethod()) { |
| eapConfig.setEapMethod(supplicantToWifiConfigurationEapMethod(mEapMethod)); |
| } else { |
| // Invalid eap method could be because it's not an enterprise config. |
| Log.e(TAG, "Failed to get eap method. Assuming not an enterprise network"); |
| return true; |
| } |
| /** EAP Phase 2 method */ |
| if (getEapPhase2Method()) { |
| eapConfig.setPhase2Method( |
| supplicantToWifiConfigurationEapPhase2Method(mEapPhase2Method)); |
| } else { |
| // We cannot have an invalid eap phase 2 method. Return failure. |
| Log.e(TAG, "Failed to get eap phase2 method"); |
| return false; |
| } |
| /** EAP Identity */ |
| if (getEapIdentity() && !ArrayUtils.isEmpty(mEapIdentity)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.IDENTITY_KEY, |
| NativeUtil.stringFromByteArray(mEapIdentity)); |
| } |
| /** EAP Anonymous Identity */ |
| if (getEapAnonymousIdentity() && !ArrayUtils.isEmpty(mEapAnonymousIdentity)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.ANON_IDENTITY_KEY, |
| NativeUtil.stringFromByteArray(mEapAnonymousIdentity)); |
| } |
| /** EAP Password */ |
| if (getEapPassword() && !ArrayUtils.isEmpty(mEapPassword)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.PASSWORD_KEY, |
| NativeUtil.stringFromByteArray(mEapPassword)); |
| } |
| /** EAP Client Cert */ |
| if (getEapClientCert() && !TextUtils.isEmpty(mEapClientCert)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY, mEapClientCert); |
| } |
| /** EAP CA Cert */ |
| if (getEapCACert() && !TextUtils.isEmpty(mEapCACert)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, mEapCACert); |
| } |
| /** EAP OCSP type */ |
| if (getOcsp()) { |
| eapConfig.setOcsp(mOcsp); |
| } |
| /** EAP Subject Match */ |
| if (getEapSubjectMatch() && !TextUtils.isEmpty(mEapSubjectMatch)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY, mEapSubjectMatch); |
| } |
| /** EAP Engine ID */ |
| if (getEapEngineId() && !TextUtils.isEmpty(mEapEngineID)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY, mEapEngineID); |
| } |
| /** EAP Engine. Set this only if the engine id is non null. */ |
| if (getEapEngine() && !TextUtils.isEmpty(mEapEngineID)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.ENGINE_KEY, |
| mEapEngine |
| ? WifiEnterpriseConfig.ENGINE_ENABLE |
| : WifiEnterpriseConfig.ENGINE_DISABLE); |
| } |
| /** EAP Private Key */ |
| if (getEapPrivateKeyId() && !TextUtils.isEmpty(mEapPrivateKeyId)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY, mEapPrivateKeyId); |
| } |
| /** EAP Alt Subject Match */ |
| if (getEapAltSubjectMatch() && !TextUtils.isEmpty(mEapAltSubjectMatch)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY, mEapAltSubjectMatch); |
| } |
| /** EAP Domain Suffix Match */ |
| if (getEapDomainSuffixMatch() && !TextUtils.isEmpty(mEapDomainSuffixMatch)) { |
| eapConfig.setFieldValue( |
| WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY, mEapDomainSuffixMatch); |
| } |
| /** EAP CA Path*/ |
| if (getEapCAPath() && !TextUtils.isEmpty(mEapCAPath)) { |
| eapConfig.setFieldValue(WifiEnterpriseConfig.CA_PATH_KEY, mEapCAPath); |
| } |
| return true; |
| } |
| } |
| |
| /** |
| * save network variables from the provided dpp configuration to wpa_supplicant. |
| * |
| * @param config wificonfiguration object to be saved |
| * @return true if succeeds, false otherwise. |
| */ |
| private boolean saveDppConnectionConfig(WifiConfiguration config) { |
| synchronized (mLock) { |
| final String methodStr = "setDppKeys"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| DppConnectionKeys keys = new DppConnectionKeys(); |
| keys.connector = config.getDppConnector(); |
| keys.cSign = config.getDppCSignKey(); |
| keys.netAccessKey = config.getDppNetAccessKey(); |
| mISupplicantStaNetwork.setDppKeys(keys); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Save network variables from the provided SuiteB configuration to wpa_supplicant. |
| * |
| * @param config WifiConfiguration object to be saved |
| * @return true if succeeds, false otherwise. |
| */ |
| private boolean saveSuiteBConfig(WifiConfiguration config) { |
| synchronized (mLock) { |
| SecurityParams securityParams = config.getNetworkSelectionStatus() |
| .getCandidateSecurityParams(); |
| if (securityParams == null) { |
| Log.wtf(TAG, "No available security params."); |
| return false; |
| } |
| |
| /** Group Cipher **/ |
| BitSet allowedGroupCiphers = securityParams.getAllowedGroupCiphers(); |
| if (allowedGroupCiphers.cardinality() != 0 |
| && !setGroupCipher(wifiConfigurationToSupplicantGroupCipherMask( |
| allowedGroupCiphers))) { |
| Log.e(TAG, "Failed to set Group Cipher"); |
| return false; |
| } |
| /** Pairwise Cipher*/ |
| BitSet allowedPairwiseCiphers = securityParams.getAllowedPairwiseCiphers(); |
| if (allowedPairwiseCiphers.cardinality() != 0 |
| && !setPairwiseCipher(wifiConfigurationToSupplicantPairwiseCipherMask( |
| allowedPairwiseCiphers))) { |
| Log.e(TAG, "Failed to set PairwiseCipher"); |
| return false; |
| } |
| /** GroupMgmt Cipher */ |
| BitSet allowedGroupManagementCiphers = |
| securityParams.getAllowedGroupManagementCiphers(); |
| if (allowedGroupManagementCiphers.cardinality() != 0 |
| && !setGroupMgmtCipher(wifiConfigurationToSupplicantGroupMgmtCipherMask( |
| allowedGroupManagementCiphers))) { |
| Log.e(TAG, "Failed to set GroupMgmtCipher"); |
| return false; |
| } |
| |
| BitSet allowedSuiteBCiphers = securityParams.getAllowedSuiteBCiphers(); |
| if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)) { |
| if (!enableTlsSuiteBEapPhase1Param(true)) { |
| Log.e(TAG, "Failed to set TLSSuiteB"); |
| return false; |
| } |
| } else if (allowedSuiteBCiphers.get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)) { |
| if (!enableSuiteBEapOpenSslCiphers()) { |
| Log.e(TAG, "Failed to set OpensslCipher"); |
| return false; |
| } |
| } |
| |
| return true; |
| } |
| } |
| |
| /** |
| * Save network variables from the provided WifiEnterpriseConfig object to wpa_supplicant. |
| * |
| * @param ssid SSID of the network. (Used for logging purposes only) |
| * @param eapConfig WifiEnterpriseConfig object to be saved. |
| * @return true if succeeds, false otherwise. |
| */ |
| private boolean saveWifiEnterpriseConfig(String ssid, WifiEnterpriseConfig eapConfig) { |
| synchronized (mLock) { |
| if (eapConfig == null) { |
| return false; |
| } |
| /** EAP method */ |
| if (!setEapMethod(wifiConfigurationToSupplicantEapMethod(eapConfig.getEapMethod()))) { |
| Log.e(TAG, ssid + ": failed to set eap method: " + eapConfig.getEapMethod()); |
| return false; |
| } |
| /** EAP Phase 2 method */ |
| if (!setEapPhase2Method(wifiConfigurationToSupplicantEapPhase2Method( |
| eapConfig.getPhase2Method()))) { |
| Log.e(TAG, ssid + ": failed to set eap phase 2 method: " |
| + eapConfig.getPhase2Method()); |
| return false; |
| } |
| String eapParam = null; |
| /** EAP Identity */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.IDENTITY_KEY); |
| if (!TextUtils.isEmpty(eapParam) |
| && !setEapIdentity(NativeUtil.stringToByteArray(eapParam))) { |
| Log.e(TAG, ssid + ": failed to set eap identity: " + eapParam); |
| return false; |
| } |
| /** EAP Anonymous Identity */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ANON_IDENTITY_KEY); |
| if (!TextUtils.isEmpty(eapParam)) { |
| String decoratedUsernamePrefix = |
| eapConfig.getFieldValue(WifiEnterpriseConfig.DECORATED_IDENTITY_PREFIX_KEY); |
| if (!TextUtils.isEmpty(decoratedUsernamePrefix)) { |
| eapParam = decoratedUsernamePrefix + eapParam; |
| } |
| if (!setEapAnonymousIdentity(NativeUtil.stringToByteArray(eapParam))) { |
| Log.e(TAG, ssid + ": failed to set eap anonymous identity: " + eapParam); |
| return false; |
| } |
| } |
| /** EAP Password */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PASSWORD_KEY); |
| if (!TextUtils.isEmpty(eapParam) |
| && !setEapPassword(NativeUtil.stringToByteArray(eapParam))) { |
| Log.e(TAG, ssid + ": failed to set eap password"); |
| return false; |
| } |
| /** EAP Client Cert */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CLIENT_CERT_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapClientCert(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap client cert: " + eapParam); |
| return false; |
| } |
| /** EAP CA Cert */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapCACert(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap ca cert: " + eapParam); |
| return false; |
| } |
| /** EAP Subject Match */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.SUBJECT_MATCH_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapSubjectMatch(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap subject match: " + eapParam); |
| return false; |
| } |
| /** EAP Engine ID */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_ID_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapEngineID(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap engine id: " + eapParam); |
| return false; |
| } |
| /** EAP Engine */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ENGINE_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapEngine( |
| eapParam.equals(WifiEnterpriseConfig.ENGINE_ENABLE) ? true : false)) { |
| Log.e(TAG, ssid + ": failed to set eap engine: " + eapParam); |
| return false; |
| } |
| /** EAP Private Key */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.PRIVATE_KEY_ID_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapPrivateKeyId(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap private key: " + eapParam); |
| return false; |
| } |
| /** EAP Alt Subject Match */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.ALTSUBJECT_MATCH_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapAltSubjectMatch(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap alt subject match: " + eapParam); |
| return false; |
| } |
| /** EAP Domain Suffix Match */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.DOM_SUFFIX_MATCH_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapDomainSuffixMatch(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap domain suffix match: " + eapParam); |
| return false; |
| } |
| /** EAP CA Path*/ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.CA_PATH_KEY); |
| if (!TextUtils.isEmpty(eapParam) && !setEapCAPath(eapParam)) { |
| Log.e(TAG, ssid + ": failed to set eap ca path: " + eapParam); |
| return false; |
| } |
| /** EAP Proactive Key Caching */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.OPP_KEY_CACHING); |
| if (!TextUtils.isEmpty(eapParam) |
| && !setEapProactiveKeyCaching(eapParam.equals("1") ? true : false)) { |
| Log.e(TAG, ssid + ": failed to set proactive key caching: " + eapParam); |
| return false; |
| } |
| /** OCSP (Online Certificate Status Protocol) */ |
| if (!setOcsp(eapConfig.getOcsp())) { |
| Log.e(TAG, "failed to set ocsp"); |
| return false; |
| } |
| /** EAP ERP */ |
| eapParam = eapConfig.getFieldValue(WifiEnterpriseConfig.EAP_ERP); |
| if (!TextUtils.isEmpty(eapParam) && eapParam.equals("1")) { |
| if (!setEapErp(true)) { |
| Log.e(TAG, ssid + ": failed to set eap erp"); |
| return false; |
| } |
| } |
| return true; |
| } |
| } |
| |
| /** |
| * Maps WifiConfiguration Key Management BitSet to Supplicant AIDL bitmask int |
| * |
| * @return bitmask int describing the allowed Key Management schemes, readable by the Supplicant |
| * AIDL hal |
| */ |
| private static int wifiConfigurationToSupplicantKeyMgmtMask(BitSet keyMgmt) { |
| int mask = 0; |
| for (int bit = keyMgmt.nextSetBit(0); bit != -1; |
| bit = keyMgmt.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.KeyMgmt.NONE: |
| mask |= KeyMgmtMask.NONE; |
| break; |
| case WifiConfiguration.KeyMgmt.WPA_PSK: |
| mask |= KeyMgmtMask.WPA_PSK; |
| break; |
| case WifiConfiguration.KeyMgmt.WPA_EAP: |
| mask |= KeyMgmtMask.WPA_EAP; |
| break; |
| case WifiConfiguration.KeyMgmt.IEEE8021X: |
| mask |= KeyMgmtMask.IEEE8021X; |
| break; |
| case WifiConfiguration.KeyMgmt.OSEN: |
| mask |= KeyMgmtMask.OSEN; |
| break; |
| case WifiConfiguration.KeyMgmt.FT_PSK: |
| mask |= KeyMgmtMask.FT_PSK; |
| break; |
| case WifiConfiguration.KeyMgmt.FT_EAP: |
| mask |= KeyMgmtMask.FT_EAP; |
| break; |
| case WifiConfiguration.KeyMgmt.OWE: |
| mask |= KeyMgmtMask.OWE; |
| break; |
| case WifiConfiguration.KeyMgmt.SAE: |
| mask |= KeyMgmtMask.SAE; |
| break; |
| case WifiConfiguration.KeyMgmt.SUITE_B_192: |
| mask |= KeyMgmtMask.SUITE_B_192; |
| break; |
| case WifiConfiguration.KeyMgmt.WPA_PSK_SHA256: |
| mask |= KeyMgmtMask.WPA_PSK_SHA256; |
| break; |
| case WifiConfiguration.KeyMgmt.WPA_EAP_SHA256: |
| mask |= KeyMgmtMask.WPA_EAP_SHA256; |
| break; |
| case WifiConfiguration.KeyMgmt.WAPI_PSK: |
| mask |= KeyMgmtMask.WAPI_PSK; |
| break; |
| case WifiConfiguration.KeyMgmt.WAPI_CERT: |
| mask |= KeyMgmtMask.WAPI_CERT; |
| break; |
| case WifiConfiguration.KeyMgmt.FILS_SHA256: |
| mask |= KeyMgmtMask.FILS_SHA256; |
| break; |
| case WifiConfiguration.KeyMgmt.FILS_SHA384: |
| mask |= KeyMgmtMask.FILS_SHA384; |
| break; |
| case WifiConfiguration.KeyMgmt.DPP: |
| mask |= KeyMgmtMask.DPP; |
| break; |
| case WifiConfiguration.KeyMgmt.WPA2_PSK: // This should never happen |
| default: |
| throw new IllegalArgumentException( |
| "Invalid protoMask bit in keyMgmt: " + bit); |
| } |
| } |
| return mask; |
| } |
| |
| private static int wifiConfigurationToSupplicantProtoMask(BitSet protoMask) { |
| int mask = 0; |
| for (int bit = protoMask.nextSetBit(0); bit != -1; |
| bit = protoMask.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.Protocol.WPA: |
| mask |= ProtoMask.WPA; |
| break; |
| case WifiConfiguration.Protocol.RSN: |
| mask |= ProtoMask.RSN; |
| break; |
| case WifiConfiguration.Protocol.OSEN: |
| mask |= ProtoMask.OSEN; |
| break; |
| case WifiConfiguration.Protocol.WAPI: |
| mask |= ProtoMask.WAPI; |
| break; |
| default: |
| throw new IllegalArgumentException( |
| "Invalid protoMask bit in wificonfig: " + bit); |
| } |
| } |
| return mask; |
| } |
| |
| private static int wifiConfigurationToSupplicantAuthAlgMask(BitSet authAlgMask) { |
| int mask = 0; |
| for (int bit = authAlgMask.nextSetBit(0); bit != -1; |
| bit = authAlgMask.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.AuthAlgorithm.OPEN: |
| mask |= AuthAlgMask.OPEN; |
| break; |
| case WifiConfiguration.AuthAlgorithm.SHARED: |
| mask |= AuthAlgMask.SHARED; |
| break; |
| case WifiConfiguration.AuthAlgorithm.LEAP: |
| mask |= AuthAlgMask.LEAP; |
| break; |
| case WifiConfiguration.AuthAlgorithm.SAE: |
| mask |= AuthAlgMask.SAE; |
| break; |
| default: |
| throw new IllegalArgumentException( |
| "Invalid authAlgMask bit in wificonfig: " + bit); |
| } |
| } |
| return mask; |
| } |
| |
| private int wifiConfigurationToSupplicantGroupCipherMask(BitSet groupCipherMask) { |
| synchronized (mLock) { |
| int mask = 0; |
| for (int bit = groupCipherMask.nextSetBit(0); bit != -1; bit = |
| groupCipherMask.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.GroupCipher.WEP40: |
| mask |= GroupCipherMask.WEP40; |
| break; |
| case WifiConfiguration.GroupCipher.WEP104: |
| mask |= GroupCipherMask.WEP104; |
| break; |
| case WifiConfiguration.GroupCipher.TKIP: |
| mask |= GroupCipherMask.TKIP; |
| break; |
| case WifiConfiguration.GroupCipher.CCMP: |
| mask |= GroupCipherMask.CCMP; |
| break; |
| case WifiConfiguration.GroupCipher.GTK_NOT_USED: |
| mask |= GroupCipherMask.GTK_NOT_USED; |
| break; |
| case WifiConfiguration.GroupCipher.GCMP_256: |
| if (0 == (mAdvanceKeyMgmtFeatures |
| & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) { |
| Log.d(TAG, "Ignore unsupported GCMP_256 cipher."); |
| break; |
| } |
| mask |= GroupCipherMask.GCMP_256; |
| break; |
| case WifiConfiguration.GroupCipher.SMS4: |
| mask |= GroupCipherMask.SMS4; |
| break; |
| case WifiConfiguration.GroupCipher.GCMP_128: |
| mask |= GroupCipherMask.GCMP_128; |
| break; |
| default: |
| throw new IllegalArgumentException( |
| "Invalid GroupCipherMask bit in wificonfig: " + bit); |
| } |
| } |
| return mask; |
| } |
| } |
| |
| private static int wifiConfigurationToSupplicantGroupMgmtCipherMask(BitSet |
| groupMgmtCipherMask) { |
| int mask = 0; |
| |
| for (int bit = groupMgmtCipherMask.nextSetBit(0); bit != -1; bit = |
| groupMgmtCipherMask.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.GroupMgmtCipher.BIP_CMAC_256: |
| mask |= GroupMgmtCipherMask.BIP_CMAC_256; |
| break; |
| case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_128: |
| mask |= GroupMgmtCipherMask.BIP_GMAC_128; |
| break; |
| case WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256: |
| mask |= GroupMgmtCipherMask.BIP_GMAC_256; |
| break; |
| default: |
| throw new IllegalArgumentException( |
| "Invalid GroupMgmtCipherMask bit in wificonfig: " + bit); |
| } |
| } |
| return mask; |
| } |
| |
| private int wifiConfigurationToSupplicantPairwiseCipherMask(BitSet pairwiseCipherMask) { |
| synchronized (mLock) { |
| int mask = 0; |
| for (int bit = pairwiseCipherMask.nextSetBit(0); bit != -1; |
| bit = pairwiseCipherMask.nextSetBit(bit + 1)) { |
| switch (bit) { |
| case WifiConfiguration.PairwiseCipher.NONE: |
| mask |= PairwiseCipherMask.NONE; |
| break; |
| case WifiConfiguration.PairwiseCipher.TKIP: |
| mask |= PairwiseCipherMask.TKIP; |
| break; |
| case WifiConfiguration.PairwiseCipher.CCMP: |
| mask |= PairwiseCipherMask.CCMP; |
| break; |
| case WifiConfiguration.PairwiseCipher.GCMP_256: |
| if (0 == (mAdvanceKeyMgmtFeatures |
| & WifiManager.WIFI_FEATURE_WPA3_SUITE_B)) { |
| Log.d(TAG, "Ignore unsupporting GCMP_256 cipher."); |
| break; |
| } |
| mask |= PairwiseCipherMask.GCMP_256; |
| break; |
| case WifiConfiguration.PairwiseCipher.SMS4: |
| mask |= PairwiseCipherMask.SMS4; |
| break; |
| case WifiConfiguration.PairwiseCipher.GCMP_128: |
| mask |= PairwiseCipherMask.GCMP_128; |
| break; |
| default: |
| throw new IllegalArgumentException( |
| "Invalid pairwiseCipherMask bit in wificonfig: " + bit); |
| } |
| } |
| return mask; |
| } |
| } |
| |
| private static int supplicantToWifiConfigurationEapMethod(int value) { |
| switch (value) { |
| case EapMethod.PEAP: |
| return WifiEnterpriseConfig.Eap.PEAP; |
| case EapMethod.TLS: |
| return WifiEnterpriseConfig.Eap.TLS; |
| case EapMethod.TTLS: |
| return WifiEnterpriseConfig.Eap.TTLS; |
| case EapMethod.PWD: |
| return WifiEnterpriseConfig.Eap.PWD; |
| case EapMethod.SIM: |
| return WifiEnterpriseConfig.Eap.SIM; |
| case EapMethod.AKA: |
| return WifiEnterpriseConfig.Eap.AKA; |
| case EapMethod.AKA_PRIME: |
| return WifiEnterpriseConfig.Eap.AKA_PRIME; |
| case EapMethod.WFA_UNAUTH_TLS: |
| return WifiEnterpriseConfig.Eap.UNAUTH_TLS; |
| // WifiEnterpriseConfig.Eap.NONE: |
| default: |
| Log.e(TAG, "invalid eap method value from supplicant: " + value); |
| return -1; |
| } |
| } |
| |
| private static int supplicantToWifiConfigurationEapPhase2Method(int value) { |
| switch (value) { |
| case EapPhase2Method.NONE: |
| return WifiEnterpriseConfig.Phase2.NONE; |
| case EapPhase2Method.PAP: |
| return WifiEnterpriseConfig.Phase2.PAP; |
| case EapPhase2Method.MSPAP: |
| return WifiEnterpriseConfig.Phase2.MSCHAP; |
| case EapPhase2Method.MSPAPV2: |
| return WifiEnterpriseConfig.Phase2.MSCHAPV2; |
| case EapPhase2Method.GTC: |
| return WifiEnterpriseConfig.Phase2.GTC; |
| case EapPhase2Method.SIM: |
| return WifiEnterpriseConfig.Phase2.SIM; |
| case EapPhase2Method.AKA: |
| return WifiEnterpriseConfig.Phase2.AKA; |
| case EapPhase2Method.AKA_PRIME: |
| return WifiEnterpriseConfig.Phase2.AKA_PRIME; |
| default: |
| Log.e(TAG, "Invalid eap phase2 method value from supplicant: " + value); |
| return -1; |
| } |
| } |
| |
| private static int supplicantMaskValueToWifiConfigurationBitSet(int supplicantMask, |
| int supplicantValue, BitSet bitset, int bitSetPosition) { |
| bitset.set(bitSetPosition, (supplicantMask & supplicantValue) == supplicantValue); |
| int modifiedSupplicantMask = supplicantMask & ~supplicantValue; |
| return modifiedSupplicantMask; |
| } |
| |
| private static BitSet supplicantToWifiConfigurationKeyMgmtMask(int mask) { |
| BitSet bitset = new BitSet(); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.NONE, bitset, |
| WifiConfiguration.KeyMgmt.NONE); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WPA_PSK, bitset, |
| WifiConfiguration.KeyMgmt.WPA_PSK); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WPA_EAP, bitset, |
| WifiConfiguration.KeyMgmt.WPA_EAP); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.IEEE8021X, bitset, |
| WifiConfiguration.KeyMgmt.IEEE8021X); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.OSEN, bitset, |
| WifiConfiguration.KeyMgmt.OSEN); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.FT_PSK, bitset, |
| WifiConfiguration.KeyMgmt.FT_PSK); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.FT_EAP, bitset, |
| WifiConfiguration.KeyMgmt.FT_EAP); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.SAE, |
| bitset, WifiConfiguration.KeyMgmt.SAE); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.OWE, |
| bitset, WifiConfiguration.KeyMgmt.OWE); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.SUITE_B_192, |
| bitset, WifiConfiguration.KeyMgmt.SUITE_B_192); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WPA_PSK_SHA256, |
| bitset, WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WPA_EAP_SHA256, |
| bitset, WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WAPI_PSK, |
| bitset, WifiConfiguration.KeyMgmt.WAPI_PSK); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.WAPI_CERT, |
| bitset, WifiConfiguration.KeyMgmt.WAPI_CERT); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.FILS_SHA256, |
| bitset, WifiConfiguration.KeyMgmt.FILS_SHA256); |
| mask = supplicantMaskValueToWifiConfigurationBitSet( |
| mask, KeyMgmtMask.FILS_SHA384, |
| bitset, WifiConfiguration.KeyMgmt.FILS_SHA384); |
| if (mask != 0) { |
| throw new IllegalArgumentException( |
| "invalid key mgmt mask from supplicant: " + mask); |
| } |
| return bitset; |
| } |
| |
| private static int wifiConfigurationToSupplicantEapMethod(int value) { |
| switch (value) { |
| case WifiEnterpriseConfig.Eap.PEAP: |
| return EapMethod.PEAP; |
| case WifiEnterpriseConfig.Eap.TLS: |
| return EapMethod.TLS; |
| case WifiEnterpriseConfig.Eap.TTLS: |
| return EapMethod.TTLS; |
| case WifiEnterpriseConfig.Eap.PWD: |
| return EapMethod.PWD; |
| case WifiEnterpriseConfig.Eap.SIM: |
| return EapMethod.SIM; |
| case WifiEnterpriseConfig.Eap.AKA: |
| return EapMethod.AKA; |
| case WifiEnterpriseConfig.Eap.AKA_PRIME: |
| return EapMethod.AKA_PRIME; |
| case WifiEnterpriseConfig.Eap.UNAUTH_TLS: |
| return EapMethod.WFA_UNAUTH_TLS; |
| // WifiEnterpriseConfig.Eap.NONE: |
| default: |
| Log.e(TAG, "Invalid eap method value from WifiConfiguration: " + value); |
| return -1; |
| } |
| } |
| |
| private static int wifiConfigurationToSupplicantEapPhase2Method(int value) { |
| switch (value) { |
| case WifiEnterpriseConfig.Phase2.NONE: |
| return EapPhase2Method.NONE; |
| case WifiEnterpriseConfig.Phase2.PAP: |
| return EapPhase2Method.PAP; |
| case WifiEnterpriseConfig.Phase2.MSCHAP: |
| return EapPhase2Method.MSPAP; |
| case WifiEnterpriseConfig.Phase2.MSCHAPV2: |
| return EapPhase2Method.MSPAPV2; |
| case WifiEnterpriseConfig.Phase2.GTC: |
| return EapPhase2Method.GTC; |
| case WifiEnterpriseConfig.Phase2.SIM: |
| return EapPhase2Method.SIM; |
| case WifiEnterpriseConfig.Phase2.AKA: |
| return EapPhase2Method.AKA; |
| case WifiEnterpriseConfig.Phase2.AKA_PRIME: |
| return EapPhase2Method.AKA_PRIME; |
| default: |
| Log.e(TAG, "Invalid eap phase2 method value from WifiConfiguration: " + value); |
| return -1; |
| } |
| } |
| |
| /** |
| * Retrieves the ID allocated to this network by the supplicant. |
| * Result is stored in mNetworkId. |
| * |
| * This is not the |SSID| of the network, but an internal identifier for |
| * this network used by the supplicant. |
| * |
| * @return true if ID was retrieved, false otherwise |
| */ |
| private boolean getId() { |
| synchronized (mLock) { |
| final String methodStr = "getId"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mNetworkId = mISupplicantStaNetwork.getId(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** Get current network id */ |
| public int getNetworkId() { |
| synchronized (mLock) { |
| if (!getId()) { |
| return -1; |
| } |
| return mNetworkId; |
| } |
| } |
| |
| private boolean registerCallback(ISupplicantStaNetworkCallback callback) { |
| synchronized (mLock) { |
| final String methodStr = "registerCallback"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.registerCallback(callback); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| private boolean registerNewCallback(int networkId, String ssid) { |
| synchronized (mLock) { |
| ISupplicantStaNetworkCallback callback = |
| new SupplicantStaNetworkCallbackAidlImpl( |
| SupplicantStaNetworkHalAidlImpl.this, |
| networkId, ssid, mIfaceName, mLock, mWifiMonitor); |
| if (!registerCallback(callback)) { |
| Log.e(TAG, "Failed to register callback."); |
| return false; |
| } |
| mISupplicantStaNetworkCallback = callback; |
| return true; |
| } |
| } |
| |
| /** |
| * Set SSID for this network. |
| * |
| * @param ssid Value to set. |
| * Max length of |ParamSizeLimits.SSID_MAX_LEN_IN_BYTES|. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setSsid(byte[] ssid) { |
| synchronized (mLock) { |
| final String methodStr = "setSsid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setSsid(ssid); |
| Log.i(TAG, "Successfully set SSID"); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set the BSSID for this network. |
| * |
| * @param bssidStr MAC address in "XX:XX:XX:XX:XX:XX" form or "any" to reset the mac address. |
| * @return true if it succeeds, false otherwise. |
| */ |
| public boolean setBssid(String bssidStr) { |
| synchronized (mLock) { |
| try { |
| return setBssid(NativeUtil.macAddressToByteArray(bssidStr)); |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "Illegal argument " + bssidStr, e); |
| return false; |
| } |
| } |
| } |
| |
| private boolean setBssid(byte[/* 6 */] bssid) { |
| synchronized (mLock) { |
| final String methodStr = "setBssid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setBssid(bssid); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set whether to send probe requests for this network (hidden). |
| * |
| * @param enable true to set, false otherwise. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setScanSsid(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setScanSsid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setScanSsid(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set key management mask for the network. |
| * |
| * @param keyMgmtMask value to set. |
| * Combination of |KeyMgmtMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setKeyMgmt(int keyMgmtMask) { |
| synchronized (mLock) { |
| final String methodStr = "setKeyMgmt"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setKeyMgmt(keyMgmtMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set proto mask for the network. |
| * |
| * @param protoMask value to set. |
| * Combination of |ProtoMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setProto(int protoMask) { |
| synchronized (mLock) { |
| final String methodStr = "setProto"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setProto(protoMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set auth alg mask for the network. |
| * |
| * @param authAlgMask value to set. |
| * Combination of |ProtoMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setAuthAlg(int authAlgMask) { |
| synchronized (mLock) { |
| final String methodStr = "setAuthAlg"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setAuthAlg(authAlgMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set group cipher mask for the network. |
| * |
| * @param groupCipherMask value to set. |
| * Combination of |ProtoMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setGroupCipher(int groupCipherMask) { |
| synchronized (mLock) { |
| final String methodStr = "setGroupCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setGroupCipher(groupCipherMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Enable TLS Suite-B in EAP Phase1 |
| * |
| * @param enable Set to true to enable TLS Suite-B in EAP phase1 |
| * @return true if successful, false otherwise |
| */ |
| private boolean enableTlsSuiteBEapPhase1Param(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setEapPhase1Params"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.enableTlsSuiteBEapPhase1Param(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP OpenSSL Suite-B-192 ciphers for WPA3-Enterprise |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean enableSuiteBEapOpenSslCiphers() { |
| synchronized (mLock) { |
| final String methodStr = "setEapOpenSslCiphers"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.enableSuiteBEapOpenSslCiphers(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set pairwise cipher mask for the network. |
| * |
| * @param pairwiseCipherMask value to set. |
| * Combination of |ProtoMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setPairwiseCipher(int pairwiseCipherMask) { |
| synchronized (mLock) { |
| final String methodStr = "setPairwiseCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setPairwiseCipher(pairwiseCipherMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set group management cipher mask for the network. |
| * |
| * @param groupMgmtCipherMask value to set. |
| * Combination of |GroupMgmtCipherMask| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setGroupMgmtCipher(int groupMgmtCipherMask) { |
| synchronized (mLock) { |
| final String methodStr = "setGroupMgmtCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setGroupMgmtCipher(groupMgmtCipherMask); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set passphrase for WPA_PSK network. |
| * |
| * @param psk value to set. |
| * Length of value must be between |
| * |ParamSizeLimits.PSK_PASSPHRASE_MIN_LEN_IN_BYTES| and |
| * |ParamSizeLimits.PSK_PASSPHRASE_MAX_LEN_IN_BYTES|. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setPskPassphrase(String psk) { |
| synchronized (mLock) { |
| final String methodStr = "setPskPassphrase"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setPskPassphrase(psk); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set raw psk for WPA_PSK network. |
| * |
| * @param psk value to set as specified in IEEE 802.11i-2004 standard. |
| * This is the calculated using 'wpa_passphrase <ssid> [passphrase]' |
| * @return true if successful, false otherwise |
| */ |
| private boolean setPsk(byte[] psk) { |
| synchronized (mLock) { |
| final String methodStr = "setPsk"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setPsk(psk); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ArrayIndexOutOfBoundsException e) { |
| Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed: " + e); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set WEP key for WEP network. |
| * |
| * @param keyIdx Index of wep key to set. |
| * Max of |ParamSizeLimits.WEP_KEYS_MAX_NUM|. |
| * @param wepKey value to set. |
| * Length of each key must be either |
| * |ParamSizeLimits.WEP40_KEY_LEN_IN_BYTES| or |
| * |ParamSizeLimits.WEP104_KEY_LEN_IN_BYTES|. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setWepKey(int keyIdx, byte[] wepKey) { |
| synchronized (mLock) { |
| final String methodStr = "setWepKey"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setWepKey(keyIdx, wepKey); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set default Tx key index for WEP network. |
| * |
| * @param keyIdx value to set. |
| * Max of |ParamSizeLimits.WEP_KEYS_MAX_NUM|. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setWepTxKeyIdx(int keyIdx) { |
| synchronized (mLock) { |
| final String methodStr = "setWepTxKeyIdx"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setWepTxKeyIdx(keyIdx); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set whether RequirePmf is enabled for this network. |
| * |
| * @param enable true to set, false otherwise. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setRequirePmf(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setRequirePmf"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setRequirePmf(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set PPS MO ID for this network. |
| * (Hotspot 2.0 PerProviderSubscription/UpdateIdentifier) |
| * |
| * @param identifier ID value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setUpdateIdentifier(int identifier) { |
| synchronized (mLock) { |
| final String methodStr = "setUpdateIdentifier"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setUpdateIdentifier(identifier); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set WAPI certificate suite name for this network. |
| * |
| * @param certSuite value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setWapiCertSuite(String certSuite) { |
| synchronized (mLock) { |
| final String methodStr = "setWapiCertSuite"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setWapiCertSuite(certSuite); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Method for this network. |
| * |
| * @param method value to be set. |
| * Must be one of |EapMethod| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapMethod(int method) { |
| synchronized (mLock) { |
| final String methodStr = "setEapMethod"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapMethod(method); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Phase2 Method for this network. |
| * |
| * EAP method needs to be set for this to work. |
| * |
| * @param method value to set. |
| * Must be one of |EapPhase2Method| values. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapPhase2Method(int method) { |
| synchronized (mLock) { |
| final String methodStr = "setEapPhase2Method"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapPhase2Method(method); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Identity for this network. |
| * |
| * @param identity value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapIdentity(byte[] identity) { |
| synchronized (mLock) { |
| final String methodStr = "setEapIdentity"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapIdentity(identity); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Anonymous Identity for this network. |
| * |
| * @param identity value to set. |
| * @return true if successful, false otherwise |
| */ |
| public boolean setEapAnonymousIdentity(byte[] identity) { |
| synchronized (mLock) { |
| final String methodStr = "setEapAnonymousIdentity"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapAnonymousIdentity(identity); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Password for this network. |
| * |
| * @param password value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapPassword(byte[] password) { |
| synchronized (mLock) { |
| final String methodStr = "setEapPassword"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapPassword(password); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP CA certificate file path for this network. |
| * |
| * @param path value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapCACert(String path) { |
| synchronized (mLock) { |
| final String methodStr = "setEapCACert"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapCACert(path); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP CA certificate directory path for this network. |
| * |
| * @param path value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapCAPath(String path) { |
| synchronized (mLock) { |
| final String methodStr = "setEapCAPath"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapCAPath(path); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Client certificate file path for this network. |
| * |
| * @param path value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapClientCert(String path) { |
| synchronized (mLock) { |
| final String methodStr = "setEapClientCert"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapClientCert(path); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP private key Id for this network. |
| * This is used if private key operations for EAP-TLS are performed |
| * using a smartcard. |
| * |
| * @param id value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapPrivateKeyId(String id) { |
| synchronized (mLock) { |
| final String methodStr = "setEapPrivateKeyId"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapPrivateKeyId(id); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP subject match for this network. |
| * |
| * @param match value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapSubjectMatch(String match) { |
| synchronized (mLock) { |
| final String methodStr = "setEapSubjectMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapSubjectMatch(match); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Alt subject match for this network. |
| * |
| * @param match value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapAltSubjectMatch(String match) { |
| synchronized (mLock) { |
| final String methodStr = "setEapAltSubjectMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapAltSubjectMatch(match); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Enable EAP Open SSL Engine for this network. |
| * |
| * @param enable true to set, false otherwise. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapEngine(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setEapEngine"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapEngine(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Open SSL Engine ID for this network. |
| * |
| * @param id value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapEngineID(String id) { |
| synchronized (mLock) { |
| final String methodStr = "setEapEngineID"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapEngineID(id); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set EAP Domain suffix match for this network. |
| * |
| * @param match value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapDomainSuffixMatch(String match) { |
| synchronized (mLock) { |
| final String methodStr = "setEapDomainSuffixMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapDomainSuffixMatch(match); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * This field can be used to enable proactive key caching which is also |
| * known as opportunistic PMKSA caching for WPA2. This is disabled (0) |
| * by default unless default value is changed with the global okc=1 |
| * parameter. |
| * |
| * Proactive key caching is used to make supplicant assume that the APs |
| * are using the same PMK and generate PMKSA cache entries without |
| * doing RSN pre-authentication. This requires support from the AP side |
| * and is normally used with wireless switches that co-locate the |
| * authenticator. |
| * |
| * @param enable true to set, false otherwise. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapProactiveKeyCaching(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setEapProactiveKeyCaching"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setProactiveKeyCaching(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set ID string for this network. |
| * Network identifier string for external scripts. |
| * |
| * @param idString ID string value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setIdStr(String idString) { |
| synchronized (mLock) { |
| final String methodStr = "setIdStr"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setIdStr(idString); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set SAE password for WPA3-Personal |
| * |
| * @param saePassword string with the above option |
| * @return true if successful, false otherwise |
| */ |
| private boolean setSaePassword(String saePassword) { |
| synchronized (mLock) { |
| final String methodStr = "setSaePassword"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setSaePassword(saePassword); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Enable Extensible Authentication (EAP) - Re-authentication Protocol (ERP) for this network. |
| * |
| * @param enable true to set, false otherwise. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setEapErp(boolean enable) { |
| synchronized (mLock) { |
| final String methodStr = "setEapErp"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setEapErp(enable); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get SSID for this network. Result is stored in mSsid. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getSsid() { |
| synchronized (mLock) { |
| final String methodStr = "getSsid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mSsid = mISupplicantStaNetwork.getSsid(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the BSSID set for this network. Result is stored in mBssid. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getBssid() { |
| synchronized (mLock) { |
| final String methodStr = "getBssid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mBssid = mISupplicantStaNetwork.getBssid(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get whether Probe Requests are being sent for this network (hidden). |
| * Result is stored in mScanSsid. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getScanSsid() { |
| synchronized (mLock) { |
| final String methodStr = "getScanSsid"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mScanSsid = mISupplicantStaNetwork.getScanSsid(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the key mgmt mask set for the network. Result is stored in mKeyMgmtMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getKeyMgmt() { |
| synchronized (mLock) { |
| final String methodStr = "getKeyMgmt"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mKeyMgmtMask = mISupplicantStaNetwork.getKeyMgmt(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the proto mask set for the network. Result is stored in mProtoMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getProto() { |
| synchronized (mLock) { |
| final String methodStr = "getProto"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mProtoMask = mISupplicantStaNetwork.getProto(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the auth alg mask set for the network. Result is stored in mAuthAlgMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getAuthAlg() { |
| synchronized (mLock) { |
| final String methodStr = "getAuthAlg"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mAuthAlgMask = mISupplicantStaNetwork.getAuthAlg(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the group cipher mask set for the network. Result is stored in mGroupCipherMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getGroupCipher() { |
| synchronized (mLock) { |
| final String methodStr = "getGroupCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mGroupCipherMask = mISupplicantStaNetwork.getGroupCipher(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get the pairwise cipher mask set for the network. Result is stored in mPairwiseCipherMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getPairwiseCipher() { |
| synchronized (mLock) { |
| final String methodStr = "getPairwiseCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mPairwiseCipherMask = mISupplicantStaNetwork.getPairwiseCipher(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| |
| } |
| |
| /** |
| * Get the group management cipher mask set for the network. Result is stored in |
| * mGroupMgmtCipherMask. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getGroupMgmtCipher() { |
| synchronized (mLock) { |
| final String methodStr = "getGroupMgmtCipher"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mGroupMgmtCipherMask = mISupplicantStaNetwork.getGroupMgmtCipher(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get passphrase for WPA_PSK network. Result is stored in mPskPassphrase if retrieved. |
| * Must return a failure if network has no passphrase set (use |getPsk| if |
| * network was configured with raw psk instead). |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getPskPassphrase() { |
| synchronized (mLock) { |
| final String methodStr = "getPskPassphrase"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mPskPassphrase = mISupplicantStaNetwork.getPskPassphrase(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get SAE password for WPA3-Personal. Result is stored in mSaePassword. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getSaePassword() { |
| synchronized (mLock) { |
| final String methodStr = "getSaePassword"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mSaePassword = mISupplicantStaNetwork.getSaePassword(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get raw psk for WPA_PSK network. Result is stored in mPsk. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getPsk() { |
| synchronized (mLock) { |
| final String methodStr = "getPsk"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mPsk = mISupplicantStaNetwork.getPsk(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get WEP key for WEP network. Result is stored in mWepKey. |
| * |
| * @param keyIdx Index of wep key to be fetched. |
| * Max of |WEP_KEYS_MAX_NUM|. |
| * @return true if successful, false otherwise |
| */ |
| private boolean getWepKey(int keyIdx) { |
| synchronized (mLock) { |
| final String methodStr = "keyIdx"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mWepKey = mISupplicantStaNetwork.getWepKey(keyIdx); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get default Tx key index for WEP network. Result is stored in mWepTxKeyIdx. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getWepTxKeyIdx() { |
| synchronized (mLock) { |
| final String methodStr = "getWepTxKeyIdx"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mWepTxKeyIdx = mISupplicantStaNetwork.getWepTxKeyIdx(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get whether RequirePmf is enabled for this network. Result is stored in mWepTxKeyIdx. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getRequirePmf() { |
| synchronized (mLock) { |
| final String methodStr = "getRequirePmf"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mRequirePmf = mISupplicantStaNetwork.getRequirePmf(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get WAPI certificate suite name set for this network. Result is stored in mWapiCertSuite. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getWapiCertSuite() { |
| synchronized (mLock) { |
| final String methodStr = "getWapiCertSuite"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mWapiCertSuite = mISupplicantStaNetwork.getWapiCertSuite(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Method set for this network. Result is stored in mEapMethod. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapMethod() { |
| synchronized (mLock) { |
| final String methodStr = "getEapMethod"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapMethod = mISupplicantStaNetwork.getEapMethod(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Phase2 Method set for this network. Result is stored in mEapPhase2Method. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapPhase2Method() { |
| synchronized (mLock) { |
| final String methodStr = "getEapPhase2Method"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapPhase2Method = mISupplicantStaNetwork.getEapPhase2Method(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Identity set for this network. Result is stored in mEapIdentity. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapIdentity() { |
| synchronized (mLock) { |
| final String methodStr = "getEapIdentity"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapIdentity = mISupplicantStaNetwork.getEapIdentity(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Anonymous Identity set for this network. Result is stored in mEapAnonymousIdentity. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapAnonymousIdentity() { |
| synchronized (mLock) { |
| final String methodStr = "getEapAnonymousIdentity"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapAnonymousIdentity = mISupplicantStaNetwork.getEapAnonymousIdentity(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Wrapper method for getEapAnonymousIdentity(). Gets the anonymous identity |
| * from supplicant and returns it as a string. |
| * |
| * @return anonymous identity string if successful, null otherwise. |
| */ |
| public String fetchEapAnonymousIdentity() { |
| synchronized (mLock) { |
| if (!getEapAnonymousIdentity()) { |
| return null; |
| } |
| return NativeUtil.stringFromByteArray(mEapAnonymousIdentity); |
| } |
| } |
| |
| /** |
| * Get EAP Password set for this network. Result is stored in mEapPassword. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapPassword() { |
| synchronized (mLock) { |
| final String methodStr = "getEapPassword"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapPassword = mISupplicantStaNetwork.getEapPassword(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP CA certificate file path set for this network. Result is stored in mEapCACert. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapCACert() { |
| synchronized (mLock) { |
| final String methodStr = "getEapCACert"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapCACert = mISupplicantStaNetwork.getEapCACert(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP CA certificate directory path set for this network. Result is stored in mEapCAPath. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapCAPath() { |
| synchronized (mLock) { |
| final String methodStr = "getEapCAPath"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapCAPath = mISupplicantStaNetwork.getEapCAPath(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Client certificate file path set for this network. |
| * Result is stored in mEapClientCert. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapClientCert() { |
| synchronized (mLock) { |
| final String methodStr = "getEapClientCert"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapClientCert = mISupplicantStaNetwork.getEapClientCert(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP private key Id set for this network. Result is stored in mEapPrivateKeyId. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapPrivateKeyId() { |
| synchronized (mLock) { |
| final String methodStr = "getEapPrivateKeyId"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapPrivateKeyId = mISupplicantStaNetwork.getEapPrivateKeyId(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP subject match set for this network. Result is stored in mEapSubjectMatch. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapSubjectMatch() { |
| synchronized (mLock) { |
| final String methodStr = "getEapSubjectMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapSubjectMatch = mISupplicantStaNetwork.getEapSubjectMatch(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Alt subject match set for this network. Result is stored in mEapAltSubjectMatch. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapAltSubjectMatch() { |
| synchronized (mLock) { |
| final String methodStr = "getEapAltSubjectMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapAltSubjectMatch = mISupplicantStaNetwork.getEapAltSubjectMatch(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get whether EAP Open SSL Engine is enabled for this network. Result is stored in mEapEngine. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapEngine() { |
| synchronized (mLock) { |
| final String methodStr = "getEapEngine"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapEngine = mISupplicantStaNetwork.getEapEngine(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Open SSL Engine ID set for this network. Result is stored in mEapEngineID. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapEngineId() { |
| synchronized (mLock) { |
| final String methodStr = "getEapEngineId"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapEngineID = mISupplicantStaNetwork.getEapEngineId(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get EAP Domain suffix match set for this network. Result is stored in mEapDomainSuffixMatch. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getEapDomainSuffixMatch() { |
| synchronized (mLock) { |
| final String methodStr = "getEapDomainSuffixMatch"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mEapDomainSuffixMatch = mISupplicantStaNetwork.getEapDomainSuffixMatch(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get ID string set for this network. Network identifier string for external scripts. |
| * Result is stored in mIdStr. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getIdStr() { |
| synchronized (mLock) { |
| final String methodStr = "getIdStr"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mIdStr = mISupplicantStaNetwork.getIdStr(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Enable the network for connection purposes. |
| * |
| * This must trigger a connection to the network if: |
| * a) |noConnect| is false, and |
| * b) This is the only network configured, and |
| * c) Is visible in the current scan results. |
| * |
| * @param noConnect Only enable the network, don't trigger a connect. |
| * @return true if successful, false otherwise |
| */ |
| public boolean enable(boolean noConnect) { |
| synchronized (mLock) { |
| final String methodStr = "enable"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.enable(noConnect); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Disable the network for connection purposes. |
| * This must trigger a disconnection from the network, if currently |
| * connected to this one. |
| * |
| * @return true if successful, false otherwise |
| */ |
| public boolean disable() { |
| synchronized (mLock) { |
| final String methodStr = "disable"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.disable(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Trigger a connection to this network. |
| * |
| * @return true if it succeeds, false otherwise. |
| */ |
| public boolean select() { |
| synchronized (mLock) { |
| final String methodStr = "select"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.select(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send GSM auth response. |
| * |
| * @param paramsStr Response params as a string. |
| * @return true if succeeds, false otherwise. |
| */ |
| public boolean sendNetworkEapSimGsmAuthResponse(String paramsStr) { |
| synchronized (mLock) { |
| try { |
| Matcher match = GSM_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); |
| ArrayList<NetworkResponseEapSimGsmAuthParams> params = new ArrayList<>(); |
| while (match.find()) { |
| if (match.groupCount() != 2) { |
| Log.e(TAG, "Malformed gsm auth response params: " + paramsStr); |
| return false; |
| } |
| NetworkResponseEapSimGsmAuthParams param = |
| new NetworkResponseEapSimGsmAuthParams(); |
| param.kc = new byte[8]; |
| param.sres = new byte[4]; |
| byte[] kc = NativeUtil.hexStringToByteArray(match.group(1)); |
| if (kc == null || kc.length != param.kc.length) { |
| Log.e(TAG, "Invalid kc value: " + match.group(1)); |
| return false; |
| } |
| byte[] sres = NativeUtil.hexStringToByteArray(match.group(2)); |
| if (sres == null || sres.length != param.sres.length) { |
| Log.e(TAG, "Invalid sres value: " + match.group(2)); |
| return false; |
| } |
| System.arraycopy(kc, 0, param.kc, 0, param.kc.length); |
| System.arraycopy(sres, 0, param.sres, 0, param.sres.length); |
| params.add(param); |
| } |
| // The number of kc/sres pairs can either be 2 or 3 depending on the request. |
| if (params.size() > 3 || params.size() < 2) { |
| Log.e(TAG, "Malformed gsm auth response params: " + paramsStr); |
| return false; |
| } |
| NetworkResponseEapSimGsmAuthParams[] paramsArr = |
| new NetworkResponseEapSimGsmAuthParams[params.size()]; |
| for (int i = 0; i < params.size(); i++) { |
| paramsArr[i] = params.get(i); |
| } |
| return sendNetworkEapSimGsmAuthResponse(paramsArr); |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "Illegal argument " + paramsStr, e); |
| return false; |
| } |
| } |
| } |
| |
| private boolean sendNetworkEapSimGsmAuthResponse( |
| NetworkResponseEapSimGsmAuthParams[] params) { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapSimGsmAuthResponse"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapSimGsmAuthResponse(params); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send GSM auth failure. |
| * |
| * @return true if successful, false otherwise |
| */ |
| public boolean sendNetworkEapSimGsmAuthFailure() { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapSimGsmAuthFailure"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapSimGsmAuthFailure(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send UMTS auth response. |
| * |
| * @param paramsStr Response params as a string. |
| * @return true if succeeds, false otherwise. |
| */ |
| public boolean sendNetworkEapSimUmtsAuthResponse(String paramsStr) { |
| synchronized (mLock) { |
| try { |
| Matcher match = UMTS_AUTH_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); |
| if (!match.find() || match.groupCount() != 3) { |
| Log.e(TAG, "Malformed umts auth response params: " + paramsStr); |
| return false; |
| } |
| NetworkResponseEapSimUmtsAuthParams params = |
| new NetworkResponseEapSimUmtsAuthParams(); |
| params.ik = new byte[16]; |
| params.ck = new byte[16]; |
| byte[] ik = NativeUtil.hexStringToByteArray(match.group(1)); |
| if (ik == null || ik.length != params.ik.length) { |
| Log.e(TAG, "Invalid ik value: " + match.group(1)); |
| return false; |
| } |
| byte[] ck = NativeUtil.hexStringToByteArray(match.group(2)); |
| if (ck == null || ck.length != params.ck.length) { |
| Log.e(TAG, "Invalid ck value: " + match.group(2)); |
| return false; |
| } |
| byte[] res = NativeUtil.hexStringToByteArray(match.group(3)); |
| if (res == null || res.length == 0) { |
| Log.e(TAG, "Invalid res value: " + match.group(3)); |
| return false; |
| } |
| params.res = new byte[res.length]; |
| System.arraycopy(ik, 0, params.ik, 0, params.ik.length); |
| System.arraycopy(ck, 0, params.ck, 0, params.ck.length); |
| System.arraycopy(res, 0, params.res, 0, params.res.length); |
| return sendNetworkEapSimUmtsAuthResponse(params); |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "Illegal argument " + paramsStr, e); |
| return false; |
| } |
| } |
| } |
| |
| private boolean sendNetworkEapSimUmtsAuthResponse( |
| NetworkResponseEapSimUmtsAuthParams params) { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapSimUmtsAuthResponse"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthResponse(params); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send UMTS auts response. |
| * |
| * @param paramsStr Response params as a string. |
| * @return true if succeeds, false otherwise. |
| */ |
| public boolean sendNetworkEapSimUmtsAutsResponse(String paramsStr) { |
| synchronized (mLock) { |
| try { |
| Matcher match = UMTS_AUTS_RESPONSE_PARAMS_PATTERN.matcher(paramsStr); |
| if (!match.find() || match.groupCount() != 1) { |
| Log.e(TAG, "Malformed umts auts response params: " + paramsStr); |
| return false; |
| } |
| byte[] auts = NativeUtil.hexStringToByteArray(match.group(1)); |
| if (auts == null || auts.length != 14) { |
| Log.e(TAG, "Invalid auts value: " + match.group(1)); |
| return false; |
| } |
| return sendNetworkEapSimUmtsAutsResponse(auts); |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "Illegal argument " + paramsStr, e); |
| return false; |
| } |
| } |
| } |
| |
| private boolean sendNetworkEapSimUmtsAutsResponse(byte[/* 14 */] auts) { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapSimUmtsAutsResponse"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapSimUmtsAutsResponse(auts); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send UMTS auth failure. |
| * |
| * @return true if successful, false otherwise |
| */ |
| public boolean sendNetworkEapSimUmtsAuthFailure() { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapSimUmtsAuthFailure"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapSimUmtsAuthFailure(); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Send eap identity response. |
| * |
| * @param identityStr identity used for EAP-Identity |
| * @param encryptedIdentityStr encrypted identity used for EAP-AKA/EAP-SIM |
| * @return true if succeeds, false otherwise. |
| */ |
| public boolean sendNetworkEapIdentityResponse(String identityStr, |
| String encryptedIdentityStr) { |
| synchronized (mLock) { |
| try { |
| byte[] unencryptedIdentity = NativeUtil.stringToByteArray(identityStr); |
| byte[] encryptedIdentity = new byte[0]; |
| if (!TextUtils.isEmpty(encryptedIdentityStr)) { |
| encryptedIdentity = NativeUtil.stringToByteArray(encryptedIdentityStr); |
| } |
| return sendNetworkEapIdentityResponse(unencryptedIdentity, encryptedIdentity); |
| } catch (IllegalArgumentException e) { |
| Log.e(TAG, "Illegal argument " + identityStr + "," + encryptedIdentityStr, e); |
| return false; |
| } |
| } |
| } |
| |
| private boolean sendNetworkEapIdentityResponse(byte[] unencryptedIdentity, |
| byte[] encryptedIdentity) { |
| synchronized (mLock) { |
| final String methodStr = "sendNetworkEapIdentityResponse"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.sendNetworkEapIdentityResponse( |
| unencryptedIdentity, encryptedIdentity); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set OCSP (Online Certificate Status Protocol) type for this network. |
| * |
| * @param ocsp value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setOcsp(@WifiEnterpriseConfig.Ocsp int ocsp) { |
| synchronized (mLock) { |
| final String methodStr = "setOcsp"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| |
| int halOcspValue = OcspType.NONE; |
| switch (ocsp) { |
| case WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS: |
| halOcspValue = OcspType.REQUEST_CERT_STATUS; |
| break; |
| case WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS: |
| halOcspValue = OcspType.REQUIRE_CERT_STATUS; |
| break; |
| case WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS: |
| halOcspValue = OcspType.REQUIRE_ALL_CERTS_STATUS; |
| break; |
| } |
| |
| try { |
| mISupplicantStaNetwork.setOcsp(halOcspValue); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Get OCSP (Online Certificate Status Protocol) type for this network. Value stored in mOcsp. |
| * |
| * @return true if successful, false otherwise |
| */ |
| private boolean getOcsp() { |
| synchronized (mLock) { |
| final String methodStr = "getOcsp"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| |
| try { |
| int halOcspValue = mISupplicantStaNetwork.getOcsp(); |
| mOcsp = WifiEnterpriseConfig.OCSP_NONE; |
| switch (halOcspValue) { |
| case OcspType.REQUEST_CERT_STATUS: |
| mOcsp = WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS; |
| break; |
| case OcspType.REQUIRE_CERT_STATUS: |
| mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS; |
| break; |
| case OcspType.REQUIRE_ALL_CERTS_STATUS: |
| mOcsp = WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS; |
| break; |
| default: |
| Log.e(TAG, "Invalid HAL OCSP value " + halOcspValue); |
| break; |
| } |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Add a pairwise master key (PMK) into supplicant PMK cache. |
| * |
| * @param serializedEntry is serialized PMK cache entry, the content is |
| * opaque for the framework and depends on the native implementation. |
| * @return true if successful, false otherwise |
| */ |
| public boolean setPmkCache(byte[] serializedEntry) { |
| synchronized (mLock) { |
| final String methodStr = "setPmkCache"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setPmkCache(serializedEntry); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Set SAE H2E (Hash-to-Element) mode. |
| * |
| * @param mode SAE H2E supporting mode. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setSaeH2eMode(byte mode) { |
| synchronized (mLock) { |
| final String methodStr = "setSaeH2eMode"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| try { |
| mISupplicantStaNetwork.setSaeH2eMode(mode); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| |
| /** |
| * Retrieve the NFC token for this network. |
| * |
| * @return Hex string corresponding to the NFC token or null for failure. |
| */ |
| public String getWpsNfcConfigurationToken() { |
| synchronized (mLock) { |
| byte[] token = getWpsNfcConfigurationTokenInternal(); |
| if (token == null) { |
| return null; |
| } |
| return NativeUtil.hexStringFromByteArray(token); |
| } |
| } |
| |
| private byte[] getWpsNfcConfigurationTokenInternal() { |
| synchronized (mLock) { |
| final String methodStr = "getWpsNfcConfigurationToken"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return null; |
| } |
| try { |
| return mISupplicantStaNetwork.getWpsNfcConfigurationToken(); |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return null; |
| } |
| } |
| |
| private String getTag() { |
| synchronized (mLock) { |
| return TAG + "[" + mIfaceName + "]"; |
| } |
| } |
| |
| /** |
| * Helper function to log callbacks. |
| */ |
| protected void logCallback(final String methodStr) { |
| synchronized (mLock) { |
| if (mVerboseLoggingEnabled) { |
| Log.d(TAG, "ISupplicantStaNetworkCallback." + methodStr + " received"); |
| } |
| } |
| } |
| |
| /** |
| * Returns false if mISupplicantStaNetwork is null, and logs failure containing methodStr |
| */ |
| private boolean checkStaNetworkAndLogFailure(final String methodStr) { |
| synchronized (mLock) { |
| if (mISupplicantStaNetwork == null) { |
| Log.e(TAG, "Can't call " + methodStr + ", ISupplicantStaNetwork is null"); |
| return false; |
| } |
| return true; |
| } |
| } |
| |
| private void handleRemoteException(RemoteException e, String methodStr) { |
| synchronized (mLock) { |
| mISupplicantStaNetwork = null; |
| Log.e(TAG, |
| "ISupplicantStaNetwork." + methodStr + " failed with remote exception: ", e); |
| } |
| } |
| |
| private void handleServiceSpecificException(ServiceSpecificException e, String methodStr) { |
| synchronized (mLock) { |
| Log.e(TAG, "ISupplicantStaNetwork." + methodStr + " failed with " |
| + "service specific exception: ", e); |
| } |
| } |
| |
| /** |
| * Adds FT flags for networks if the device supports it. |
| */ |
| private BitSet addFastTransitionFlags(BitSet keyManagementFlags) { |
| synchronized (mLock) { |
| if (!mContext.getResources().getBoolean( |
| R.bool.config_wifi_fast_bss_transition_enabled)) { |
| return keyManagementFlags; |
| } |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_PSK); |
| } |
| if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) { |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.FT_EAP); |
| } |
| return modifiedFlags; |
| } |
| } |
| |
| /** |
| * Removes FT flags for networks if the device supports it. |
| */ |
| private BitSet removeFastTransitionFlags(BitSet keyManagementFlags) { |
| synchronized (mLock) { |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_PSK); |
| modifiedFlags.clear(WifiConfiguration.KeyMgmt.FT_EAP); |
| return modifiedFlags; |
| } |
| } |
| |
| /** |
| * Adds SHA256 key management flags for networks. |
| */ |
| private BitSet addSha256KeyMgmtFlags(BitSet keyManagementFlags) { |
| synchronized (mLock) { |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK)) { |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); |
| } |
| if (keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_EAP)) { |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); |
| } |
| return modifiedFlags; |
| } |
| } |
| |
| /** |
| * Removes SHA256 key management flags for networks. |
| */ |
| private BitSet removeSha256KeyMgmtFlags(BitSet keyManagementFlags) { |
| synchronized (mLock) { |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_PSK_SHA256); |
| modifiedFlags.clear(WifiConfiguration.KeyMgmt.WPA_EAP_SHA256); |
| return modifiedFlags; |
| } |
| } |
| |
| /** |
| * Update PMF requirement if auto-upgrade offload is supported. |
| * |
| * If SAE auto-upgrade offload is supported and this config enables |
| * both PSK and SAE, do not set PMF requirement to |
| * mandatory to allow the device to roam between PSK and SAE BSSes. |
| * wpa_supplicant will set PMF requirement to optional by default. |
| */ |
| private boolean getOptimalPmfSettingForConfig(WifiConfiguration config, |
| boolean isPmfRequiredFromSelectedSecurityParams) { |
| if (config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK) |
| && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled() |
| && config.isSecurityType(WifiConfiguration.SECURITY_TYPE_SAE) |
| && config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_SAE).isEnabled() |
| && mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) { |
| if (mVerboseLoggingEnabled) { |
| Log.d(TAG, "Keep optional PMF for SAE auto-upgrade offload."); |
| } |
| return false; |
| } |
| return isPmfRequiredFromSelectedSecurityParams; |
| } |
| |
| /** |
| * Adds both PSK and SAE AKM if auto-upgrade offload is supported. |
| */ |
| private BitSet addPskSaeUpgradableTypeFlagsIfSupported( |
| WifiConfiguration config, BitSet keyManagementFlags) { |
| synchronized (mLock) { |
| if (!config.isSecurityType(WifiConfiguration.SECURITY_TYPE_PSK) |
| || !config.getSecurityParams(WifiConfiguration.SECURITY_TYPE_PSK).isEnabled() |
| || !mWifiGlobals.isWpa3SaeUpgradeOffloadEnabled()) { |
| return keyManagementFlags; |
| } |
| |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.WPA_PSK); |
| modifiedFlags.set(WifiConfiguration.KeyMgmt.SAE); |
| return modifiedFlags; |
| } |
| } |
| |
| /** |
| * Removes SAE AKM when PSK and SAE AKM are both set, it only happens when |
| * auto-upgrade offload is supported. |
| */ |
| private BitSet removePskSaeUpgradableTypeFlags(BitSet keyManagementFlags) { |
| if (!keyManagementFlags.get(WifiConfiguration.KeyMgmt.WPA_PSK) |
| || !keyManagementFlags.get(WifiConfiguration.KeyMgmt.SAE)) { |
| return keyManagementFlags; |
| } |
| BitSet modifiedFlags = (BitSet) keyManagementFlags.clone(); |
| modifiedFlags.clear(WifiConfiguration.KeyMgmt.SAE); |
| return modifiedFlags; |
| } |
| |
| /** |
| * Creates the JSON encoded network extra using the map of string key, value pairs. |
| */ |
| public static String createNetworkExtra(Map<String, String> values) { |
| final String encoded; |
| try { |
| encoded = URLEncoder.encode(new JSONObject(values).toString(), "UTF-8"); |
| } catch (NullPointerException e) { |
| Log.e(TAG, "Unable to serialize networkExtra: " + e.toString()); |
| return null; |
| } catch (UnsupportedEncodingException e) { |
| Log.e(TAG, "Unable to serialize networkExtra: " + e.toString()); |
| return null; |
| } |
| return encoded; |
| } |
| |
| /** |
| * Parse the network extra JSON encoded string to a map of string key, value pairs. |
| */ |
| public static Map<String, String> parseNetworkExtra(String encoded) { |
| if (TextUtils.isEmpty(encoded)) { |
| return null; |
| } |
| try { |
| // This method reads a JSON dictionary that was written by setNetworkExtra(). However, |
| // on devices that upgraded from Marshmallow, it may encounter a legacy value instead - |
| // an FQDN stored as a plain string. If such a value is encountered, the JSONObject |
| // constructor will thrown a JSONException and the method will return null. |
| final JSONObject json = new JSONObject(URLDecoder.decode(encoded, "UTF-8")); |
| final Map<String, String> values = new HashMap<>(); |
| final Iterator<?> it = json.keys(); |
| while (it.hasNext()) { |
| final String key = (String) it.next(); |
| final Object value = json.get(key); |
| if (value instanceof String) { |
| values.put(key, (String) value); |
| } |
| } |
| return values; |
| } catch (UnsupportedEncodingException e) { |
| Log.e(TAG, "Unable to deserialize networkExtra: " + e.toString()); |
| return null; |
| } catch (JSONException e) { |
| // This is not necessarily an error. This exception will also occur if we encounter a |
| // legacy FQDN stored as a plain string. We want to return null in this case as no JSON |
| // dictionary of extras was found. |
| return null; |
| } |
| } |
| |
| /** |
| * Returns a big-endian representation of {@code rcoi} in an 3 or 5-element byte array. |
| */ |
| private static byte[] rcoiToByteArray(long rcoi) { |
| // An RCOI is either 3- or 5-octet array, IEEE Std 802.11, section 9.4.1.31: Organization |
| // Identifier field |
| int arraySize = 3; |
| rcoi &= 0xffffffffffL; |
| if ((rcoi & 0xffff000000L) != 0) { |
| // This is a 5-octet RCOI |
| arraySize = 5; |
| } |
| |
| byte[] result = new byte[arraySize]; |
| for (int i = arraySize - 1; i >= 0; i--) { |
| result[i] = (byte) (rcoi & 0xffL); |
| rcoi >>= 8; |
| } |
| return result; |
| } |
| |
| /** |
| * Set the selected RCOI for this Passpoint network. |
| * |
| * @param selectedRcoi value to set. |
| * @return true if successful, false otherwise |
| */ |
| private boolean setSelectedRcoi(long selectedRcoi) { |
| if (selectedRcoi == 0) { |
| // Nothing to set |
| return true; |
| } |
| synchronized (mLock) { |
| final String methodStr = "setSelectedRcoi"; |
| if (!checkStaNetworkAndLogFailure(methodStr)) { |
| return false; |
| } |
| |
| try { |
| mISupplicantStaNetwork |
| .setRoamingConsortiumSelection(rcoiToByteArray(selectedRcoi)); |
| return true; |
| } catch (RemoteException e) { |
| handleRemoteException(e, methodStr); |
| } catch (ServiceSpecificException e) { |
| handleServiceSpecificException(e, methodStr); |
| } |
| return false; |
| } |
| } |
| } |