Merge "[CTS]It should be more reasonable to use setBatterySaverMode API to leave power-save mode instead of plugging in charger for "CtsHostsideNetworkTests" test case." into nougat-mr1-cts-dev
am: 6ee31c8e8f
Change-Id: Id8398453ea4b85d04da963ab48876407b0237e41
diff --git a/tests/cts/hostside/aidl/Android.mk b/tests/cts/hostside/aidl/Android.mk
index a7ec6ef..4aa55b6 100644
--- a/tests/cts/hostside/aidl/Android.mk
+++ b/tests/cts/hostside/aidl/Android.mk
@@ -19,4 +19,4 @@
LOCAL_SDK_VERSION := current
LOCAL_SRC_FILES := com/android/cts/net/hostside/IRemoteSocketFactory.aidl
LOCAL_MODULE := CtsHostsideNetworkTestsAidl
-include $(BUILD_JAVA_LIBRARY)
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
index d2720d6..a500348 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/AbstractRestrictBackgroundNetworkTestCase.java
@@ -99,7 +99,6 @@
protected ConnectivityManager mCm;
protected WifiManager mWfm;
protected int mUid;
- private int mMyUid;
private String mMeteredWifi;
private boolean mHasWatch;
private String mDeviceIdleConstantsSetting;
@@ -114,7 +113,7 @@
mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
mWfm = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mUid = getUid(TEST_APP2_PKG);
- mMyUid = getUid(mContext.getPackageName());
+ final int myUid = getUid(mContext.getPackageName());
mHasWatch = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_WATCH);
if (mHasWatch) {
@@ -125,7 +124,7 @@
mSupported = setUpActiveNetworkMeteringState();
Log.i(TAG, "Apps status on " + getName() + ":\n"
- + "\ttest app: uid=" + mMyUid + ", state=" + getProcessStateByUid(mMyUid) + "\n"
+ + "\ttest app: uid=" + myUid + ", state=" + getProcessStateByUid(myUid) + "\n"
+ "\tapp2: uid=" + mUid + ", state=" + getProcessStateByUid(mUid));
}
@@ -200,21 +199,6 @@
assertEquals("wrong status", toString(expectedStatus), actualStatus);
}
- protected void assertMyRestrictBackgroundStatus(int expectedStatus) throws Exception {
- final int actualStatus = mCm.getRestrictBackgroundStatus();
- assertEquals("Wrong status", toString(expectedStatus), toString(actualStatus));
- }
-
- protected boolean isMyRestrictBackgroundStatus(int expectedStatus) throws Exception {
- final int actualStatus = mCm.getRestrictBackgroundStatus();
- if (expectedStatus != actualStatus) {
- Log.d(TAG, "Expected: " + toString(expectedStatus)
- + " but actual: " + toString(actualStatus));
- return false;
- }
- return true;
- }
-
protected void assertBackgroundNetworkAccess(boolean expectAllowed) throws Exception {
assertBackgroundState(); // Sanity check.
assertNetworkAccess(expectAllowed);
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
index 72d0be9..9e4b0c1 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/DataSaverModeTest.java
@@ -20,21 +20,16 @@
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_ENABLED;
import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
-import android.util.Log;
-
public class DataSaverModeTest extends AbstractRestrictBackgroundNetworkTestCase {
private static final String[] REQUIRED_WHITELISTED_PACKAGES = {
"com.android.providers.downloads"
};
- private boolean mIsDataSaverSupported;
-
@Override
public void setUp() throws Exception {
super.setUp();
- mIsDataSaverSupported = isDataSaverSupported();
if (!isSupported()) return;
// Set initial state.
@@ -64,32 +59,6 @@
return setMeteredNetwork();
}
- @Override
- protected boolean isSupported() throws Exception {
- if (!mIsDataSaverSupported) {
- Log.i(TAG, "Skipping " + getClass() + "." + getName()
- + "() because device does not support Data Saver Mode");
- }
- return mIsDataSaverSupported && super.isSupported();
- }
-
- /**
- * As per CDD requirements, if the device doesn't support data saver mode then
- * ConnectivityManager.getRestrictBackgroundStatus() will always return
- * RESTRICT_BACKGROUND_STATUS_DISABLED. So, enable the data saver mode and check if
- * ConnectivityManager.getRestrictBackgroundStatus() for an app in background returns
- * RESTRICT_BACKGROUND_STATUS_DISABLED or not.
- */
- private boolean isDataSaverSupported() throws Exception {
- assertMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
- try {
- setRestrictBackground(true);
- return !isMyRestrictBackgroundStatus(RESTRICT_BACKGROUND_STATUS_DISABLED);
- } finally {
- setRestrictBackground(false);
- }
- }
-
public void testGetRestrictBackgroundStatus_disabled() throws Exception {
if (!isSupported()) return;
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
index 799fe50..80f99b6 100644
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/RemoteSocketFactoryClient.java
@@ -22,11 +22,15 @@
import android.content.ServiceConnection;
import android.os.ConditionVariable;
import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
import com.android.cts.net.hostside.IRemoteSocketFactory;
import java.io.FileDescriptor;
+import java.io.IOException;
public class RemoteSocketFactoryClient {
private static final int TIMEOUT_MS = 5000;
@@ -76,9 +80,14 @@
}
}
- public FileDescriptor openSocketFd(
- String host, int port, int timeoutMs) throws RemoteException {
- return mService.openSocketFd(host, port, timeoutMs).getFileDescriptor();
+ public FileDescriptor openSocketFd(String host, int port, int timeoutMs)
+ throws RemoteException, ErrnoException, IOException {
+ // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
+ // and cause our fd to become invalid. http://b/35927643 .
+ ParcelFileDescriptor pfd = mService.openSocketFd(host, port, timeoutMs);
+ FileDescriptor fd = Os.dup(pfd.getFileDescriptor());
+ pfd.close();
+ return fd;
}
public String getPackageName() throws RemoteException {
diff --git a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
index 12fe625..2bd3c39 100755
--- a/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
+++ b/tests/cts/hostside/app/src/com/android/cts/net/hostside/VpnTest.java
@@ -84,6 +84,11 @@
* https://android-review.googlesource.com/#/c/99225/
* https://android-review.googlesource.com/#/c/100557/
*
+ * To ensure that the kernel has the required commits, run the kernel unit
+ * tests described at:
+ *
+ * https://source.android.com/devices/tech/config/kernel_network_tests.html
+ *
*/
public class VpnTest extends InstrumentationTestCase {
@@ -476,7 +481,11 @@
private FileDescriptor openSocketFd(String host, int port, int timeoutMs) throws Exception {
Socket s = new Socket(host, port);
s.setSoTimeout(timeoutMs);
- return ParcelFileDescriptor.fromSocket(s).getFileDescriptor();
+ // Dup the filedescriptor so ParcelFileDescriptor's finalizer doesn't garbage collect it
+ // and cause our fd to become invalid. http://b/35927643 .
+ FileDescriptor fd = Os.dup(ParcelFileDescriptor.fromSocket(s).getFileDescriptor());
+ s.close();
+ return fd;
}
private FileDescriptor openSocketFdInOtherApp(
@@ -506,7 +515,9 @@
private void assertSocketStillOpen(FileDescriptor fd, String host) throws Exception {
try {
+ assertTrue(fd.valid());
sendRequest(fd, host);
+ assertTrue(fd.valid());
} finally {
Os.close(fd);
}
@@ -514,10 +525,12 @@
private void assertSocketClosed(FileDescriptor fd, String host) throws Exception {
try {
+ assertTrue(fd.valid());
sendRequest(fd, host);
fail("Socket opened before VPN connects should be closed when VPN connects");
} catch (ErrnoException expected) {
assertEquals(ECONNABORTED, expected.errno);
+ assertTrue(fd.valid());
} finally {
Os.close(fd);
}
diff --git a/tests/cts/net/Android.mk b/tests/cts/net/Android.mk
index c553a9b..7d2b0ba 100644
--- a/tests/cts/net/Android.mk
+++ b/tests/cts/net/Android.mk
@@ -34,8 +34,14 @@
LOCAL_PACKAGE_NAME := CtsNetTestCases
-LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support ctsdeviceutil \
- ctstestrunner ctstestserver mockwebserver
+LOCAL_STATIC_JAVA_LIBRARIES := \
+ core-tests-support \
+ ctsdeviceutil \
+ ctstestrunner \
+ ctstestserver \
+ mockwebserver \
+ junit \
+ legacy-android-test
# uncomment when b/13249961 is fixed
#LOCAL_SDK_VERSION := current
diff --git a/tests/cts/net/assets/HSR1ProfileWithCACert.base64 b/tests/cts/net/assets/HSR1ProfileWithCACert.base64
new file mode 100644
index 0000000..995963d
--- /dev/null
+++ b/tests/cts/net/assets/HSR1ProfileWithCACert.base64
@@ -0,0 +1,85 @@
+Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu
+dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh
+cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6
+IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n
+SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo
+YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn
+UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi
+V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ
+M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM
+MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth
+VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt
+RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD
+QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD
+QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD
+QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx
+bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1
+MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv
+Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2
+ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo
+YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4
+VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo
+YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi
+RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj
+bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i
+MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM
+MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy
+UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX
+eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD
+QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD
+OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3
+dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0
+S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV
+K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G
+dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur
+TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn
+SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2
+WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0
+VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM
+MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ
+Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi
+V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ
+a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX
+eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD
+QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q
+VTJSbWx1WjJWeWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
+KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG
+bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB
+OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB
+Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4
+VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs
+UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn
+SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2
+WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk
+V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU
+bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ
+QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94
+LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD
+UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR
+VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U
+bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU
+azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V
+VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw
+TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY
+TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T
+dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV
+RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo
+U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK
+ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz
+M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh
+CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX
+TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH
+U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF
+YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk
+MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV
+akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ
+MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD
+amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY
+ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew
+OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX
+MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF
+MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw
+aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG
+S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS
+a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts
+RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
diff --git a/tests/cts/net/assets/PerProviderSubscription.xml b/tests/cts/net/assets/PerProviderSubscription.xml
new file mode 100644
index 0000000..7f2d95d
--- /dev/null
+++ b/tests/cts/net/assets/PerProviderSubscription.xml
@@ -0,0 +1,399 @@
+<MgmtTree xmlns="syncml:dmddf1.2">
+ <VerDTD>1.2</VerDTD>
+ <Node>
+ <NodeName>PerProviderSubscription</NodeName>
+ <RTProperties>
+ <Type>
+ <DDFName>urn:wfa:mo:hotspot2dot0-perprovidersubscription:1.0</DDFName>
+ </Type>
+ </RTProperties>
+ <Node>
+ <NodeName>UpdateIdentifier</NodeName>
+ <Value>12</Value>
+ </Node>
+ <Node>
+ <NodeName>i001</NodeName>
+ <Node>
+ <NodeName>HomeSP</NodeName>
+ <Node>
+ <NodeName>FriendlyName</NodeName>
+ <Value>Century House</Value>
+ </Node>
+ <Node>
+ <NodeName>FQDN</NodeName>
+ <Value>mi6.co.uk</Value>
+ </Node>
+ <Node>
+ <NodeName>RoamingConsortiumOI</NodeName>
+ <Value>112233,445566</Value>
+ </Node>
+ <Node>
+ <NodeName>IconURL</NodeName>
+ <Value>icon.test.com</Value>
+ </Node>
+ <Node>
+ <NodeName>NetworkID</NodeName>
+ <Node>
+ <NodeName>n001</NodeName>
+ <Node>
+ <NodeName>SSID</NodeName>
+ <Value>TestSSID</Value>
+ </Node>
+ <Node>
+ <NodeName>HESSID</NodeName>
+ <Value>12345678</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>n002</NodeName>
+ <Node>
+ <NodeName>SSID</NodeName>
+ <Value>NullHESSID</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>HomeOIList</NodeName>
+ <Node>
+ <NodeName>h001</NodeName>
+ <Node>
+ <NodeName>HomeOI</NodeName>
+ <Value>11223344</Value>
+ </Node>
+ <Node>
+ <NodeName>HomeOIRequired</NodeName>
+ <Value>true</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>h002</NodeName>
+ <Node>
+ <NodeName>HomeOI</NodeName>
+ <Value>55667788</Value>
+ </Node>
+ <Node>
+ <NodeName>HomeOIRequired</NodeName>
+ <Value>false</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>OtherHomePartners</NodeName>
+ <Node>
+ <NodeName>o001</NodeName>
+ <Node>
+ <NodeName>FQDN</NodeName>
+ <Value>other.fqdn.com</Value>
+ </Node>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>Credential</NodeName>
+ <Node>
+ <NodeName>CreationDate</NodeName>
+ <Value>2016-01-01T10:00:00Z</Value>
+ </Node>
+ <Node>
+ <NodeName>ExpirationDate</NodeName>
+ <Value>2016-02-01T10:00:00Z</Value>
+ </Node>
+ <Node>
+ <NodeName>Realm</NodeName>
+ <Value>shaken.stirred.com</Value>
+ </Node>
+ <Node>
+ <NodeName>CheckAAAServerCertStatus</NodeName>
+ <Value>true</Value>
+ </Node>
+ <Node>
+ <NodeName>UsernamePassword</NodeName>
+ <Node>
+ <NodeName>Username</NodeName>
+ <Value>james</Value>
+ </Node>
+ <Node>
+ <NodeName>Password</NodeName>
+ <Value>Ym9uZDAwNw==</Value>
+ </Node>
+ <Node>
+ <NodeName>MachineManaged</NodeName>
+ <Value>true</Value>
+ </Node>
+ <Node>
+ <NodeName>SoftTokenApp</NodeName>
+ <Value>TestApp</Value>
+ </Node>
+ <Node>
+ <NodeName>AbleToShare</NodeName>
+ <Value>true</Value>
+ </Node>
+ <Node>
+ <NodeName>EAPMethod</NodeName>
+ <Node>
+ <NodeName>EAPType</NodeName>
+ <Value>21</Value>
+ </Node>
+ <Node>
+ <NodeName>InnerMethod</NodeName>
+ <Value>MS-CHAP-V2</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>DigitalCertificate</NodeName>
+ <Node>
+ <NodeName>CertificateType</NodeName>
+ <Value>x509v3</Value>
+ </Node>
+ <Node>
+ <NodeName>CertSHA256Fingerprint</NodeName>
+ <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>SIM</NodeName>
+ <Node>
+ <NodeName>IMSI</NodeName>
+ <Value>imsi</Value>
+ </Node>
+ <Node>
+ <NodeName>EAPType</NodeName>
+ <Value>24</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>Policy</NodeName>
+ <Node>
+ <NodeName>PreferredRoamingPartnerList</NodeName>
+ <Node>
+ <NodeName>p001</NodeName>
+ <Node>
+ <NodeName>FQDN_Match</NodeName>
+ <Value>test1.fqdn.com,exactMatch</Value>
+ </Node>
+ <Node>
+ <NodeName>Priority</NodeName>
+ <Value>127</Value>
+ </Node>
+ <Node>
+ <NodeName>Country</NodeName>
+ <Value>us,fr</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>p002</NodeName>
+ <Node>
+ <NodeName>FQDN_Match</NodeName>
+ <Value>test2.fqdn.com,includeSubdomains</Value>
+ </Node>
+ <Node>
+ <NodeName>Priority</NodeName>
+ <Value>200</Value>
+ </Node>
+ <Node>
+ <NodeName>Country</NodeName>
+ <Value>*</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>MinBackhaulThreshold</NodeName>
+ <Node>
+ <NodeName>m001</NodeName>
+ <Node>
+ <NodeName>NetworkType</NodeName>
+ <Value>home</Value>
+ </Node>
+ <Node>
+ <NodeName>DLBandwidth</NodeName>
+ <Value>23412</Value>
+ </Node>
+ <Node>
+ <NodeName>ULBandwidth</NodeName>
+ <Value>9823</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>m002</NodeName>
+ <Node>
+ <NodeName>NetworkType</NodeName>
+ <Value>roaming</Value>
+ </Node>
+ <Node>
+ <NodeName>DLBandwidth</NodeName>
+ <Value>9271</Value>
+ </Node>
+ <Node>
+ <NodeName>ULBandwidth</NodeName>
+ <Value>2315</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>PolicyUpdate</NodeName>
+ <Node>
+ <NodeName>UpdateInterval</NodeName>
+ <Value>120</Value>
+ </Node>
+ <Node>
+ <NodeName>UpdateMethod</NodeName>
+ <Value>OMA-DM-ClientInitiated</Value>
+ </Node>
+ <Node>
+ <NodeName>Restriction</NodeName>
+ <Value>HomeSP</Value>
+ </Node>
+ <Node>
+ <NodeName>URI</NodeName>
+ <Value>policy.update.com</Value>
+ </Node>
+ <Node>
+ <NodeName>UsernamePassword</NodeName>
+ <Node>
+ <NodeName>Username</NodeName>
+ <Value>updateUser</Value>
+ </Node>
+ <Node>
+ <NodeName>Password</NodeName>
+ <Value>updatePass</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>TrustRoot</NodeName>
+ <Node>
+ <NodeName>CertURL</NodeName>
+ <Value>update.cert.com</Value>
+ </Node>
+ <Node>
+ <NodeName>CertSHA256Fingerprint</NodeName>
+ <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>SPExclusionList</NodeName>
+ <Node>
+ <NodeName>s001</NodeName>
+ <Node>
+ <NodeName>SSID</NodeName>
+ <Value>excludeSSID</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>RequiredProtoPortTuple</NodeName>
+ <Node>
+ <NodeName>r001</NodeName>
+ <Node>
+ <NodeName>IPProtocol</NodeName>
+ <Value>12</Value>
+ </Node>
+ <Node>
+ <NodeName>PortNumber</NodeName>
+ <Value>34,92,234</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>MaximumBSSLoadValue</NodeName>
+ <Value>23</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>CredentialPriority</NodeName>
+ <Value>99</Value>
+ </Node>
+ <Node>
+ <NodeName>AAAServerTrustRoot</NodeName>
+ <Node>
+ <NodeName>a001</NodeName>
+ <Node>
+ <NodeName>CertURL</NodeName>
+ <Value>server1.trust.root.com</Value>
+ </Node>
+ <Node>
+ <NodeName>CertSHA256Fingerprint</NodeName>
+ <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>SubscriptionUpdate</NodeName>
+ <Node>
+ <NodeName>UpdateInterval</NodeName>
+ <Value>120</Value>
+ </Node>
+ <Node>
+ <NodeName>UpdateMethod</NodeName>
+ <Value>SSP-ClientInitiated</Value>
+ </Node>
+ <Node>
+ <NodeName>Restriction</NodeName>
+ <Value>RoamingPartner</Value>
+ </Node>
+ <Node>
+ <NodeName>URI</NodeName>
+ <Value>subscription.update.com</Value>
+ </Node>
+ <Node>
+ <NodeName>UsernamePassword</NodeName>
+ <Node>
+ <NodeName>Username</NodeName>
+ <Value>subscriptionUser</Value>
+ </Node>
+ <Node>
+ <NodeName>Password</NodeName>
+ <Value>subscriptionPass</Value>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>TrustRoot</NodeName>
+ <Node>
+ <NodeName>CertURL</NodeName>
+ <Value>subscription.update.cert.com</Value>
+ </Node>
+ <Node>
+ <NodeName>CertSHA256Fingerprint</NodeName>
+ <Value>1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f</Value>
+ </Node>
+ </Node>
+ </Node>
+ <Node>
+ <NodeName>SubscriptionParameter</NodeName>
+ <Node>
+ <NodeName>CreationDate</NodeName>
+ <Value>2016-02-01T10:00:00Z</Value>
+ </Node>
+ <Node>
+ <NodeName>ExpirationDate</NodeName>
+ <Value>2016-03-01T10:00:00Z</Value>
+ </Node>
+ <Node>
+ <NodeName>TypeOfSubscription</NodeName>
+ <Value>Gold</Value>
+ </Node>
+ <Node>
+ <NodeName>UsageLimits</NodeName>
+ <Node>
+ <NodeName>DataLimit</NodeName>
+ <Value>921890</Value>
+ </Node>
+ <Node>
+ <NodeName>StartDate</NodeName>
+ <Value>2016-12-01T10:00:00Z</Value>
+ </Node>
+ <Node>
+ <NodeName>TimeLimit</NodeName>
+ <Value>120</Value>
+ </Node>
+ <Node>
+ <NodeName>UsageTimePeriod</NodeName>
+ <Value>99910</Value>
+ </Node>
+ </Node>
+ </Node>
+ </Node>
+ </Node>
+</MgmtTree>
diff --git a/tests/cts/net/jni/NativeDnsJni.c b/tests/cts/net/jni/NativeDnsJni.c
index 4eb3c7a..352c0c5 100644
--- a/tests/cts/net/jni/NativeDnsJni.c
+++ b/tests/cts/net/jni/NativeDnsJni.c
@@ -126,7 +126,7 @@
return JNI_FALSE;
}
- memset(buf, sizeof(buf), 0);
+ memset(buf, 0, sizeof(buf));
res = getnameinfo((const struct sockaddr*)&sa6, sizeof(sa6), buf, sizeof(buf), NULL, 0, flags);
if (res != 0) {
ALOGD("getnameinfo(%s (GoogleDNS) ) gave error %d (%s)", GoogleDNSIpV6Address2,
diff --git a/tests/cts/net/jni/NativeMultinetworkJni.c b/tests/cts/net/jni/NativeMultinetworkJni.c
index ad56b51..9156504 100644
--- a/tests/cts/net/jni/NativeMultinetworkJni.c
+++ b/tests/cts/net/jni/NativeMultinetworkJni.c
@@ -30,7 +30,7 @@
#include <sys/time.h>
#include <android/multinetwork.h>
-#define UNUSED(X) ((void) X)
+#define UNUSED(X) ((void) (X))
static const char kHostname[] = "connectivitycheck.android.com";
@@ -88,7 +88,9 @@
return rval == 0 ? 0 : -saved_errno;
}
-static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535");
+// Use sizeof("x") - 1 because we need a compile-time constant, and strlen("x")
+// isn't guaranteed to fold to a constant.
+static const int kSockaddrStrLen = INET6_ADDRSTRLEN + sizeof("[]:65535") - 1;
void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) {
char addrstr[INET6_ADDRSTRLEN];
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 185ebfa..24871ca 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -18,6 +18,7 @@
import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -384,6 +385,57 @@
}
/**
+ * Exercises the requestNetwork with NetworkCallback API. This checks to
+ * see if we get a callback for an INTERNET request.
+ */
+ public void testRequestNetworkCallback() {
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.requestNetwork(new NetworkRequest.Builder()
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .build(), callback);
+
+ try {
+ // Wait to get callback for availability of internet
+ Network internetNetwork = callback.waitForAvailable();
+ assertNotNull("Did not receive NetworkCallback#onAvailable for INTERNET",
+ internetNetwork);
+ } catch (InterruptedException e) {
+ fail("NetworkCallback wait was interrupted.");
+ } finally {
+ mCm.unregisterNetworkCallback(callback);
+ }
+ }
+
+ /**
+ * Exercises the requestNetwork with NetworkCallback API with timeout - expected to
+ * fail. Use WIFI and switch Wi-Fi off.
+ */
+ public void testRequestNetworkCallback_onUnavailable() {
+ final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+ if (previousWifiEnabledState) {
+ disconnectFromWifi(null);
+ }
+
+ final TestNetworkCallback callback = new TestNetworkCallback();
+ mCm.requestNetwork(new NetworkRequest.Builder()
+ .addTransportType(TRANSPORT_WIFI)
+ .build(), 100, callback);
+
+ try {
+ // Wait to get callback for unavailability of requested network
+ assertTrue("Did not receive NetworkCallback#onUnavailable",
+ callback.waitForUnavailable());
+ } catch (InterruptedException e) {
+ fail("NetworkCallback wait was interrupted.");
+ } finally {
+ mCm.unregisterNetworkCallback(callback);
+ if (previousWifiEnabledState) {
+ connectToWifi();
+ }
+ }
+ }
+
+ /**
* Tests reporting of connectivity changed.
*/
public void testConnectivityChanged_manifestRequestOnly_shouldNotReceiveIntent() {
@@ -639,6 +691,7 @@
private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
private final CountDownLatch mLostLatch = new CountDownLatch(1);
+ private final CountDownLatch mUnavailableLatch = new CountDownLatch(1);
public Network currentNetwork;
public Network lastLostNetwork;
@@ -651,6 +704,11 @@
return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null;
}
+ public boolean waitForUnavailable() throws InterruptedException {
+ return mUnavailableLatch.await(2, TimeUnit.SECONDS);
+ }
+
+
@Override
public void onAvailable(Network network) {
currentNetwork = network;
@@ -665,6 +723,11 @@
}
mLostLatch.countDown();
}
+
+ @Override
+ public void onUnavailable() {
+ mUnavailableLatch.countDown();
+ }
}
private Network getWifiNetwork() {
diff --git a/tests/cts/net/src/android/net/cts/IpSecManagerTest.java b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
new file mode 100644
index 0000000..39d683d
--- /dev/null
+++ b/tests/cts/net/src/android/net/cts/IpSecManagerTest.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2017 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 android.net.cts;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.IpSecAlgorithm;
+import android.net.IpSecManager;
+import android.net.IpSecTransform;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+public class IpSecManagerTest extends AndroidTestCase {
+
+ private static final String TAG = IpSecManagerTest.class.getSimpleName();
+
+ private IpSecManager mISM;
+
+ private ConnectivityManager mCM;
+
+ private static final InetAddress GOOGLE_DNS_4;
+ private static final InetAddress GOOGLE_DNS_6;
+
+ static {
+ try {
+ // Google Public DNS Addresses;
+ GOOGLE_DNS_4 = InetAddress.getByName("8.8.8.8");
+ GOOGLE_DNS_6 = InetAddress.getByName("2001:4860:4860::8888");
+ } catch (UnknownHostException e) {
+ throw new RuntimeException("Could not resolve DNS Addresses", e);
+ }
+ }
+
+ private static final InetAddress[] GOOGLE_DNS_LIST =
+ new InetAddress[] {GOOGLE_DNS_4, GOOGLE_DNS_6};
+
+ private static final int DROID_SPI = 0xD1201D;
+
+ private static final byte[] CRYPT_KEY =
+ new byte[] {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+ 0x0E, 0x0F
+ };
+ private static final byte[] AUTH_KEY =
+ new byte[] {
+ 0x7A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x7F
+ };
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+ mISM = (IpSecManager) getContext().getSystemService(Context.IPSEC_SERVICE);
+ }
+
+ /*
+ * Allocate a random SPI
+ * Allocate a specific SPI using previous randomly created SPI value
+ * Realloc the same SPI that was specifically created (expect SpiUnavailable)
+ * Close SPIs
+ */
+ public void testAllocSpi() throws Exception {
+ for (InetAddress addr : GOOGLE_DNS_LIST) {
+ IpSecManager.SecurityParameterIndex randomSpi = null, droidSpi = null;
+ randomSpi =
+ mISM.reserveSecurityParameterIndex(
+ IpSecTransform.DIRECTION_OUT,
+ addr);
+ assertTrue(randomSpi.getSpi() != IpSecManager.INVALID_SECURITY_PARAMETER_INDEX);
+
+ droidSpi =
+ mISM.reserveSecurityParameterIndex(
+ IpSecTransform.DIRECTION_IN, addr, DROID_SPI);
+ assertTrue(droidSpi.getSpi() == DROID_SPI);
+
+ try {
+ mISM.reserveSecurityParameterIndex(IpSecTransform.DIRECTION_IN, addr, DROID_SPI);
+ fail("Duplicate SPI was allowed to be created");
+ } catch (IpSecManager.SpiUnavailableException expected) {
+ // This is a success case because we expect a dupe SPI to throw
+ }
+
+ randomSpi.close();
+ droidSpi.close();
+ }
+ }
+
+ /*
+ * Alloc outbound SPI
+ * Alloc inbound SPI
+ * Create transport mode transform
+ * open socket
+ * apply transform to socket
+ * send data on socket
+ * release transform
+ * send data (expect exception)
+ */
+ public void testCreateTransform() throws Exception {
+ InetAddress local = InetAddress.getLoopbackAddress();
+ IpSecManager.SecurityParameterIndex outSpi =
+ mISM.reserveSecurityParameterIndex(
+ IpSecTransform.DIRECTION_OUT,
+ local);
+
+ IpSecManager.SecurityParameterIndex inSpi =
+ mISM.reserveSecurityParameterIndex(
+ IpSecTransform.DIRECTION_IN, local, outSpi.getSpi());
+
+ IpSecTransform transform =
+ new IpSecTransform.Builder(mContext)
+ .setSpi(IpSecTransform.DIRECTION_OUT, outSpi)
+ .setEncryption(
+ IpSecTransform.DIRECTION_OUT,
+ new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+ .setAuthentication(
+ IpSecTransform.DIRECTION_OUT,
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_HMAC_SHA256,
+ AUTH_KEY,
+ AUTH_KEY.length * 8))
+ .setSpi(IpSecTransform.DIRECTION_IN, inSpi)
+ .setEncryption(
+ IpSecTransform.DIRECTION_IN,
+ new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, CRYPT_KEY))
+ .setAuthentication(
+ IpSecTransform.DIRECTION_IN,
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_HMAC_SHA256,
+ AUTH_KEY,
+ CRYPT_KEY.length * 8))
+ .buildTransportModeTransform(local);
+
+ DatagramSocket localSocket;
+ localSocket = new DatagramSocket(8888);
+
+ localSocket.setSoTimeout(500);
+ mISM.applyTransportModeTransform(localSocket, transform);
+ byte[] data = new String("Best test data ever!").getBytes("UTF-8");
+
+ DatagramPacket out = new DatagramPacket(data, data.length, local, 8888);
+ localSocket.send(out);
+ DatagramPacket in = new DatagramPacket(new byte[data.length], data.length);
+
+ localSocket.receive(in);
+ Log.d(TAG, Arrays.toString(data));
+ Log.d(TAG, Arrays.toString(in.getData()));
+ assertTrue(Arrays.equals(data, in.getData()));
+ transform.close();
+ try {
+ localSocket.send(out);
+ } catch (IOException e) {
+ }
+
+ mISM.removeTransportModeTransform(localSocket, transform);
+ }
+}
diff --git a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java
index 103d1da..7c5a1b3 100644
--- a/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java
+++ b/tests/cts/net/src/android/net/cts/LocalServerSocketTest.java
@@ -38,6 +38,9 @@
clientSocket.connect(new LocalSocketAddress(address));
LocalSocket serverSocket = localServerSocket.accept();
+ assertTrue(serverSocket.isConnected());
+ assertTrue(serverSocket.isBound());
+
// send data from client to server
OutputStream clientOutStream = clientSocket.getOutputStream();
clientOutStream.write(12);
diff --git a/tests/cts/net/src/android/net/cts/LocalSocketTest.java b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
index 0ff4a30..6e61705 100644
--- a/tests/cts/net/src/android/net/cts/LocalSocketTest.java
+++ b/tests/cts/net/src/android/net/cts/LocalSocketTest.java
@@ -50,7 +50,20 @@
assertFalse(clientSocket.isConnected());
clientSocket.connect(locSockAddr);
assertTrue(clientSocket.isConnected());
+
LocalSocket serverSocket = localServerSocket.accept();
+ assertTrue(serverSocket.isConnected());
+ assertTrue(serverSocket.isBound());
+ try {
+ serverSocket.bind(localServerSocket.getLocalSocketAddress());
+ fail("Cannot bind a LocalSocket from accept()");
+ } catch (IOException expected) {
+ }
+ try {
+ serverSocket.connect(locSockAddr);
+ fail("Cannot connect a LocalSocket from accept()");
+ } catch (IOException expected) {
+ }
Credentials credent = clientSocket.getPeerCredentials();
assertTrue(0 != credent.getPid());
@@ -274,6 +287,42 @@
}
}
+ // http://b/34095140
+ public void testLocalSocketCreatedFromFileDescriptor() throws Exception {
+ String address = ADDRESS_PREFIX + "_testLocalSocketCreatedFromFileDescriptor";
+
+ // Establish connection between a local client and server to get a valid client socket file
+ // descriptor.
+ try (LocalSocketPair socketPair = LocalSocketPair.createConnectedSocketPair(address)) {
+ // Extract the client FileDescriptor we can use.
+ FileDescriptor fileDescriptor = socketPair.clientSocket.getFileDescriptor();
+ assertTrue(fileDescriptor.valid());
+
+ // Create the LocalSocket we want to test.
+ LocalSocket clientSocketCreatedFromFileDescriptor =
+ LocalSocket.createConnectedLocalSocket(fileDescriptor);
+ assertTrue(clientSocketCreatedFromFileDescriptor.isConnected());
+ assertTrue(clientSocketCreatedFromFileDescriptor.isBound());
+
+ // Test the LocalSocket can be used for communication.
+ LocalSocket serverSocket = socketPair.serverSocket.accept();
+ OutputStream clientOutputStream =
+ clientSocketCreatedFromFileDescriptor.getOutputStream();
+ InputStream serverInputStream = serverSocket.getInputStream();
+
+ clientOutputStream.write(12);
+ assertEquals(12, serverInputStream.read());
+
+ // Closing clientSocketCreatedFromFileDescriptor does not close the file descriptor.
+ clientSocketCreatedFromFileDescriptor.close();
+ assertTrue(fileDescriptor.valid());
+
+ // .. while closing the LocalSocket that owned the file descriptor does.
+ socketPair.clientSocket.close();
+ assertFalse(fileDescriptor.valid());
+ }
+ }
+
public void testFlush() throws Exception {
String address = ADDRESS_PREFIX + "_testFlush";
diff --git a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
index 545541d..7987a50 100644
--- a/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
+++ b/tests/cts/net/src/android/net/http/cts/HttpResponseCacheTest.java
@@ -38,10 +38,11 @@
public final class HttpResponseCacheTest extends TestCase {
private File cacheDir;
- private MockWebServer server = new MockWebServer();
+ private MockWebServer server;
@Override public void setUp() throws Exception {
super.setUp();
+ server = new MockWebServer();
String tmp = System.getProperty("java.io.tmpdir");
cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
cacheDir.mkdirs();
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
new file mode 100644
index 0000000..1f7b31b
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/aware/cts/SingleDeviceTest.java
@@ -0,0 +1,738 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.aware.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.ConnectivityManager;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.WifiManager;
+import android.net.wifi.aware.AttachCallback;
+import android.net.wifi.aware.Characteristics;
+import android.net.wifi.aware.DiscoverySessionCallback;
+import android.net.wifi.aware.IdentityChangedListener;
+import android.net.wifi.aware.PeerHandle;
+import android.net.wifi.aware.PublishConfig;
+import android.net.wifi.aware.PublishDiscoverySession;
+import android.net.wifi.aware.SubscribeConfig;
+import android.net.wifi.aware.SubscribeDiscoverySession;
+import android.net.wifi.aware.WifiAwareManager;
+import android.net.wifi.aware.WifiAwareSession;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Wi-Fi Aware CTS test suite: single device testing. Performs tests on a single
+ * device to validate Wi-Fi Aware.
+ */
+public class SingleDeviceTest extends AndroidTestCase {
+ private static final String TAG = "WifiAwareCtsTests";
+
+ // wait for Wi-Fi Aware to become available
+ static private final int WAIT_FOR_AWARE_CHANGE_SECS = 10;
+
+ private final Object mLock = new Object();
+ private final HandlerThread mHandlerThread = new HandlerThread("SingleDeviceTest");
+ private final Handler mHandler;
+ {
+ mHandlerThread.start();
+ mHandler = new Handler(mHandlerThread.getLooper());
+ }
+
+ private WifiAwareManager mWifiAwareManager;
+ private WifiManager mWifiManager;
+ private WifiManager.WifiLock mWifiLock;
+ private ConnectivityManager mConnectivityManager;
+
+ // used to store any WifiAwareSession allocated during tests - will clean-up after tests
+ private List<WifiAwareSession> mSessions = new ArrayList<>();
+
+ private class WifiAwareBroadcastReceiver extends BroadcastReceiver {
+ private CountDownLatch mBlocker = new CountDownLatch(1);
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED.equals(intent.getAction())) {
+ mBlocker.countDown();
+ }
+ }
+
+ boolean waitForStateChange() throws InterruptedException {
+ return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
+ }
+ }
+
+ private class AttachCallbackTest extends AttachCallback {
+ static final int ATTACHED = 0;
+ static final int ATTACH_FAILED = 1;
+ static final int ERROR = 2; // no callback: timeout, interruption
+
+ private CountDownLatch mBlocker = new CountDownLatch(1);
+ private int mCallbackCalled = ERROR; // garbage init
+ private WifiAwareSession mSession = null;
+
+ @Override
+ public void onAttached(WifiAwareSession session) {
+ mCallbackCalled = ATTACHED;
+ mSession = session;
+ synchronized (mLock) {
+ mSessions.add(session);
+ }
+ mBlocker.countDown();
+ }
+
+ @Override
+ public void onAttachFailed() {
+ mCallbackCalled = ATTACH_FAILED;
+ mBlocker.countDown();
+ }
+
+ /**
+ * Waits for any of the callbacks to be called - or an error (timeout, interruption).
+ * Returns one of the ATTACHED, ATTACH_FAILED, or ERROR values.
+ */
+ int waitForAnyCallback() {
+ try {
+ boolean noTimeout = mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
+ if (noTimeout) {
+ return mCallbackCalled;
+ } else {
+ return ERROR;
+ }
+ } catch (InterruptedException e) {
+ return ERROR;
+ }
+ }
+
+ /**
+ * Access the session created by a callback. Only useful to be called after calling
+ * waitForAnyCallback() and getting the ATTACHED code back.
+ */
+ WifiAwareSession getSession() {
+ return mSession;
+ }
+ }
+
+ private class IdentityChangedListenerTest extends IdentityChangedListener {
+ private CountDownLatch mBlocker = new CountDownLatch(1);
+ private byte[] mMac = null;
+
+ @Override
+ public void onIdentityChanged(byte[] mac) {
+ mMac = mac;
+ mBlocker.countDown();
+ }
+
+ /**
+ * Waits for the listener callback to be called - or an error (timeout, interruption).
+ * Returns true on callback called, false on error (timeout, interruption).
+ */
+ boolean waitForListener() {
+ try {
+ return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the MAC address of the discovery interface supplied to the triggered callback.
+ */
+ byte[] getMac() {
+ return mMac;
+ }
+ }
+
+ private class DiscoverySessionCallbackTest extends DiscoverySessionCallback {
+ static final int ON_PUBLISH_STARTED = 0;
+ static final int ON_SUBSCRIBE_STARTED = 1;
+ static final int ON_SESSION_CONFIG_UPDATED = 2;
+ static final int ON_SESSION_CONFIG_FAILED = 3;
+ static final int ON_SESSION_TERMINATED = 4;
+ static final int ON_SERVICE_DISCOVERED = 5;
+ static final int ON_MESSAGE_SEND_SUCCEEDED = 6;
+ static final int ON_MESSAGE_SEND_FAILED = 7;
+ static final int ON_MESSAGE_RECEIVED = 8;
+
+ private final Object mLocalLock = new Object();
+
+ private CountDownLatch mBlocker;
+ private int mCurrentWaitForCallback;
+ private ArrayDeque<Integer> mCallbackQueue = new ArrayDeque<>();
+
+ private PublishDiscoverySession mPublishDiscoverySession;
+ private SubscribeDiscoverySession mSubscribeDiscoverySession;
+
+ private void processCallback(int callback) {
+ synchronized (mLocalLock) {
+ if (mBlocker != null && mCurrentWaitForCallback == callback) {
+ mBlocker.countDown();
+ } else {
+ mCallbackQueue.addLast(callback);
+ }
+ }
+ }
+
+ @Override
+ public void onPublishStarted(PublishDiscoverySession session) {
+ mPublishDiscoverySession = session;
+ processCallback(ON_PUBLISH_STARTED);
+ }
+
+ @Override
+ public void onSubscribeStarted(SubscribeDiscoverySession session) {
+ mSubscribeDiscoverySession = session;
+ processCallback(ON_SUBSCRIBE_STARTED);
+ }
+
+ @Override
+ public void onSessionConfigUpdated() {
+ processCallback(ON_SESSION_CONFIG_UPDATED);
+ }
+
+ @Override
+ public void onSessionConfigFailed() {
+ processCallback(ON_SESSION_CONFIG_FAILED);
+ }
+
+ @Override
+ public void onSessionTerminated() {
+ processCallback(ON_SESSION_TERMINATED);
+ }
+
+ @Override
+ public void onServiceDiscovered(PeerHandle peerHandle, byte[] serviceSpecificInfo,
+ List<byte[]> matchFilter) {
+ processCallback(ON_SERVICE_DISCOVERED);
+ }
+
+ @Override
+ public void onMessageSendSucceeded(int messageId) {
+ processCallback(ON_MESSAGE_SEND_SUCCEEDED);
+ }
+
+ @Override
+ public void onMessageSendFailed(int messageId) {
+ processCallback(ON_MESSAGE_SEND_FAILED);
+ }
+
+ @Override
+ public void onMessageReceived(PeerHandle peerHandle, byte[] message) {
+ processCallback(ON_MESSAGE_RECEIVED);
+ }
+
+ /**
+ * Wait for the specified callback - any of the ON_* constants. Returns a true
+ * on success (specified callback triggered) or false on failure (timed-out or
+ * interrupted while waiting for the requested callback).
+ *
+ * Note: other callbacks happening while while waiting for the specified callback will
+ * be queued.
+ */
+ boolean waitForCallback(int callback) {
+ synchronized (mLocalLock) {
+ boolean found = mCallbackQueue.remove(callback);
+ if (found) {
+ return true;
+ }
+
+ mCurrentWaitForCallback = callback;
+ mBlocker = new CountDownLatch(1);
+ }
+
+ try {
+ return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Indicates whether the specified callback (any of the ON_* constants) has already
+ * happened and in the queue. Useful when the order of events is important.
+ */
+ boolean hasCallbackAlreadyHappened(int callback) {
+ synchronized (mLocalLock) {
+ return mCallbackQueue.contains(callback);
+ }
+ }
+
+ /**
+ * Returns the last created publish discovery session.
+ */
+ PublishDiscoverySession getPublishDiscoverySession() {
+ PublishDiscoverySession session = mPublishDiscoverySession;
+ mPublishDiscoverySession = null;
+ return session;
+ }
+
+ /**
+ * Returns the last created subscribe discovery session.
+ */
+ SubscribeDiscoverySession getSubscribeDiscoverySession() {
+ SubscribeDiscoverySession session = mSubscribeDiscoverySession;
+ mSubscribeDiscoverySession = null;
+ return session;
+ }
+ }
+
+ private class NetworkCallbackTest extends ConnectivityManager.NetworkCallback {
+ private CountDownLatch mBlocker = new CountDownLatch(1);
+
+ @Override
+ public void onUnavailable() {
+ mBlocker.countDown();
+ }
+
+ /**
+ * Wait for the onUnavailable() callback to be triggered. Returns true if triggered,
+ * otherwise (timed-out, interrupted) returns false.
+ */
+ boolean waitForOnUnavailable() {
+ try {
+ return mBlocker.await(WAIT_FOR_AWARE_CHANGE_SECS, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ mWifiAwareManager = (WifiAwareManager) getContext().getSystemService(
+ Context.WIFI_AWARE_SERVICE);
+ assertNotNull("Wi-Fi Aware Manager", mWifiAwareManager);
+
+ mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+ assertNotNull("Wi-Fi Manager", mWifiManager);
+ mWifiLock = mWifiManager.createWifiLock(TAG);
+ mWifiLock.acquire();
+ if (!mWifiManager.isWifiEnabled()) {
+ mWifiManager.setWifiEnabled(true);
+ }
+
+ mConnectivityManager = (ConnectivityManager) getContext().getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ assertNotNull("Connectivity Manager", mConnectivityManager);
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
+ WifiAwareBroadcastReceiver receiver = new WifiAwareBroadcastReceiver();
+ mContext.registerReceiver(receiver, intentFilter);
+ if (!mWifiAwareManager.isAvailable()) {
+ assertTrue("Timeout waiting for Wi-Fi Aware to change status",
+ receiver.waitForStateChange());
+ assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
+ }
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ super.tearDown();
+ return;
+ }
+
+ synchronized (mLock) {
+ for (WifiAwareSession session : mSessions) {
+ // no damage from destroying twice (i.e. ok if test cleaned up after itself already)
+ session.destroy();
+ }
+ mSessions.clear();
+ }
+
+ super.tearDown();
+ }
+
+ /**
+ * Validate:
+ * - Characteristics are available
+ * - Characteristics values are legitimate. Not in the CDD. However, the tested values are
+ * based on the Wi-Fi Aware protocol.
+ */
+ public void testCharacteristics() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ Characteristics characteristics = mWifiAwareManager.getCharacteristics();
+ assertNotNull("Wi-Fi Aware characteristics are null", characteristics);
+ assertEquals("Service Name Length", characteristics.getMaxServiceNameLength(), 255);
+ assertEquals("Service Specific Information Length",
+ characteristics.getMaxServiceSpecificInfoLength(), 255);
+ assertEquals("Match Filter Length", characteristics.getMaxMatchFilterLength(), 255);
+ }
+
+ /**
+ * Validate that on Wi-Fi Aware availability change we get a broadcast + the API returns
+ * correct status.
+ */
+ public void testAvailabilityStatusChange() throws Exception {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(WifiAwareManager.ACTION_WIFI_AWARE_STATE_CHANGED);
+
+ // 1. Disable Wi-Fi
+ WifiAwareBroadcastReceiver receiver1 = new WifiAwareBroadcastReceiver();
+ mContext.registerReceiver(receiver1, intentFilter);
+ mWifiManager.setWifiEnabled(false);
+
+ assertTrue("Timeout waiting for Wi-Fi Aware to change status",
+ receiver1.waitForStateChange());
+ assertFalse("Wi-Fi Aware is available (should not be)", mWifiAwareManager.isAvailable());
+
+ // 2. Enable Wi-Fi
+ WifiAwareBroadcastReceiver receiver2 = new WifiAwareBroadcastReceiver();
+ mContext.registerReceiver(receiver2, intentFilter);
+ mWifiManager.setWifiEnabled(true);
+
+ assertTrue("Timeout waiting for Wi-Fi Aware to change status",
+ receiver2.waitForStateChange());
+ assertTrue("Wi-Fi Aware is not available (should be)", mWifiAwareManager.isAvailable());
+ }
+
+ /**
+ * Validate that can attach to Wi-Fi Aware.
+ */
+ public void testAttachNoIdentity() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+ session.destroy();
+ }
+
+ /**
+ * Validate that can attach to Wi-Fi Aware and get identity information. Use the identity
+ * information to validate that MAC address changes on every attach.
+ *
+ * Note: relies on no other entity using Wi-Fi Aware during the CTS test. Since if it is used
+ * then the attach/destroy will not correspond to enable/disable and will not result in a new
+ * MAC address being generated.
+ */
+ public void testAttachDiscoveryAddressChanges() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ final int numIterations = 10;
+ Set<TestUtils.MacWrapper> macs = new HashSet<>();
+
+ for (int i = 0; i < numIterations; ++i) {
+ AttachCallbackTest attachCb = new AttachCallbackTest();
+ IdentityChangedListenerTest identityL = new IdentityChangedListenerTest();
+ mWifiAwareManager.attach(attachCb, identityL, mHandler);
+ assertEquals("Wi-Fi Aware attach: iteration " + i, AttachCallbackTest.ATTACHED,
+ attachCb.waitForAnyCallback());
+ assertTrue("Wi-Fi Aware attach: iteration " + i, identityL.waitForListener());
+
+ WifiAwareSession session = attachCb.getSession();
+ assertNotNull("Wi-Fi Aware session: iteration " + i, session);
+
+ byte[] mac = identityL.getMac();
+ assertNotNull("Wi-Fi Aware discovery MAC: iteration " + i, mac);
+
+ session.destroy();
+
+ macs.add(new TestUtils.MacWrapper(mac));
+ }
+
+ assertEquals("", numIterations, macs.size());
+ }
+
+ /**
+ * Validate a successful publish discovery session lifetime: publish, update publish, destroy.
+ */
+ public void testPublishDiscoverySuccess() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ final String serviceName = "ValidName";
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ serviceName).build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+
+ // 1. publish
+ session.publish(publishConfig, discoveryCb, mHandler);
+ assertTrue("Publish started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
+ PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
+ assertNotNull("Publish session", discoverySession);
+
+ // 2. update-publish
+ publishConfig = new PublishConfig.Builder().setServiceName(
+ serviceName).setServiceSpecificInfo("extras".getBytes()).build();
+ discoverySession.updatePublish(publishConfig);
+ assertTrue("Publish update", discoveryCb.waitForCallback(
+ DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
+
+ // 3. destroy
+ assertFalse("Publish not terminated", discoveryCb.hasCallbackAlreadyHappened(
+ DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
+ discoverySession.destroy();
+
+ // 4. try update post-destroy: should time-out waiting for cb
+ discoverySession.updatePublish(publishConfig);
+ assertFalse("Publish update post destroy", discoveryCb.waitForCallback(
+ DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
+
+ session.destroy();
+ }
+
+ /**
+ * Validate a successful subscribe discovery session lifetime: subscribe, update subscribe,
+ * destroy.
+ */
+ public void testSubscribeDiscoverySuccess() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ final String serviceName = "ValidName";
+
+ WifiAwareSession session = attachAndGetSession();
+
+ SubscribeConfig subscribeConfig = new SubscribeConfig.Builder().setServiceName(
+ serviceName).build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+
+ // 1. subscribe
+ session.subscribe(subscribeConfig, discoveryCb, mHandler);
+ assertTrue("Subscribe started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_SUBSCRIBE_STARTED));
+ SubscribeDiscoverySession discoverySession = discoveryCb.getSubscribeDiscoverySession();
+ assertNotNull("Subscribe session", discoverySession);
+
+ // 2. update-subscribe
+ subscribeConfig = new SubscribeConfig.Builder().setServiceName(
+ serviceName).setServiceSpecificInfo("extras".getBytes()).build();
+ discoverySession.updateSubscribe(subscribeConfig);
+ assertTrue("Subscribe update", discoveryCb.waitForCallback(
+ DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
+
+ // 3. destroy
+ assertFalse("Subscribe not terminated", discoveryCb.hasCallbackAlreadyHappened(
+ DiscoverySessionCallbackTest.ON_SESSION_TERMINATED));
+ discoverySession.destroy();
+
+ // 4. try update post-destroy: should time-out waiting for cb
+ discoverySession.updateSubscribe(subscribeConfig);
+ assertFalse("Subscribe update post destroy", discoveryCb.waitForCallback(
+ DiscoverySessionCallbackTest.ON_SESSION_CONFIG_UPDATED));
+
+ session.destroy();
+ }
+
+ /**
+ * Test the send message flow. Since testing single device cannot send to a real peer -
+ * validate that sending to a bogus peer fails.
+ */
+ public void testSendMessageFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+
+ // 1. publish
+ session.publish(publishConfig, discoveryCb, mHandler);
+ assertTrue("Publish started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
+ PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
+ assertNotNull("Publish session", discoverySession);
+
+ // 2. send a message with a null peer-handle - expect exception
+ try {
+ discoverySession.sendMessage(null, -1290, "some message".getBytes());
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException e) {
+ // empty
+ }
+
+ discoverySession.destroy();
+ session.destroy();
+ }
+
+ /**
+ * Request an Aware data-path (open) on a Publish discovery session (which can be done with a
+ * null peer - to accept all requests). Validate that times-out.
+ */
+ public void testDataPathOpenInContextOfDiscoveryFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+ NetworkCallbackTest networkCb = new NetworkCallbackTest();
+
+ // 1. publish
+ session.publish(publishConfig, discoveryCb, mHandler);
+ assertTrue("Publish started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
+ PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
+ assertNotNull("Publish session", discoverySession);
+
+ // 2. request an AWARE network
+ NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
+ discoverySession.createNetworkSpecifierOpen(null)).build();
+ mConnectivityManager.requestNetwork(nr, networkCb, 2000);
+ assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
+
+ discoverySession.destroy();
+ session.destroy();
+ }
+
+ /**
+ * Request an Aware data-path (encrypted) on a Publish discovery session (which can be done
+ * with a null peer - to accept all requests). Validate that times-out.
+ */
+ public void testDataPathPassphraseInContextOfDiscoveryFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+ NetworkCallbackTest networkCb = new NetworkCallbackTest();
+
+ // 1. publish
+ session.publish(publishConfig, discoveryCb, mHandler);
+ assertTrue("Publish started",
+ discoveryCb.waitForCallback(DiscoverySessionCallbackTest.ON_PUBLISH_STARTED));
+ PublishDiscoverySession discoverySession = discoveryCb.getPublishDiscoverySession();
+ assertNotNull("Publish session", discoverySession);
+
+ // 2. request an AWARE network
+ NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
+ discoverySession.createNetworkSpecifierPassphrase(null,
+ "Some very long but not very good passphrase")).build();
+ mConnectivityManager.requestNetwork(nr, networkCb, 2000);
+ assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
+
+ discoverySession.destroy();
+ session.destroy();
+ }
+
+ /**
+ * Request an Aware data-path (open) as a Responder with no peer MAC address (i.e. accept any
+ * peer request). Validate that times-out.
+ */
+ public void testDataPathOpenOutOfBandFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+ NetworkCallbackTest networkCb = new NetworkCallbackTest();
+
+ // 1. request an AWARE network
+ NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
+ session.createNetworkSpecifierOpen(
+ WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null)).build();
+ mConnectivityManager.requestNetwork(nr, networkCb, 2000);
+ assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
+
+ session.destroy();
+ }
+
+ /**
+ * Request an Aware data-path (encrypted) as a Responder with no peer MAC address (i.e.
+ * accept any peer request). Validate that times-out.
+ */
+ public void testDataPathPassphraseOutOfBandFail() {
+ if (!TestUtils.shouldTestWifiAware(getContext())) {
+ return;
+ }
+
+ WifiAwareSession session = attachAndGetSession();
+
+ PublishConfig publishConfig = new PublishConfig.Builder().setServiceName(
+ "ValidName").build();
+ DiscoverySessionCallbackTest discoveryCb = new DiscoverySessionCallbackTest();
+ NetworkCallbackTest networkCb = new NetworkCallbackTest();
+
+ // 1. request an AWARE network
+ NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
+ NetworkCapabilities.TRANSPORT_WIFI_AWARE).setNetworkSpecifier(
+ session.createNetworkSpecifierPassphrase(
+ WifiAwareManager.WIFI_AWARE_DATA_PATH_ROLE_RESPONDER, null,
+ "abcdefghihk")).build();
+ mConnectivityManager.requestNetwork(nr, networkCb, 2000);
+ assertTrue("OnUnavailable received", networkCb.waitForOnUnavailable());
+
+ session.destroy();
+ }
+
+ // local utilities
+
+ private WifiAwareSession attachAndGetSession() {
+ AttachCallbackTest attachCb = new AttachCallbackTest();
+ mWifiAwareManager.attach(attachCb, mHandler);
+ int cbCalled = attachCb.waitForAnyCallback();
+ assertEquals("Wi-Fi Aware attach", AttachCallbackTest.ATTACHED, cbCalled);
+
+ WifiAwareSession session = attachCb.getSession();
+ assertNotNull("Wi-Fi Aware session", session);
+
+ return session;
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java
new file mode 100644
index 0000000..a12c8bb
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/aware/cts/TestUtils.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.aware.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+
+import java.util.Arrays;
+
+/**
+ * Test utilities for Wi-Fi Aware CTS test suite.
+ */
+class TestUtils {
+ static final String TAG = "WifiAwareCtsTests";
+
+ /**
+ * Returns a flag indicating whether or not Wi-Fi Aware should be tested. Wi-Fi Aware
+ * should be tested if the feature is supported on the current device.
+ */
+ static boolean shouldTestWifiAware(Context context) {
+ final PackageManager pm = context.getPackageManager();
+ return pm.hasSystemFeature(PackageManager.FEATURE_WIFI_AWARE);
+ }
+
+ /**
+ * Wraps a byte[] (MAC address representation). Intended to provide hash and equality operators
+ * so that the MAC address can be used in containers.
+ */
+ static class MacWrapper {
+ private byte[] mMac;
+
+ MacWrapper(byte[] mac) {
+ mMac = mac;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (!(o instanceof MacWrapper)) {
+ return false;
+ }
+
+ MacWrapper lhs = (MacWrapper) o;
+ return Arrays.equals(mMac, lhs.mMac);
+ }
+
+ @Override
+ public int hashCode() {
+ return Arrays.hashCode(mMac);
+ }
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java
new file mode 100644
index 0000000..52ed2a6
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/cts/ConfigParserTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.cts;
+
+import android.net.wifi.hotspot2.ConfigParser;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
+import android.test.AndroidTestCase;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+/**
+ * CTS tests for Hotspot 2.0 Release 1 installation file parsing API.
+ */
+public class ConfigParserTest extends AndroidTestCase {
+ /**
+ * Hotspot 2.0 Release 1 installation file that contains a Passpoint profile and a
+ * CA (Certificate Authority) X.509 certificate {@link FakeKeys#CA_CERT0}.
+ */
+ private static final String PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT =
+ "assets/HSR1ProfileWithCACert.base64";
+
+ /**
+ * Read the content of the given resource file into a String.
+ *
+ * @param filename String name of the file
+ * @return String
+ * @throws IOException
+ */
+ private String loadResourceFile(String filename) throws IOException {
+ InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder builder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ builder.append(line).append("\n");
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
+ * XML file {@link #PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT}.
+ *
+ * @return {@link PasspointConfiguration}
+ */
+ private PasspointConfiguration generateConfigurationFromProfile() {
+ PasspointConfiguration config = new PasspointConfiguration();
+
+ // HomeSP configuration.
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFriendlyName("Century House");
+ homeSp.setFqdn("mi6.co.uk");
+ homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
+ config.setHomeSp(homeSp);
+
+ // Credential configuration.
+ Credential credential = new Credential();
+ credential.setRealm("shaken.stirred.com");
+ Credential.UserCredential userCredential = new Credential.UserCredential();
+ userCredential.setUsername("james");
+ userCredential.setPassword("Ym9uZDAwNw==");
+ userCredential.setEapType(21);
+ userCredential.setNonEapInnerMethod("MS-CHAP-V2");
+ credential.setUserCredential(userCredential);
+ Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+ certCredential.setCertType("x509v3");
+ byte[] certSha256Fingerprint = new byte[32];
+ Arrays.fill(certSha256Fingerprint, (byte)0x1f);
+ certCredential.setCertSha256Fingerprint(certSha256Fingerprint);
+ credential.setCertCredential(certCredential);
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("imsi");
+ simCredential.setEapType(24);
+ credential.setSimCredential(simCredential);
+ credential.setCaCertificate(FakeKeys.CA_CERT0);
+ config.setCredential(credential);
+ return config;
+ }
+
+ /**
+ * Verify a valid installation file is parsed successfully with the matching contents.
+ *
+ * @throws Exception
+ */
+ public void testParseConfigFile() throws Exception {
+ String configStr = loadResourceFile(PASSPOINT_INSTALLATION_FILE_WITH_CA_CERT);
+ PasspointConfiguration expectedConfig = generateConfigurationFromProfile();
+ PasspointConfiguration actualConfig =
+ ConfigParser.parsePasspointConfig(
+ "application/x-wifi-config", configStr.getBytes());
+ assertTrue(actualConfig.equals(expectedConfig));
+ }
+}
\ No newline at end of file
diff --git a/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java
new file mode 100644
index 0000000..f422c2f
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/cts/FakeKeys.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2016 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 android.net.wifi.cts;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+/**
+ * A class containing test certificates and private keys.
+ */
+public class FakeKeys {
+ private static final String CA_CERT0_STRING = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDKDCCAhCgAwIBAgIJAILlFdwzLVurMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
+ "BAMTB0VBUCBDQTEwHhcNMTYwMTEyMTE1MDE1WhcNMjYwMTA5MTE1MDE1WjASMRAw\n" +
+ "DgYDVQQDEwdFQVAgQ0ExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
+ "znAPUz26Msae4ws43czR41/J2QtrSIZUKmVUsVumDbYHrPNvTXKSMXAcewORDQYX\n" +
+ "RqvHvpn8CscB1+oGXZvHwxj4zV0WKoK2zeXkau3vcyl3HIKupJfq2TEACefVjj0t\n" +
+ "JW+X35PGWp9/H5zIUNVNVjS7Ums84IvKhRB8512PB9UyHagXYVX5GWpAcVpyfrlR\n" +
+ "FI9Qdhh+Pbk0uyktdbf/CdfgHOoebrTtwRljM0oDtX+2Cv6j0wBK7hD8pPvf1+uy\n" +
+ "GzczigAU/4Kw7eZqydf9B+5RupR+IZipX41xEiIrKRwqi517WWzXcjaG2cNbf451\n" +
+ "xpH5PnV3i1tq04jMGQUzFwIDAQABo4GAMH4wHQYDVR0OBBYEFIwX4vs8BiBcScod\n" +
+ "5noZHRM8E4+iMEIGA1UdIwQ7MDmAFIwX4vs8BiBcScod5noZHRM8E4+ioRakFDAS\n" +
+ "MRAwDgYDVQQDEwdFQVAgQ0ExggkAguUV3DMtW6swDAYDVR0TBAUwAwEB/zALBgNV\n" +
+ "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFfQqOTA7Rv7K+luQ7pnas4BYwHE\n" +
+ "9GEP/uohv6KOy0TGQFbrRTjFoLVNB9BZ1ymMDZ0/TIwIUc7wi7a8t5mEqYH153wW\n" +
+ "aWooiSjyLLhuI4sNrNCOtisdBq2r2MFXt6h0mAQYOPv8R8K7/fgSxGFqzhyNmmVL\n" +
+ "1qBJldx34SpwsTALQVPb4hGwJzZfr1PcpEQx6xMnTl8xEWZE3Ms99uaUxbQqIwRu\n" +
+ "LgAOkNCmY2m89VhzaHJ1uV85AdM/tD+Ysmlnnjt9LRCejbBipjIGjOXrg1JP+lxV\n" +
+ "muM4vH+P/mlmxsPPz0d65b+EGmJZpoLkO/tdNNvCYzjJpTEWpEsO6NMhKYo=\n" +
+ "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CA_CERT0 = loadCertificate(CA_CERT0_STRING);
+
+ private static final String CA_CERT1_STRING = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIDKDCCAhCgAwIBAgIJAOM5SzKO2pzCMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV\n" +
+ "BAMTB0VBUCBDQTAwHhcNMTYwMTEyMDAxMDQ3WhcNMjYwMTA5MDAxMDQ3WjASMRAw\n" +
+ "DgYDVQQDEwdFQVAgQ0EwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" +
+ "89ug+IEKVQXnJGKg5g4uVHg6J/8iRUxR5k2eH5o03hrJNMfN2D+cBe/wCiZcnWbI\n" +
+ "GbGZACWm2nQth2wy9Zgm2LOd3b4ocrHYls3XLq6Qb5Dd7a0JKU7pdGufiNVEkrmF\n" +
+ "EB+N64wgwH4COTvCiN4erp5kyJwkfqAl2xLkZo0C464c9XoyQOXbmYD9A8v10wZu\n" +
+ "jyNsEo7Nr2USyw+qhjWSbFbEirP77Tvx+7pJQJwdtk1V9Tn73T2dGF2WHYejei9S\n" +
+ "mcWpdIUqsu9etYH+zDmtu7I1xlkwiaVsNr2+D+qaCJyOYqrDTKVNK5nmbBPXDWZc\n" +
+ "NoDbTOoqquX7xONpq9M6jQIDAQABo4GAMH4wHQYDVR0OBBYEFAZ3A2S4qJZZwuNY\n" +
+ "wkJ6mAdc0gVdMEIGA1UdIwQ7MDmAFAZ3A2S4qJZZwuNYwkJ6mAdc0gVdoRakFDAS\n" +
+ "MRAwDgYDVQQDEwdFQVAgQ0EwggkA4zlLMo7anMIwDAYDVR0TBAUwAwEB/zALBgNV\n" +
+ "HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAHmdMwEhtys4d0E+t7owBmoVR+lU\n" +
+ "hMCcRtWs8YKX5WIM2kTweT0h/O1xwE1mWmRv/IbDAEb8od4BjAQLhIcolStr2JaO\n" +
+ "9ZzyxjOnNzqeErh/1DHDbb/moPpqfeJ8YiEz7nH/YU56Q8iCPO7TsgS0sNNE7PfN\n" +
+ "IUsBW0yHRgpQ4OxWmiZG2YZWiECRzAC0ecPzo59N5iH4vLQIMTMYquiDeMPQnn1e\n" +
+ "NDGxG8gCtDKIaS6tMg3a28MvWB094pr2ETou8O1C8Ji0Y4hE8QJmSdT7I4+GZjgW\n" +
+ "g94DZ5RiL7sdp3vC48CXOmeT61YBIvhGUsE1rPhXqkpqQ3Z3C4TFF0jXZZc=\n" +
+ "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CA_CERT1 = loadCertificate(CA_CERT1_STRING);
+
+ private static final String CLIENT_CERT_STR = "-----BEGIN CERTIFICATE-----\n" +
+ "MIIE/DCCAuQCAQEwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxCzAJBgNV\n" +
+ "BAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdUZXN0aW5n\n" +
+ "MB4XDTE2MDkzMDIwNTQyOFoXDTE3MDkzMDIwNTQyOFowRDELMAkGA1UEBhMCVVMx\n" +
+ "CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MRAwDgYDVQQKDAdU\n" +
+ "ZXN0aW5nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnpmcbuaeHfnJ\n" +
+ "k+2QNvxmdVFTawyFMNk0USCq5sexscwmxbewG/Rb8YnixwJWS44v2XkSujB67z5C\n" +
+ "s2qudFEhRXKdEuC6idbAuA97KjipHh0AAniWMsyv61fvbgsUC0b0canx3LiDq81p\n" +
+ "y28NNGmAvoazLZUZ4AhBRiwYZY6FKk723gmZoGbEIeG7J1dlXPusc1662rIjz4eU\n" +
+ "zlmmlvqyHfNqnNk8L14Vug6Xh+lOEGN85xhu1YHAEKGrS89kZxs5rum/cZU8KH2V\n" +
+ "v6eKnY03kxjiVLQtnLpm/7VUEoCMGHyruRj+p3my4+DgqMsmsH52RZCBsjyGlpbU\n" +
+ "NOwOTIX6xh+Rqloduz4AnrMYYIiIw2s8g+2zJM7VbcVKx0fGS26BKdrxgrXWfmNE\n" +
+ "nR0/REQ5AxDGw0jfTUvtdTkXAf+K4MDjcNLEZ+MA4rHfAfQWZtUR5BkHCQYxNpJk\n" +
+ "pA0gyk+BpKdC4WdzI14NSWsu5sRCmBCFqH6BTOSEq/V1cNorBxNwLSSTwFFqUDqx\n" +
+ "Y5nQLXygkJf9WHZWtSKeSjtOYgilz7UKzC2s3CsjmIyGFe+SwpuHJnuE4Uc8Z5Cb\n" +
+ "bjNGHPzqL6XnmzZHJp7RF8kBdKdjGC7dCUltzOfICZeKlzOOq+Kw42T/nXjuXvpb\n" +
+ "nkXNxg741Nwd6RecykXJbseFwm3EYxkCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEA\n" +
+ "Ga1mGwI9aXkL2fTPXO9YkAPzoGeX8aeuVYSQaSkNq+5vnogYCyAt3YDHjRG+ewTT\n" +
+ "WbnPA991xRAPac+biJeXWmwvgGj0YuT7e79phAiGkTTnbAjFHGfYnBy/tI/v7btO\n" +
+ "hRNElA5yTJ1m2fVbBEKXzMR83jrT9iyI+YLRN86zUZIaC86xxSbqnrdWN2jOK6MX\n" +
+ "dS8Arp9tPQjC/4gW+2Ilxv68jiYh+5auWHQZVjppWVY//iu4mAbkq1pTwQEhZ8F8\n" +
+ "Zrmh9DHh60hLFcfSuhIAwf/NMzppwdkjy1ruKVrpijhGKGp4OWu8nvOUgHSzxc7F\n" +
+ "PwpVZ5N2Ku4L8MLO6BG2VasRJK7l17TzDXlfLZHJjkuryOFxVaQKt8ZNFgTOaCXS\n" +
+ "E+gpTLksKU7riYckoiP4+H1sn9qcis0e8s4o/uf1UVc8GSdDw61ReGM5oZEDm1u8\n" +
+ "H9x20QU6igLqzyBpqvCKv7JNgU1uB2PAODHH78zJiUfnKd1y+o+J1iWzaGj3EFji\n" +
+ "T8AXksbTP733FeFXfggXju2dyBH+Z1S5BBTEOd1brWgXlHSAZGm97MKZ94r6/tkX\n" +
+ "qfv3fCos0DKz0oV7qBxYS8wiYhzrRVxG6ITAoH8uuUVVQaZF+G4nJ2jEqNbfuKyX\n" +
+ "ATQsVNjNNlDA0J33GobPMjT326wa4YAWMx8PI5PJZ3g=\n" +
+ "-----END CERTIFICATE-----\n";
+ public static final X509Certificate CLIENT_CERT = loadCertificate(CLIENT_CERT_STR);
+
+ private static final byte[] FAKE_RSA_KEY_1 = new byte[] {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
+ (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
+ (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
+ (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
+ (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
+ (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
+ (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
+ (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
+ (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
+ (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
+ (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
+ (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
+ (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
+ (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
+ (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
+ (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
+ (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
+ (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
+ (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
+ (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
+ (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
+ (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
+ (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
+ (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
+ (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
+ (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
+ (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
+ (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
+ (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
+ (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
+ (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
+ (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
+ (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
+ (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
+ (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
+ (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
+ (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
+ (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
+ (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
+ (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
+ (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
+ (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
+ (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
+ (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
+ (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
+ (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
+ (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
+ (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
+ (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
+ (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
+ (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
+ (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
+ (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
+ (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
+ (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
+ (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
+ (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
+ (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
+ (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
+ (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
+ (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
+ (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
+ (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
+ (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
+ (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
+ (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
+ (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
+ (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+ (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
+ (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
+ (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
+ (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
+ (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
+ (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
+ (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
+ (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
+ (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
+ (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
+ (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
+ (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
+ (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
+ (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
+ (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
+ (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
+ (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
+ (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
+ (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
+ (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
+ (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
+ (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
+ (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
+ (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
+ (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
+ (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
+ (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
+ (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
+ (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
+ (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
+ (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
+ (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
+ (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
+ };
+ public static final PrivateKey RSA_KEY1 = loadPrivateRSAKey(FAKE_RSA_KEY_1);
+
+ private static X509Certificate loadCertificate(String blob) {
+ try {
+ final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+ InputStream stream = new ByteArrayInputStream(blob.getBytes(StandardCharsets.UTF_8));
+
+ return (X509Certificate) certFactory.generateCertificate(stream);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private static PrivateKey loadPrivateRSAKey(byte[] fakeKey) {
+ try {
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey));
+ } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
+ return null;
+ }
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java
new file mode 100644
index 0000000..b5e2f77
--- /dev/null
+++ b/tests/cts/net/src/android/net/wifi/cts/PpsMoParserTest.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2017 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 android.net.wifi.cts;
+
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.omadm.PpsMoParser;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
+import android.net.wifi.hotspot2.pps.Policy;
+import android.net.wifi.hotspot2.pps.UpdateParameter;
+import android.test.AndroidTestCase;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * CTS tests for PPS MO (PerProviderSubscription Management Object) XML string parsing API.
+ */
+public class PpsMoParserTest extends AndroidTestCase {
+ private static final String PPS_MO_XML_FILE = "assets/PerProviderSubscription.xml";
+
+ /**
+ * Read the content of the given resource file into a String.
+ *
+ * @param filename String name of the file
+ * @return String
+ * @throws IOException
+ */
+ private String loadResourceFile(String filename) throws IOException {
+ InputStream in = getClass().getClassLoader().getResourceAsStream(filename);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+ StringBuilder builder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ builder.append(line).append("\n");
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Generate a {@link PasspointConfiguration} that matches the configuration specified in the
+ * XML file {@link #PPS_MO_XML_FILE}.
+ *
+ * @return {@link PasspointConfiguration}
+ */
+ private PasspointConfiguration generateConfigurationFromPPSMOTree() throws Exception {
+ DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ byte[] certFingerprint = new byte[32];
+ Arrays.fill(certFingerprint, (byte) 0x1f);
+
+ PasspointConfiguration config = new PasspointConfiguration();
+ config.setUpdateIdentifier(12);
+ assertEquals(12, config.getUpdateIdentifier());
+ config.setCredentialPriority(99);
+ assertEquals(99, config.getCredentialPriority());
+
+ // AAA Server trust root.
+ Map<String, byte[]> trustRootCertList = new HashMap<>();
+ trustRootCertList.put("server1.trust.root.com", certFingerprint);
+ config.setTrustRootCertList(trustRootCertList);
+ assertEquals(trustRootCertList, config.getTrustRootCertList());
+
+ // Subscription update.
+ UpdateParameter subscriptionUpdate = new UpdateParameter();
+ subscriptionUpdate.setUpdateIntervalInMinutes(120);
+ assertEquals(120, subscriptionUpdate.getUpdateIntervalInMinutes());
+ subscriptionUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_SSP);
+ assertEquals(UpdateParameter.UPDATE_METHOD_SSP, subscriptionUpdate.getUpdateMethod());
+ subscriptionUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER);
+ assertEquals(UpdateParameter.UPDATE_RESTRICTION_ROAMING_PARTNER,
+ subscriptionUpdate.getRestriction());
+ subscriptionUpdate.setServerUri("subscription.update.com");
+ assertEquals("subscription.update.com", subscriptionUpdate.getServerUri());
+ subscriptionUpdate.setUsername("subscriptionUser");
+ assertEquals("subscriptionUser", subscriptionUpdate.getUsername());
+ subscriptionUpdate.setBase64EncodedPassword("subscriptionPass");
+ assertEquals("subscriptionPass", subscriptionUpdate.getBase64EncodedPassword());
+ subscriptionUpdate.setTrustRootCertUrl("subscription.update.cert.com");
+ assertEquals("subscription.update.cert.com", subscriptionUpdate.getTrustRootCertUrl());
+ subscriptionUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
+ assertTrue(Arrays.equals(certFingerprint,
+ subscriptionUpdate.getTrustRootCertSha256Fingerprint()));
+ config.setSubscriptionUpdate(subscriptionUpdate);
+ assertEquals(subscriptionUpdate, config.getSubscriptionUpdate());
+
+ // Subscription parameters.
+ config.setSubscriptionCreationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
+ assertEquals(format.parse("2016-02-01T10:00:00Z").getTime(),
+ config.getSubscriptionCreationTimeInMs());
+ config.setSubscriptionExpirationTimeInMs(format.parse("2016-03-01T10:00:00Z").getTime());
+ assertEquals(format.parse("2016-03-01T10:00:00Z").getTime(),
+ config.getSubscriptionExpirationTimeInMs());
+ config.setSubscriptionType("Gold");
+ assertEquals("Gold", config.getSubscriptionType());
+ config.setUsageLimitDataLimit(921890);
+ assertEquals(921890, config.getUsageLimitDataLimit());
+ config.setUsageLimitStartTimeInMs(format.parse("2016-12-01T10:00:00Z").getTime());
+ assertEquals(format.parse("2016-12-01T10:00:00Z").getTime(),
+ config.getUsageLimitStartTimeInMs());
+ config.setUsageLimitTimeLimitInMinutes(120);
+ assertEquals(120, config.getUsageLimitTimeLimitInMinutes());
+ config.setUsageLimitUsageTimePeriodInMinutes(99910);
+ assertEquals(99910, config.getUsageLimitUsageTimePeriodInMinutes());
+
+ // HomeSP configuration.
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFriendlyName("Century House");
+ assertEquals("Century House", homeSp.getFriendlyName());
+ homeSp.setFqdn("mi6.co.uk");
+ assertEquals("mi6.co.uk", homeSp.getFqdn());
+ homeSp.setRoamingConsortiumOis(new long[] {0x112233L, 0x445566L});
+ assertTrue(Arrays.equals(new long[] {0x112233L, 0x445566L},
+ homeSp.getRoamingConsortiumOis()));
+ homeSp.setIconUrl("icon.test.com");
+ assertEquals("icon.test.com", homeSp.getIconUrl());
+ Map<String, Long> homeNetworkIds = new HashMap<>();
+ homeNetworkIds.put("TestSSID", 0x12345678L);
+ homeNetworkIds.put("NullHESSID", null);
+ homeSp.setHomeNetworkIds(homeNetworkIds);
+ assertEquals(homeNetworkIds, homeSp.getHomeNetworkIds());
+ homeSp.setMatchAllOis(new long[] {0x11223344});
+ assertTrue(Arrays.equals(new long[] {0x11223344}, homeSp.getMatchAllOis()));
+ homeSp.setMatchAnyOis(new long[] {0x55667788});
+ assertTrue(Arrays.equals(new long[] {0x55667788}, homeSp.getMatchAnyOis()));
+ homeSp.setOtherHomePartners(new String[] {"other.fqdn.com"});
+ assertTrue(Arrays.equals(new String[] {"other.fqdn.com"},
+ homeSp.getOtherHomePartners()));
+ config.setHomeSp(homeSp);
+ assertEquals(homeSp, config.getHomeSp());
+
+ // Credential configuration.
+ Credential credential = new Credential();
+ credential.setCreationTimeInMs(format.parse("2016-01-01T10:00:00Z").getTime());
+ assertEquals(format.parse("2016-01-01T10:00:00Z").getTime(),
+ credential.getCreationTimeInMs());
+ credential.setExpirationTimeInMs(format.parse("2016-02-01T10:00:00Z").getTime());
+ assertEquals(format.parse("2016-02-01T10:00:00Z").getTime(),
+ credential.getExpirationTimeInMs());
+ credential.setRealm("shaken.stirred.com");
+ assertEquals("shaken.stirred.com", credential.getRealm());
+ credential.setCheckAaaServerCertStatus(true);
+ assertTrue(credential.getCheckAaaServerCertStatus());
+ Credential.UserCredential userCredential = new Credential.UserCredential();
+ userCredential.setUsername("james");
+ assertEquals("james", userCredential.getUsername());
+ userCredential.setPassword("Ym9uZDAwNw==");
+ assertEquals("Ym9uZDAwNw==", userCredential.getPassword());
+ userCredential.setMachineManaged(true);
+ assertTrue(userCredential.getMachineManaged());
+ userCredential.setSoftTokenApp("TestApp");
+ assertEquals("TestApp", userCredential.getSoftTokenApp());
+ userCredential.setAbleToShare(true);
+ assertTrue(userCredential.getAbleToShare());
+ userCredential.setEapType(21);
+ assertEquals(21, userCredential.getEapType());
+ userCredential.setNonEapInnerMethod("MS-CHAP-V2");
+ assertEquals("MS-CHAP-V2", userCredential.getNonEapInnerMethod());
+ credential.setUserCredential(userCredential);
+ assertEquals(userCredential, credential.getUserCredential());
+ Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+ certCredential.setCertType("x509v3");
+ assertEquals("x509v3", certCredential.getCertType());
+ certCredential.setCertSha256Fingerprint(certFingerprint);
+ assertTrue(Arrays.equals(certFingerprint, certCredential.getCertSha256Fingerprint()));
+ credential.setCertCredential(certCredential);
+ assertEquals(certCredential, credential.getCertCredential());
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("imsi");
+ assertEquals("imsi", simCredential.getImsi());
+ simCredential.setEapType(24);
+ assertEquals(24, simCredential.getEapType());
+ credential.setSimCredential(simCredential);
+ assertEquals(simCredential, credential.getSimCredential());
+ config.setCredential(credential);
+ assertEquals(credential, config.getCredential());
+
+ // Policy configuration.
+ Policy policy = new Policy();
+ List<Policy.RoamingPartner> preferredRoamingPartnerList = new ArrayList<>();
+ Policy.RoamingPartner partner1 = new Policy.RoamingPartner();
+ partner1.setFqdn("test1.fqdn.com");
+ assertEquals("test1.fqdn.com", partner1.getFqdn());
+ partner1.setFqdnExactMatch(true);
+ assertTrue(partner1.getFqdnExactMatch());
+ partner1.setPriority(127);
+ assertEquals(127, partner1.getPriority());
+ partner1.setCountries("us,fr");
+ assertEquals("us,fr", partner1.getCountries());
+ Policy.RoamingPartner partner2 = new Policy.RoamingPartner();
+ partner2.setFqdn("test2.fqdn.com");
+ assertEquals("test2.fqdn.com", partner2.getFqdn());
+ partner2.setFqdnExactMatch(false);
+ assertFalse(partner2.getFqdnExactMatch());
+ partner2.setPriority(200);
+ assertEquals(200, partner2.getPriority());
+ partner2.setCountries("*");
+ assertEquals("*", partner2.getCountries());
+ preferredRoamingPartnerList.add(partner1);
+ preferredRoamingPartnerList.add(partner2);
+ policy.setPreferredRoamingPartnerList(preferredRoamingPartnerList);
+ assertEquals(preferredRoamingPartnerList, policy.getPreferredRoamingPartnerList());
+ policy.setMinHomeDownlinkBandwidth(23412);
+ assertEquals(23412, policy.getMinHomeDownlinkBandwidth());
+ policy.setMinHomeUplinkBandwidth(9823);
+ assertEquals(9823, policy.getMinHomeUplinkBandwidth());
+ policy.setMinRoamingDownlinkBandwidth(9271);
+ assertEquals(9271, policy.getMinRoamingDownlinkBandwidth());
+ policy.setMinRoamingUplinkBandwidth(2315);
+ assertEquals(2315, policy.getMinRoamingUplinkBandwidth());
+ policy.setExcludedSsidList(new String[] {"excludeSSID"});
+ assertTrue(Arrays.equals(new String[] {"excludeSSID"}, policy.getExcludedSsidList()));
+ Map<Integer, String> requiredProtoPortMap = new HashMap<>();
+ requiredProtoPortMap.put(12, "34,92,234");
+ policy.setRequiredProtoPortMap(requiredProtoPortMap);
+ assertEquals(requiredProtoPortMap, policy.getRequiredProtoPortMap());
+ policy.setMaximumBssLoadValue(23);
+ assertEquals(23, policy.getMaximumBssLoadValue());
+ UpdateParameter policyUpdate = new UpdateParameter();
+ policyUpdate.setUpdateIntervalInMinutes(120);
+ assertEquals(120, policyUpdate.getUpdateIntervalInMinutes());
+ policyUpdate.setUpdateMethod(UpdateParameter.UPDATE_METHOD_OMADM);
+ assertEquals(UpdateParameter.UPDATE_METHOD_OMADM, policyUpdate.getUpdateMethod());
+ policyUpdate.setRestriction(UpdateParameter.UPDATE_RESTRICTION_HOMESP);
+ assertEquals(UpdateParameter.UPDATE_RESTRICTION_HOMESP, policyUpdate.getRestriction());
+ policyUpdate.setServerUri("policy.update.com");
+ assertEquals("policy.update.com", policyUpdate.getServerUri());
+ policyUpdate.setUsername("updateUser");
+ assertEquals("updateUser", policyUpdate.getUsername());
+ policyUpdate.setBase64EncodedPassword("updatePass");
+ assertEquals("updatePass", policyUpdate.getBase64EncodedPassword());
+ policyUpdate.setTrustRootCertUrl("update.cert.com");
+ assertEquals("update.cert.com", policyUpdate.getTrustRootCertUrl());
+ policyUpdate.setTrustRootCertSha256Fingerprint(certFingerprint);
+ assertTrue(Arrays.equals(certFingerprint,
+ policyUpdate.getTrustRootCertSha256Fingerprint()));
+ policy.setPolicyUpdate(policyUpdate);
+ assertEquals(policyUpdate, policy.getPolicyUpdate());
+ config.setPolicy(policy);
+ assertEquals(policy, config.getPolicy());
+ return config;
+ }
+
+ /**
+ * Parse and verify all supported fields under PPS MO tree.
+ *
+ * @throws Exception
+ */
+ public void testParsePPSMOTree() throws Exception {
+ String ppsMoTree = loadResourceFile(PPS_MO_XML_FILE);
+ PasspointConfiguration expectedConfig = generateConfigurationFromPPSMOTree();
+ PasspointConfiguration actualConfig = PpsMoParser.parseMoText(ppsMoTree);
+ assertTrue(actualConfig.equals(expectedConfig));
+ }
+}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
index f3eb4e9..d3235da 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -26,8 +26,11 @@
import android.test.AndroidTestCase;
import java.io.ByteArrayInputStream;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
public class WifiEnterpriseConfigTest extends AndroidTestCase {
private WifiManager mWifiManager;
@@ -432,6 +435,246 @@
(byte) 0x9e, (byte) 0x34, (byte) 0x73
};
+ /**
+ * Client certificate generated from above and converted with:
+ *
+ * openssl x509 -outform d -in usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
+ */
+ private static final byte[] FAKE_EC_3 = {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0xdf, (byte) 0x30, (byte) 0x82,
+ (byte) 0x01, (byte) 0xc7, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
+ (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
+ (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+ (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x0b, (byte) 0x05,
+ (byte) 0x00, (byte) 0x30, (byte) 0x64, (byte) 0x31, (byte) 0x0b, (byte) 0x30,
+ (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x06,
+ (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53, (byte) 0x31, (byte) 0x0b,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43, (byte) 0x41, (byte) 0x31,
+ (byte) 0x16, (byte) 0x30, (byte) 0x14, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x07, (byte) 0x0c, (byte) 0x0d, (byte) 0x4d, (byte) 0x6f,
+ (byte) 0x75, (byte) 0x6e, (byte) 0x74, (byte) 0x61, (byte) 0x69, (byte) 0x6e,
+ (byte) 0x20, (byte) 0x56, (byte) 0x69, (byte) 0x65, (byte) 0x77, (byte) 0x31,
+ (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06, (byte) 0x47, (byte) 0x6f,
+ (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65, (byte) 0x31, (byte) 0x10,
+ (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41, (byte) 0x6e, (byte) 0x64,
+ (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64, (byte) 0x31, (byte) 0x0d,
+ (byte) 0x30, (byte) 0x0b, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
+ (byte) 0x03, (byte) 0x0c, (byte) 0x04, (byte) 0x54, (byte) 0x45, (byte) 0x53,
+ (byte) 0x54, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31,
+ (byte) 0x37, (byte) 0x30, (byte) 0x31, (byte) 0x32, (byte) 0x37, (byte) 0x31,
+ (byte) 0x37, (byte) 0x35, (byte) 0x38, (byte) 0x31, (byte) 0x32, (byte) 0x5a,
+ (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x37, (byte) 0x30, (byte) 0x31,
+ (byte) 0x32, (byte) 0x35, (byte) 0x31, (byte) 0x37, (byte) 0x35, (byte) 0x38,
+ (byte) 0x31, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x50, (byte) 0x31,
+ (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55,
+ (byte) 0x04, (byte) 0x06, (byte) 0x13, (byte) 0x02, (byte) 0x55, (byte) 0x53,
+ (byte) 0x31, (byte) 0x0b, (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x08, (byte) 0x0c, (byte) 0x02, (byte) 0x43,
+ (byte) 0x41, (byte) 0x31, (byte) 0x0f, (byte) 0x30, (byte) 0x0d, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x06,
+ (byte) 0x47, (byte) 0x6f, (byte) 0x6f, (byte) 0x67, (byte) 0x6c, (byte) 0x65,
+ (byte) 0x31, (byte) 0x10, (byte) 0x30, (byte) 0x0e, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x0b, (byte) 0x0c, (byte) 0x07, (byte) 0x41,
+ (byte) 0x6e, (byte) 0x64, (byte) 0x72, (byte) 0x6f, (byte) 0x69, (byte) 0x64,
+ (byte) 0x31, (byte) 0x11, (byte) 0x30, (byte) 0x0f, (byte) 0x06, (byte) 0x03,
+ (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x08, (byte) 0x54,
+ (byte) 0x45, (byte) 0x53, (byte) 0x54, (byte) 0x2d, (byte) 0x55, (byte) 0x53,
+ (byte) 0x52, (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06,
+ (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d,
+ (byte) 0x02, (byte) 0x01, (byte) 0x06, (byte) 0x08, (byte) 0x2a, (byte) 0x86,
+ (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03, (byte) 0x01, (byte) 0x07,
+ (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0x4a, (byte) 0xb8,
+ (byte) 0x60, (byte) 0x17, (byte) 0x40, (byte) 0x91, (byte) 0x30, (byte) 0xf7,
+ (byte) 0xdf, (byte) 0x36, (byte) 0x83, (byte) 0x31, (byte) 0xb5, (byte) 0x3a,
+ (byte) 0xf4, (byte) 0xd4, (byte) 0xa1, (byte) 0xce, (byte) 0xd5, (byte) 0x54,
+ (byte) 0x97, (byte) 0x93, (byte) 0x7e, (byte) 0x7b, (byte) 0x08, (byte) 0x63,
+ (byte) 0x37, (byte) 0x62, (byte) 0xf1, (byte) 0x4e, (byte) 0x6a, (byte) 0x2e,
+ (byte) 0x35, (byte) 0x4e, (byte) 0x9f, (byte) 0x48, (byte) 0xcd, (byte) 0x09,
+ (byte) 0x17, (byte) 0xb3, (byte) 0xc1, (byte) 0x58, (byte) 0x02, (byte) 0x49,
+ (byte) 0x7b, (byte) 0x4c, (byte) 0xf7, (byte) 0x9b, (byte) 0xbb, (byte) 0x1b,
+ (byte) 0x2b, (byte) 0x9c, (byte) 0xe9, (byte) 0x36, (byte) 0xc4, (byte) 0x00,
+ (byte) 0x81, (byte) 0x2c, (byte) 0x28, (byte) 0xd9, (byte) 0x6b, (byte) 0xad,
+ (byte) 0xe3, (byte) 0xe8, (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79,
+ (byte) 0x30, (byte) 0x09, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d,
+ (byte) 0x13, (byte) 0x04, (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30,
+ (byte) 0x2c, (byte) 0x06, (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48,
+ (byte) 0x01, (byte) 0x86, (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d,
+ (byte) 0x04, (byte) 0x1f, (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70,
+ (byte) 0x65, (byte) 0x6e, (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20,
+ (byte) 0x47, (byte) 0x65, (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61,
+ (byte) 0x74, (byte) 0x65, (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65,
+ (byte) 0x72, (byte) 0x74, (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63,
+ (byte) 0x61, (byte) 0x74, (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06,
+ (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16,
+ (byte) 0x04, (byte) 0x14, (byte) 0xef, (byte) 0xf0, (byte) 0x15, (byte) 0xd7,
+ (byte) 0xc9, (byte) 0x3e, (byte) 0x9a, (byte) 0x73, (byte) 0xfa, (byte) 0x38,
+ (byte) 0xc5, (byte) 0x81, (byte) 0x84, (byte) 0x74, (byte) 0xd3, (byte) 0x83,
+ (byte) 0x74, (byte) 0x26, (byte) 0xf1, (byte) 0x0b, (byte) 0x30, (byte) 0x1f,
+ (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x23, (byte) 0x04,
+ (byte) 0x18, (byte) 0x30, (byte) 0x16, (byte) 0x80, (byte) 0x14, (byte) 0x38,
+ (byte) 0x6a, (byte) 0x9b, (byte) 0xf8, (byte) 0x3c, (byte) 0x0d, (byte) 0x54,
+ (byte) 0x9f, (byte) 0xdf, (byte) 0xf8, (byte) 0x53, (byte) 0x32, (byte) 0xa8,
+ (byte) 0xf7, (byte) 0x09, (byte) 0x15, (byte) 0x08, (byte) 0x76, (byte) 0xab,
+ (byte) 0x8d, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x0b, (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x82,
+ (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0xa6, (byte) 0x6c, (byte) 0x18,
+ (byte) 0xa9, (byte) 0x67, (byte) 0x16, (byte) 0x6a, (byte) 0x9e, (byte) 0x23,
+ (byte) 0xb3, (byte) 0x2a, (byte) 0xb8, (byte) 0x16, (byte) 0x7b, (byte) 0xb4,
+ (byte) 0xc8, (byte) 0xbc, (byte) 0x51, (byte) 0xe0, (byte) 0x6f, (byte) 0x05,
+ (byte) 0x66, (byte) 0xa1, (byte) 0x6f, (byte) 0x96, (byte) 0xde, (byte) 0x5b,
+ (byte) 0x41, (byte) 0x60, (byte) 0xe5, (byte) 0x29, (byte) 0x99, (byte) 0x12,
+ (byte) 0xfc, (byte) 0xa9, (byte) 0x91, (byte) 0x23, (byte) 0xb7, (byte) 0x9e,
+ (byte) 0x00, (byte) 0x5f, (byte) 0x93, (byte) 0xd4, (byte) 0xf7, (byte) 0x27,
+ (byte) 0x29, (byte) 0x77, (byte) 0xfb, (byte) 0x53, (byte) 0x09, (byte) 0xdc,
+ (byte) 0xe9, (byte) 0xd0, (byte) 0x5c, (byte) 0x92, (byte) 0x6d, (byte) 0xb7,
+ (byte) 0xcf, (byte) 0x04, (byte) 0xab, (byte) 0xf1, (byte) 0x39, (byte) 0xb9,
+ (byte) 0x49, (byte) 0x23, (byte) 0x7c, (byte) 0x0f, (byte) 0x15, (byte) 0x27,
+ (byte) 0xcd, (byte) 0x65, (byte) 0x3c, (byte) 0x6b, (byte) 0x91, (byte) 0x42,
+ (byte) 0x5a, (byte) 0xfe, (byte) 0xbe, (byte) 0xb8, (byte) 0xa2, (byte) 0xfd,
+ (byte) 0x67, (byte) 0x43, (byte) 0x4b, (byte) 0xc9, (byte) 0x28, (byte) 0x65,
+ (byte) 0x1b, (byte) 0x82, (byte) 0x5b, (byte) 0x25, (byte) 0x20, (byte) 0x9b,
+ (byte) 0xea, (byte) 0x99, (byte) 0xbb, (byte) 0x66, (byte) 0xc1, (byte) 0x8e,
+ (byte) 0x46, (byte) 0x0b, (byte) 0x4e, (byte) 0x06, (byte) 0xdd, (byte) 0x50,
+ (byte) 0x51, (byte) 0x64, (byte) 0xe8, (byte) 0x83, (byte) 0x99, (byte) 0x8e,
+ (byte) 0x53, (byte) 0xe9, (byte) 0x48, (byte) 0x47, (byte) 0x0e, (byte) 0x08,
+ (byte) 0x5e, (byte) 0x0d, (byte) 0x4a, (byte) 0x54, (byte) 0x17, (byte) 0xc1,
+ (byte) 0xf8, (byte) 0xcf, (byte) 0xba, (byte) 0x5c, (byte) 0x38, (byte) 0x70,
+ (byte) 0x33, (byte) 0x31, (byte) 0x22, (byte) 0x03, (byte) 0x6f, (byte) 0x54,
+ (byte) 0x3c, (byte) 0x41, (byte) 0xf0, (byte) 0x89, (byte) 0x85, (byte) 0xbc,
+ (byte) 0x77, (byte) 0x3c, (byte) 0xe8, (byte) 0xec, (byte) 0xb4, (byte) 0x35,
+ (byte) 0x7a, (byte) 0xcc, (byte) 0x8c, (byte) 0x5f, (byte) 0xa1, (byte) 0xed,
+ (byte) 0xa6, (byte) 0x28, (byte) 0x14, (byte) 0xc7, (byte) 0x8a, (byte) 0xef,
+ (byte) 0x56, (byte) 0x26, (byte) 0x35, (byte) 0x46, (byte) 0xab, (byte) 0xb0,
+ (byte) 0x97, (byte) 0xd2, (byte) 0xbd, (byte) 0xa9, (byte) 0x6a, (byte) 0xe4,
+ (byte) 0x3e, (byte) 0x87, (byte) 0xfb, (byte) 0xe1, (byte) 0x09, (byte) 0x8d,
+ (byte) 0x33, (byte) 0x12, (byte) 0xcf, (byte) 0xf0, (byte) 0xc0, (byte) 0xb8,
+ (byte) 0x9b, (byte) 0x9f, (byte) 0xb1, (byte) 0xcb, (byte) 0xac, (byte) 0x76,
+ (byte) 0xa8, (byte) 0x05, (byte) 0x6b, (byte) 0xcc, (byte) 0x41, (byte) 0xd2,
+ (byte) 0x26, (byte) 0x73, (byte) 0xfa, (byte) 0x69, (byte) 0xd3, (byte) 0x1f,
+ (byte) 0xa9, (byte) 0x0c, (byte) 0x6a, (byte) 0xd6, (byte) 0xc9, (byte) 0x35,
+ (byte) 0xc5, (byte) 0xad, (byte) 0xa1, (byte) 0x98, (byte) 0xc9, (byte) 0x78,
+ (byte) 0xa0, (byte) 0xe8, (byte) 0x02, (byte) 0x69, (byte) 0x80, (byte) 0x44,
+ (byte) 0xd9, (byte) 0xe6, (byte) 0xe5, (byte) 0x26, (byte) 0x4f, (byte) 0xcf,
+ (byte) 0x38, (byte) 0xcb, (byte) 0x55, (byte) 0x8c, (byte) 0x7d, (byte) 0x3c,
+ (byte) 0xa8, (byte) 0x82, (byte) 0x69, (byte) 0xa3, (byte) 0xdf, (byte) 0x0a,
+ (byte) 0x79, (byte) 0x7b, (byte) 0xdd, (byte) 0x24, (byte) 0x6a, (byte) 0x21,
+ (byte) 0x7b, (byte) 0x20, (byte) 0x94, (byte) 0xcd, (byte) 0x15, (byte) 0x92,
+ (byte) 0xad, (byte) 0x4a, (byte) 0x72, (byte) 0x0b, (byte) 0x0e, (byte) 0xb2,
+ (byte) 0xc9
+ };
+
+ private static final byte[] FAKE_KEY_3 = {
+ (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x78, (byte) 0x02, (byte) 0x01,
+ (byte) 0x00, (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a,
+ (byte) 0x86, (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01,
+ (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x04, (byte) 0x82,
+ (byte) 0x02, (byte) 0x62, (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x5e,
+ (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x81,
+ (byte) 0x00, (byte) 0xce, (byte) 0x29, (byte) 0xeb, (byte) 0xf6, (byte) 0x5b,
+ (byte) 0x25, (byte) 0xdc, (byte) 0xa1, (byte) 0xa6, (byte) 0x2c, (byte) 0x66,
+ (byte) 0xcb, (byte) 0x20, (byte) 0x90, (byte) 0x27, (byte) 0x86, (byte) 0x8a,
+ (byte) 0x44, (byte) 0x71, (byte) 0x50, (byte) 0xda, (byte) 0xd3, (byte) 0x02,
+ (byte) 0x77, (byte) 0x55, (byte) 0xe9, (byte) 0xe8, (byte) 0x08, (byte) 0xf3,
+ (byte) 0x36, (byte) 0x9a, (byte) 0xae, (byte) 0xab, (byte) 0x04, (byte) 0x6d,
+ (byte) 0x00, (byte) 0x99, (byte) 0xbf, (byte) 0x7d, (byte) 0x0f, (byte) 0x67,
+ (byte) 0x8b, (byte) 0x1d, (byte) 0xd4, (byte) 0x2b, (byte) 0x7c, (byte) 0xcb,
+ (byte) 0xcd, (byte) 0x33, (byte) 0xc7, (byte) 0x84, (byte) 0x30, (byte) 0xe2,
+ (byte) 0x45, (byte) 0x21, (byte) 0xb3, (byte) 0x75, (byte) 0xf5, (byte) 0x79,
+ (byte) 0x02, (byte) 0xda, (byte) 0x50, (byte) 0xa3, (byte) 0x8b, (byte) 0xce,
+ (byte) 0xc3, (byte) 0x8e, (byte) 0x0f, (byte) 0x25, (byte) 0xeb, (byte) 0x08,
+ (byte) 0x2c, (byte) 0xdd, (byte) 0x1c, (byte) 0xcf, (byte) 0xff, (byte) 0x3b,
+ (byte) 0xde, (byte) 0xb6, (byte) 0xaa, (byte) 0x2a, (byte) 0xa9, (byte) 0xc4,
+ (byte) 0x8a, (byte) 0x24, (byte) 0x24, (byte) 0xe6, (byte) 0x29, (byte) 0x0d,
+ (byte) 0x98, (byte) 0x4c, (byte) 0x32, (byte) 0xa1, (byte) 0x7b, (byte) 0x23,
+ (byte) 0x2b, (byte) 0x42, (byte) 0x30, (byte) 0xee, (byte) 0x78, (byte) 0x08,
+ (byte) 0x47, (byte) 0xad, (byte) 0xf2, (byte) 0x96, (byte) 0xd5, (byte) 0xf1,
+ (byte) 0x62, (byte) 0x42, (byte) 0x2d, (byte) 0x35, (byte) 0x19, (byte) 0xb4,
+ (byte) 0x3c, (byte) 0xc9, (byte) 0xc3, (byte) 0x5f, (byte) 0x03, (byte) 0x16,
+ (byte) 0x3a, (byte) 0x23, (byte) 0xac, (byte) 0xcb, (byte) 0xce, (byte) 0x9e,
+ (byte) 0x51, (byte) 0x2e, (byte) 0x6d, (byte) 0x02, (byte) 0x03, (byte) 0x01,
+ (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x16,
+ (byte) 0x59, (byte) 0xc3, (byte) 0x24, (byte) 0x1d, (byte) 0x33, (byte) 0x98,
+ (byte) 0x9c, (byte) 0xc9, (byte) 0xc8, (byte) 0x2c, (byte) 0x88, (byte) 0xbf,
+ (byte) 0x0a, (byte) 0x01, (byte) 0xce, (byte) 0xfb, (byte) 0x34, (byte) 0x7a,
+ (byte) 0x58, (byte) 0x7a, (byte) 0xb0, (byte) 0xbf, (byte) 0xa6, (byte) 0xb2,
+ (byte) 0x60, (byte) 0xbe, (byte) 0x70, (byte) 0x21, (byte) 0xf5, (byte) 0xfc,
+ (byte) 0x85, (byte) 0x0d, (byte) 0x33, (byte) 0x58, (byte) 0xa1, (byte) 0xe5,
+ (byte) 0x09, (byte) 0x36, (byte) 0x84, (byte) 0xb2, (byte) 0x04, (byte) 0x0a,
+ (byte) 0x02, (byte) 0xd3, (byte) 0x88, (byte) 0x1f, (byte) 0x0c, (byte) 0x2b,
+ (byte) 0x1d, (byte) 0xe9, (byte) 0x3d, (byte) 0xe7, (byte) 0x79, (byte) 0xf9,
+ (byte) 0x32, (byte) 0x5c, (byte) 0x8a, (byte) 0x75, (byte) 0x49, (byte) 0x12,
+ (byte) 0xe4, (byte) 0x05, (byte) 0x26, (byte) 0xd4, (byte) 0x2e, (byte) 0x9e,
+ (byte) 0x1f, (byte) 0xcc, (byte) 0x54, (byte) 0xad, (byte) 0x33, (byte) 0x8d,
+ (byte) 0x99, (byte) 0x00, (byte) 0xdc, (byte) 0xf5, (byte) 0xb4, (byte) 0xa2,
+ (byte) 0x2f, (byte) 0xba, (byte) 0xe5, (byte) 0x62, (byte) 0x30, (byte) 0x6d,
+ (byte) 0xe6, (byte) 0x3d, (byte) 0xeb, (byte) 0x24, (byte) 0xc2, (byte) 0xdc,
+ (byte) 0x5f, (byte) 0xb7, (byte) 0x16, (byte) 0x35, (byte) 0xa3, (byte) 0x98,
+ (byte) 0x98, (byte) 0xa8, (byte) 0xef, (byte) 0xe8, (byte) 0xc4, (byte) 0x96,
+ (byte) 0x6d, (byte) 0x38, (byte) 0xab, (byte) 0x26, (byte) 0x6d, (byte) 0x30,
+ (byte) 0xc2, (byte) 0xa0, (byte) 0x44, (byte) 0xe4, (byte) 0xff, (byte) 0x7e,
+ (byte) 0xbe, (byte) 0x7c, (byte) 0x33, (byte) 0xa5, (byte) 0x10, (byte) 0xad,
+ (byte) 0xd7, (byte) 0x1e, (byte) 0x13, (byte) 0x20, (byte) 0xb3, (byte) 0x1f,
+ (byte) 0x41, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xf1, (byte) 0x89,
+ (byte) 0x07, (byte) 0x0f, (byte) 0xe8, (byte) 0xcf, (byte) 0xab, (byte) 0x13,
+ (byte) 0x2a, (byte) 0x8f, (byte) 0x88, (byte) 0x80, (byte) 0x11, (byte) 0x9a,
+ (byte) 0x79, (byte) 0xb6, (byte) 0x59, (byte) 0x3a, (byte) 0x50, (byte) 0x6e,
+ (byte) 0x57, (byte) 0x37, (byte) 0xab, (byte) 0x2a, (byte) 0xd2, (byte) 0xaa,
+ (byte) 0xd9, (byte) 0x72, (byte) 0x73, (byte) 0xff, (byte) 0x8b, (byte) 0x47,
+ (byte) 0x76, (byte) 0xdd, (byte) 0xdc, (byte) 0xf5, (byte) 0x97, (byte) 0x44,
+ (byte) 0x3a, (byte) 0x78, (byte) 0xbe, (byte) 0x17, (byte) 0xb4, (byte) 0x22,
+ (byte) 0x6f, (byte) 0xe5, (byte) 0x23, (byte) 0x70, (byte) 0x1d, (byte) 0x10,
+ (byte) 0x5d, (byte) 0xba, (byte) 0x16, (byte) 0x81, (byte) 0xf1, (byte) 0x45,
+ (byte) 0xce, (byte) 0x30, (byte) 0xb4, (byte) 0xab, (byte) 0x80, (byte) 0xe4,
+ (byte) 0x98, (byte) 0x31, (byte) 0x02, (byte) 0x41, (byte) 0x00, (byte) 0xda,
+ (byte) 0x82, (byte) 0x9d, (byte) 0x3f, (byte) 0xca, (byte) 0x2f, (byte) 0xe1,
+ (byte) 0xd4, (byte) 0x86, (byte) 0x77, (byte) 0x48, (byte) 0xa6, (byte) 0xab,
+ (byte) 0xab, (byte) 0x1c, (byte) 0x42, (byte) 0x5c, (byte) 0xd5, (byte) 0xc7,
+ (byte) 0x46, (byte) 0x59, (byte) 0x91, (byte) 0x3f, (byte) 0xfc, (byte) 0xcc,
+ (byte) 0xec, (byte) 0xc2, (byte) 0x40, (byte) 0x12, (byte) 0x2c, (byte) 0x8d,
+ (byte) 0x1f, (byte) 0xa2, (byte) 0x18, (byte) 0x88, (byte) 0xee, (byte) 0x82,
+ (byte) 0x4a, (byte) 0x5a, (byte) 0x5e, (byte) 0x88, (byte) 0x20, (byte) 0xe3,
+ (byte) 0x7b, (byte) 0xe0, (byte) 0xd8, (byte) 0x3a, (byte) 0x52, (byte) 0x9a,
+ (byte) 0x26, (byte) 0x6a, (byte) 0x04, (byte) 0xec, (byte) 0xe8, (byte) 0xb9,
+ (byte) 0x48, (byte) 0x40, (byte) 0xe1, (byte) 0xe1, (byte) 0x83, (byte) 0xa6,
+ (byte) 0x67, (byte) 0xa6, (byte) 0xfd, (byte) 0x02, (byte) 0x41, (byte) 0x00,
+ (byte) 0x89, (byte) 0x72, (byte) 0x3e, (byte) 0xb0, (byte) 0x90, (byte) 0xfd,
+ (byte) 0x4c, (byte) 0x0e, (byte) 0xd6, (byte) 0x13, (byte) 0x63, (byte) 0xcb,
+ (byte) 0xed, (byte) 0x38, (byte) 0x88, (byte) 0xb6, (byte) 0x79, (byte) 0xc4,
+ (byte) 0x33, (byte) 0x6c, (byte) 0xf6, (byte) 0xf8, (byte) 0xd8, (byte) 0xd0,
+ (byte) 0xbf, (byte) 0x9d, (byte) 0x35, (byte) 0xac, (byte) 0x69, (byte) 0xd2,
+ (byte) 0x2b, (byte) 0xc1, (byte) 0xf9, (byte) 0x24, (byte) 0x7b, (byte) 0xce,
+ (byte) 0xcd, (byte) 0xcb, (byte) 0xa7, (byte) 0xb2, (byte) 0x7a, (byte) 0x0a,
+ (byte) 0x27, (byte) 0x19, (byte) 0xc9, (byte) 0xaf, (byte) 0x0d, (byte) 0x21,
+ (byte) 0x89, (byte) 0x88, (byte) 0x7c, (byte) 0xad, (byte) 0x9e, (byte) 0x8d,
+ (byte) 0x47, (byte) 0x6d, (byte) 0x3f, (byte) 0xce, (byte) 0x7b, (byte) 0xa1,
+ (byte) 0x74, (byte) 0xf1, (byte) 0xa0, (byte) 0xa1, (byte) 0x02, (byte) 0x41,
+ (byte) 0x00, (byte) 0xd9, (byte) 0xa8, (byte) 0xf5, (byte) 0xfe, (byte) 0xce,
+ (byte) 0xe6, (byte) 0x77, (byte) 0x6b, (byte) 0xfe, (byte) 0x2d, (byte) 0xe0,
+ (byte) 0x1e, (byte) 0xb6, (byte) 0x2e, (byte) 0x12, (byte) 0x4e, (byte) 0x40,
+ (byte) 0xaf, (byte) 0x6a, (byte) 0x7b, (byte) 0x37, (byte) 0x49, (byte) 0x2a,
+ (byte) 0x96, (byte) 0x25, (byte) 0x83, (byte) 0x49, (byte) 0xd4, (byte) 0x0c,
+ (byte) 0xc6, (byte) 0x78, (byte) 0x25, (byte) 0x24, (byte) 0x90, (byte) 0x90,
+ (byte) 0x06, (byte) 0x15, (byte) 0x9e, (byte) 0xfe, (byte) 0xf9, (byte) 0xdf,
+ (byte) 0x5b, (byte) 0xf3, (byte) 0x7e, (byte) 0x38, (byte) 0x70, (byte) 0xeb,
+ (byte) 0x57, (byte) 0xd0, (byte) 0xd9, (byte) 0xa7, (byte) 0x0e, (byte) 0x14,
+ (byte) 0xf7, (byte) 0x95, (byte) 0x68, (byte) 0xd5, (byte) 0xc8, (byte) 0xab,
+ (byte) 0x9d, (byte) 0x3a, (byte) 0x2b, (byte) 0x51, (byte) 0xf9, (byte) 0x02,
+ (byte) 0x41, (byte) 0x00, (byte) 0x96, (byte) 0xdf, (byte) 0xe9, (byte) 0x67,
+ (byte) 0x6c, (byte) 0xdc, (byte) 0x90, (byte) 0x14, (byte) 0xb4, (byte) 0x1d,
+ (byte) 0x22, (byte) 0x33, (byte) 0x4a, (byte) 0x31, (byte) 0xc1, (byte) 0x9d,
+ (byte) 0x2e, (byte) 0xff, (byte) 0x9a, (byte) 0x2a, (byte) 0x95, (byte) 0x4b,
+ (byte) 0x27, (byte) 0x74, (byte) 0xcb, (byte) 0x21, (byte) 0xc3, (byte) 0xd2,
+ (byte) 0x0b, (byte) 0xb2, (byte) 0x46, (byte) 0x87, (byte) 0xf8, (byte) 0x28,
+ (byte) 0x01, (byte) 0x8b, (byte) 0xd8, (byte) 0xb9, (byte) 0x4b, (byte) 0xcd,
+ (byte) 0x9a, (byte) 0x96, (byte) 0x41, (byte) 0x0e, (byte) 0x36, (byte) 0x6d,
+ (byte) 0x40, (byte) 0x42, (byte) 0xbc, (byte) 0xd9, (byte) 0xd3, (byte) 0x7b,
+ (byte) 0xbc, (byte) 0xa7, (byte) 0x92, (byte) 0x90, (byte) 0xdd, (byte) 0xa1,
+ (byte) 0x9c, (byte) 0xce, (byte) 0xa1, (byte) 0x87, (byte) 0x11, (byte) 0x51
+ };
private boolean hasWifi() {
return getContext().getPackageManager().hasSystemFeature(
@@ -492,7 +735,32 @@
X509Certificate[] certs = config.getCaCertificates();
assertTrue(cert1.getSerialNumber().equals(certs[0].getSerialNumber()));
assertTrue(cert2.getSerialNumber().equals(certs[1].getSerialNumber()));
+
+ X509Certificate clientCert = (X509Certificate) factory.generateCertificate(
+ new ByteArrayInputStream(FAKE_EC_3));
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ PrivateKey clientKey = kf.generatePrivate(new PKCS8EncodedKeySpec(FAKE_KEY_3));
+
+ config.setClientKeyEntry(clientKey, clientCert);
+ X509Certificate testClientCert = config.getClientCertificate();
+ X509Certificate[] testClientCertChain = config.getClientCertificateChain();
+ assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber()));
+ assertTrue(testClientCertChain.length == 1);
+ assertTrue(testClientCertChain[0] == testClientCert);
+
config.setClientKeyEntry(null, null);
+ assertTrue(config.getClientCertificate() == null);
+ assertTrue(config.getClientCertificateChain() == null);
+
+ config.setClientKeyEntryWithCertificateChain(clientKey,
+ new X509Certificate[]{clientCert, cert1});
+ testClientCert = config.getClientCertificate();
+ testClientCertChain = config.getClientCertificateChain();
+ assertTrue(clientCert.getSerialNumber().equals(testClientCert.getSerialNumber()));
+ assertTrue(testClientCertChain.length == 2);
+ assertTrue(testClientCertChain[0] == testClientCert);
+ assertTrue(testClientCertChain[1] == cert1);
+
config.setSubjectMatch(SUBJECT_MATCH);
assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
// Hotspot 2.0 related attributes
@@ -532,4 +800,15 @@
}
return false;
}
+
+ public void testEnterpriseConfigDoesNotPrintPassword() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ final String identity = "IdentityIsOkayToBeDisplayedHere";
+ final String password = "PasswordIsNotOkayToBeDisplayedHere";
+ enterpriseConfig.setIdentity(identity);
+ enterpriseConfig.setPassword(password);
+ final String stringRepresentation = enterpriseConfig.toString();
+ assertTrue(stringRepresentation.contains(identity));
+ assertFalse(stringRepresentation.contains(password));
+ }
}
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
index 8719b6b..696d215 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiInfoTest.java
@@ -26,6 +26,7 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
+import android.net.wifi.WifiSsid;
import android.test.AndroidTestCase;
import java.util.concurrent.Callable;
@@ -123,7 +124,7 @@
SupplicantState.isValidState(wifiInfo.getSupplicantState());
WifiInfo.getDetailedStateOf(SupplicantState.DISCONNECTED);
String ssid = wifiInfo.getSSID();
- if (ssid.startsWith("0x") == false) {
+ if (!ssid.startsWith("0x") && !ssid.equals(WifiSsid.NONE)) {
// Non-hex string should be quoted
assertTrue(ssid.charAt(0) == '"');
assertTrue(ssid.charAt(ssid.length() - 1) == '"');
diff --git a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
index 897e5cf..f05ff82 100644
--- a/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/cts/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -22,7 +22,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.location.LocationManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
@@ -30,13 +29,20 @@
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.TxPacketCountListener;
import android.net.wifi.WifiManager.WifiLock;
+import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.pps.Credential;
+import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.SystemClock;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.util.Log;
+import com.android.compatibility.common.util.WifiConfigCreator;
+
import java.net.HttpURLConnection;
import java.net.URL;
+import java.security.MessageDigest;
+import java.security.cert.X509Certificate;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -68,6 +74,8 @@
private static final String TAG = "WifiManagerTest";
private static final String SSID1 = "\"WifiManagerTest\"";
private static final String SSID2 = "\"WifiManagerTestModified\"";
+ private static final String PROXY_TEST_SSID = "SomeProxyAp";
+ private static final String ADD_NETWORK_EXCEPTION_SUBSTR = "addNetwork";
private static final int TIMEOUT_MSEC = 6000;
private static final int WAIT_MSEC = 60;
private static final int DURATION = 10000;
@@ -75,6 +83,8 @@
private static final int WIFI_SCAN_TEST_CACHE_DELAY_MILLIS = 3 * 60 * 1000;
private static final int WIFI_SCAN_TEST_ITERATIONS = 5;
+ private static final String TEST_PAC_URL = "http://www.example.com/proxy.pac";
+
private IntentFilter mIntentFilter;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -213,16 +223,6 @@
return -1;
}
- private void assertDisableOthers(WifiConfiguration wifiConfiguration, boolean disableOthers) {
- for (WifiConfiguration w : mWifiManager.getConfiguredNetworks()) {
- if ((!w.SSID.equals(wifiConfiguration.SSID)) && w.status != Status.CURRENT) {
- if (disableOthers) {
- assertEquals(Status.DISABLED, w.status);
- }
- }
- }
- }
-
/**
* test point of wifiManager actions:
* 1.reconnect
@@ -378,7 +378,6 @@
boolean disableOthers = true;
assertTrue(mWifiManager.enableNetwork(netId, disableOthers));
wifiConfiguration = mWifiManager.getConfiguredNetworks().get(pos);
- assertDisableOthers(wifiConfiguration, disableOthers);
assertEquals(Status.ENABLED, wifiConfiguration.status);
assertTrue(mWifiManager.disableNetwork(netId));
@@ -405,6 +404,31 @@
}
}
+ /**
+ * Verifies that addNetwork() fails for WifiConfigurations containing a non-null http proxy when
+ * the caller doesn't have OVERRIDE_WIFI_CONFIG permission, DeviceOwner or ProfileOwner device
+ * management policies
+ */
+ public void testSetHttpProxy_PermissionFail() throws Exception {
+ if (!WifiFeature.isWifiSupported(getContext())) {
+ // skip the test if WiFi is not supported
+ return;
+ }
+ WifiConfigCreator configCreator = new WifiConfigCreator(getContext());
+ boolean exceptionThrown = false;
+ try {
+ configCreator.addHttpProxyNetworkVerifyAndRemove(
+ PROXY_TEST_SSID, TEST_PAC_URL);
+ } catch (IllegalStateException e) {
+ // addHttpProxyNetworkVerifyAndRemove throws three IllegalStateException,
+ // expect it to throw for the addNetwork operation
+ if (e.getMessage().contains(ADD_NETWORK_EXCEPTION_SUBSTR)) {
+ exceptionThrown = true;
+ }
+ }
+ assertTrue(exceptionThrown);
+ }
+
private Set<String> getEnabledNetworks(List<WifiConfiguration> configuredNetworks) {
Set<String> ssids = new HashSet<String>();
for (WifiConfiguration wifiConfig : configuredNetworks) {
@@ -524,4 +548,130 @@
}
assertTrue(i < 15);
}
+
+ /**
+ * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint
+ * configuration with an user credential.
+ *
+ * @throws Exception
+ */
+ public void testAddPasspointConfigWithUserCredential() throws Exception {
+ testAddPasspointConfig(generatePasspointConfig(generateUserCredential()));
+ }
+
+ /**
+ * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint
+ * configuration with a certificate credential.
+ *
+ * @throws Exception
+ */
+ public void testAddPasspointConfigWithCertCredential() throws Exception {
+ testAddPasspointConfig(generatePasspointConfig(generateCertCredential()));
+ }
+
+ /**
+ * Verify Passpoint configuration management APIs (add, remove, get) for a Passpoint
+ * configuration with a SIm credential.
+ *
+ * @throws Exception
+ */
+ public void testAddPasspointConfigWithSimCredential() throws Exception {
+ testAddPasspointConfig(generatePasspointConfig(generateSimCredential()));
+ }
+
+ /**
+ * Helper function for generating a {@link PasspointConfiguration} for testing.
+ *
+ * @return {@link PasspointConfiguration}
+ */
+ private PasspointConfiguration generatePasspointConfig(Credential credential) {
+ PasspointConfiguration config = new PasspointConfiguration();
+ config.setCredential(credential);
+
+ // Setup HomeSp.
+ HomeSp homeSp = new HomeSp();
+ homeSp.setFqdn("Test.com");
+ homeSp.setFriendlyName("Test Provider");
+ config.setHomeSp(homeSp);
+
+ return config;
+ }
+
+ /**
+ * Helper function for generating an user credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private Credential generateUserCredential() {
+ Credential credential = new Credential();
+ credential.setRealm("test.net");
+ Credential.UserCredential userCred = new Credential.UserCredential();
+ userCred.setEapType(21 /* EAP_TTLS */);
+ userCred.setUsername("username");
+ userCred.setPassword("password");
+ userCred.setNonEapInnerMethod("PAP");
+ credential.setUserCredential(userCred);
+ credential.setCaCertificate(FakeKeys.CA_CERT0);
+ return credential;
+ }
+
+ /**
+ * Helper function for generating a certificate credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private Credential generateCertCredential() throws Exception {
+ Credential credential = new Credential();
+ credential.setRealm("test.net");
+ Credential.CertificateCredential certCredential = new Credential.CertificateCredential();
+ certCredential.setCertType("x509v3");
+ certCredential.setCertSha256Fingerprint(
+ MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
+ credential.setCertCredential(certCredential);
+ credential.setCaCertificate(FakeKeys.CA_CERT0);
+ credential.setClientCertificateChain(new X509Certificate[] {FakeKeys.CLIENT_CERT});
+ credential.setClientPrivateKey(FakeKeys.RSA_KEY1);
+ return credential;
+ }
+
+ /**
+ * Helper function for generating a SIM credential for testing.
+ *
+ * @return {@link Credential}
+ */
+ private Credential generateSimCredential() throws Exception {
+ Credential credential = new Credential();
+ credential.setRealm("test.net");
+ Credential.SimCredential simCredential = new Credential.SimCredential();
+ simCredential.setImsi("1234*");
+ simCredential.setEapType(18 /* EAP_SIM */);
+ credential.setSimCredential(simCredential);
+ return credential;
+ }
+
+ /**
+ * Helper function verifying Passpoint configuration management APIs (add, remove, get) for
+ * a given configuration.
+ *
+ * @param config The configuration to test with
+ */
+ private void testAddPasspointConfig(PasspointConfiguration config) throws Exception {
+ mWifiManager.addOrUpdatePasspointConfiguration(config);
+
+ // Certificates and keys will be set to null after it is installed to the KeyStore by
+ // WifiManager. Reset them in the expected config so that it can be used to compare
+ // against the retrieved config.
+ config.getCredential().setCaCertificate(null);
+ config.getCredential().setClientCertificateChain(null);
+ config.getCredential().setClientPrivateKey(null);
+
+ // Retrieve the configuration and verify it.
+ List<PasspointConfiguration> configList = mWifiManager.getPasspointConfigurations();
+ assertEquals(1, configList.size());
+ assertEquals(config, configList.get(0));
+
+ // Remove the configuration and verify no installed configuration.
+ mWifiManager.removePasspointConfiguration(config.getHomeSp().getFqdn());
+ assertTrue(mWifiManager.getPasspointConfigurations().isEmpty());
+ }
}