From ff7fe1e5fe7cbfc5e3f89062baa6a8f52155336b Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 00:49:54 +0000 Subject: [PATCH 1/3] Add CTS for building IKE and Child SaProposal Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ic50d70f35216a065ff398c38262f2de0b370c5ef Merged-In: Ic50d70f35216a065ff398c38262f2de0b370c5ef (cherry picked from commit 7f95e39c2534b370a28e4d6cf08ebb8b74950fcb) --- .../net/ipsec/ike/cts/SaProposalTest.java | 232 +++++++++++++++++- 1 file changed, 229 insertions(+), 3 deletions(-) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java index 47e8f0174d..e0d3be0540 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/SaProposalTest.java @@ -16,15 +16,241 @@ package android.net.ipsec.ike.cts; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_192; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256; +import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_384; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_512; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.IkeSaProposal; +import android.util.Pair; + import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + @RunWith(AndroidJUnit4.class) public class SaProposalTest { - @Test - public void testBuildIkeSaProposal() { - // TODO(b/148689509): Add real tests here + private static final List> NORMAL_MODE_CIPHERS = new ArrayList<>(); + private static final List> COMBINED_MODE_CIPHERS = new ArrayList<>(); + private static final List INTEGRITY_ALGOS = new ArrayList<>(); + private static final List DH_GROUPS = new ArrayList<>(); + private static final List DH_GROUPS_WITH_NONE = new ArrayList<>(); + private static final List PRFS = new ArrayList<>(); + + static { + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_128)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_192)); + NORMAL_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)); + + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_128)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_192)); + COMBINED_MODE_CIPHERS.add(new Pair<>(ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256)); + + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_AES_XCBC_96); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192); + INTEGRITY_ALGOS.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256); + + DH_GROUPS.add(DH_GROUP_1024_BIT_MODP); + DH_GROUPS.add(DH_GROUP_2048_BIT_MODP); + + DH_GROUPS_WITH_NONE.add(DH_GROUP_NONE); + DH_GROUPS_WITH_NONE.addAll(DH_GROUPS); + + PRFS.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1); + PRFS.add(PSEUDORANDOM_FUNCTION_AES128_XCBC); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_256); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_384); + PRFS.add(PSEUDORANDOM_FUNCTION_SHA2_512); } + + // Package private + static IkeSaProposal buildIkeSaProposalWithNormalModeCipher() { + return buildIkeSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, PRFS, DH_GROUPS); + } + + // Package private + static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher() { + return buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static IkeSaProposal buildIkeSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + return buildIkeSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, PRFS, DH_GROUPS); + } + + private static IkeSaProposal buildIkeSaProposal( + List> ciphers, + List integrityAlgos, + List prfs, + List dhGroups) { + IkeSaProposal.Builder builder = new IkeSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : prfs) { + builder.addPseudorandomFunction(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithNormalModeCipher() { + return buildChildSaProposal(NORMAL_MODE_CIPHERS, INTEGRITY_ALGOS, DH_GROUPS_WITH_NONE); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithCombinedModeCipher() { + return buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + } + + private static ChildSaProposal buildChildSaProposalWithCombinedModeCipher( + boolean hasIntegrityNone) { + List integerAlgos = new ArrayList<>(); + if (hasIntegrityNone) { + integerAlgos.add(INTEGRITY_ALGORITHM_NONE); + } + + return buildChildSaProposal(COMBINED_MODE_CIPHERS, integerAlgos, DH_GROUPS_WITH_NONE); + } + + private static ChildSaProposal buildChildSaProposal( + List> ciphers, + List integrityAlgos, + List dhGroups) { + ChildSaProposal.Builder builder = new ChildSaProposal.Builder(); + + for (Pair pair : ciphers) { + builder.addEncryptionAlgorithm(pair.first, pair.second); + } + for (int algo : integrityAlgos) { + builder.addIntegrityAlgorithm(algo); + } + for (int algo : dhGroups) { + builder.addDhGroup(algo); + } + + return builder.build(); + } + + // Package private + static ChildSaProposal buildChildSaProposalWithOnlyCiphers() { + return buildChildSaProposal( + COMBINED_MODE_CIPHERS, Collections.EMPTY_LIST, Collections.EMPTY_LIST); + } + + @Test + public void testBuildIkeSaProposalWithNormalModeCipher() { + IkeSaProposal saProposal = buildIkeSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipher() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + } + + @Test + public void testBuildIkeSaProposalWithCombinedModeCipherAndIntegrityNone() { + IkeSaProposal saProposal = + buildIkeSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(PRFS, saProposal.getPseudorandomFunctions()); + assertEquals(DH_GROUPS, saProposal.getDhGroups()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + } + + @Test + public void testBuildChildSaProposalWithNormalModeCipher() { + ChildSaProposal saProposal = buildChildSaProposalWithNormalModeCipher(); + + assertEquals(NORMAL_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(INTEGRITY_ALGOS, saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipher() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(false /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildProposalWithCombinedModeCipherAndIntegrityNone() { + ChildSaProposal saProposal = + buildChildSaProposalWithCombinedModeCipher(true /* hasIntegrityNone */); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertEquals(Arrays.asList(INTEGRITY_ALGORITHM_NONE), saProposal.getIntegrityAlgorithms()); + assertEquals(DH_GROUPS_WITH_NONE, saProposal.getDhGroups()); + } + + @Test + public void testBuildChildSaProposalWithOnlyCiphers() { + ChildSaProposal saProposal = buildChildSaProposalWithOnlyCiphers(); + + assertEquals(COMBINED_MODE_CIPHERS, saProposal.getEncryptionAlgorithms()); + assertTrue(saProposal.getIntegrityAlgorithms().isEmpty()); + assertTrue(saProposal.getDhGroups().isEmpty()); + } + + // TODO(b/148689509): Test throwing exception when algorithm combination is invalid } From 2b98dce4e9dcb18d18a1567822afc3edcf3c26de Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 00:50:24 +0000 Subject: [PATCH 2/3] Test setting proposal, TS and lifetime for ChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: If19fb12c92f65d487478fda172acb21f6cfb1717 Merged-In: If19fb12c92f65d487478fda172acb21f6cfb1717 (cherry picked from commit ee06cc4c06e54c7cf9cb46acd38066106bdc1cba) --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 140 ++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 83 +++++++++++ 2 files changed, 223 insertions(+) create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java create mode 100644 tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java new file mode 100644 index 0000000000..316355252a --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.ipsec.ike.cts; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import android.net.ipsec.ike.ChildSaProposal; +import android.net.ipsec.ike.ChildSessionParams; +import android.net.ipsec.ike.TransportModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.Arrays; +import java.util.concurrent.TimeUnit; + +@RunWith(AndroidJUnit4.class) +public class ChildSessionParamsTest extends IkeTestBase { + private static final int HARD_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(3L); + private static final int SOFT_LIFETIME_SECONDS = (int) TimeUnit.HOURS.toSeconds(1L); + + // Random proposal. Content doesn't matter + private final ChildSaProposal mSaProposal = + SaProposalTest.buildChildSaProposalWithCombinedModeCipher(); + + private void verifyTunnelModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTunnelModeChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TunnelModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyTransportModeChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithDefaultValues(childParams); + } + + private void verifyTransportModeChildParamsWithCustomizedValues( + ChildSessionParams childParams) { + assertTrue(childParams instanceof TransportModeChildSessionParams); + verifyChildParamsWithCustomizedValues(childParams); + } + + private void verifyChildParamsWithDefaultValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + // Do not do assertEquals to the default values to be avoid being a change-detector test + assertTrue(childParams.getHardLifetimeSeconds() > childParams.getSoftLifetimeSeconds()); + assertTrue(childParams.getSoftLifetimeSeconds() > 0); + + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(DEFAULT_V4_TS, DEFAULT_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + private void verifyChildParamsWithCustomizedValues(ChildSessionParams childParams) { + assertEquals(Arrays.asList(mSaProposal), childParams.getSaProposals()); + + assertEquals(HARD_LIFETIME_SECONDS, childParams.getHardLifetimeSeconds()); + assertEquals(SOFT_LIFETIME_SECONDS, childParams.getSoftLifetimeSeconds()); + + assertEquals( + Arrays.asList(INBOUND_V4_TS, INBOUND_V6_TS), + childParams.getInboundTrafficSelectors()); + assertEquals( + Arrays.asList(OUTBOUND_V4_TS, OUTBOUND_V6_TS), + childParams.getOutboundTrafficSelectors()); + } + + @Test + public void testBuildTransportModeParamsWithDefaultValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTransportModeChildParamsWithDefaultValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithDefaultValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder().addSaProposal(mSaProposal).build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + assertTrue(childParams.getConfigurationRequests().isEmpty()); + } + + @Test + public void testBuildTransportModeParamsWithCustomizedValues() { + TransportModeChildSessionParams childParams = + new TransportModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTransportModeChildParamsWithCustomizedValues(childParams); + } + + @Test + public void testBuildTunnelModeParamsWithCustomizedValues() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .setLifetimeSeconds(HARD_LIFETIME_SECONDS, SOFT_LIFETIME_SECONDS) + .addInboundTrafficSelectors(INBOUND_V4_TS) + .addInboundTrafficSelectors(INBOUND_V6_TS) + .addOutboundTrafficSelectors(OUTBOUND_V4_TS) + .addOutboundTrafficSelectors(OUTBOUND_V6_TS) + .build(); + + verifyTunnelModeChildParamsWithCustomizedValues(childParams); + } +} diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java new file mode 100644 index 0000000000..d4b431e837 --- /dev/null +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.ipsec.ike.cts; + +import android.net.InetAddresses; +import android.net.ipsec.ike.IkeTrafficSelector; + +import java.net.Inet4Address; +import java.net.Inet6Address; + +/** Shared parameters and util methods for testing different components of IKE */ +abstract class IkeTestBase { + private static final int MIN_PORT = 0; + private static final int MAX_PORT = 65535; + private static final int INBOUND_TS_START_PORT = MIN_PORT; + private static final int INBOUND_TS_END_PORT = 65520; + private static final int OUTBOUND_TS_START_PORT = 16; + private static final int OUTBOUND_TS_END_PORT = MAX_PORT; + + static final int IP4_PREFIX_LEN = 32; + static final int IP6_PREFIX_LEN = 64; + + static final Inet4Address IPV4_ADDRESS_LOCAL = + (Inet4Address) (InetAddresses.parseNumericAddress("192.0.2.100")); + static final Inet4Address IPV4_ADDRESS_REMOTE = + (Inet4Address) (InetAddresses.parseNumericAddress("198.51.100.100")); + static final Inet6Address IPV6_ADDRESS_LOCAL = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8::100")); + static final Inet6Address IPV6_ADDRESS_REMOTE = + (Inet6Address) (InetAddresses.parseNumericAddress("2001:db8:255::100")); + + static final IkeTrafficSelector DEFAULT_V4_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("0.0.0.0"), + InetAddresses.parseNumericAddress("255.255.255.255")); + static final IkeTrafficSelector DEFAULT_V6_TS = + new IkeTrafficSelector( + MIN_PORT, + MAX_PORT, + InetAddresses.parseNumericAddress("::"), + InetAddresses.parseNumericAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")); + static final IkeTrafficSelector INBOUND_V4_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("192.0.2.10"), + InetAddresses.parseNumericAddress("192.0.2.20")); + static final IkeTrafficSelector OUTBOUND_V4_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("198.51.100.0"), + InetAddresses.parseNumericAddress("198.51.100.255")); + + static final IkeTrafficSelector INBOUND_V6_TS = + new IkeTrafficSelector( + INBOUND_TS_START_PORT, + INBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8::10"), + InetAddresses.parseNumericAddress("2001:db8::128")); + static final IkeTrafficSelector OUTBOUND_V6_TS = + new IkeTrafficSelector( + OUTBOUND_TS_START_PORT, + OUTBOUND_TS_END_PORT, + InetAddresses.parseNumericAddress("2001:db8:255::64"), + InetAddresses.parseNumericAddress("2001:db8:255::255")); +} From 5e89d115fbb0ac48c55484ace010cd7ceb0c6414 Mon Sep 17 00:00:00 2001 From: Yan Yan Date: Wed, 15 Apr 2020 17:29:01 +0000 Subject: [PATCH 3/3] Test setting config requests for TunnelModeChildSessionParams Bug: 148689509 Test: atest CtsIkeTestCases Change-Id: Ib3e803159cdf42a8655c0e4d0f22faeabe161c4c Merged-In: Ib3e803159cdf42a8655c0e4d0f22faeabe161c4c (cherry picked from commit 7ec4cf34cc443984889c5728a2b538ea91ec5036) --- .../ipsec/ike/cts/ChildSessionParamsTest.java | 90 +++++++++++++++++++ .../net/ipsec/ike/cts/IkeTestBase.java | 37 ++++++++ 2 files changed, 127 insertions(+) diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java index 316355252a..7fb1b6dc43 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/ChildSessionParamsTest.java @@ -16,20 +16,36 @@ package android.net.ipsec.ike.cts; +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.assertTrue; +import android.net.LinkAddress; import android.net.ipsec.ike.ChildSaProposal; import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.TransportModeChildSessionParams; import android.net.ipsec.ike.TunnelModeChildSessionParams; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DhcpServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv4Netmask; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6Address; +import android.net.ipsec.ike.TunnelModeChildSessionParams.ConfigRequestIpv6DnsServer; +import android.net.ipsec.ike.TunnelModeChildSessionParams.TunnelModeChildConfigRequest; import androidx.test.ext.junit.runners.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import java.net.Inet4Address; import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) @@ -137,4 +153,78 @@ public class ChildSessionParamsTest extends IkeTestBase { verifyTunnelModeChildParamsWithCustomizedValues(childParams); } + + @Test + public void testBuildChildSessionParamsWithConfigReq() { + TunnelModeChildSessionParams childParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(mSaProposal) + .addInternalAddressRequest(AF_INET) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(AF_INET6) + .addInternalAddressRequest(IPV4_ADDRESS_REMOTE) + .addInternalAddressRequest(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN) + .addInternalDnsServerRequest(AF_INET) + .addInternalDnsServerRequest(AF_INET6) + .addInternalDhcpServerRequest(AF_INET) + .addInternalDhcpServerRequest(AF_INET) + .build(); + + verifyTunnelModeChildParamsWithDefaultValues(childParams); + + // Verify config request types and number of requests for each type + Map, Integer> expectedAttributeCounts = + new HashMap<>(); + expectedAttributeCounts.put(ConfigRequestIpv4Address.class, 2); + expectedAttributeCounts.put(ConfigRequestIpv6Address.class, 3); + expectedAttributeCounts.put(ConfigRequestIpv4Netmask.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv6DnsServer.class, 1); + expectedAttributeCounts.put(ConfigRequestIpv4DhcpServer.class, 2); + verifyConfigRequestTypes(expectedAttributeCounts, childParams.getConfigurationRequests()); + + // Verify specific IPv4 address request + Set expectedV4Addresses = new HashSet<>(); + expectedV4Addresses.add(IPV4_ADDRESS_REMOTE); + verifySpecificV4AddrConfigReq(expectedV4Addresses, childParams); + + // Verify specific IPv6 address request + Set expectedV6Addresses = new HashSet<>(); + expectedV6Addresses.add(new LinkAddress(IPV6_ADDRESS_REMOTE, IP6_PREFIX_LEN)); + verifySpecificV6AddrConfigReq(expectedV6Addresses, childParams); + } + + protected void verifySpecificV4AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv4Address + && ((ConfigRequestIpv4Address) req).getAddress() != null) { + Inet4Address address = ((ConfigRequestIpv4Address) req).getAddress(); + + // Fail if expectedAddresses does not contain this address + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } + + protected void verifySpecificV6AddrConfigReq( + Set expectedAddresses, TunnelModeChildSessionParams childParams) { + for (TunnelModeChildConfigRequest req : childParams.getConfigurationRequests()) { + if (req instanceof ConfigRequestIpv6Address + && ((ConfigRequestIpv6Address) req).getAddress() != null) { + ConfigRequestIpv6Address ipv6AddrReq = (ConfigRequestIpv6Address) req; + + // Fail if expectedAddresses does not contain this address + LinkAddress address = + new LinkAddress(ipv6AddrReq.getAddress(), ipv6AddrReq.getPrefixLength()); + assertTrue(expectedAddresses.remove(address)); + } + } + + // Fail if any expected address is not found in result + assertTrue(expectedAddresses.isEmpty()); + } } diff --git a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java index d4b431e837..d3aa8d03d5 100644 --- a/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java +++ b/tests/cts/net/ipsec/src/android/net/ipsec/ike/cts/IkeTestBase.java @@ -16,11 +16,17 @@ package android.net.ipsec.ike.cts; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + import android.net.InetAddresses; import android.net.ipsec.ike.IkeTrafficSelector; import java.net.Inet4Address; import java.net.Inet6Address; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** Shared parameters and util methods for testing different components of IKE */ abstract class IkeTestBase { @@ -80,4 +86,35 @@ abstract class IkeTestBase { OUTBOUND_TS_END_PORT, InetAddresses.parseNumericAddress("2001:db8:255::64"), InetAddresses.parseNumericAddress("2001:db8:255::255")); + + // Verify Config requests in TunnelModeChildSessionParams and IkeSessionParams + void verifyConfigRequestTypes( + Map, Integer> expectedReqCntMap, List resultReqList) { + Map, Integer> resultReqCntMap = new HashMap<>(); + + // Verify that every config request type in resultReqList is expected, and build + // resultReqCntMap at the same time + for (T resultReq : resultReqList) { + boolean isResultReqExpected = false; + + for (Class expectedReqInterface : expectedReqCntMap.keySet()) { + if (expectedReqInterface.isInstance(resultReq)) { + isResultReqExpected = true; + + resultReqCntMap.put( + expectedReqInterface, + resultReqCntMap.getOrDefault(expectedReqInterface, 0) + 1); + } + } + + if (!isResultReqExpected) { + fail("Failed due to unexpected config request " + resultReq); + } + } + + assertEquals(expectedReqCntMap, resultReqCntMap); + + // TODO: Think of a neat way to validate both counts and values in this method. Probably can + // build Runnables as validators for count and values. + } }