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 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package android.ipsec.ike.cts; 17 18 import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; 19 import static android.system.OsConstants.AF_INET; 20 import static android.system.OsConstants.AF_INET6; 21 22 import static org.junit.Assert.assertEquals; 23 import static org.junit.Assert.assertNotNull; 24 import static org.junit.Assert.assertTrue; 25 26 import android.annotation.NonNull; 27 import android.app.AppOpsManager; 28 import android.content.pm.PackageManager; 29 import android.ipsec.ike.cts.IkeTunUtils.PortPair; 30 import android.net.InetAddresses; 31 import android.net.IpSecManager; 32 import android.net.IpSecTransform; 33 import android.net.LinkAddress; 34 import android.net.ipsec.ike.ChildSessionCallback; 35 import android.net.ipsec.ike.ChildSessionConfiguration; 36 import android.net.ipsec.ike.IkeSessionCallback; 37 import android.net.ipsec.ike.IkeSessionConfiguration; 38 import android.net.ipsec.ike.IkeSessionConnectionInfo; 39 import android.net.ipsec.ike.IkeTrafficSelector; 40 import android.net.ipsec.ike.TransportModeChildSessionParams; 41 import android.net.ipsec.ike.TunnelModeChildSessionParams; 42 import android.net.ipsec.ike.exceptions.IkeException; 43 import android.os.UserHandle; 44 import android.platform.test.annotations.AppModeFull; 45 46 import androidx.test.ext.junit.runners.AndroidJUnit4; 47 48 import com.android.compatibility.common.util.SystemUtil; 49 import com.android.internal.net.annotations.PolicyDirection; 50 import com.android.net.module.util.ArrayTrackRecord; 51 52 import org.junit.After; 53 import org.junit.Before; 54 import org.junit.runner.RunWith; 55 56 import java.net.Inet4Address; 57 import java.net.Inet6Address; 58 import java.net.InetAddress; 59 import java.util.ArrayList; 60 import java.util.HashSet; 61 import java.util.List; 62 import java.util.Objects; 63 import java.util.Set; 64 import java.util.concurrent.CompletableFuture; 65 import java.util.concurrent.Executor; 66 import java.util.concurrent.Executors; 67 import java.util.concurrent.TimeUnit; 68 69 /** 70 * Package private base class for testing IkeSessionParams and IKE exchanges. 71 * 72 * <p>Subclasses MUST explicitly call #setUpTestNetwork and #tearDownTestNetwork to be able to use 73 * the test network 74 * 75 * <p>All IKE Sessions running in test mode will generate SPIs deterministically. That is to say 76 * each IKE Session will always generate the same IKE INIT SPI and test vectors are generated based 77 * on this deterministic IKE SPI. Each test will use different local and remote addresses to avoid 78 * the case that the next test try to allocate the same SPI before the previous test has released 79 * it, since SPI resources are not released in testing thread. Similarly, each test MUST use 80 * different Network instances to avoid sharing the same IkeSocket and hitting IKE SPI collision. 81 */ 82 @RunWith(AndroidJUnit4.class) 83 @AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps") 84 abstract class IkeSessionTestBase extends IkeTestNetworkBase { 85 // Package-wide common expected results that will be shared by all IKE/Child SA creation tests 86 static final String EXPECTED_REMOTE_APP_VERSION_EMPTY = ""; 87 static final byte[] EXPECTED_PROTOCOL_ERROR_DATA_NONE = new byte[0]; 88 89 static final InetAddress EXPECTED_DNS_SERVERS_ONE = 90 InetAddresses.parseNumericAddress("8.8.8.8"); 91 static final InetAddress EXPECTED_DNS_SERVERS_TWO = 92 InetAddresses.parseNumericAddress("8.8.4.4"); 93 94 static final InetAddress EXPECTED_INTERNAL_ADDR = 95 InetAddresses.parseNumericAddress("198.51.100.10"); 96 static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR = 97 new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN); 98 static final InetAddress EXPECTED_INTERNAL_ADDR_V6 = 99 InetAddresses.parseNumericAddress("2001:db8::2"); 100 static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR_V6 = 101 new LinkAddress(EXPECTED_INTERNAL_ADDR_V6, IP6_PREFIX_LEN); 102 103 static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS = 104 new IkeTrafficSelector( 105 MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR); 106 static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS = DEFAULT_V4_TS; 107 static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS_V6 = 108 new IkeTrafficSelector( 109 MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR_V6, EXPECTED_INTERNAL_ADDR_V6); 110 static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS_V6 = DEFAULT_V6_TS; 111 112 // This value is align with the test vectors hex that are generated in an IPv4 environment 113 static final IkeTrafficSelector TRANSPORT_MODE_OUTBOUND_TS = 114 new IkeTrafficSelector( 115 MIN_PORT, 116 MAX_PORT, 117 InetAddresses.parseNumericAddress("10.138.0.2"), 118 InetAddresses.parseNumericAddress("10.138.0.2")); 119 120 static final long IKE_DETERMINISTIC_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16); 121 122 private static final int TIMEOUT_MS = 1000; 123 124 // Constants to be used for providing different IP addresses for each tests 125 private static final byte IP_ADDR_LAST_BYTE_MAX = (byte) 100; 126 private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_LOCAL = 127 InetAddresses.parseNumericAddress("192.0.2.1").getAddress(); 128 private static final byte[] INITIAL_AVAILABLE_IP4_ADDR_REMOTE = 129 InetAddresses.parseNumericAddress("198.51.100.1").getAddress(); 130 private static final byte[] NEXT_AVAILABLE_IP4_ADDR_LOCAL = INITIAL_AVAILABLE_IP4_ADDR_LOCAL; 131 private static final byte[] NEXT_AVAILABLE_IP4_ADDR_REMOTE = INITIAL_AVAILABLE_IP4_ADDR_REMOTE; 132 133 private static final byte[] INITIAL_AVAILABLE_IP6_ADDR_LOCAL = 134 InetAddresses.parseNumericAddress("2a00:1000::0").getAddress(); 135 private static final byte[] INITIAL_AVAILABLE_IP6_ADDR_REMOTE = 136 InetAddresses.parseNumericAddress("2404:6800:4004:820::2004").getAddress(); 137 private static final byte[] NEXT_AVAILABLE_IP6_ADDR_LOCAL = INITIAL_AVAILABLE_IP6_ADDR_LOCAL; 138 private static final byte[] NEXT_AVAILABLE_IP6_ADDR_REMOTE = INITIAL_AVAILABLE_IP6_ADDR_REMOTE; 139 140 TunNetworkContext mTunNetworkContext; 141 142 InetAddress mLocalAddress; 143 InetAddress mRemoteAddress; 144 145 Executor mUserCbExecutor; 146 TestIkeSessionCallback mIkeSessionCallback; 147 TestChildSessionCallback mFirstChildSessionCallback; 148 149 @Before setUp()150 public void setUp() throws Exception { 151 mLocalAddress = getNextAvailableIpv4AddressLocal(); 152 mRemoteAddress = getNextAvailableIpv4AddressRemote(); 153 mTunNetworkContext = new TunNetworkContext(mLocalAddress); 154 155 mUserCbExecutor = Executors.newSingleThreadExecutor(); 156 mIkeSessionCallback = new DefaultTestIkeSessionCallback(); 157 mFirstChildSessionCallback = new DefaultTestChildSessionCallback(); 158 } 159 160 @After tearDown()161 public void tearDown() throws Exception { 162 if (mTunNetworkContext != null) { 163 mTunNetworkContext.close(); 164 } 165 } 166 setAppOp(int appop, boolean allow)167 static void setAppOp(int appop, boolean allow) { 168 String opName = AppOpsManager.opToName(appop); 169 for (String pkg : new String[] {"com.android.shell", sContext.getPackageName()}) { 170 String cmd = 171 String.format( 172 "appops set %s %s %s --user %d", 173 pkg, // Package name 174 opName, // Appop 175 (allow ? "allow" : "deny"), // Action 176 UserHandle.myUserId()); 177 178 SystemUtil.runShellCommand(cmd); 179 } 180 } 181 getNextAvailableIpv4AddressLocal()182 Inet4Address getNextAvailableIpv4AddressLocal() throws Exception { 183 return (Inet4Address) 184 getNextAvailableAddress( 185 NEXT_AVAILABLE_IP4_ADDR_LOCAL, 186 INITIAL_AVAILABLE_IP4_ADDR_LOCAL, 187 false /* isIp6 */); 188 } 189 getNextAvailableIpv4AddressRemote()190 Inet4Address getNextAvailableIpv4AddressRemote() throws Exception { 191 return (Inet4Address) 192 getNextAvailableAddress( 193 NEXT_AVAILABLE_IP4_ADDR_REMOTE, 194 INITIAL_AVAILABLE_IP4_ADDR_REMOTE, 195 false /* isIp6 */); 196 } 197 getNextAvailableIpv6AddressLocal()198 Inet6Address getNextAvailableIpv6AddressLocal() throws Exception { 199 return (Inet6Address) 200 getNextAvailableAddress( 201 NEXT_AVAILABLE_IP6_ADDR_LOCAL, 202 INITIAL_AVAILABLE_IP6_ADDR_LOCAL, 203 true /* isIp6 */); 204 } 205 getNextAvailableIpv6AddressRemote()206 Inet6Address getNextAvailableIpv6AddressRemote() throws Exception { 207 return (Inet6Address) 208 getNextAvailableAddress( 209 NEXT_AVAILABLE_IP6_ADDR_REMOTE, 210 INITIAL_AVAILABLE_IP6_ADDR_REMOTE, 211 true /* isIp6 */); 212 } 213 getNextAvailableAddress( byte[] nextAddressBytes, byte[] initialAddressBytes, boolean isIp6)214 InetAddress getNextAvailableAddress( 215 byte[] nextAddressBytes, byte[] initialAddressBytes, boolean isIp6) throws Exception { 216 int addressLen = isIp6 ? IP6_ADDRESS_LEN : IP4_ADDRESS_LEN; 217 218 synchronized (nextAddressBytes) { 219 if (nextAddressBytes[addressLen - 1] == IP_ADDR_LAST_BYTE_MAX) { 220 resetNextAvailableAddress(nextAddressBytes, initialAddressBytes); 221 } 222 223 InetAddress address = InetAddress.getByAddress(nextAddressBytes); 224 nextAddressBytes[addressLen - 1]++; 225 return address; 226 } 227 } 228 resetNextAvailableAddress(byte[] nextAddressBytes, byte[] initialAddressBytes)229 private void resetNextAvailableAddress(byte[] nextAddressBytes, byte[] initialAddressBytes) { 230 synchronized (nextAddressBytes) { 231 System.arraycopy( 232 nextAddressBytes, 0, initialAddressBytes, 0, initialAddressBytes.length); 233 } 234 } 235 buildTransportModeChildParamsWithTs( IkeTrafficSelector inboundTs, IkeTrafficSelector outboundTs)236 TransportModeChildSessionParams buildTransportModeChildParamsWithTs( 237 IkeTrafficSelector inboundTs, IkeTrafficSelector outboundTs) { 238 return new TransportModeChildSessionParams.Builder() 239 .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher()) 240 .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher()) 241 .addInboundTrafficSelectors(inboundTs) 242 .addOutboundTrafficSelectors(outboundTs) 243 .build(); 244 } 245 buildTransportModeChildParamsWithDefaultTs()246 TransportModeChildSessionParams buildTransportModeChildParamsWithDefaultTs() { 247 return new TransportModeChildSessionParams.Builder() 248 .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher()) 249 .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher()) 250 .build(); 251 } 252 buildTunnelModeChildSessionParams()253 TunnelModeChildSessionParams buildTunnelModeChildSessionParams() { 254 return new TunnelModeChildSessionParams.Builder() 255 .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher()) 256 .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher()) 257 .addInternalAddressRequest(AF_INET) 258 .addInternalAddressRequest(AF_INET6) 259 .build(); 260 } 261 performSetupIkeAndFirstChildBlocking(String ikeInitRespHex, String... ikeAuthRespHexes)262 PortPair performSetupIkeAndFirstChildBlocking(String ikeInitRespHex, String... ikeAuthRespHexes) 263 throws Exception { 264 return performSetupIkeAndFirstChildBlocking( 265 ikeInitRespHex, 266 1 /* expectedAuthReqPktCnt */, 267 true /*expectedAuthUseEncap*/, 268 ikeAuthRespHexes); 269 } 270 performSetupIkeAndFirstChildBlocking( String ikeInitRespHex, boolean expectedAuthUseEncap, String... ikeAuthRespHexes)271 PortPair performSetupIkeAndFirstChildBlocking( 272 String ikeInitRespHex, boolean expectedAuthUseEncap, String... ikeAuthRespHexes) 273 throws Exception { 274 return performSetupIkeAndFirstChildBlocking( 275 ikeInitRespHex, 276 1 /* expectedAuthReqPktCnt */, 277 expectedAuthUseEncap, 278 ikeAuthRespHexes); 279 } 280 performSetupIkeAndFirstChildBlocking( String ikeInitRespHex, int expectedAuthReqPktCnt, boolean expectedAuthUseEncap, String... ikeAuthRespHexes)281 PortPair performSetupIkeAndFirstChildBlocking( 282 String ikeInitRespHex, 283 int expectedAuthReqPktCnt, 284 boolean expectedAuthUseEncap, 285 String... ikeAuthRespHexes) 286 throws Exception { 287 mTunNetworkContext.tunUtils.awaitReqAndInjectResp( 288 IKE_DETERMINISTIC_INITIATOR_SPI, 289 0 /* expectedMsgId */, 290 false /* expectedUseEncap */, 291 ikeInitRespHex); 292 293 byte[] ikeAuthReqPkt = 294 mTunNetworkContext 295 .tunUtils 296 .awaitReqAndInjectResp( 297 IKE_DETERMINISTIC_INITIATOR_SPI, 298 1 /* expectedMsgId */, 299 expectedAuthUseEncap, 300 expectedAuthReqPktCnt, 301 ikeAuthRespHexes) 302 .get(0); 303 return IkeTunUtils.getSrcDestPortPair(ikeAuthReqPkt); 304 } 305 performCloseIkeBlocking(int expectedMsgId, String deleteIkeRespHex)306 void performCloseIkeBlocking(int expectedMsgId, String deleteIkeRespHex) throws Exception { 307 performCloseIkeBlocking(expectedMsgId, true /* expectedUseEncap*/, deleteIkeRespHex); 308 } 309 performCloseIkeBlocking( int expectedMsgId, boolean expectedUseEncap, String deleteIkeRespHex)310 void performCloseIkeBlocking( 311 int expectedMsgId, boolean expectedUseEncap, String deleteIkeRespHex) throws Exception { 312 mTunNetworkContext.tunUtils.awaitReqAndInjectResp( 313 IKE_DETERMINISTIC_INITIATOR_SPI, expectedMsgId, expectedUseEncap, deleteIkeRespHex); 314 } 315 316 /** 317 * Base testing callback that allows caller to block current thread until a method get called 318 */ 319 abstract static class TestIkeSessionCallback implements IkeSessionCallback { 320 private CompletableFuture<IkeSessionConfiguration> mFutureIkeConfig = 321 new CompletableFuture<>(); 322 private CompletableFuture<Boolean> mFutureOnClosedCall = new CompletableFuture<>(); 323 private CompletableFuture<IkeSessionConnectionInfo> mFutureConnectionConfig = 324 new CompletableFuture<>(); 325 326 private int mOnErrorExceptionsCount = 0; 327 private ArrayTrackRecord<IkeException> mOnErrorExceptionsTrackRecord = 328 new ArrayTrackRecord<>(); 329 330 protected CompletableFuture<IkeException> mFutureOnClosedException = 331 new CompletableFuture<>(); 332 333 @Override onOpened(@onNull IkeSessionConfiguration sessionConfiguration)334 public void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration) { 335 mFutureIkeConfig.complete(sessionConfiguration); 336 } 337 338 @Override onClosed()339 public void onClosed() { 340 mFutureOnClosedCall.complete(true /* unused */); 341 } 342 343 @Override onError(@onNull IkeException exception)344 public void onError(@NonNull IkeException exception) { 345 IkeSessionCallback.super.onError(exception); 346 mOnErrorExceptionsTrackRecord.add(exception); 347 } 348 349 @Override onIkeSessionConnectionInfoChanged( @onNull IkeSessionConnectionInfo connectionInfo)350 public void onIkeSessionConnectionInfoChanged( 351 @NonNull IkeSessionConnectionInfo connectionInfo) { 352 IkeSessionCallback.super.onIkeSessionConnectionInfoChanged(connectionInfo); 353 mFutureConnectionConfig.complete(connectionInfo); 354 } 355 awaitIkeConfig()356 public IkeSessionConfiguration awaitIkeConfig() throws Exception { 357 return mFutureIkeConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 358 } 359 awaitOnClosedException()360 public IkeException awaitOnClosedException() throws Exception { 361 return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 362 } 363 awaitNextOnErrorException()364 public IkeException awaitNextOnErrorException() { 365 return mOnErrorExceptionsTrackRecord.poll( 366 (long) TIMEOUT_MS, 367 mOnErrorExceptionsCount++, 368 (transform) -> { 369 return true; 370 }); 371 } 372 awaitOnClosed()373 public void awaitOnClosed() throws Exception { 374 mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 375 } 376 awaitOnIkeSessionConnectionInfoChanged()377 public IkeSessionConnectionInfo awaitOnIkeSessionConnectionInfoChanged() throws Exception { 378 return mFutureConnectionConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 379 } 380 } 381 382 /** Default testing callback for all IKE exchange tests */ 383 static class DefaultTestIkeSessionCallback extends TestIkeSessionCallback { 384 @Override onClosedWithException(@onNull IkeException exception)385 public void onClosedWithException(@NonNull IkeException exception) { 386 mFutureOnClosedException.complete(exception); 387 } 388 } 389 390 /** Testing callback to verify deprecated methods before they are removed */ 391 static class LegacyTestIkeSessionCallback extends TestIkeSessionCallback { 392 @Override onClosedExceptionally(@onNull IkeException exception)393 public void onClosedExceptionally(@NonNull IkeException exception) { 394 mFutureOnClosedException.complete(exception); 395 } 396 } 397 398 /** 399 * Base testing callback that allows caller to block current thread until a method get called 400 */ 401 abstract static class TestChildSessionCallback implements ChildSessionCallback { 402 private CompletableFuture<ChildSessionConfiguration> mFutureChildConfig = 403 new CompletableFuture<>(); 404 private CompletableFuture<Boolean> mFutureOnClosedCall = new CompletableFuture<>(); 405 406 protected CompletableFuture<IkeException> mFutureOnClosedException = 407 new CompletableFuture<>(); 408 409 private int mCreatedIpSecTransformCount = 0; 410 private int mMigratedIpSecTransformCount = 0; 411 private int mDeletedIpSecTransformCount = 0; 412 private ArrayTrackRecord<IpSecTransformCallRecord> mCreatedIpSecTransformsTrackRecord = 413 new ArrayTrackRecord<>(); 414 private ArrayTrackRecord<IpSecTransformCallRecord[]> mMigratedIpSecTransformsTrackRecord = 415 new ArrayTrackRecord<>(); 416 private ArrayTrackRecord<IpSecTransformCallRecord> mDeletedIpSecTransformsTrackRecord = 417 new ArrayTrackRecord<>(); 418 419 @Override onOpened(@onNull ChildSessionConfiguration sessionConfiguration)420 public void onOpened(@NonNull ChildSessionConfiguration sessionConfiguration) { 421 mFutureChildConfig.complete(sessionConfiguration); 422 } 423 424 @Override onClosed()425 public void onClosed() { 426 mFutureOnClosedCall.complete(true /* unused */); 427 } 428 429 @Override onIpSecTransformCreated(@onNull IpSecTransform ipSecTransform, int direction)430 public void onIpSecTransformCreated(@NonNull IpSecTransform ipSecTransform, int direction) { 431 mCreatedIpSecTransformsTrackRecord.add( 432 new IpSecTransformCallRecord(ipSecTransform, direction)); 433 } 434 435 @Override onIpSecTransformsMigrated( IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform)436 public void onIpSecTransformsMigrated( 437 IpSecTransform inIpSecTransform, IpSecTransform outIpSecTransform) { 438 ChildSessionCallback.super.onIpSecTransformsMigrated( 439 inIpSecTransform, outIpSecTransform); 440 441 IpSecTransformCallRecord inRecord = 442 new IpSecTransformCallRecord(inIpSecTransform, IpSecManager.DIRECTION_IN); 443 IpSecTransformCallRecord outRecord = 444 new IpSecTransformCallRecord(outIpSecTransform, IpSecManager.DIRECTION_OUT); 445 mMigratedIpSecTransformsTrackRecord.add( 446 new IpSecTransformCallRecord[] {inRecord, outRecord}); 447 } 448 449 @Override onIpSecTransformDeleted(@onNull IpSecTransform ipSecTransform, int direction)450 public void onIpSecTransformDeleted(@NonNull IpSecTransform ipSecTransform, int direction) { 451 mDeletedIpSecTransformsTrackRecord.add( 452 new IpSecTransformCallRecord(ipSecTransform, direction)); 453 } 454 awaitChildConfig()455 public ChildSessionConfiguration awaitChildConfig() throws Exception { 456 return mFutureChildConfig.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 457 } 458 awaitOnClosedException()459 public IkeException awaitOnClosedException() throws Exception { 460 return mFutureOnClosedException.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 461 } 462 awaitNextCreatedIpSecTransform()463 public IpSecTransformCallRecord awaitNextCreatedIpSecTransform() { 464 return mCreatedIpSecTransformsTrackRecord.poll( 465 (long) TIMEOUT_MS, 466 mCreatedIpSecTransformCount++, 467 (transform) -> { 468 return true; 469 }); 470 } 471 awaitNextMigratedIpSecTransform()472 public IpSecTransformCallRecord[] awaitNextMigratedIpSecTransform() { 473 return mMigratedIpSecTransformsTrackRecord.poll( 474 (long) TIMEOUT_MS, 475 mMigratedIpSecTransformCount++, 476 (transform) -> { 477 return true; 478 }); 479 } 480 481 public IpSecTransformCallRecord awaitNextDeletedIpSecTransform() { 482 return mDeletedIpSecTransformsTrackRecord.poll( 483 (long) TIMEOUT_MS, 484 mDeletedIpSecTransformCount++, 485 (transform) -> { 486 return true; 487 }); 488 } 489 490 public void awaitOnClosed() throws Exception { 491 mFutureOnClosedCall.get(TIMEOUT_MS, TimeUnit.MILLISECONDS); 492 } 493 } 494 495 /** Default testing callback for all IKE exchange tests */ 496 static class DefaultTestChildSessionCallback extends TestChildSessionCallback { 497 @Override 498 public void onClosedWithException(@NonNull IkeException exception) { 499 mFutureOnClosedException.complete(exception); 500 } 501 } 502 503 /** Testing callback to verify deprecated methods before they are removed */ 504 static class LegacyTestChildSessionCallback extends TestChildSessionCallback { 505 @Override 506 public void onClosedExceptionally(@NonNull IkeException exception) { 507 mFutureOnClosedException.complete(exception); 508 } 509 } 510 511 /** 512 * This class represents a created or deleted IpSecTransfrom that is provided by 513 * ChildSessionCallback 514 */ 515 static class IpSecTransformCallRecord { 516 public final IpSecTransform ipSecTransform; 517 public final int direction; 518 519 IpSecTransformCallRecord(IpSecTransform ipSecTransform, @PolicyDirection int direction) { 520 this.ipSecTransform = ipSecTransform; 521 this.direction = direction; 522 } 523 524 @Override 525 public int hashCode() { 526 return Objects.hash(ipSecTransform, direction); 527 } 528 529 @Override 530 public boolean equals(Object o) { 531 if (!(o instanceof IpSecTransformCallRecord)) return false; 532 533 IpSecTransformCallRecord record = (IpSecTransformCallRecord) o; 534 return ipSecTransform.equals(record.ipSecTransform) && direction == record.direction; 535 } 536 } 537 538 // TODO: b/275938211 Rename the method to reflect that it will return a value besides doing 539 // validations 540 IkeSessionConnectionInfo verifyIkeSessionSetupBlocking() throws Exception { 541 return verifyIkeSessionSetupBlocking(EXTENSION_TYPE_FRAGMENTATION); 542 } 543 544 IkeSessionConnectionInfo verifyIkeSessionSetupBlocking(int... expectedIkeExtensions) 545 throws Exception { 546 IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig(); 547 assertNotNull(ikeConfig); 548 assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion()); 549 assertTrue(ikeConfig.getRemoteVendorIds().isEmpty()); 550 assertTrue(ikeConfig.getPcscfServers().isEmpty()); 551 for (int ikeExtension : expectedIkeExtensions) { 552 assertTrue(ikeConfig.isIkeExtensionEnabled(ikeExtension)); 553 } 554 555 IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo(); 556 assertNotNull(ikeConnectInfo); 557 assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress()); 558 assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress()); 559 assertEquals(mTunNetworkContext.tunNetwork, ikeConnectInfo.getNetwork()); 560 561 return ikeConnectInfo; 562 } 563 564 ChildSessionConfiguration verifyChildSessionSetupBlocking( 565 TestChildSessionCallback childCallback, 566 List<IkeTrafficSelector> expectedInboundTs, 567 List<IkeTrafficSelector> expectedOutboundTs, 568 List<LinkAddress> expectedInternalAddresses) 569 throws Exception { 570 return verifyChildSessionSetupBlocking( 571 childCallback, 572 expectedInboundTs, 573 expectedOutboundTs, 574 expectedInternalAddresses, 575 new ArrayList<InetAddress>() /* expectedDnsServers */); 576 } 577 578 ChildSessionConfiguration verifyChildSessionSetupBlocking( 579 TestChildSessionCallback childCallback, 580 List<IkeTrafficSelector> expectedInboundTs, 581 List<IkeTrafficSelector> expectedOutboundTs, 582 List<LinkAddress> expectedInternalAddresses, 583 List<InetAddress> expectedDnsServers) 584 throws Exception { 585 ChildSessionConfiguration childConfig = childCallback.awaitChildConfig(); 586 assertNotNull(childConfig); 587 assertEquals(expectedInboundTs, childConfig.getInboundTrafficSelectors()); 588 assertEquals(expectedOutboundTs, childConfig.getOutboundTrafficSelectors()); 589 assertEquals(expectedInternalAddresses, childConfig.getInternalAddresses()); 590 assertEquals(expectedDnsServers, childConfig.getInternalDnsServers()); 591 assertTrue(childConfig.getInternalSubnets().isEmpty()); 592 assertTrue(childConfig.getInternalDhcpServers().isEmpty()); 593 return childConfig; 594 } 595 596 void verifyCloseIkeAndChildBlocking( 597 IpSecTransformCallRecord expectedTransformRecordA, 598 IpSecTransformCallRecord expectedTransformRecordB) 599 throws Exception { 600 verifyDeleteIpSecTransformPair( 601 mFirstChildSessionCallback, expectedTransformRecordA, expectedTransformRecordB); 602 mFirstChildSessionCallback.awaitOnClosed(); 603 mIkeSessionCallback.awaitOnClosed(); 604 } 605 606 static void verifyCreateIpSecTransformPair( 607 IpSecTransformCallRecord transformRecordA, IpSecTransformCallRecord transformRecordB) { 608 IpSecTransform transformA = transformRecordA.ipSecTransform; 609 IpSecTransform transformB = transformRecordB.ipSecTransform; 610 611 assertNotNull(transformA); 612 assertNotNull(transformB); 613 614 Set<Integer> expectedDirections = new HashSet<>(); 615 expectedDirections.add(IpSecManager.DIRECTION_IN); 616 expectedDirections.add(IpSecManager.DIRECTION_OUT); 617 618 Set<Integer> resultDirections = new HashSet<>(); 619 resultDirections.add(transformRecordA.direction); 620 resultDirections.add(transformRecordB.direction); 621 622 assertEquals(expectedDirections, resultDirections); 623 } 624 625 static void verifyDeleteIpSecTransformPair( 626 TestChildSessionCallback childCb, 627 IpSecTransformCallRecord expectedTransformRecordA, 628 IpSecTransformCallRecord expectedTransformRecordB) { 629 Set<IpSecTransformCallRecord> expectedTransforms = new HashSet<>(); 630 expectedTransforms.add(expectedTransformRecordA); 631 expectedTransforms.add(expectedTransformRecordB); 632 633 Set<IpSecTransformCallRecord> resultTransforms = new HashSet<>(); 634 resultTransforms.add(childCb.awaitNextDeletedIpSecTransform()); 635 resultTransforms.add(childCb.awaitNextDeletedIpSecTransform()); 636 637 assertEquals(expectedTransforms, resultTransforms); 638 } 639 640 /** Package private method to check if device has IPsec tunnels feature */ 641 static boolean hasTunnelsFeature() { 642 return sContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNELS); 643 } 644 645 /** Package private method to check if device has IPsec tunnel migration feature */ 646 static boolean hasTunnelMigrationFeature() { 647 return sContext.getPackageManager() 648 .hasSystemFeature(PackageManager.FEATURE_IPSEC_TUNNEL_MIGRATION); 649 } 650 651 // TODO(b/148689509): Verify hostname based creation 652 } 653