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