Move common logic in testing and verification to IkeSessionTestBase
This commit moves following logics to IkeSessionTestBase so that all
subclasses can share it:
- build ChildParams
- perform IKE and first Child setup
- perform deleting IKE
- verifying IKE and first Child setup
Bug: 155821007
Test: atest CtsIkeTestCases:IkeSessionDigitalSignatureTest
Change-Id: Ib35b18240396a7b4823111e37be9a338d8ff6f06
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
index ca7ee1f..661457f 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
@@ -16,25 +16,17 @@
package android.net.ipsec.ike.cts;
-import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static com.android.internal.util.HexDump.hexStringToByteArray;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
-import android.net.ipsec.ike.ChildSessionConfiguration;
+import android.net.LinkAddress;
import android.net.ipsec.ike.IkeFqdnIdentification;
import android.net.ipsec.ike.IkeSession;
-import android.net.ipsec.ike.IkeSessionConfiguration;
-import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.IkeSessionParams;
-import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
import android.platform.test.annotations.AppModeFull;
@@ -45,10 +37,11 @@
import org.junit.runner.RunWith;
import java.net.InetAddress;
+import java.util.ArrayList;
import java.util.Arrays;
@RunWith(AndroidJUnit4.class)
-@AppModeFull(reason = "MANAGE_TEST_NETWORKS permission can't be granted to instant apps")
+@AppModeFull(reason = "MANAGE_IPSEC_TUNNELS permission can't be granted to instant apps")
public class IkeSessionPskTest extends IkeSessionTestBase {
// Test vectors for success workflow
private static final String SUCCESS_IKE_INIT_RESP =
@@ -89,16 +82,6 @@
+ "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
+ "6743A7CEB2BE34AC00095A5B8";
- private static final long IKE_INIT_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
-
- private static final TunnelModeChildSessionParams CHILD_PARAMS =
- new TunnelModeChildSessionParams.Builder()
- .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
- .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
- .addInternalAddressRequest(AF_INET)
- .addInternalAddressRequest(AF_INET6)
- .build();
-
private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
IkeSessionParams ikeParams =
new IkeSessionParams.Builder(sContext)
@@ -113,7 +96,7 @@
return new IkeSession(
sContext,
ikeParams,
- CHILD_PARAMS,
+ buildTunnelModeChildSessionParams(),
mUserCbExecutor,
mIkeSessionCallback,
mFirstChildSessionCallback);
@@ -125,45 +108,17 @@
// Open IKE Session
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
- int expectedMsgId = 0;
- mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
- expectedMsgId++,
- false /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
+ performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
- mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
- expectedMsgId++,
- true /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
+ // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
+ int expectedMsgId = 2;
- // Verify opening IKE Session
- IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig();
- assertNotNull(ikeConfig);
- assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion());
- assertTrue(ikeConfig.getRemoteVendorIds().isEmpty());
- assertTrue(ikeConfig.getPcscfServers().isEmpty());
- assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION));
-
- IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo();
- assertNotNull(ikeConnectInfo);
- assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress());
- assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress());
- assertEquals(mTunNetwork, ikeConnectInfo.getNetwork());
-
- // Verify opening first Child Session
- ChildSessionConfiguration firstChildConfig = mFirstChildSessionCallback.awaitChildConfig();
- assertNotNull(firstChildConfig);
- assertEquals(
- Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors());
- assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors());
- assertEquals(
- Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR),
- firstChildConfig.getInternalAddresses());
- assertTrue(firstChildConfig.getInternalSubnets().isEmpty());
- assertTrue(firstChildConfig.getInternalDnsServers().isEmpty());
- assertTrue(firstChildConfig.getInternalDhcpServers().isEmpty());
+ verifyIkeSessionSetupBlocking();
+ verifyChildSessionSetupBlocking(
+ mFirstChildSessionCallback,
+ Arrays.asList(TUNNEL_MODE_INBOUND_TS),
+ Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
+ Arrays.asList(EXPECTED_INTERNAL_LINK_ADDR));
IpSecTransformCallRecord firstTransformRecordA =
mFirstChildSessionCallback.awaitNextCreatedIpSecTransform();
@@ -173,24 +128,19 @@
// Open additional Child Session
TestChildSessionCallback additionalChildCb = new TestChildSessionCallback();
- ikeSession.openChildSession(CHILD_PARAMS, additionalChildCb);
+ ikeSession.openChildSession(buildTunnelModeChildSessionParams(), additionalChildCb);
mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
+ IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++,
true /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_CREATE_CHILD_RESP));
+ SUCCESS_CREATE_CHILD_RESP);
// Verify opening additional Child Session
- ChildSessionConfiguration additionalChildConfig = additionalChildCb.awaitChildConfig();
- assertNotNull(additionalChildConfig);
- assertEquals(
- Arrays.asList(EXPECTED_INBOUND_TS), firstChildConfig.getInboundTrafficSelectors());
- assertEquals(Arrays.asList(DEFAULT_V4_TS), firstChildConfig.getOutboundTrafficSelectors());
- assertTrue(additionalChildConfig.getInternalAddresses().isEmpty());
- assertTrue(additionalChildConfig.getInternalSubnets().isEmpty());
- assertTrue(additionalChildConfig.getInternalDnsServers().isEmpty());
- assertTrue(additionalChildConfig.getInternalDhcpServers().isEmpty());
-
+ verifyChildSessionSetupBlocking(
+ additionalChildCb,
+ Arrays.asList(TUNNEL_MODE_INBOUND_TS),
+ Arrays.asList(TUNNEL_MODE_OUTBOUND_TS),
+ new ArrayList<LinkAddress>());
IpSecTransformCallRecord additionalTransformRecordA =
additionalChildCb.awaitNextCreatedIpSecTransform();
IpSecTransformCallRecord additionalTransformRecordB =
@@ -200,10 +150,10 @@
// Close additional Child Session
ikeSession.closeChildSession(additionalChildCb);
mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
+ IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++,
true /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_DELETE_CHILD_RESP));
+ SUCCESS_DELETE_CHILD_RESP);
verifyDeleteIpSecTransformPair(
additionalChildCb, additionalTransformRecordA, additionalTransformRecordB);
@@ -211,16 +161,8 @@
// Close IKE Session
ikeSession.close();
- mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
- expectedMsgId++,
- true /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_DELETE_IKE_RESP));
-
- verifyDeleteIpSecTransformPair(
- mFirstChildSessionCallback, firstTransformRecordA, firstTransformRecordB);
- mFirstChildSessionCallback.awaitOnClosed();
- mIkeSessionCallback.awaitOnClosed();
+ performCloseIkeBlocking(expectedMsgId++, SUCCESS_DELETE_IKE_RESP);
+ verifyCloseIkeAndChildBlocking(firstTransformRecordA, firstTransformRecordB);
}
@Test
@@ -229,18 +171,7 @@
// Open IKE Session
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
- int expectedMsgId = 0;
- mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
- expectedMsgId++,
- false /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_IKE_INIT_RESP));
-
- mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
- expectedMsgId++,
- true /* expectedUseEncap */,
- hexStringToByteArray(SUCCESS_IKE_AUTH_RESP));
+ performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
ikeSession.kill();
mFirstChildSessionCallback.awaitOnClosed();
@@ -256,10 +187,10 @@
IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
int expectedMsgId = 0;
mTunUtils.awaitReqAndInjectResp(
- IKE_INIT_SPI,
+ IKE_DETERMINISTIC_INITIATOR_SPI,
expectedMsgId++,
false /* expectedUseEncap */,
- hexStringToByteArray(ikeInitFailRespHex));
+ ikeInitFailRespHex);
mFirstChildSessionCallback.awaitOnClosed();
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
index e49f75f..ade9813 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
@@ -16,9 +16,13 @@
package android.net.ipsec.ike.cts;
import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
+import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION;
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import android.annotation.NonNull;
import android.app.AppOpsManager;
@@ -37,7 +41,9 @@
import android.net.ipsec.ike.ChildSessionConfiguration;
import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.IkeTrafficSelector;
+import android.net.ipsec.ike.TunnelModeChildSessionParams;
import android.net.ipsec.ike.cts.TestNetworkUtils.TestNetworkCallback;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
@@ -60,6 +66,7 @@
import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.HashSet;
+import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -90,9 +97,13 @@
InetAddresses.parseNumericAddress("198.51.100.10");
static final LinkAddress EXPECTED_INTERNAL_LINK_ADDR =
new LinkAddress(EXPECTED_INTERNAL_ADDR, IP4_PREFIX_LEN);
- static final IkeTrafficSelector EXPECTED_INBOUND_TS =
+
+ static final IkeTrafficSelector TUNNEL_MODE_INBOUND_TS =
new IkeTrafficSelector(
MIN_PORT, MAX_PORT, EXPECTED_INTERNAL_ADDR, EXPECTED_INTERNAL_ADDR);
+ static final IkeTrafficSelector TUNNEL_MODE_OUTBOUND_TS = DEFAULT_V4_TS;
+
+ static final long IKE_DETERMINISTIC_INITIATOR_SPI = Long.parseLong("46B8ECA1E0D72A18", 16);
// Static state to reduce setup/teardown
static Context sContext = InstrumentationRegistry.getContext();
@@ -238,6 +249,45 @@
}
}
+ TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
+ return new TunnelModeChildSessionParams.Builder()
+ .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
+ .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
+ .addInternalAddressRequest(AF_INET)
+ .addInternalAddressRequest(AF_INET6)
+ .build();
+ }
+
+ void performSetupIkeAndFirstChildBlocking(String ikeInitRespHex, String ikeAuthRespHex)
+ throws Exception {
+ mTunUtils.awaitReqAndInjectResp(
+ IKE_DETERMINISTIC_INITIATOR_SPI,
+ 0 /* expectedMsgId */,
+ false /* expectedUseEncap */,
+ ikeInitRespHex);
+
+ mTunUtils.awaitReqAndInjectResp(
+ IKE_DETERMINISTIC_INITIATOR_SPI,
+ 1 /* expectedMsgId */,
+ true /* expectedUseEncap */,
+ ikeAuthRespHex);
+ }
+
+ void performSetupIkeAndFirstChildBlocking(
+ String ikeInitRespHex, int expectedAuthReqPktCnt, String... ikeAuthRespPktHex)
+ throws Exception {
+ // TODO: Implemented in followup CL (aosp/1308675) to support awaiting multiple IKE AUTH
+ // request fragments and injecting multiple IKE AUTH response fragments
+ }
+
+ void performCloseIkeBlocking(int expectedMsgId, String deleteIkeRespHex) throws Exception {
+ mTunUtils.awaitReqAndInjectResp(
+ IKE_DETERMINISTIC_INITIATOR_SPI,
+ expectedMsgId,
+ true /* expectedUseEncap */,
+ deleteIkeRespHex);
+ }
+
/** Testing callback that allows caller to block current thread until a method get called */
static class TestIkeSessionCallback implements IkeSessionCallback {
private CompletableFuture<IkeSessionConfiguration> mFutureIkeConfig =
@@ -392,6 +442,47 @@
}
}
+ void verifyIkeSessionSetupBlocking() throws Exception {
+ IkeSessionConfiguration ikeConfig = mIkeSessionCallback.awaitIkeConfig();
+ assertNotNull(ikeConfig);
+ assertEquals(EXPECTED_REMOTE_APP_VERSION_EMPTY, ikeConfig.getRemoteApplicationVersion());
+ assertTrue(ikeConfig.getRemoteVendorIds().isEmpty());
+ assertTrue(ikeConfig.getPcscfServers().isEmpty());
+ assertTrue(ikeConfig.isIkeExtensionEnabled(EXTENSION_TYPE_FRAGMENTATION));
+
+ IkeSessionConnectionInfo ikeConnectInfo = ikeConfig.getIkeSessionConnectionInfo();
+ assertNotNull(ikeConnectInfo);
+ assertEquals(mLocalAddress, ikeConnectInfo.getLocalAddress());
+ assertEquals(mRemoteAddress, ikeConnectInfo.getRemoteAddress());
+ assertEquals(mTunNetwork, ikeConnectInfo.getNetwork());
+ }
+
+ void verifyChildSessionSetupBlocking(
+ TestChildSessionCallback childCallback,
+ List<IkeTrafficSelector> expectedInboundTs,
+ List<IkeTrafficSelector> expectedOutboundTs,
+ List<LinkAddress> expectedInternalAddresses)
+ throws Exception {
+ ChildSessionConfiguration childConfig = childCallback.awaitChildConfig();
+ assertNotNull(childConfig);
+ assertEquals(expectedInboundTs, childConfig.getInboundTrafficSelectors());
+ assertEquals(expectedOutboundTs, childConfig.getOutboundTrafficSelectors());
+ assertEquals(expectedInternalAddresses, childConfig.getInternalAddresses());
+ assertTrue(childConfig.getInternalSubnets().isEmpty());
+ assertTrue(childConfig.getInternalDnsServers().isEmpty());
+ assertTrue(childConfig.getInternalDhcpServers().isEmpty());
+ }
+
+ void verifyCloseIkeAndChildBlocking(
+ IpSecTransformCallRecord expectedTransformRecordA,
+ IpSecTransformCallRecord expectedTransformRecordB)
+ throws Exception {
+ verifyDeleteIpSecTransformPair(
+ mFirstChildSessionCallback, expectedTransformRecordA, expectedTransformRecordB);
+ mFirstChildSessionCallback.awaitOnClosed();
+ mIkeSessionCallback.awaitOnClosed();
+ }
+
static void verifyCreateIpSecTransformPair(
IpSecTransformCallRecord transformRecordA, IpSecTransformCallRecord transformRecordB) {
IpSecTransform transformA = transformRecordA.ipSecTransform;
diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
index f52b88b..2bff63a 100644
--- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
+++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTunUtils.java
@@ -26,6 +26,8 @@
import static android.net.ipsec.ike.cts.PacketUtils.UdpHeader;
import static android.system.OsConstants.IPPROTO_UDP;
+import static com.android.internal.util.HexDump.hexStringToByteArray;
+
import static org.junit.Assert.fail;
import android.os.ParcelFileDescriptor;
@@ -35,6 +37,7 @@
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.util.Arrays;
+import java.util.function.Predicate;
public class IkeTunUtils extends TunUtils {
private static final int PORT_LEN = 2;
@@ -54,17 +57,24 @@
/**
* Await the expected IKE request and inject an IKE response.
*
- * @param respIkePkt IKE response packet without IP/UDP headers or NON ESP MARKER.
+ * @param ikeRespDataHex IKE response hex without IP/UDP headers or NON ESP MARKER.
*/
public byte[] awaitReqAndInjectResp(
- long expectedInitIkeSpi, int expectedMsgId, boolean expectedUseEncap, byte[] respIkePkt)
+ long expectedInitIkeSpi,
+ int expectedMsgId,
+ boolean expectedUseEncap,
+ String ikeRespDataHex)
throws Exception {
byte[] request =
awaitIkePacket(
- expectedInitIkeSpi,
- expectedMsgId,
- false /* expectedResp */,
- expectedUseEncap);
+ (pkt) -> {
+ return isExpectedIkePkt(
+ pkt,
+ expectedInitIkeSpi,
+ expectedMsgId,
+ false /* expectedResp */,
+ expectedUseEncap);
+ });
// Build response header by flipping address and port
InetAddress srcAddr = getAddress(request, false /* shouldGetSource */);
@@ -73,32 +83,26 @@
int dstPort = getPort(request, true /* shouldGetSource */);
byte[] response =
- buildIkePacket(srcAddr, dstAddr, srcPort, dstPort, expectedUseEncap, respIkePkt);
+ buildIkePacket(
+ srcAddr,
+ dstAddr,
+ srcPort,
+ dstPort,
+ expectedUseEncap,
+ hexStringToByteArray(ikeRespDataHex));
injectPacket(response);
return request;
}
- private byte[] awaitIkePacket(
- long expectedInitIkeSpi,
- int expectedMsgId,
- boolean expectedResp,
- boolean expectedUseEncap)
- throws Exception {
+ // TODO: Implemented in followup CL (aosp/1308675) to support awaiting multiple
+ // request fragments and injecting multiple response fragments
+
+ private byte[] awaitIkePacket(Predicate<byte[]> pktVerifier) throws Exception {
long endTime = System.currentTimeMillis() + TIMEOUT;
int startIndex = 0;
synchronized (mPackets) {
while (System.currentTimeMillis() < endTime) {
- byte[] ikePkt =
- getFirstMatchingPacket(
- (pkt) -> {
- return isIke(
- pkt,
- expectedInitIkeSpi,
- expectedMsgId,
- expectedResp,
- expectedUseEncap);
- },
- startIndex);
+ byte[] ikePkt = getFirstMatchingPacket(pktVerifier, startIndex);
if (ikePkt != null) {
return ikePkt; // We've found the packet we're looking for.
}
@@ -112,21 +116,14 @@
}
}
- String direction = expectedResp ? "response" : "request";
- fail(
- "No such IKE "
- + direction
- + " found with Initiator SPI "
- + expectedInitIkeSpi
- + " and message ID "
- + expectedMsgId);
+ fail("No matching packet found");
}
throw new IllegalStateException(
"Hit an impossible case where fail() didn't throw an exception");
}
- private static boolean isIke(
+ private static boolean isExpectedIkePkt(
byte[] pkt,
long expectedInitIkeSpi,
int expectedMsgId,
@@ -153,7 +150,7 @@
}
return pkt[ipProtocolOffset] == IPPROTO_UDP
- && areSpiAndMsgIdEqual(
+ && isExpectedSpiAndMsgId(
pkt, ikeOffset, expectedInitIkeSpi, expectedMsgId, expectedResp);
}
@@ -170,10 +167,10 @@
return Arrays.equals(NON_ESP_MARKER, nonEspMarker);
}
- private static boolean areSpiAndMsgIdEqual(
+ private static boolean isExpectedSpiAndMsgId(
byte[] pkt,
int ikeOffset,
- long expectedIkeInitSpi,
+ long expectedInitIkeSpi,
int expectedMsgId,
boolean expectedResp) {
if (pkt.length <= ikeOffset + IKE_HEADER_LEN) return false;