diff options
author | Hai Shalom <haishalom@google.com> | 2019-05-10 15:21:58 -0700 |
---|---|---|
committer | Hai Shalom <haishalom@google.com> | 2019-05-12 17:40:26 +0000 |
commit | b70a500802ff55d13c71f7431e0c32d0220e9d04 (patch) | |
tree | c6d91bcae5e7838013c8fd86337f74d40461ac36 | |
parent | fcafe95467db28e1fd687abe71b396e313ce14ce (diff) |
[OWE] Fix Open-OWE transition connectivity for non-supporting devices
Device running Q without OWE support could not connect to Open-OWE
transition network. In InformationElementUti.java We check if OWE
is supported because we are adding the OWE capabilities to the Open
BSS. Non-supporting devices need to see this open network and
ignore this element. Supporting devices need to parse the OWE IE,
hide the Open BSS of OWE in transition, mode and connect to the
Hidden one.
Bug: 132455533
Test: Connect to OWE transition network with non-supporting device
Test: Connect to OWE transition network with supporting device
Test: Connect to OWE network with supporting device
Test: Verify correct scan results on both devices
Change-Id: I2d0d9f68abb36126aae0f011f6bc15a480bcff07
3 files changed, 113 insertions, 19 deletions
diff --git a/service/java/com/android/server/wifi/WificondControl.java b/service/java/com/android/server/wifi/WificondControl.java index c58c56471..bd756f643 100644 --- a/service/java/com/android/server/wifi/WificondControl.java +++ b/service/java/com/android/server/wifi/WificondControl.java @@ -16,6 +16,8 @@ package com.android.server.wifi; +import static android.net.wifi.WifiManager.WIFI_FEATURE_OWE; + import android.annotation.NonNull; import android.app.AlarmManager; import android.net.wifi.IApInterface; @@ -88,6 +90,7 @@ public class WificondControl implements IBinder.DeathRecipient { private AlarmManager mAlarmManager; private Handler mEventHandler; private Clock mClock; + private WifiNative mWifiNative = null; // Cached wificond binder handlers. private IWificond mWificond; @@ -102,6 +105,8 @@ public class WificondControl implements IBinder.DeathRecipient { * Ensures that no more than one sendMgmtFrame operation runs concurrently. */ private AtomicBoolean mSendMgmtFrameInProgress = new AtomicBoolean(false); + private boolean mIsEnhancedOpenSupportedInitialized = false; + private boolean mIsEnhancedOpenSupported; private class ScanEventHandler extends IScanEvent.Stub { private String mIfaceName; @@ -591,7 +596,7 @@ public class WificondControl implements IBinder.DeathRecipient { InformationElementUtil.parseInformationElements(result.infoElement); InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, result.capability); + capabilities.from(ies, result.capability, isEnhancedOpenSupported()); String flags = capabilities.generateCapabilitiesString(); NetworkDetail networkDetail; try { @@ -918,4 +923,34 @@ public class WificondControl implements IBinder.DeathRecipient { mApInterfaceListeners.clear(); mSendMgmtFrameInProgress.set(false); } + + /** + * Check if OWE (Enhanced Open) is supported on the device + * + * @return true if OWE is supported + */ + private boolean isEnhancedOpenSupported() { + if (mIsEnhancedOpenSupportedInitialized) { + return mIsEnhancedOpenSupported; + } + + // WifiNative handle might be null, check this here + if (mWifiNative == null) { + mWifiNative = mWifiInjector.getWifiNative(); + if (mWifiNative == null) { + return false; + } + } + + String iface = mWifiNative.getClientInterfaceName(); + if (iface == null) { + // Client interface might not be initialized during boot or Wi-Fi off + return false; + } + + mIsEnhancedOpenSupportedInitialized = true; + mIsEnhancedOpenSupported = (mWifiNative.getSupportedFeatureSet(iface) + & WIFI_FEATURE_OWE) != 0; + return mIsEnhancedOpenSupported; + } } diff --git a/service/java/com/android/server/wifi/util/InformationElementUtil.java b/service/java/com/android/server/wifi/util/InformationElementUtil.java index f75d57eff..994cd2d65 100644 --- a/service/java/com/android/server/wifi/util/InformationElementUtil.java +++ b/service/java/com/android/server/wifi/util/InformationElementUtil.java @@ -665,9 +665,10 @@ public class InformationElementUtil { * * @param ies -- Information Element array * @param beaconCap -- 16-bit Beacon Capability Information field + * @param isOweSupported -- Boolean flag to indicate if OWE is supported by the device */ - public void from(InformationElement[] ies, BitSet beaconCap) { + public void from(InformationElement[] ies, BitSet beaconCap, boolean isOweSupported) { protocol = new ArrayList<Integer>(); keyManagement = new ArrayList<ArrayList<Integer>>(); groupCipher = new ArrayList<Integer>(); @@ -691,7 +692,7 @@ public class InformationElementUtil { // TODO(b/62134557): parse WPS IE to provide finer granularity information. isWPS = true; } - if (isOweElement(ie)) { + if (isOweSupported && isOweElement(ie)) { /* From RFC 8110: Once the client and AP have finished 802.11 association, they then complete the Diffie-Hellman key exchange and create a Pairwise Master Key (PMK) and its associated identifier, PMKID [IEEE802.11]. @@ -700,8 +701,12 @@ public class InformationElementUtil { handshake generates a Key-Encrypting Key (KEK), a Key-Confirmation Key (KCK), and a Message Integrity Code (MIC) to use for protection of the frames that define the 4-way handshake. - */ + We check if OWE is supported here because we are adding the OWE + capabilities to the Open BSS. Non-supporting devices need to see this + open network and ignore this element. Supporting devices need to hide + the Open BSS of OWE in transition mode and connect to the Hidden one. + */ protocol.add(ScanResult.PROTOCOL_RSN); groupCipher.add(ScanResult.CIPHER_CCMP); ArrayList<Integer> owePairwiseCipher = new ArrayList<>(); diff --git a/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java b/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java index cbb728644..46830f3f5 100644 --- a/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java +++ b/tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java @@ -265,7 +265,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN-PSK-CCMP+TKIP]", result); @@ -291,7 +291,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN]", result); @@ -319,7 +319,7 @@ public class InformationElementUtilTest { beaconCap.set(4); InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[WPA-PSK-CCMP+TKIP]", result); @@ -343,7 +343,7 @@ public class InformationElementUtilTest { beaconCap.set(4); InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[WPA]", result); @@ -381,7 +381,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[WPA-PSK-CCMP+TKIP][RSN-PSK-CCMP+TKIP]", result); @@ -420,7 +420,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, true); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN-PSK+SAE-CCMP]", result); @@ -459,7 +459,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, true); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN-SAE+FT/SAE-CCMP]", result); @@ -496,13 +496,67 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, true); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN-OWE-CCMP]", result); } /** + * Test Capabilities.generateCapabilitiesString() with OWE IE. + * Expect the function to return a string with the proper security information. + */ + @Test + public void buildCapabilities_oweVsElementOweSupported() { + InformationElement ieOwe = new InformationElement(); + ieOwe.id = InformationElement.EID_VSA; + ieOwe.bytes = new byte[] { + // OWE vendor specific + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x1C, + // OWE IE contains BSSID, SSID and channel of other BSS, but we don't parse it. + (byte) 0x00, (byte) 0x000, (byte) 0x00, (byte) 0x00 }; + + InformationElement[] ies = new InformationElement[] { ieOwe }; + + BitSet beaconCap = new BitSet(16); + beaconCap.set(0); + + InformationElementUtil.Capabilities capabilities = + new InformationElementUtil.Capabilities(); + capabilities.from(ies, beaconCap, true); + String result = capabilities.generateCapabilitiesString(); + + assertEquals("[RSN-OWE-CCMP][ESS]", result); + } + + /** + * Test Capabilities.generateCapabilitiesString() with OWE IE. + * Expect the function to return a string with the proper security information. + */ + @Test + public void buildCapabilities_oweVsElementOweNotSupported() { + InformationElement ieOwe = new InformationElement(); + ieOwe.id = InformationElement.EID_VSA; + ieOwe.bytes = new byte[] { + // OWE vendor specific + (byte) 0x50, (byte) 0x6F, (byte) 0x9A, (byte) 0x1C, + // OWE IE contains BSSID, SSID and channel of other BSS, but we don't parse it. + (byte) 0x00, (byte) 0x000, (byte) 0x00, (byte) 0x00 }; + + InformationElement[] ies = new InformationElement[] { ieOwe }; + + BitSet beaconCap = new BitSet(16); + beaconCap.set(0); + + InformationElementUtil.Capabilities capabilities = + new InformationElementUtil.Capabilities(); + capabilities.from(ies, beaconCap, false); + String result = capabilities.generateCapabilitiesString(); + + assertEquals("[ESS]", result); + } + + /** * Test Capabilities.generateCapabilitiesString() with RSN IE, GCMP-256 and SUITE_B_192. * Expect the function to return a string with the proper security information. */ @@ -533,7 +587,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[RSN-EAP_SUITE_B_192-GCMP-256]", result); @@ -565,7 +619,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[WPA][RSN]", result); @@ -599,7 +653,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); assertEquals("[WPA-PSK-CCMP+TKIP][WPS]", result); @@ -627,7 +681,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); @@ -656,7 +710,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); @@ -684,7 +738,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); @@ -713,7 +767,7 @@ public class InformationElementUtilTest { InformationElementUtil.Capabilities capabilities = new InformationElementUtil.Capabilities(); - capabilities.from(ies, beaconCap); + capabilities.from(ies, beaconCap, false); String result = capabilities.generateCapabilitiesString(); |