summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHai Shalom <haishalom@google.com>2019-05-10 15:21:58 -0700
committerHai Shalom <haishalom@google.com>2019-05-12 17:40:26 +0000
commitb70a500802ff55d13c71f7431e0c32d0220e9d04 (patch)
treec6d91bcae5e7838013c8fd86337f74d40461ac36
parentfcafe95467db28e1fd687abe71b396e313ce14ce (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
-rw-r--r--service/java/com/android/server/wifi/WificondControl.java37
-rw-r--r--service/java/com/android/server/wifi/util/InformationElementUtil.java11
-rw-r--r--tests/wifitests/src/com/android/server/wifi/util/InformationElementUtilTest.java84
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();