1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.net.cts; 18 19 import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; 20 import static android.net.NetworkCapabilities.TRANSPORT_VPN; 21 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback; 22 23 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 24 25 import static org.junit.Assert.assertArrayEquals; 26 import static org.junit.Assert.assertEquals; 27 import static org.junit.Assert.assertFalse; 28 import static org.junit.Assert.assertNotNull; 29 import static org.junit.Assert.assertNull; 30 import static org.junit.Assert.assertTrue; 31 import static org.junit.Assert.fail; 32 import static org.junit.Assume.assumeTrue; 33 34 import android.Manifest; 35 import android.annotation.NonNull; 36 import android.app.AppOpsManager; 37 import android.content.Context; 38 import android.content.Intent; 39 import android.net.ConnectivityManager; 40 import android.net.Ikev2VpnProfile; 41 import android.net.IpSecAlgorithm; 42 import android.net.Network; 43 import android.net.NetworkCapabilities; 44 import android.net.NetworkRequest; 45 import android.net.ProxyInfo; 46 import android.net.TestNetworkInterface; 47 import android.net.VpnManager; 48 import android.net.cts.util.CtsNetUtils; 49 import android.os.Build; 50 import android.os.Process; 51 import android.platform.test.annotations.AppModeFull; 52 53 import androidx.test.InstrumentationRegistry; 54 55 import com.android.internal.util.HexDump; 56 import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo; 57 import com.android.testutils.DevSdkIgnoreRunner; 58 59 import org.bouncycastle.x509.X509V1CertificateGenerator; 60 import org.junit.After; 61 import org.junit.Test; 62 import org.junit.runner.RunWith; 63 64 import java.math.BigInteger; 65 import java.net.InetAddress; 66 import java.security.KeyPair; 67 import java.security.KeyPairGenerator; 68 import java.security.PrivateKey; 69 import java.security.cert.X509Certificate; 70 import java.util.Arrays; 71 import java.util.Date; 72 import java.util.List; 73 import java.util.concurrent.TimeUnit; 74 75 import javax.security.auth.x500.X500Principal; 76 77 @RunWith(DevSdkIgnoreRunner.class) 78 @IgnoreUpTo(Build.VERSION_CODES.Q) 79 @AppModeFull(reason = "Appops state changes disallowed for instant apps (OP_ACTIVATE_PLATFORM_VPN)") 80 public class Ikev2VpnTest { 81 private static final String TAG = Ikev2VpnTest.class.getSimpleName(); 82 83 // Test vectors for IKE negotiation in test mode. 84 private static final String SUCCESSFUL_IKE_INIT_RESP_V4 = 85 "46b8eca1e0d72a18b2b5d9006d47a0022120222000000000000002d0220000300000002c01010004030000" 86 + "0c0100000c800e0100030000080300000c030000080200000400000008040000102800020800" 87 + "100000b8070f159fe5141d8754ca86f72ecc28d66f514927e96cbe9eec0adb42bf2c276a0ab7" 88 + "a97fa93555f4be9218c14e7f286bb28c6b4fb13825a420f2ffc165854f200bab37d69c8963d4" 89 + "0acb831d983163aa50622fd35c182efe882cf54d6106222abcfaa597255d302f1b95ab71c142" 90 + "c279ea5839a180070bff73f9d03fab815f0d5ee2adec7e409d1e35979f8bd92ffd8aab13d1a0" 91 + "0657d816643ae767e9ae84d2ccfa2bcce1a50572be8d3748ae4863c41ae90da16271e014270f" 92 + "77edd5cd2e3299f3ab27d7203f93d770bacf816041cdcecd0f9af249033979da4369cb242dd9" 93 + "6d172e60513ff3db02de63e50eb7d7f596ada55d7946cad0af0669d1f3e2804846ab3f2a930d" 94 + "df56f7f025f25c25ada694e6231abbb87ee8cfd072c8481dc0b0f6b083fdc3bd89b080e49feb" 95 + "0288eef6fdf8a26ee2fc564a11e7385215cf2deaf2a9965638fc279c908ccdf04094988d91a2" 96 + "464b4a8c0326533aff5119ed79ecbd9d99a218b44f506a5eb09351e67da86698b4c58718db25" 97 + "d55f426fb4c76471b27a41fbce00777bc233c7f6e842e39146f466826de94f564cad8b92bfbe" 98 + "87c99c4c7973ec5f1eea8795e7da82819753aa7c4fcfdab77066c56b939330c4b0d354c23f83" 99 + "ea82fa7a64c4b108f1188379ea0eb4918ee009d804100e6bf118771b9058d42141c847d5ec37" 100 + "6e5ec591c71fc9dac01063c2bd31f9c783b28bf1182900002430f3d5de3449462b31dd28bc27" 101 + "297b6ad169bccce4f66c5399c6e0be9120166f2900001c0000400428b8df2e66f69c8584a186" 102 + "c5eac66783551d49b72900001c000040054e7a622e802d5cbfb96d5f30a6e433994370173529" 103 + "0000080000402e290000100000402f00020003000400050000000800004014"; 104 private static final String SUCCESSFUL_IKE_INIT_RESP_V6 = 105 "46b8eca1e0d72a1800d9ea1babce26bf2120222000000000000002d0220000300000002c01010004030000" 106 + "0c0100000c800e0100030000080300000c030000080200000400000008040000102800020800" 107 + "100000ea0e6dd9ca5930a9a45c323a41f64bfd8cdef7730f5fbff37d7c377da427f489a42aa8" 108 + "c89233380e6e925990d49de35c2cdcf63a61302c731a4b3569df1ee1bf2457e55a6751838ede" 109 + "abb75cc63ba5c9e4355e8e784f383a5efe8a44727dc14aeaf8dacc2620fb1c8875416dc07739" 110 + "7fe4decc1bd514a9c7d270cf21fd734c63a25c34b30b68686e54e8a198f37f27cb491fe27235" 111 + "fab5476b036d875ccab9a68d65fbf3006197f9bebbf94de0d3802b4fafe1d48d931ce3a1a346" 112 + "2d65bd639e9bd7fa46299650a9dbaf9b324e40b466942d91a59f41ef8042f8474c4850ed0f63" 113 + "e9238949d41cd8bbaea9aefdb65443a6405792839563aa5dc5c36b5ce8326ccf8a94d9622b85" 114 + "038d390d5fc0299e14e1f022966d4ac66515f6108ca04faec44821fe5bbf2ed4f84ff5671219" 115 + "608cb4c36b44a31ba010c9088f8d5ff943bb9ff857f74be1755f57a5783874adc57f42bb174e" 116 + "4ad3215de628707014dbcb1707bd214658118fdd7a42b3e1638b991ce5b812a667f1145be811" 117 + "685e3cd3baf9b18d062657b64c206a4d19a531c252a6a51a04aeaf42c618620cdbab65baca23" 118 + "82c57ed888422aeaacf7f1bc3fe2247ff7e7eaca218b74d7b31d02f2b0afa123f802529e7e6c" 119 + "3259d418290740ddbf55686e26998d7edcbbf895664972fed666f2f20af40503aa2af436ec6d" 120 + "4ec981ab19b9088755d94ae7a7c2066ea331d4e56e290000243fefe5555fce552d57a84e682c" 121 + "d4a6dfb3f2f94a94464d5bec3d88b88e9559642900001c00004004eb4afff764e7b79bca78b1" 122 + "3a89100d36d678ae982900001c00004005d177216a3c26f782076e12570d40bfaaa148822929" 123 + "0000080000402e290000100000402f00020003000400050000000800004014"; 124 private static final String SUCCESSFUL_IKE_AUTH_RESP_V4 = 125 "46b8eca1e0d72a18b2b5d9006d47a0022e20232000000001000000e0240000c420a2500a3da4c66fa6929e" 126 + "600f36349ba0e38de14f78a3ad0416cba8c058735712a3d3f9a0a6ed36de09b5e9e02697e7c4" 127 + "2d210ac86cfbd709503cfa51e2eab8cfdc6427d136313c072968f6506a546eb5927164200592" 128 + "6e36a16ee994e63f029432a67bc7d37ca619e1bd6e1678df14853067ecf816b48b81e8746069" 129 + "406363e5aa55f13cb2afda9dbebee94256c29d630b17dd7f1ee52351f92b6e1c3d8551c513f1" 130 + "d74ac52a80b2041397e109fe0aeb3c105b0d4be0ae343a943398764281"; 131 private static final String SUCCESSFUL_IKE_AUTH_RESP_V6 = 132 "46b8eca1e0d72a1800d9ea1babce26bf2e20232000000001000000f0240000d4aaf6eaa6c06b50447e6f54" 133 + "827fd8a9d9d6ac8015c1ebb3e8cb03fc6e54b49a107441f50004027cc5021600828026367f03" 134 + "bc425821cd7772ee98637361300c9b76056e874fea2bd4a17212370b291894264d8c023a01d1" 135 + "c3b691fd4b7c0b534e8c95af4c4638e2d125cb21c6267e2507cd745d72e8da109c47b9259c6c" 136 + "57a26f6bc5b337b9b9496d54bdde0333d7a32e6e1335c9ee730c3ecd607a8689aa7b0577b74f" 137 + "3bf437696a9fd5fc0aee3ed346cd9e15d1dda293df89eb388a8719388a60ca7625754de12cdb" 138 + "efe4c886c5c401"; 139 private static final long IKE_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16); 140 141 private static final InetAddress LOCAL_OUTER_4 = InetAddress.parseNumericAddress("192.0.2.1"); 142 private static final InetAddress LOCAL_OUTER_6 = 143 InetAddress.parseNumericAddress("2001:db8::1"); 144 145 private static final int IP4_PREFIX_LEN = 32; 146 private static final int IP6_PREFIX_LEN = 128; 147 148 // TODO: Use IPv6 address when we can generate test vectors (GCE does not allow IPv6 yet). 149 private static final String TEST_SERVER_ADDR_V4 = "192.0.2.2"; 150 private static final String TEST_SERVER_ADDR_V6 = "2001:db8::2"; 151 private static final String TEST_IDENTITY = "client.cts.android.com"; 152 private static final List<String> TEST_ALLOWED_ALGORITHMS = 153 Arrays.asList(IpSecAlgorithm.AUTH_CRYPT_AES_GCM); 154 155 private static final ProxyInfo TEST_PROXY_INFO = 156 ProxyInfo.buildDirectProxy("proxy.cts.android.com", 1234); 157 private static final int TEST_MTU = 1300; 158 159 private static final byte[] TEST_PSK = "ikeAndroidPsk".getBytes(); 160 private static final String TEST_USER = "username"; 161 private static final String TEST_PASSWORD = "pa55w0rd"; 162 163 // Static state to reduce setup/teardown 164 private static final Context sContext = InstrumentationRegistry.getContext(); 165 private static final ConnectivityManager sCM = 166 (ConnectivityManager) sContext.getSystemService(Context.CONNECTIVITY_SERVICE); 167 private static final VpnManager sVpnMgr = 168 (VpnManager) sContext.getSystemService(Context.VPN_MANAGEMENT_SERVICE); 169 private static final CtsNetUtils mCtsNetUtils = new CtsNetUtils(sContext); 170 171 private final X509Certificate mServerRootCa; 172 private final CertificateAndKey mUserCertKey; 173 Ikev2VpnTest()174 public Ikev2VpnTest() throws Exception { 175 // Build certificates 176 mServerRootCa = generateRandomCertAndKeyPair().cert; 177 mUserCertKey = generateRandomCertAndKeyPair(); 178 } 179 180 @After tearDown()181 public void tearDown() { 182 setAppop(AppOpsManager.OP_ACTIVATE_VPN, false); 183 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false); 184 } 185 186 /** 187 * Sets the given appop using shell commands 188 * 189 * <p>This method must NEVER be called from within a shell permission, as it will attempt to 190 * acquire, and then drop the shell permission identity. This results in the caller losing the 191 * shell permission identity due to these calls not being reference counted. 192 */ setAppop(int appop, boolean allow)193 public void setAppop(int appop, boolean allow) { 194 // Requires shell permission to update appops. 195 runWithShellPermissionIdentity(() -> { 196 mCtsNetUtils.setAppopPrivileged(appop, allow); 197 }, Manifest.permission.MANAGE_TEST_NETWORKS); 198 } 199 buildIkev2VpnProfileCommon( Ikev2VpnProfile.Builder builder, boolean isRestrictedToTestNetworks)200 private Ikev2VpnProfile buildIkev2VpnProfileCommon( 201 Ikev2VpnProfile.Builder builder, boolean isRestrictedToTestNetworks) throws Exception { 202 if (isRestrictedToTestNetworks) { 203 builder.restrictToTestNetworks(); 204 } 205 206 return builder.setBypassable(true) 207 .setAllowedAlgorithms(TEST_ALLOWED_ALGORITHMS) 208 .setProxy(TEST_PROXY_INFO) 209 .setMaxMtu(TEST_MTU) 210 .setMetered(false) 211 .build(); 212 } 213 buildIkev2VpnProfilePsk(boolean isRestrictedToTestNetworks)214 private Ikev2VpnProfile buildIkev2VpnProfilePsk(boolean isRestrictedToTestNetworks) 215 throws Exception { 216 return buildIkev2VpnProfilePsk(TEST_SERVER_ADDR_V6, isRestrictedToTestNetworks); 217 } 218 buildIkev2VpnProfilePsk( String remote, boolean isRestrictedToTestNetworks)219 private Ikev2VpnProfile buildIkev2VpnProfilePsk( 220 String remote, boolean isRestrictedToTestNetworks) throws Exception { 221 final Ikev2VpnProfile.Builder builder = 222 new Ikev2VpnProfile.Builder(remote, TEST_IDENTITY).setAuthPsk(TEST_PSK); 223 224 return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks); 225 } 226 buildIkev2VpnProfileUsernamePassword(boolean isRestrictedToTestNetworks)227 private Ikev2VpnProfile buildIkev2VpnProfileUsernamePassword(boolean isRestrictedToTestNetworks) 228 throws Exception { 229 final Ikev2VpnProfile.Builder builder = 230 new Ikev2VpnProfile.Builder(TEST_SERVER_ADDR_V6, TEST_IDENTITY) 231 .setAuthUsernamePassword(TEST_USER, TEST_PASSWORD, mServerRootCa); 232 233 return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks); 234 } 235 buildIkev2VpnProfileDigitalSignature(boolean isRestrictedToTestNetworks)236 private Ikev2VpnProfile buildIkev2VpnProfileDigitalSignature(boolean isRestrictedToTestNetworks) 237 throws Exception { 238 final Ikev2VpnProfile.Builder builder = 239 new Ikev2VpnProfile.Builder(TEST_SERVER_ADDR_V6, TEST_IDENTITY) 240 .setAuthDigitalSignature( 241 mUserCertKey.cert, mUserCertKey.key, mServerRootCa); 242 243 return buildIkev2VpnProfileCommon(builder, isRestrictedToTestNetworks); 244 } 245 checkBasicIkev2VpnProfile(@onNull Ikev2VpnProfile profile)246 private void checkBasicIkev2VpnProfile(@NonNull Ikev2VpnProfile profile) throws Exception { 247 assertEquals(TEST_SERVER_ADDR_V6, profile.getServerAddr()); 248 assertEquals(TEST_IDENTITY, profile.getUserIdentity()); 249 assertEquals(TEST_PROXY_INFO, profile.getProxyInfo()); 250 assertEquals(TEST_ALLOWED_ALGORITHMS, profile.getAllowedAlgorithms()); 251 assertTrue(profile.isBypassable()); 252 assertFalse(profile.isMetered()); 253 assertEquals(TEST_MTU, profile.getMaxMtu()); 254 assertFalse(profile.isRestrictedToTestNetworks()); 255 } 256 257 @Test testBuildIkev2VpnProfilePsk()258 public void testBuildIkev2VpnProfilePsk() throws Exception { 259 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 260 261 final Ikev2VpnProfile profile = 262 buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */); 263 264 checkBasicIkev2VpnProfile(profile); 265 assertArrayEquals(TEST_PSK, profile.getPresharedKey()); 266 267 // Verify nothing else is set. 268 assertNull(profile.getUsername()); 269 assertNull(profile.getPassword()); 270 assertNull(profile.getServerRootCaCert()); 271 assertNull(profile.getRsaPrivateKey()); 272 assertNull(profile.getUserCert()); 273 } 274 275 @Test testBuildIkev2VpnProfileUsernamePassword()276 public void testBuildIkev2VpnProfileUsernamePassword() throws Exception { 277 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 278 279 final Ikev2VpnProfile profile = 280 buildIkev2VpnProfileUsernamePassword(false /* isRestrictedToTestNetworks */); 281 282 checkBasicIkev2VpnProfile(profile); 283 assertEquals(TEST_USER, profile.getUsername()); 284 assertEquals(TEST_PASSWORD, profile.getPassword()); 285 assertEquals(mServerRootCa, profile.getServerRootCaCert()); 286 287 // Verify nothing else is set. 288 assertNull(profile.getPresharedKey()); 289 assertNull(profile.getRsaPrivateKey()); 290 assertNull(profile.getUserCert()); 291 } 292 293 @Test testBuildIkev2VpnProfileDigitalSignature()294 public void testBuildIkev2VpnProfileDigitalSignature() throws Exception { 295 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 296 297 final Ikev2VpnProfile profile = 298 buildIkev2VpnProfileDigitalSignature(false /* isRestrictedToTestNetworks */); 299 300 checkBasicIkev2VpnProfile(profile); 301 assertEquals(mUserCertKey.cert, profile.getUserCert()); 302 assertEquals(mUserCertKey.key, profile.getRsaPrivateKey()); 303 assertEquals(mServerRootCa, profile.getServerRootCaCert()); 304 305 // Verify nothing else is set. 306 assertNull(profile.getUsername()); 307 assertNull(profile.getPassword()); 308 assertNull(profile.getPresharedKey()); 309 } 310 verifyProvisionVpnProfile( boolean hasActivateVpn, boolean hasActivatePlatformVpn, boolean expectIntent)311 private void verifyProvisionVpnProfile( 312 boolean hasActivateVpn, boolean hasActivatePlatformVpn, boolean expectIntent) 313 throws Exception { 314 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 315 316 setAppop(AppOpsManager.OP_ACTIVATE_VPN, hasActivateVpn); 317 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, hasActivatePlatformVpn); 318 319 final Ikev2VpnProfile profile = 320 buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */); 321 final Intent intent = sVpnMgr.provisionVpnProfile(profile); 322 assertEquals(expectIntent, intent != null); 323 } 324 325 @Test testProvisionVpnProfileNoPreviousConsent()326 public void testProvisionVpnProfileNoPreviousConsent() throws Exception { 327 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 328 329 verifyProvisionVpnProfile(false /* hasActivateVpn */, 330 false /* hasActivatePlatformVpn */, true /* expectIntent */); 331 } 332 333 @Test testProvisionVpnProfilePlatformVpnConsented()334 public void testProvisionVpnProfilePlatformVpnConsented() throws Exception { 335 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 336 337 verifyProvisionVpnProfile(false /* hasActivateVpn */, 338 true /* hasActivatePlatformVpn */, false /* expectIntent */); 339 } 340 341 @Test testProvisionVpnProfileVpnServiceConsented()342 public void testProvisionVpnProfileVpnServiceConsented() throws Exception { 343 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 344 345 verifyProvisionVpnProfile(true /* hasActivateVpn */, 346 false /* hasActivatePlatformVpn */, false /* expectIntent */); 347 } 348 349 @Test testProvisionVpnProfileAllPreConsented()350 public void testProvisionVpnProfileAllPreConsented() throws Exception { 351 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 352 353 verifyProvisionVpnProfile(true /* hasActivateVpn */, 354 true /* hasActivatePlatformVpn */, false /* expectIntent */); 355 } 356 357 @Test testDeleteVpnProfile()358 public void testDeleteVpnProfile() throws Exception { 359 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 360 361 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true); 362 363 final Ikev2VpnProfile profile = 364 buildIkev2VpnProfilePsk(false /* isRestrictedToTestNetworks */); 365 assertNull(sVpnMgr.provisionVpnProfile(profile)); 366 367 // Verify that deleting the profile works (even without the appop) 368 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false); 369 sVpnMgr.deleteProvisionedVpnProfile(); 370 371 // Test that the profile was deleted - starting it should throw an IAE. 372 try { 373 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true); 374 sVpnMgr.startProvisionedVpnProfile(); 375 fail("Expected IllegalArgumentException due to missing profile"); 376 } catch (IllegalArgumentException expected) { 377 } 378 } 379 380 @Test testStartVpnProfileNoPreviousConsent()381 public void testStartVpnProfileNoPreviousConsent() throws Exception { 382 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 383 384 setAppop(AppOpsManager.OP_ACTIVATE_VPN, false); 385 setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false); 386 387 // Make sure the VpnProfile is not provisioned already. 388 sVpnMgr.stopProvisionedVpnProfile(); 389 390 try { 391 sVpnMgr.startProvisionedVpnProfile(); 392 fail("Expected SecurityException for missing consent"); 393 } catch (SecurityException expected) { 394 } 395 } 396 checkStartStopVpnProfileBuildsNetworks(IkeTunUtils tunUtils, boolean testIpv6)397 private void checkStartStopVpnProfileBuildsNetworks(IkeTunUtils tunUtils, boolean testIpv6) 398 throws Exception { 399 String serverAddr = testIpv6 ? TEST_SERVER_ADDR_V6 : TEST_SERVER_ADDR_V4; 400 String initResp = testIpv6 ? SUCCESSFUL_IKE_INIT_RESP_V6 : SUCCESSFUL_IKE_INIT_RESP_V4; 401 String authResp = testIpv6 ? SUCCESSFUL_IKE_AUTH_RESP_V6 : SUCCESSFUL_IKE_AUTH_RESP_V4; 402 boolean hasNat = !testIpv6; 403 404 // Requires MANAGE_TEST_NETWORKS to provision a test-mode profile. 405 mCtsNetUtils.setAppopPrivileged(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, true); 406 407 final Ikev2VpnProfile profile = 408 buildIkev2VpnProfilePsk(serverAddr, true /* isRestrictedToTestNetworks */); 409 assertNull(sVpnMgr.provisionVpnProfile(profile)); 410 411 sVpnMgr.startProvisionedVpnProfile(); 412 413 // Inject IKE negotiation 414 int expectedMsgId = 0; 415 tunUtils.awaitReqAndInjectResp(IKE_INITIATOR_SPI, expectedMsgId++, false /* isEncap */, 416 HexDump.hexStringToByteArray(initResp)); 417 tunUtils.awaitReqAndInjectResp(IKE_INITIATOR_SPI, expectedMsgId++, hasNat /* isEncap */, 418 HexDump.hexStringToByteArray(authResp)); 419 420 // Verify the VPN network came up 421 final NetworkRequest nr = new NetworkRequest.Builder() 422 .clearCapabilities().addTransportType(TRANSPORT_VPN).build(); 423 424 final TestNetworkCallback cb = new TestNetworkCallback(); 425 sCM.requestNetwork(nr, cb); 426 cb.waitForAvailable(); 427 final Network vpnNetwork = cb.currentNetwork; 428 assertNotNull(vpnNetwork); 429 430 final NetworkCapabilities caps = sCM.getNetworkCapabilities(vpnNetwork); 431 assertTrue(caps.hasTransport(TRANSPORT_VPN)); 432 assertTrue(caps.hasCapability(NET_CAPABILITY_INTERNET)); 433 assertEquals(Process.myUid(), caps.getOwnerUid()); 434 435 sVpnMgr.stopProvisionedVpnProfile(); 436 cb.waitForLost(); 437 assertEquals(vpnNetwork, cb.lastLostNetwork); 438 } 439 440 private class VerifyStartStopVpnProfileTest implements TestNetworkRunnable.Test { 441 private final boolean mTestIpv6Only; 442 443 /** 444 * Constructs the test 445 * 446 * @param testIpv6Only if true, builds a IPv6-only test; otherwise builds a IPv4-only test 447 */ VerifyStartStopVpnProfileTest(boolean testIpv6Only)448 VerifyStartStopVpnProfileTest(boolean testIpv6Only) { 449 mTestIpv6Only = testIpv6Only; 450 } 451 452 @Override runTest(TestNetworkInterface testIface, TestNetworkCallback tunNetworkCallback)453 public void runTest(TestNetworkInterface testIface, TestNetworkCallback tunNetworkCallback) 454 throws Exception { 455 final IkeTunUtils tunUtils = new IkeTunUtils(testIface.getFileDescriptor()); 456 457 checkStartStopVpnProfileBuildsNetworks(tunUtils, mTestIpv6Only); 458 } 459 460 @Override cleanupTest()461 public void cleanupTest() { 462 sVpnMgr.stopProvisionedVpnProfile(); 463 } 464 465 @Override getTestNetworkAddresses()466 public InetAddress[] getTestNetworkAddresses() { 467 if (mTestIpv6Only) { 468 return new InetAddress[] {LOCAL_OUTER_6}; 469 } else { 470 return new InetAddress[] {LOCAL_OUTER_4}; 471 } 472 } 473 } 474 475 @Test testStartStopVpnProfileV4()476 public void testStartStopVpnProfileV4() throws Exception { 477 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 478 479 // Requires shell permission to update appops. 480 runWithShellPermissionIdentity( 481 new TestNetworkRunnable(new VerifyStartStopVpnProfileTest(false))); 482 } 483 484 @Test testStartStopVpnProfileV6()485 public void testStartStopVpnProfileV6() throws Exception { 486 assumeTrue(mCtsNetUtils.hasIpsecTunnelsFeature()); 487 488 // Requires shell permission to update appops. 489 runWithShellPermissionIdentity( 490 new TestNetworkRunnable(new VerifyStartStopVpnProfileTest(true))); 491 } 492 493 private static class CertificateAndKey { 494 public final X509Certificate cert; 495 public final PrivateKey key; 496 CertificateAndKey(X509Certificate cert, PrivateKey key)497 CertificateAndKey(X509Certificate cert, PrivateKey key) { 498 this.cert = cert; 499 this.key = key; 500 } 501 } 502 generateRandomCertAndKeyPair()503 private static CertificateAndKey generateRandomCertAndKeyPair() throws Exception { 504 final Date validityBeginDate = 505 new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1L)); 506 final Date validityEndDate = 507 new Date(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1L)); 508 509 // Generate a keypair 510 final KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 511 keyPairGenerator.initialize(512); 512 final KeyPair keyPair = keyPairGenerator.generateKeyPair(); 513 514 final X500Principal dnName = new X500Principal("CN=test.android.com"); 515 final X509V1CertificateGenerator certGen = new X509V1CertificateGenerator(); 516 certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); 517 certGen.setSubjectDN(dnName); 518 certGen.setIssuerDN(dnName); 519 certGen.setNotBefore(validityBeginDate); 520 certGen.setNotAfter(validityEndDate); 521 certGen.setPublicKey(keyPair.getPublic()); 522 certGen.setSignatureAlgorithm("SHA256WithRSAEncryption"); 523 524 final X509Certificate cert = certGen.generate(keyPair.getPrivate(), "AndroidOpenSSL"); 525 return new CertificateAndKey(cert, keyPair.getPrivate()); 526 } 527 } 528