Loading api/current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -29131,15 +29131,18 @@ package android.net.wifi { method public android.net.wifi.WifiNetworkSuggestion buildNetworkSuggestion(); method public android.net.wifi.WifiNetworkConfigBuilder setBssid(android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setBssidPattern(android.net.MacAddress, android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setIsAppInteractionRequired(); method public android.net.wifi.WifiNetworkConfigBuilder setIsEnhancedOpen(); method public android.net.wifi.WifiNetworkConfigBuilder setIsHiddenSsid(); method public android.net.wifi.WifiNetworkConfigBuilder setIsMetered(); method public android.net.wifi.WifiNetworkConfigBuilder setIsUserInteractionRequired(); method public android.net.wifi.WifiNetworkConfigBuilder setPriority(int); method public android.net.wifi.WifiNetworkConfigBuilder setPskPassphrase(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsid(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsidPattern(android.os.PatternMatcher); method public android.net.wifi.WifiNetworkConfigBuilder setWpa2EnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setWpa2Passphrase(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setWpa3EnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setWpa3Passphrase(java.lang.String); } public final class WifiNetworkSuggestion implements android.os.Parcelable { wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java +122 −36 Original line number Diff line number Diff line Loading @@ -59,15 +59,28 @@ public class WifiNetworkConfigBuilder { * Pair of <BaseAddress, Mask>. */ private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher; /** * Whether this is an OWE network or not. */ private boolean mIsEnhancedOpen; /** * Pre-shared key for use with WPA-PSK networks. */ private @Nullable String mPskPassphrase; private @Nullable String mWpa2PskPassphrase; /** * Pre-shared key for use with WPA3-SAE networks. */ private @Nullable String mWpa3SaePassphrase; /** * The enterprise configuration details specifying the EAP method, * certificates and other settings associated with the WPA-EAP networks. */ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig; /** * The enterprise configuration details specifying the EAP method, * certificates and other settings associated with the EAP. * certificates and other settings associated with the SuiteB networks. */ private @Nullable WifiEnterpriseConfig mEnterpriseConfig; private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig; /** * This is a network that does not broadcast its SSID, so an * SSID-specific probe request must be used for scans. Loading @@ -94,8 +107,11 @@ public class WifiNetworkConfigBuilder { public WifiNetworkConfigBuilder() { mSsidPatternMatcher = null; mBssidPatternMatcher = null; mPskPassphrase = null; mEnterpriseConfig = null; mIsEnhancedOpen = false; mWpa2PskPassphrase = null; mWpa3SaePassphrase = null; mWpa2EnterpriseConfig = null; mWpa3EnterpriseConfig = null; mIsHiddenSSID = false; mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; Loading Loading @@ -188,36 +204,81 @@ public class WifiNetworkConfigBuilder { } /** * Set the ASCII PSK passphrase for this network. Needed for authenticating to * WPA_PSK networks. * Specifies whether this represents an Enhanced Open (OWE) network. * * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setIsEnhancedOpen() { mIsEnhancedOpen = true; return this; } /** * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to * WPA2-PSK networks. * * @param passphrase passphrase of the network. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. * @throws IllegalArgumentException if the passphrase is not ASCII encodable. */ public WifiNetworkConfigBuilder setWpa2Passphrase(@NonNull String passphrase) { checkNotNull(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } mWpa2PskPassphrase = passphrase; return this; } /** * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to * WPA3-SAE networks. * * @param pskPassphrase PSK passphrase of the network. * @param passphrase passphrase of the network. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. * @throws IllegalArgumentException if the passphrase is not ASCII encodable. */ public WifiNetworkConfigBuilder setPskPassphrase(@NonNull String pskPassphrase) { checkNotNull(pskPassphrase); public WifiNetworkConfigBuilder setWpa3Passphrase(@NonNull String passphrase) { checkNotNull(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(pskPassphrase)) { if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } mPskPassphrase = pskPassphrase; mWpa3SaePassphrase = passphrase; return this; } /** * Set the associated enterprise configuration for this network. Needed for authenticating to * WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description. * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setWpa2EnterpriseConfig( @NonNull WifiEnterpriseConfig enterpriseConfig) { checkNotNull(enterpriseConfig); mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); return this; } /** * Set the associated enterprise configuration for this network. Needed for authenticating to * WPA_EAP networks. See {@link WifiEnterpriseConfig} for description. * WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description. * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setEnterpriseConfig( public WifiNetworkConfigBuilder setWpa3EnterpriseConfig( @NonNull WifiEnterpriseConfig enterpriseConfig) { checkNotNull(enterpriseConfig); mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); return this; } Loading Loading @@ -324,16 +385,38 @@ public class WifiNetworkConfigBuilder { configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); } private void setKeyMgmtInWifiConfiguration(@NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mPskPassphrase)) { // WPA_PSK network. private void setSecurityParamsInWifiConfiguration(@NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); } else if (mEnterpriseConfig != null) { // WPA_EAP network // WifiConfiguration.preSharedKey needs quotes around ASCII password. configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\""; } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); // PMF mandatory for SAE. configuration.requirePMF = true; // WifiConfiguration.preSharedKey needs quotes around ASCII password. configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\""; } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); } else { // Open network configuration.enterpriseConfig = mWpa2EnterpriseConfig; } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); // TODO (b/113878056): Verify these params once we verify SuiteB configuration. configuration.allowedGroupMgmtCiphers.set( WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); configuration.allowedSuiteBCiphers.set( WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); configuration.allowedSuiteBCiphers.set( WifiConfiguration.SuiteBCipher.ECDHE_RSA); configuration.requirePMF = true; configuration.enterpriseConfig = mWpa3EnterpriseConfig; } else if (mIsEnhancedOpen) { // OWE network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); // PMF mandatory. configuration.requirePMF = true; } else { // Open network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } } Loading @@ -349,12 +432,7 @@ public class WifiNetworkConfigBuilder { if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) { wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\""; } setKeyMgmtInWifiConfiguration(wifiConfiguration); // WifiConfiguration.preSharedKey needs quotes around ASCII password. if (mPskPassphrase != null) { wifiConfiguration.preSharedKey = "\"" + mPskPassphrase + "\""; } wifiConfiguration.enterpriseConfig = mEnterpriseConfig; setSecurityParamsInWifiConfiguration(wifiConfiguration); wifiConfiguration.hiddenSSID = mIsHiddenSSID; wifiConfiguration.priority = mPriority; wifiConfiguration.meteredOverride = Loading Loading @@ -396,6 +474,20 @@ public class WifiNetworkConfigBuilder { return false; } private void validateSecurityParams() { int numSecurityTypes = 0; numSecurityTypes += mIsEnhancedOpen ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0; numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0; numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0; if (numSecurityTypes > 1) { throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase," + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig" + " can be invoked for network specifier"); } } /** * Create a specifier object used to request a Wi-Fi network. The generated * {@link NetworkSpecifier} should be used in Loading Loading @@ -464,10 +556,7 @@ public class WifiNetworkConfigBuilder { + "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for " + "specifier"); } if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + " be invoked for network specifier"); } validateSecurityParams(); return new WifiNetworkSpecifier( mSsidPatternMatcher, Loading @@ -493,10 +582,7 @@ public class WifiNetworkConfigBuilder { throw new IllegalStateException("none of setSsidPattern/setBssidPattern/setBssid are" + " allowed for suggestion"); } if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + "be invoked for suggestion"); } validateSecurityParams(); return new WifiNetworkSuggestion( buildWifiConfiguration(), Loading wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java +129 −16 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; Loading Loading @@ -81,11 +82,11 @@ public class WifiNetworkConfigBuilderTest { * pattern. */ @Test public void testWifiNetworkSpecifierBuilderForWpaPskNetworkWithBssidPattern() { public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() { NetworkSpecifier specifier = new WifiNetworkConfigBuilder() .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .buildNetworkSpecifier(); assertTrue(specifier instanceof WifiNetworkSpecifier); Loading Loading @@ -119,7 +120,7 @@ public class WifiNetworkConfigBuilderTest { * SSID and BSSID pattern. */ @Test public void testWifiNetworkSpecifierBuilderForEnterpriseHiddenNetworkWithSsidAndBssid() { public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); Loading @@ -127,7 +128,7 @@ public class WifiNetworkConfigBuilderTest { NetworkSpecifier specifier = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setBssid(MacAddress.fromString(TEST_BSSID)) .setEnterpriseConfig(enterpriseConfig) .setWpa2EnterpriseConfig(enterpriseConfig) .setIsHiddenSsid() .buildNetworkSpecifier(); Loading Loading @@ -174,14 +175,14 @@ public class WifiNetworkConfigBuilderTest { } /** * Ensure {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} throws an exception * Ensure {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} throws an exception * when the string is not ASCII encodable. */ @Test(expected = IllegalArgumentException.class) public void testSetPskPassphraseWithNonAsciiString() { public void testSetWpa2PasphraseWithNonAsciiString() { new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase("salvē") .setWpa2Passphrase("salvē") .buildNetworkSpecifier(); } Loading Loading @@ -275,15 +276,15 @@ public class WifiNetworkConfigBuilderTest { /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} and * {@link WifiNetworkConfigBuilder#setEnterpriseConfig(WifiEnterpriseConfig)} are invoked. * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothPskPassphraseAndEnterpriseConfig() { public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setPskPassphrase(TEST_PRESHARED_KEY) .setEnterpriseConfig(new WifiEnterpriseConfig()) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) .buildNetworkSpecifier(); } Loading Loading @@ -375,10 +376,11 @@ public class WifiNetworkConfigBuilderTest { * app interaction and has a priority of zero set. */ @Test public void testWifiNetworkSuggestionBuilderForWpaEapNetworkWithPriorityAndReqAppInteraction() { public void testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired() .setPriority(0) .buildNetworkSuggestion(); Loading @@ -401,10 +403,11 @@ public class WifiNetworkConfigBuilderTest { * user interaction and is metered. */ @Test public void testWifiNetworkSuggestionBuilderForWpaPskNetworkWithMeteredAndReqUserInteraction() { public void testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsUserInteractionRequired() .setIsMetered() .buildNetworkSuggestion(); Loading @@ -421,6 +424,74 @@ public class WifiNetworkConfigBuilderTest { assertEquals(-1, suggestion.wifiConfiguration.priority); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for OWE network. */ @Test public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetwork() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setIsEnhancedOpen() .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SAE network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.SAE)); assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SuiteB network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setWpa3EnterpriseConfig(enterpriseConfig) .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers .get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(suggestion.wifiConfiguration.allowedGroupMgmtCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers .get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)); assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers .get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)); assertTrue(suggestion.wifiConfiguration.requirePMF); assertNull(suggestion.wifiConfiguration.preSharedKey); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception * when {@link WifiNetworkConfigBuilder#setSsidPattern(PatternMatcher)} is set. Loading Loading @@ -478,4 +549,46 @@ public class WifiNetworkConfigBuilderTest { .setPriority(-1) .buildNetworkSuggestion(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setWpa3Passphrase(TEST_PRESHARED_KEY) .buildNetworkSpecifier(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) .buildNetworkSpecifier(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setIsEnhancedOpen(} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setIsEnhancedOpen() .buildNetworkSpecifier(); } } Loading
api/current.txt +5 −2 Original line number Diff line number Diff line Loading @@ -29131,15 +29131,18 @@ package android.net.wifi { method public android.net.wifi.WifiNetworkSuggestion buildNetworkSuggestion(); method public android.net.wifi.WifiNetworkConfigBuilder setBssid(android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setBssidPattern(android.net.MacAddress, android.net.MacAddress); method public android.net.wifi.WifiNetworkConfigBuilder setEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setIsAppInteractionRequired(); method public android.net.wifi.WifiNetworkConfigBuilder setIsEnhancedOpen(); method public android.net.wifi.WifiNetworkConfigBuilder setIsHiddenSsid(); method public android.net.wifi.WifiNetworkConfigBuilder setIsMetered(); method public android.net.wifi.WifiNetworkConfigBuilder setIsUserInteractionRequired(); method public android.net.wifi.WifiNetworkConfigBuilder setPriority(int); method public android.net.wifi.WifiNetworkConfigBuilder setPskPassphrase(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsid(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setSsidPattern(android.os.PatternMatcher); method public android.net.wifi.WifiNetworkConfigBuilder setWpa2EnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setWpa2Passphrase(java.lang.String); method public android.net.wifi.WifiNetworkConfigBuilder setWpa3EnterpriseConfig(android.net.wifi.WifiEnterpriseConfig); method public android.net.wifi.WifiNetworkConfigBuilder setWpa3Passphrase(java.lang.String); } public final class WifiNetworkSuggestion implements android.os.Parcelable {
wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java +122 −36 Original line number Diff line number Diff line Loading @@ -59,15 +59,28 @@ public class WifiNetworkConfigBuilder { * Pair of <BaseAddress, Mask>. */ private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher; /** * Whether this is an OWE network or not. */ private boolean mIsEnhancedOpen; /** * Pre-shared key for use with WPA-PSK networks. */ private @Nullable String mPskPassphrase; private @Nullable String mWpa2PskPassphrase; /** * Pre-shared key for use with WPA3-SAE networks. */ private @Nullable String mWpa3SaePassphrase; /** * The enterprise configuration details specifying the EAP method, * certificates and other settings associated with the WPA-EAP networks. */ private @Nullable WifiEnterpriseConfig mWpa2EnterpriseConfig; /** * The enterprise configuration details specifying the EAP method, * certificates and other settings associated with the EAP. * certificates and other settings associated with the SuiteB networks. */ private @Nullable WifiEnterpriseConfig mEnterpriseConfig; private @Nullable WifiEnterpriseConfig mWpa3EnterpriseConfig; /** * This is a network that does not broadcast its SSID, so an * SSID-specific probe request must be used for scans. Loading @@ -94,8 +107,11 @@ public class WifiNetworkConfigBuilder { public WifiNetworkConfigBuilder() { mSsidPatternMatcher = null; mBssidPatternMatcher = null; mPskPassphrase = null; mEnterpriseConfig = null; mIsEnhancedOpen = false; mWpa2PskPassphrase = null; mWpa3SaePassphrase = null; mWpa2EnterpriseConfig = null; mWpa3EnterpriseConfig = null; mIsHiddenSSID = false; mIsAppInteractionRequired = false; mIsUserInteractionRequired = false; Loading Loading @@ -188,36 +204,81 @@ public class WifiNetworkConfigBuilder { } /** * Set the ASCII PSK passphrase for this network. Needed for authenticating to * WPA_PSK networks. * Specifies whether this represents an Enhanced Open (OWE) network. * * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setIsEnhancedOpen() { mIsEnhancedOpen = true; return this; } /** * Set the ASCII WPA2 passphrase for this network. Needed for authenticating to * WPA2-PSK networks. * * @param passphrase passphrase of the network. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. * @throws IllegalArgumentException if the passphrase is not ASCII encodable. */ public WifiNetworkConfigBuilder setWpa2Passphrase(@NonNull String passphrase) { checkNotNull(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } mWpa2PskPassphrase = passphrase; return this; } /** * Set the ASCII WPA3 passphrase for this network. Needed for authenticating to * WPA3-SAE networks. * * @param pskPassphrase PSK passphrase of the network. * @param passphrase passphrase of the network. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. * @throws IllegalArgumentException if the passphrase is not ASCII encodable. */ public WifiNetworkConfigBuilder setPskPassphrase(@NonNull String pskPassphrase) { checkNotNull(pskPassphrase); public WifiNetworkConfigBuilder setWpa3Passphrase(@NonNull String passphrase) { checkNotNull(passphrase); final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder(); if (!asciiEncoder.canEncode(pskPassphrase)) { if (!asciiEncoder.canEncode(passphrase)) { throw new IllegalArgumentException("passphrase not ASCII encodable"); } mPskPassphrase = pskPassphrase; mWpa3SaePassphrase = passphrase; return this; } /** * Set the associated enterprise configuration for this network. Needed for authenticating to * WPA2-EAP networks. See {@link WifiEnterpriseConfig} for description. * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setWpa2EnterpriseConfig( @NonNull WifiEnterpriseConfig enterpriseConfig) { checkNotNull(enterpriseConfig); mWpa2EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); return this; } /** * Set the associated enterprise configuration for this network. Needed for authenticating to * WPA_EAP networks. See {@link WifiEnterpriseConfig} for description. * WPA3-SuiteB networks. See {@link WifiEnterpriseConfig} for description. * * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}. * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder * method. */ public WifiNetworkConfigBuilder setEnterpriseConfig( public WifiNetworkConfigBuilder setWpa3EnterpriseConfig( @NonNull WifiEnterpriseConfig enterpriseConfig) { checkNotNull(enterpriseConfig); mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); mWpa3EnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig); return this; } Loading Loading @@ -324,16 +385,38 @@ public class WifiNetworkConfigBuilder { configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP); } private void setKeyMgmtInWifiConfiguration(@NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mPskPassphrase)) { // WPA_PSK network. private void setSecurityParamsInWifiConfiguration(@NonNull WifiConfiguration configuration) { if (!TextUtils.isEmpty(mWpa2PskPassphrase)) { // WPA-PSK network. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK); } else if (mEnterpriseConfig != null) { // WPA_EAP network // WifiConfiguration.preSharedKey needs quotes around ASCII password. configuration.preSharedKey = "\"" + mWpa2PskPassphrase + "\""; } else if (!TextUtils.isEmpty(mWpa3SaePassphrase)) { // WPA3-SAE network. configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SAE); // PMF mandatory for SAE. configuration.requirePMF = true; // WifiConfiguration.preSharedKey needs quotes around ASCII password. configuration.preSharedKey = "\"" + mWpa3SaePassphrase + "\""; } else if (mWpa2EnterpriseConfig != null) { // WPA-EAP network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP); configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X); } else { // Open network configuration.enterpriseConfig = mWpa2EnterpriseConfig; } else if (mWpa3EnterpriseConfig != null) { // WPA3-SuiteB network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.SUITE_B_192); configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.GCMP_256); // TODO (b/113878056): Verify these params once we verify SuiteB configuration. configuration.allowedGroupMgmtCiphers.set( WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256); configuration.allowedSuiteBCiphers.set( WifiConfiguration.SuiteBCipher.ECDHE_ECDSA); configuration.allowedSuiteBCiphers.set( WifiConfiguration.SuiteBCipher.ECDHE_RSA); configuration.requirePMF = true; configuration.enterpriseConfig = mWpa3EnterpriseConfig; } else if (mIsEnhancedOpen) { // OWE network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.OWE); // PMF mandatory. configuration.requirePMF = true; } else { // Open network configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE); } } Loading @@ -349,12 +432,7 @@ public class WifiNetworkConfigBuilder { if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) { wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\""; } setKeyMgmtInWifiConfiguration(wifiConfiguration); // WifiConfiguration.preSharedKey needs quotes around ASCII password. if (mPskPassphrase != null) { wifiConfiguration.preSharedKey = "\"" + mPskPassphrase + "\""; } wifiConfiguration.enterpriseConfig = mEnterpriseConfig; setSecurityParamsInWifiConfiguration(wifiConfiguration); wifiConfiguration.hiddenSSID = mIsHiddenSSID; wifiConfiguration.priority = mPriority; wifiConfiguration.meteredOverride = Loading Loading @@ -396,6 +474,20 @@ public class WifiNetworkConfigBuilder { return false; } private void validateSecurityParams() { int numSecurityTypes = 0; numSecurityTypes += mIsEnhancedOpen ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa2PskPassphrase) ? 1 : 0; numSecurityTypes += !TextUtils.isEmpty(mWpa3SaePassphrase) ? 1 : 0; numSecurityTypes += mWpa2EnterpriseConfig != null ? 1 : 0; numSecurityTypes += mWpa3EnterpriseConfig != null ? 1 : 0; if (numSecurityTypes > 1) { throw new IllegalStateException("only one of setIsEnhancedOpen, setWpa2Passphrase," + "setWpa3Passphrase, setWpa2EnterpriseConfig or setWpa3EnterpriseConfig" + " can be invoked for network specifier"); } } /** * Create a specifier object used to request a Wi-Fi network. The generated * {@link NetworkSpecifier} should be used in Loading Loading @@ -464,10 +556,7 @@ public class WifiNetworkConfigBuilder { + "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for " + "specifier"); } if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + " be invoked for network specifier"); } validateSecurityParams(); return new WifiNetworkSpecifier( mSsidPatternMatcher, Loading @@ -493,10 +582,7 @@ public class WifiNetworkConfigBuilder { throw new IllegalStateException("none of setSsidPattern/setBssidPattern/setBssid are" + " allowed for suggestion"); } if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) { throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can" + "be invoked for suggestion"); } validateSecurityParams(); return new WifiNetworkSuggestion( buildWifiConfiguration(), Loading
wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java +129 −16 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import android.net.MacAddress; Loading Loading @@ -81,11 +82,11 @@ public class WifiNetworkConfigBuilderTest { * pattern. */ @Test public void testWifiNetworkSpecifierBuilderForWpaPskNetworkWithBssidPattern() { public void testWifiNetworkSpecifierBuilderForWpa2PskNetworkWithBssidPattern() { NetworkSpecifier specifier = new WifiNetworkConfigBuilder() .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS), MacAddress.fromString(TEST_BSSID_OUI_MASK)) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .buildNetworkSpecifier(); assertTrue(specifier instanceof WifiNetworkSpecifier); Loading Loading @@ -119,7 +120,7 @@ public class WifiNetworkConfigBuilderTest { * SSID and BSSID pattern. */ @Test public void testWifiNetworkSpecifierBuilderForEnterpriseHiddenNetworkWithSsidAndBssid() { public void testWifiNetworkSpecifierBuilderForWpa2EapHiddenNetworkWithSsidAndBssid() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); Loading @@ -127,7 +128,7 @@ public class WifiNetworkConfigBuilderTest { NetworkSpecifier specifier = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setBssid(MacAddress.fromString(TEST_BSSID)) .setEnterpriseConfig(enterpriseConfig) .setWpa2EnterpriseConfig(enterpriseConfig) .setIsHiddenSsid() .buildNetworkSpecifier(); Loading Loading @@ -174,14 +175,14 @@ public class WifiNetworkConfigBuilderTest { } /** * Ensure {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} throws an exception * Ensure {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} throws an exception * when the string is not ASCII encodable. */ @Test(expected = IllegalArgumentException.class) public void testSetPskPassphraseWithNonAsciiString() { public void testSetWpa2PasphraseWithNonAsciiString() { new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase("salvē") .setWpa2Passphrase("salvē") .buildNetworkSpecifier(); } Loading Loading @@ -275,15 +276,15 @@ public class WifiNetworkConfigBuilderTest { /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} and * {@link WifiNetworkConfigBuilder#setEnterpriseConfig(WifiEnterpriseConfig)} are invoked. * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa2EnterpriseConfig(WifiEnterpriseConfig)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothPskPassphraseAndEnterpriseConfig() { public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndEnterpriseConfig() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setPskPassphrase(TEST_PRESHARED_KEY) .setEnterpriseConfig(new WifiEnterpriseConfig()) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setWpa2EnterpriseConfig(new WifiEnterpriseConfig()) .buildNetworkSpecifier(); } Loading Loading @@ -375,10 +376,11 @@ public class WifiNetworkConfigBuilderTest { * app interaction and has a priority of zero set. */ @Test public void testWifiNetworkSuggestionBuilderForWpaEapNetworkWithPriorityAndReqAppInteraction() { public void testWifiNetworkSuggestionBuilderForWpa2EapNetworkWithPriorityAndReqAppInteraction() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsAppInteractionRequired() .setPriority(0) .buildNetworkSuggestion(); Loading @@ -401,10 +403,11 @@ public class WifiNetworkConfigBuilderTest { * user interaction and is metered. */ @Test public void testWifiNetworkSuggestionBuilderForWpaPskNetworkWithMeteredAndReqUserInteraction() { public void testWifiNetworkSuggestionBuilderForWpa2PskNetworkWithMeteredAndReqUserInteraction() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setPskPassphrase(TEST_PRESHARED_KEY) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setIsUserInteractionRequired() .setIsMetered() .buildNetworkSuggestion(); Loading @@ -421,6 +424,74 @@ public class WifiNetworkConfigBuilderTest { assertEquals(-1, suggestion.wifiConfiguration.priority); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for OWE network. */ @Test public void testWifiNetworkSuggestionBuilderForEnhancedOpenNetwork() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setIsEnhancedOpen() .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.OWE)); assertNull(suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SAE network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3PskNetwork() { WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setWpa3Passphrase(TEST_PRESHARED_KEY) .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.SAE)); assertEquals("\"" + TEST_PRESHARED_KEY + "\"", suggestion.wifiConfiguration.preSharedKey); assertTrue(suggestion.wifiConfiguration.requirePMF); } /** * Validate correctness of WifiNetworkSuggestion object created by * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for SuiteB network. */ @Test public void testWifiNetworkSuggestionBuilderForWpa3EapNetwork() { WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig(); enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS); enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC); WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder() .setSsid(TEST_SSID) .setWpa3EnterpriseConfig(enterpriseConfig) .buildNetworkSuggestion(); assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID); assertTrue(suggestion.wifiConfiguration.allowedKeyManagement .get(WifiConfiguration.KeyMgmt.SUITE_B_192)); assertTrue(suggestion.wifiConfiguration.allowedGroupCiphers .get(WifiConfiguration.GroupCipher.GCMP_256)); assertTrue(suggestion.wifiConfiguration.allowedGroupMgmtCiphers .get(WifiConfiguration.GroupMgmtCipher.BIP_GMAC_256)); assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers .get(WifiConfiguration.SuiteBCipher.ECDHE_ECDSA)); assertTrue(suggestion.wifiConfiguration.allowedSuiteBCiphers .get(WifiConfiguration.SuiteBCipher.ECDHE_RSA)); assertTrue(suggestion.wifiConfiguration.requirePMF); assertNull(suggestion.wifiConfiguration.preSharedKey); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception * when {@link WifiNetworkConfigBuilder#setSsidPattern(PatternMatcher)} is set. Loading Loading @@ -478,4 +549,46 @@ public class WifiNetworkConfigBuilderTest { .setPriority(-1) .buildNetworkSuggestion(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa2Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa2PasphraseAndWpa3Passphrase() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa2Passphrase(TEST_PRESHARED_KEY) .setWpa3Passphrase(TEST_PRESHARED_KEY) .buildNetworkSpecifier(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setWpa3EnterpriseConfig(WifiEnterpriseConfig)} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnterprise() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setWpa3EnterpriseConfig(new WifiEnterpriseConfig()) .buildNetworkSpecifier(); } /** * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception * when both {@link WifiNetworkConfigBuilder#setWpa3Passphrase(String)} and * {@link WifiNetworkConfigBuilder#setIsEnhancedOpen(} are invoked. */ @Test(expected = IllegalStateException.class) public void testWifiNetworkSpecifierBuilderWithBothWpa3PasphraseAndEnhancedOpen() { new WifiNetworkConfigBuilder() .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL)) .setWpa3Passphrase(TEST_PRESHARED_KEY) .setIsEnhancedOpen() .buildNetworkSpecifier(); } }