aboutsummaryrefslogtreecommitdiff
path: root/tests/iketests/src/java/android
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-11-11 21:19:18 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-11-11 21:19:18 +0000
commitdb74d7937f3a9503f0e2590ec24c3bcfbf259ce0 (patch)
treeb39c3e794945072d38b97c963c5a6f10753514e1 /tests/iketests/src/java/android
parent7ffef5cae6d3c93c93b4055fd22517d44f77acda (diff)
parenteb4c77d7228f956f928c7d3500a220339ee78388 (diff)
downloadike-db74d7937f3a9503f0e2590ec24c3bcfbf259ce0.tar.gz
Snap for 6001391 from eb4c77d7228f956f928c7d3500a220339ee78388 to qt-aml-tzdata-release
Change-Id: Ic6fc3b152696e0096d00036f460262a8b0319394
Diffstat (limited to 'tests/iketests/src/java/android')
-rw-r--r--tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java115
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java164
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java54
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java258
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java162
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java312
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java321
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java229
-rw-r--r--tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java58
9 files changed, 1673 insertions, 0 deletions
diff --git a/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java b/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
new file mode 100644
index 00000000..eed32e3e
--- /dev/null
+++ b/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 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.eap;
+
+import static android.net.eap.EapSessionConfig.DEFAULT_IDENTITY;
+import static android.telephony.TelephonyManager.APPTYPE_USIM;
+
+import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
+import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
+import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
+import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.net.eap.EapSessionConfig.EapAkaConfig;
+import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
+import android.net.eap.EapSessionConfig.EapMethodConfig;
+import android.net.eap.EapSessionConfig.EapMsChapV2Config;
+import android.net.eap.EapSessionConfig.EapSimConfig;
+
+import org.junit.Test;
+
+import java.nio.charset.StandardCharsets;
+
+public class EapSessionConfigTest {
+ private static final byte[] EAP_IDENTITY =
+ "test@android.net".getBytes(StandardCharsets.US_ASCII);
+ private static final int SUB_ID = 1;
+ private static final String NETWORK_NAME = "android.net";
+ private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = true;
+ private static final String USERNAME = "username";
+ private static final String PASSWORD = "password";
+
+ @Test
+ public void testBuildEapSim() {
+ EapSessionConfig result = new EapSessionConfig.Builder()
+ .setEapIdentity(EAP_IDENTITY)
+ .setEapSimConfig(SUB_ID, APPTYPE_USIM)
+ .build();
+
+ assertArrayEquals(EAP_IDENTITY, result.eapIdentity);
+
+ EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_SIM);
+ assertEquals(EAP_TYPE_SIM, eapMethodConfig.methodType);
+ EapSimConfig eapSimConfig = (EapSimConfig) eapMethodConfig;
+ assertEquals(SUB_ID, eapSimConfig.subId);
+ assertEquals(APPTYPE_USIM, eapSimConfig.apptype);
+ }
+
+ @Test
+ public void testBuildEapAka() {
+ EapSessionConfig result = new EapSessionConfig.Builder()
+ .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
+ .build();
+
+ assertArrayEquals(DEFAULT_IDENTITY, result.eapIdentity);
+ EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_AKA);
+ EapAkaConfig eapAkaConfig = (EapAkaConfig) eapMethodConfig;
+ assertEquals(SUB_ID, eapAkaConfig.subId);
+ assertEquals(APPTYPE_USIM, eapAkaConfig.apptype);
+ }
+
+ @Test
+ public void testBuildEapAkaPrime() {
+ EapSessionConfig result =
+ new EapSessionConfig.Builder()
+ .setEapAkaPrimeConfig(
+ SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
+ .build();
+
+ assertEquals(DEFAULT_IDENTITY, result.eapIdentity);
+ EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_AKA_PRIME);
+ EapAkaPrimeConfig eapAkaPrimeConfig = (EapAkaPrimeConfig) eapMethodConfig;
+ assertEquals(SUB_ID, eapAkaPrimeConfig.subId);
+ assertEquals(APPTYPE_USIM, eapAkaPrimeConfig.apptype);
+ assertEquals(NETWORK_NAME, eapAkaPrimeConfig.networkName);
+ assertTrue(eapAkaPrimeConfig.allowMismatchedNetworkNames);
+ }
+
+ @Test
+ public void testBuildEapMsChapV2() {
+ EapSessionConfig result =
+ new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
+
+ EapMsChapV2Config config = (EapMsChapV2Config) result.eapConfigs.get(EAP_TYPE_MSCHAP_V2);
+ assertEquals(USERNAME, config.username);
+ assertEquals(PASSWORD, config.password);
+ }
+
+ @Test
+ public void testBuildWithoutConfigs() {
+ try {
+ new EapSessionConfig.Builder().build();
+ fail("build() should throw an IllegalStateException if no EAP methods are configured");
+ } catch (IllegalStateException expected) {
+ }
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java
new file mode 100644
index 00000000..08d89942
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+import android.net.LinkAddress;
+
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.util.LinkedList;
+import java.util.List;
+
+public final class ChildSessionConfigurationTest {
+ private static final int IP4_PREFIX_LEN = 28;
+ private static final Inet4Address IPV4_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+ private static final Inet4Address IPV4_NETMASK =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.240"));
+ private static final LinkAddress IPV4_LINK_ADDRESS =
+ new LinkAddress(IPV4_ADDRESS, IP4_PREFIX_LEN);
+
+ private static final int IP6_PREFIX_LEN = 64;
+ private static final Inet6Address IPV6_ADDRESS =
+ (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1"));
+ private static final LinkAddress IPV6_LINK_ADDRESS =
+ new LinkAddress(IPV6_ADDRESS, IP6_PREFIX_LEN);
+
+ private List mMockInTsList;
+ private List mMockOutTsList;
+
+ private ConfigAttributeIpv4Address mIpv4Attr;
+ private ConfigAttributeIpv4Netmask mNetmaskAttr;
+ private ConfigAttributeIpv6Address mIpv6Attr;
+
+ @Before
+ public void setUp() throws Exception {
+ mMockInTsList = new LinkedList<IkeTrafficSelector>();
+ mMockInTsList.add(mock(IkeTrafficSelector.class));
+
+ mMockOutTsList = new LinkedList<IkeTrafficSelector>();
+ mMockOutTsList.add(mock(IkeTrafficSelector.class));
+ mMockOutTsList.add(mock(IkeTrafficSelector.class));
+
+ mIpv4Attr = new ConfigAttributeIpv4Address(IPV4_ADDRESS);
+ mNetmaskAttr = new ConfigAttributeIpv4Netmask(IPV4_NETMASK.getAddress());
+ mIpv6Attr = new ConfigAttributeIpv6Address(IPV6_LINK_ADDRESS);
+ }
+
+ private void verifySessionConfigCommon(ChildSessionConfiguration sessionConfig) {
+ verifyTsList(mMockInTsList, sessionConfig.getInboundTrafficSelectors());
+ verifyTsList(mMockOutTsList, sessionConfig.getOutboundTrafficSelectors());
+ }
+
+ private void verifyTsList(
+ List<IkeTrafficSelector> expectedList, List<IkeTrafficSelector> tsList) {
+ assertEquals(expectedList.size(), tsList.size());
+ for (int i = 0; i < expectedList.size(); i++) {
+ assertEquals(expectedList.get(i), tsList.get(i));
+ }
+ }
+
+ @Test
+ public void testBuildWithoutConfig() {
+ ChildSessionConfiguration sessionConfig =
+ new ChildSessionConfiguration(mMockInTsList, mMockOutTsList);
+
+ verifySessionConfigCommon(sessionConfig);
+ }
+
+ @Test
+ public void testBuildWithNetmaskAttr() {
+ List<ConfigAttribute> attributeList = new LinkedList<>();
+ attributeList.add(mIpv4Attr);
+ attributeList.add(mNetmaskAttr);
+ attributeList.add(mIpv6Attr);
+
+ IkeConfigPayload configPayload = new IkeConfigPayload(true /*isReply*/, attributeList);
+
+ ChildSessionConfiguration sessionConfig =
+ new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
+
+ verifySessionConfigCommon(sessionConfig);
+
+ List<LinkAddress> expectedInternalAddrList = new LinkedList<>();
+ expectedInternalAddrList.add(IPV4_LINK_ADDRESS);
+ expectedInternalAddrList.add(IPV6_LINK_ADDRESS);
+
+ assertEquals(
+ expectedInternalAddrList.size(), sessionConfig.getInternalAddressList().size());
+ for (int i = 0; i < expectedInternalAddrList.size(); i++) {
+ assertEquals(
+ expectedInternalAddrList.get(i), sessionConfig.getInternalAddressList().get(i));
+ }
+ }
+
+ @Test
+ public void testBuildWithoutNetmaskAttr() {
+ List<ConfigAttribute> attributeList = new LinkedList<>();
+ attributeList.add(mIpv4Attr);
+ attributeList.add(mIpv6Attr);
+
+ IkeConfigPayload configPayload = new IkeConfigPayload(true /*isReply*/, attributeList);
+
+ ChildSessionConfiguration sessionConfig =
+ new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
+
+ verifySessionConfigCommon(sessionConfig);
+
+ List<LinkAddress> expectedInternalAddrList = new LinkedList<>();
+ expectedInternalAddrList.add(new LinkAddress(IPV4_ADDRESS, 32));
+ expectedInternalAddrList.add(IPV6_LINK_ADDRESS);
+
+ assertEquals(
+ expectedInternalAddrList.size(), sessionConfig.getInternalAddressList().size());
+ for (int i = 0; i < expectedInternalAddrList.size(); i++) {
+ assertEquals(
+ expectedInternalAddrList.get(i), sessionConfig.getInternalAddressList().get(i));
+ }
+ }
+
+ @Test
+ public void testBuildWithConfigReq() {
+ List<ConfigAttribute> attributeList = new LinkedList<>();
+ attributeList.add(mIpv4Attr);
+ attributeList.add(mIpv6Attr);
+
+ IkeConfigPayload configPayload = new IkeConfigPayload(false /*isReply*/, attributeList);
+
+ try {
+ new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
+ fail("Expected to fail because provided config paylaod is not a reply.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java
new file mode 100644
index 00000000..242957d6
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+public final class ChildSessionOptionsTest {
+ private static final int NUM_TS = 1;
+
+ @Test
+ public void testBuild() throws Exception {
+ ChildSaProposal saProposal =
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ SaProposal.KEY_LEN_AES_128)
+ .build();
+ ChildSessionOptions sessionOptions =
+ new TunnelModeChildSessionOptions.Builder().addSaProposal(saProposal).build();
+
+ assertArrayEquals(new SaProposal[] {saProposal}, sessionOptions.getSaProposals());
+ assertEquals(NUM_TS, sessionOptions.getLocalTrafficSelectors().length);
+ assertEquals(NUM_TS, sessionOptions.getRemoteTrafficSelectors().length);
+ assertFalse(sessionOptions.isTransportMode());
+ }
+
+ @Test
+ public void testBuildWithoutSaProposal() throws Exception {
+ try {
+ new TunnelModeChildSessionOptions.Builder().build();
+ fail("Expected to fail due to the absence of SA proposal.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java
new file mode 100644
index 00000000..fa077d17
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthConfig;
+import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthDigitalSignLocalConfig;
+import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthDigitalSignRemoteConfig;
+import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthEapConfig;
+import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthPskConfig;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.net.IpSecManager;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+import android.net.eap.EapSessionConfig;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.internal.net.TestUtils;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.DSAPrivateKey;
+import java.security.interfaces.RSAPrivateKey;
+
+public final class IkeSessionOptionsTest {
+ private static final String PSK_HEX_STRING = "6A756E69706572313233";
+ private static final byte[] PSK = TestUtils.hexStringToByteArray(PSK_HEX_STRING);
+
+ private static final Inet4Address LOCAL_IPV4_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
+ private static final Inet4Address REMOTE_IPV4_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+
+ private UdpEncapsulationSocket mUdpEncapSocket;
+ private IkeSaProposal mIkeSaProposal;
+ private IkeIdentification mLocalIdentification;
+ private IkeIdentification mRemoteIdentification;
+
+ private X509Certificate mMockServerCaCert;
+ private X509Certificate mMockClientEndCert;
+ private PrivateKey mMockRsaPrivateKey;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
+ mUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket();
+
+ mIkeSaProposal =
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.KEY_LEN_AES_128)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+ mLocalIdentification = new IkeIpv4AddrIdentification(LOCAL_IPV4_ADDRESS);
+ mRemoteIdentification = new IkeIpv4AddrIdentification(REMOTE_IPV4_ADDRESS);
+
+ mMockServerCaCert = mock(X509Certificate.class);
+ mMockClientEndCert = mock(X509Certificate.class);
+ mMockRsaPrivateKey = mock(RSAPrivateKey.class);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mUdpEncapSocket.close();
+ }
+
+ private void verifyIkeSessionOptionsCommon(IkeSessionOptions sessionOptions) {
+ assertEquals(REMOTE_IPV4_ADDRESS, sessionOptions.getServerAddress());
+ assertEquals(mUdpEncapSocket, sessionOptions.getUdpEncapsulationSocket());
+ assertArrayEquals(new SaProposal[] {mIkeSaProposal}, sessionOptions.getSaProposals());
+
+ assertEquals(mLocalIdentification, sessionOptions.getLocalIdentification());
+ assertEquals(mRemoteIdentification, sessionOptions.getRemoteIdentification());
+
+ assertFalse(sessionOptions.isIkeFragmentationSupported());
+ }
+
+ @Test
+ public void testBuildWithPsk() throws Exception {
+ IkeSessionOptions sessionOptions =
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setLocalIdentification(mLocalIdentification)
+ .setRemoteIdentification(mRemoteIdentification)
+ .setAuthPsk(PSK)
+ .build();
+
+ verifyIkeSessionOptionsCommon(sessionOptions);
+
+ IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
+ assertTrue(localConfig instanceof IkeAuthPskConfig);
+ assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PSK, localConfig.mAuthMethod);
+ assertArrayEquals(PSK, ((IkeAuthPskConfig) localConfig).mPsk);
+
+ IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
+ assertTrue(remoteConfig instanceof IkeAuthPskConfig);
+ assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PSK, remoteConfig.mAuthMethod);
+ assertArrayEquals(PSK, ((IkeAuthPskConfig) remoteConfig).mPsk);
+ }
+
+ @Test
+ public void testBuildWithEap() throws Exception {
+ EapSessionConfig eapConfig = mock(EapSessionConfig.class);
+
+ IkeSessionOptions sessionOptions =
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setLocalIdentification(mLocalIdentification)
+ .setRemoteIdentification(mRemoteIdentification)
+ .setAuthEap(mMockServerCaCert, eapConfig)
+ .build();
+
+ verifyIkeSessionOptionsCommon(sessionOptions);
+
+ IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
+ assertTrue(localConfig instanceof IkeAuthEapConfig);
+ assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_EAP, localConfig.mAuthMethod);
+ assertEquals(eapConfig, ((IkeAuthEapConfig) localConfig).mEapConfig);
+
+ IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
+ assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
+ assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod);
+ assertEquals(
+ mMockServerCaCert,
+ ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert());
+ }
+
+ @Test
+ public void testBuildWithDigitalSignatureAuth() throws Exception {
+ IkeSessionOptions sessionOptions =
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setLocalIdentification(mLocalIdentification)
+ .setRemoteIdentification(mRemoteIdentification)
+ .setAuthDigitalSignature(
+ mMockServerCaCert, mMockClientEndCert, mMockRsaPrivateKey)
+ .build();
+
+ verifyIkeSessionOptionsCommon(sessionOptions);
+
+ IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
+ assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig);
+
+ IkeAuthDigitalSignLocalConfig localAuthConfig = (IkeAuthDigitalSignLocalConfig) localConfig;
+ assertEquals(
+ IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, localAuthConfig.mAuthMethod);
+ assertEquals(mMockClientEndCert, localAuthConfig.mEndCert);
+ assertTrue(localAuthConfig.mIntermediateCerts.isEmpty());
+ assertEquals(mMockRsaPrivateKey, localAuthConfig.mPrivateKey);
+
+ IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
+ assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
+ assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod);
+ assertEquals(
+ mMockServerCaCert,
+ ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert());
+ }
+
+ @Test
+ public void testBuildWithDsaDigitalSignatureAuth() throws Exception {
+ try {
+ IkeSessionOptions sessionOptions =
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setLocalIdentification(mLocalIdentification)
+ .setRemoteIdentification(mRemoteIdentification)
+ .setAuthDigitalSignature(
+ mMockServerCaCert,
+ mMockClientEndCert,
+ mock(DSAPrivateKey.class))
+ .build();
+ fail("Expected to fail because DSA is not supported");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildWithoutSaProposal() throws Exception {
+ try {
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .build();
+ fail("Expected to fail due to absence of SA proposal.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testBuildWithoutLocalId() throws Exception {
+ try {
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setRemoteIdentification(mRemoteIdentification)
+ .setAuthPsk(PSK)
+ .build();
+ fail("Expected to fail because local identification is not set.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testBuildWithoutSetAuth() throws Exception {
+ try {
+ new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_IPV4_ADDRESS)
+ .setUdpEncapsulationSocket(mUdpEncapSocket)
+ .addSaProposal(mIkeSaProposal)
+ .setLocalIdentification(mLocalIdentification)
+ .setRemoteIdentification(mRemoteIdentification)
+ .build();
+ fail("Expected to fail because authentiction method is not set.");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
new file mode 100644
index 00000000..8bf1281d
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import android.content.Context;
+import android.net.IpSecManager;
+import android.os.Looper;
+import android.os.test.TestLooper;
+import android.util.Log;
+
+import com.android.internal.net.ipsec.ike.IkeSessionStateMachine;
+import com.android.internal.net.ipsec.ike.IkeSessionStateMachineTest;
+import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+public final class IkeSessionTest {
+ private static final int TIMEOUT_MS = 500;
+
+ private static final Inet4Address LOCAL_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
+ private static final Inet4Address REMOTE_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("127.0.0.1"));
+
+ private MockIpSecTestUtils mMockIpSecTestUtils;
+ private IpSecManager mIpSecManager;
+ private Context mContext;
+
+ private IkeSessionOptions mIkeSessionOptions;
+ private ChildSessionOptions mMockChildSessionOptions;
+ private Executor mUserCbExecutor;
+ private IkeSessionCallback mMockIkeSessionCb;
+ private ChildSessionCallback mMockChildSessionCb;
+
+ @Before
+ public void setUp() throws Exception {
+ if (Looper.myLooper() == null) Looper.prepare();
+
+ mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
+ mIpSecManager = mMockIpSecTestUtils.getIpSecManager();
+ mContext = mMockIpSecTestUtils.getContext();
+
+ mIkeSessionOptions = buildIkeSessionOptions();
+ mMockChildSessionOptions = mock(ChildSessionOptions.class);
+ mUserCbExecutor = (r) -> r.run(); // Inline executor for testing purposes.
+ mMockIkeSessionCb = mock(IkeSessionCallback.class);
+ mMockChildSessionCb = mock(ChildSessionCallback.class);
+ }
+
+ private IkeSessionOptions buildIkeSessionOptions() throws Exception {
+ return new IkeSessionOptions.Builder()
+ .setServerAddress(REMOTE_ADDRESS)
+ .setUdpEncapsulationSocket(mIpSecManager.openUdpEncapsulationSocket())
+ .addSaProposal(IkeSessionStateMachineTest.buildSaProposal())
+ .setLocalIdentification(new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS))
+ .setRemoteIdentification(
+ new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS))
+ .setAuthPsk(new byte[0] /* psk, unused */)
+ .build();
+ }
+
+ @Test
+ public void testConstructIkeSession() throws Exception {
+ IkeSession ikeSession =
+ new IkeSession(
+ mContext,
+ mIkeSessionOptions,
+ mMockChildSessionOptions,
+ mUserCbExecutor,
+ mMockIkeSessionCb,
+ mMockChildSessionCb);
+ assertNotNull(ikeSession.mIkeSessionStateMachine.getHandler().getLooper());
+ }
+
+ /**
+ * Test that when users construct IkeSessions from different threads, these IkeSessions will
+ * still be running on the same IKE worker thread.
+ */
+ @Test
+ public void testConstructFromDifferentThreads() throws Exception {
+ final int numSession = 2;
+ IkeSession[] sessions = new IkeSession[numSession];
+
+ final CountDownLatch cntLatch = new CountDownLatch(2);
+
+ for (int i = 0; i < numSession; i++) {
+ int index = i;
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ sessions[index] =
+ new IkeSession(
+ mContext,
+ mIkeSessionOptions,
+ mMockChildSessionOptions,
+ mUserCbExecutor,
+ mMockIkeSessionCb,
+ mMockChildSessionCb);
+ cntLatch.countDown();
+ } catch (Exception e) {
+ Log.e("IkeSessionTest", "error encountered constructing IkeSession. ", e);
+ }
+ }
+ }.start();
+ }
+
+ assertTrue(cntLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+
+ // Verify that two sessions use the same looper.
+ assertEquals(
+ sessions[0].mIkeSessionStateMachine.getHandler().getLooper(),
+ sessions[1].mIkeSessionStateMachine.getHandler().getLooper());
+ }
+
+ @Test
+ public void testOpensIkeSession() throws Exception {
+ TestLooper testLooper = new TestLooper();
+ IkeSession ikeSession =
+ new IkeSession(
+ testLooper.getLooper(),
+ mContext,
+ mIpSecManager,
+ mIkeSessionOptions,
+ mMockChildSessionOptions,
+ mUserCbExecutor,
+ mMockIkeSessionCb,
+ mMockChildSessionCb);
+ testLooper.dispatchAll();
+
+ assertTrue(
+ ikeSession.mIkeSessionStateMachine.getCurrentState()
+ instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit);
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java
new file mode 100644
index 00000000..65cf0566
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.internal.net.TestUtils;
+import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.nio.ByteBuffer;
+
+public final class IkeTrafficSelectorTest {
+ private static final String TS_IPV4_ONE_HEX_STRING = "070000100010fff0c0000264c0000365";
+ private static final int TS_ONE_START_PORT = 16;
+ private static final int TS_ONE_END_PORT = 65520;
+ private static final Inet4Address TS_ONE_START_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+ private static final Inet4Address TS_ONE_END_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.3.101"));
+
+ private static final String TS_IPV4_TWO_HEX_STRING = "070000100000ffffc0000464c0000466";
+ private static final int TS_TWO_START_PORT = 0;
+ private static final int TS_TWO_END_PORT = 65535;
+ private static final Inet4Address TS_TWO_START_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.100"));
+ private static final Inet4Address TS_TWO_END_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.102"));
+
+ private static final String TX_IPV4_INVALID_PORT_RANGE_HEX_STRING =
+ "0700001022221111c0000464c0000466";
+ private static final String TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING =
+ "070000100000ffffc0000466c0000366";
+
+ private static final int TS_TYPE_OFFSET = 0;
+ private static final int PROTOCOL_ID_OFFSET = 1;
+ private static final int TS_LENGTH_OFFSET = 2;
+
+ private IkeTrafficSelector mTsOne;
+ private IkeTrafficSelector mTsTwo;
+
+ public IkeTrafficSelectorTest() {
+ mTsOne =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+ mTsTwo =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_TWO_START_PORT,
+ TS_TWO_END_PORT,
+ TS_TWO_START_ADDRESS,
+ TS_TWO_END_ADDRESS);
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectors() throws Exception {
+ int numTs = 2;
+
+ byte[] tsBytes =
+ TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + TS_IPV4_TWO_HEX_STRING);
+ IkeTrafficSelector[] selectors =
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+
+ assertEquals(numTs, selectors.length);
+
+ // Verify first traffic selector
+ IkeTrafficSelector tsOne = selectors[0];
+
+ assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsOne.tsType);
+ assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsOne.ipProtocolId);
+ assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsOne.selectorLength);
+ assertEquals(TS_ONE_START_PORT, tsOne.startPort);
+ assertEquals(TS_ONE_END_PORT, tsOne.endPort);
+ assertEquals(TS_ONE_START_ADDRESS, tsOne.startingAddress);
+ assertEquals(TS_ONE_END_ADDRESS, tsOne.endingAddress);
+
+ // Verify second traffic selector
+ IkeTrafficSelector tsTwo = selectors[1];
+
+ assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsTwo.tsType);
+ assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsTwo.ipProtocolId);
+ assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsTwo.selectorLength);
+ assertEquals(TS_TWO_START_PORT, tsTwo.startPort);
+ assertEquals(TS_TWO_END_PORT, tsTwo.endPort);
+ assertEquals(TS_TWO_START_ADDRESS, tsTwo.startingAddress);
+ assertEquals(TS_TWO_END_ADDRESS, tsTwo.endingAddress);
+ }
+
+ @Test
+ public void testBuildAndEncodeIkeTrafficSelector() throws Exception {
+ IkeTrafficSelector ts =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+
+ ByteBuffer byteBuffer = ByteBuffer.allocate(ts.selectorLength);
+ ts.encodeToByteBuffer(byteBuffer);
+
+ byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+ assertArrayEquals(expectedBytes, byteBuffer.array());
+ }
+
+ @Test
+ public void testEquals() throws Exception {
+ IkeTrafficSelector tsOneOther =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+
+ assertEquals(mTsOne, tsOneOther);
+ assertNotEquals(mTsOne, mTsTwo);
+ }
+
+ @Test
+ public void testContains() throws Exception {
+ IkeTrafficSelector tsOneSubset =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT + 1,
+ TS_ONE_END_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+ assertTrue(mTsOne.contains(tsOneSubset));
+ assertFalse(tsOneSubset.contains(mTsOne));
+
+ assertTrue(mTsOne.contains(mTsOne));
+ assertFalse(mTsOne.contains(mTsTwo));
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithInvalidTsType() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+ tsBytes[TS_TYPE_OFFSET] = -1;
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail due to invalid Traffic Selector Type.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithInvalidIpProtocol() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+ tsBytes[PROTOCOL_ID_OFFSET] = -1;
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail due to invalid IP Protocol ID.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithExpectedTrailing() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + "FFFF");
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail due to unexpected trailing characters.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithInvalidTsLength() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+
+ // Traffic Selector field is two octets
+ tsBytes[TS_LENGTH_OFFSET] = 0;
+ tsBytes[TS_LENGTH_OFFSET + 1] = 0;
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail due to invalid Traffic Selector length.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithInvalidPortRange() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_PORT_RANGE_HEX_STRING);
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail when start port is larger than end port.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecodeIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
+ int numTs = 1;
+ byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING);
+
+ try {
+ IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+ fail("Expected to fail when starting address is larger than ending address.");
+ } catch (InvalidSyntaxException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeTrafficSelectorWithInvalidTsType() throws Exception {
+ try {
+ IkeTrafficSelector ts =
+ new IkeTrafficSelector(
+ 0,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+ fail("Expected to fail due to unrecognized Traffic Selector type.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeTrafficSelectorWithInvalidPortRange() throws Exception {
+ try {
+ IkeTrafficSelector ts =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_END_PORT,
+ TS_ONE_START_PORT,
+ TS_ONE_START_ADDRESS,
+ TS_ONE_END_ADDRESS);
+ fail("Expected to fail due to invalid port range.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeTrafficSelectorWithMismatchedAddressType() throws Exception {
+ Inet6Address inet6Address =
+ (Inet6Address) (InetAddressUtils.parseNumericAddress("0:2001:0:db8::1"));
+ try {
+ IkeTrafficSelector ts =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ inet6Address,
+ TS_ONE_END_ADDRESS);
+ fail("Expected to fail due to mismatched address format.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
+ try {
+ IkeTrafficSelector ts =
+ new IkeTrafficSelector(
+ IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+ TS_ONE_START_PORT,
+ TS_ONE_END_PORT,
+ TS_ONE_END_ADDRESS,
+ TS_ONE_START_ADDRESS);
+ fail("Expected to fail due to invalid address range.");
+ } catch (IllegalArgumentException e) {
+ }
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
new file mode 100644
index 00000000..d4efb0c3
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128;
+import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.internal.net.ipsec.ike.message.IkePayload;
+import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
+import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
+import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
+import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
+import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
+
+import org.junit.Test;
+
+public final class SaProposalTest {
+ private final EncryptionTransform mEncryption3DesTransform;
+ private final EncryptionTransform mEncryptionAesGcm8Transform;
+ private final EncryptionTransform mEncryptionAesGcm12Transform;
+ private final IntegrityTransform mIntegrityHmacSha1Transform;
+ private final IntegrityTransform mIntegrityNoneTransform;
+ private final PrfTransform mPrfAes128XCbcTransform;
+ private final DhGroupTransform mDhGroup1024Transform;
+
+ public SaProposalTest() {
+ mEncryption3DesTransform =
+ new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED);
+ mEncryptionAesGcm8Transform =
+ new EncryptionTransform(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_128);
+ mEncryptionAesGcm12Transform =
+ new EncryptionTransform(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128);
+ mIntegrityHmacSha1Transform =
+ new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+ mIntegrityNoneTransform = new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_NONE);
+ mPrfAes128XCbcTransform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC);
+ mDhGroup1024Transform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP);
+ }
+
+ @Test
+ public void testBuildIkeSaProposalWithNormalModeCipher() throws Exception {
+ IkeSaProposal proposal =
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+
+ assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.getProtocolId());
+ assertArrayEquals(
+ new EncryptionTransform[] {mEncryption3DesTransform},
+ proposal.getEncryptionTransforms());
+ assertArrayEquals(
+ new IntegrityTransform[] {mIntegrityHmacSha1Transform},
+ proposal.getIntegrityTransforms());
+ assertArrayEquals(
+ new PrfTransform[] {mPrfAes128XCbcTransform}, proposal.getPrfTransforms());
+ assertArrayEquals(
+ new DhGroupTransform[] {mDhGroup1024Transform}, proposal.getDhGroupTransforms());
+ }
+
+ @Test
+ public void testBuildIkeSaProposalWithCombinedModeCipher() throws Exception {
+ IkeSaProposal proposal =
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+ SaProposal.KEY_LEN_AES_128)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+
+ assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.getProtocolId());
+ assertArrayEquals(
+ new EncryptionTransform[] {mEncryptionAesGcm8Transform},
+ proposal.getEncryptionTransforms());
+ assertArrayEquals(
+ new PrfTransform[] {mPrfAes128XCbcTransform}, proposal.getPrfTransforms());
+ assertArrayEquals(
+ new DhGroupTransform[] {mDhGroup1024Transform}, proposal.getDhGroupTransforms());
+ assertTrue(proposal.getIntegrityTransforms().length == 0);
+ }
+
+ @Test
+ public void testBuildChildSaProposalWithNormalCipher() throws Exception {
+ ChildSaProposal proposal =
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+
+ assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.getProtocolId());
+ assertArrayEquals(
+ new EncryptionTransform[] {mEncryption3DesTransform},
+ proposal.getEncryptionTransforms());
+ assertArrayEquals(
+ new IntegrityTransform[] {mIntegrityNoneTransform},
+ proposal.getIntegrityTransforms());
+ assertArrayEquals(
+ new DhGroupTransform[] {mDhGroup1024Transform}, proposal.getDhGroupTransforms());
+ }
+
+ @Test
+ public void testGetCopyWithoutDhGroup() throws Exception {
+ ChildSaProposal proposal =
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .build();
+ ChildSaProposal proposalWithoutDh = proposal.getCopyWithoutDhTransform();
+
+ assertArrayEquals(
+ proposal.getEncryptionTransforms(), proposalWithoutDh.getEncryptionTransforms());
+ assertArrayEquals(
+ proposal.getIntegrityTransforms(), proposalWithoutDh.getIntegrityTransforms());
+ assertTrue(proposal.getDhGroupTransforms().length == 1);
+ assertTrue(proposalWithoutDh.getDhGroupTransforms().length == 0);
+ }
+
+ @Test
+ public void testBuildEncryptAlgosWithNoAlgorithm() throws Exception {
+ try {
+ new IkeSaProposal.Builder().build();
+ fail("Expected to fail when no encryption algorithm is proposed.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildEncryptAlgosWithUnrecognizedAlgorithm() throws Exception {
+ try {
+ new IkeSaProposal.Builder().addEncryptionAlgorithm(-1, KEY_LEN_UNUSED);
+ fail("Expected to fail when unrecognized encryption algorithm is proposed.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildEncryptAlgosWithTwoModes() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128);
+ fail(
+ "Expected to fail when "
+ + "normal and combined-mode ciphers are proposed together.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeProposalWithoutPrf() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .build();
+ fail("Expected to fail when PRF is not provided in IKE SA proposal.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ // Test throwing exception when building IKE SA Proposal with AEAD and not-none integrity
+ // algorithm.
+ @Test
+ public void testBuildAeadWithIntegrityAlgo() throws Exception {
+ try {
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .build();
+
+ fail("Expected to fail when not-none integrity algorithm is proposed with AEAD");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ // Test throwing exception when building IKE SA Proposal with normal mode cipher and without
+ // integrity algorithm.
+ @Test
+ public void testBuildIkeProposalNormalCipherWithoutIntegrityAlgo() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
+ .build();
+
+ fail(
+ "Expected to fail when"
+ + " no integrity algorithm is proposed with non-combined cipher");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ // Test throwing exception when building IKE SA Proposal with normal mode cipher and none-value
+ // integrity algorithm.
+ @Test
+ public void testBuildIkeProposalNormalCipherWithNoneValueIntegrityAlgo() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .build();
+
+ fail(
+ "Expected to fail when none-value integrity algorithm is proposed"
+ + " with non-combined cipher");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeProposalWithoutDhGroup() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .build();
+
+ fail("Expected to fail when no DH Group is proposed in IKE SA proposal.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIkeProposalWithNoneValueDhGroup() throws Exception {
+ try {
+ new IkeSaProposal.Builder()
+ .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+ .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+ .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+ .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+ .addDhGroup(SaProposal.DH_GROUP_NONE)
+ .build();
+
+ fail("Expected to fail when none-value DH Group is proposed in IKE SA proposal.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testIsTransformSelectedFrom() throws Exception {
+ assertTrue(SaProposal.isTransformSelectedFrom(new Transform[0], new Transform[0]));
+ assertTrue(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[] {mEncryptionAesGcm8Transform},
+ new Transform[] {
+ mEncryptionAesGcm8Transform, mEncryptionAesGcm12Transform
+ }));
+ assertTrue(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[] {mIntegrityNoneTransform},
+ new Transform[] {mIntegrityNoneTransform}));
+
+ // No transform selected.
+ assertFalse(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[0], new Transform[] {mEncryptionAesGcm8Transform}));
+
+ // Selected transform was not part of original proposal.
+ assertFalse(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[] {mPrfAes128XCbcTransform}, new Transform[0]));
+
+ // More than one transform returned.
+ assertFalse(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[] {mEncryptionAesGcm8Transform, mEncryptionAesGcm12Transform},
+ new Transform[] {
+ mEncryptionAesGcm8Transform, mEncryptionAesGcm12Transform
+ }));
+
+ // Selected transform was not part of original proposal.
+ assertFalse(
+ SaProposal.isTransformSelectedFrom(
+ new Transform[] {mIntegrityNoneTransform},
+ new Transform[] {mIntegrityHmacSha1Transform}));
+ }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java
new file mode 100644
index 00000000..b0f81dc2
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2019 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;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS;
+import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import android.util.SparseArray;
+
+import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+
+public final class TunnelModeChildSessionOptionsTest {
+ private static final int NUM_TS = 1;
+
+ private static final int IP4_PREFIX_LEN = 32;
+ private static final int IP6_PREFIX_LEN = 64;
+
+ private static final int INVALID_ADDR_FAMILY = 5;
+
+ private static final Inet4Address IPV4_ADDRESS =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+ private static final Inet6Address IPV6_ADDRESS =
+ (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1"));
+
+ private static final Inet4Address IPV4_DNS_SERVER =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8"));
+ private static final Inet6Address IPV6_DNS_SERVER =
+ (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:4860:4860::8888"));
+
+ private static final Inet4Address IPV4_DHCP_SERVER =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
+ private ChildSaProposal mSaProposal;
+
+ @Before
+ public void setup() {
+ mSaProposal =
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
+ SaProposal.KEY_LEN_AES_128)
+ .build();
+ }
+
+ private void verifyCommon(TunnelModeChildSessionOptions childOptions) {
+ assertArrayEquals(new SaProposal[] {mSaProposal}, childOptions.getSaProposals());
+ assertEquals(NUM_TS, childOptions.getLocalTrafficSelectors().length);
+ assertEquals(NUM_TS, childOptions.getRemoteTrafficSelectors().length);
+ assertFalse(childOptions.isTransportMode());
+ }
+
+ private void verifyAttrTypes(
+ SparseArray expectedAttrCntMap, TunnelModeChildSessionOptions childOptions) {
+ ConfigAttribute[] configAttributes = childOptions.getConfigurationRequests();
+
+ SparseArray<Integer> atrrCntMap = expectedAttrCntMap.clone();
+
+ for (int i = 0; i < configAttributes.length; i++) {
+ int attType = configAttributes[i].attributeType;
+ assertNotNull(atrrCntMap.get(attType));
+
+ atrrCntMap.put(attType, atrrCntMap.get(attType) - 1);
+ if (atrrCntMap.get(attType) == 0) atrrCntMap.remove(attType);
+ }
+
+ assertEquals(0, atrrCntMap.size());
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithoutConfigReq() {
+ TunnelModeChildSessionOptions childOptions =
+ new TunnelModeChildSessionOptions.Builder().addSaProposal(mSaProposal).build();
+
+ verifyCommon(childOptions);
+ assertEquals(0, childOptions.getConfigurationRequests().length);
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithAddressReq() {
+ TunnelModeChildSessionOptions childOptions =
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalAddressRequest(AF_INET, 1)
+ .addInternalAddressRequest(AF_INET6, 2)
+ .addInternalAddressRequest(IPV4_ADDRESS, IP4_PREFIX_LEN)
+ .addInternalAddressRequest(IPV6_ADDRESS, IP6_PREFIX_LEN)
+ .build();
+
+ verifyCommon(childOptions);
+
+ SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, 2);
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, 3);
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_NETMASK, 1);
+
+ verifyAttrTypes(expectedAttrCntMap, childOptions);
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithInvalidAddressReq() {
+ try {
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalAddressRequest(IPV4_ADDRESS, 31)
+ .build();
+ fail("Expected to fail due to invalid IPv4 prefix length.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithDnsServerReq() {
+ TunnelModeChildSessionOptions childOptions =
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalDnsServerRequest(AF_INET, 1)
+ .addInternalDnsServerRequest(AF_INET6, 1)
+ .addInternalDnsServerRequest(IPV4_DNS_SERVER)
+ .addInternalDnsServerRequest(IPV6_DNS_SERVER)
+ .build();
+
+ verifyCommon(childOptions);
+
+ SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_DNS, 2);
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_DNS, 2);
+
+ verifyAttrTypes(expectedAttrCntMap, childOptions);
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithSubnetReq() {
+ TunnelModeChildSessionOptions childOptions =
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalSubnetRequest(AF_INET, 1)
+ .addInternalSubnetRequest(AF_INET6, 1)
+ .build();
+
+ verifyCommon(childOptions);
+
+ SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_SUBNET, 1);
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_SUBNET, 1);
+
+ verifyAttrTypes(expectedAttrCntMap, childOptions);
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithDhcpServerReq() {
+ TunnelModeChildSessionOptions childOptions =
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalDhcpServerRequest(AF_INET, 3)
+ .addInternalDhcpServerRequest(IPV4_DHCP_SERVER)
+ .build();
+
+ verifyCommon(childOptions);
+
+ SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
+ expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_DHCP, 4);
+
+ verifyAttrTypes(expectedAttrCntMap, childOptions);
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithDhcp6SeverReq() {
+ try {
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalDhcpServerRequest(AF_INET6, 3)
+ .build();
+ fail("Expected to fail because DHCP6 is not supported.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildChildSessionOptionsWithInvalidDhcpReq() {
+ try {
+ new TunnelModeChildSessionOptions.Builder()
+ .addSaProposal(mSaProposal)
+ .addInternalDhcpServerRequest(INVALID_ADDR_FAMILY, 3)
+ .build();
+ fail("Expected to fail due to invalid address family value");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+}
+
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java b/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java
new file mode 100644
index 00000000..8c3b16da
--- /dev/null
+++ b/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 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.exceptions;
+
+import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
+import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
+import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
+import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
+
+import org.junit.Test;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public final class IkeProtocolExceptionTest {
+ @Test
+ public void buildNotifyPayloadWithData() throws Exception {
+ List<Integer> unsupportedTypes = new LinkedList<>();
+ unsupportedTypes.add(55); // 0x37 in hex
+ unsupportedTypes.add(56);
+ unsupportedTypes.add(57);
+ UnsupportedCriticalPayloadException exception =
+ new UnsupportedCriticalPayloadException(unsupportedTypes);
+
+ IkeNotifyPayload payload = exception.buildNotifyPayload();
+ assertEquals(ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, payload.notifyType);
+ assertArrayEquals(new byte[] {(byte) 0x37}, payload.notifyData);
+ }
+
+ @Test
+ public void buildNotifyPayloadWithoutData() throws Exception {
+ NoValidProposalChosenException exception =
+ new NoValidProposalChosenException("IkeProtocolExceptionTest");
+
+ IkeNotifyPayload payload = exception.buildNotifyPayload();
+ assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, payload.notifyType);
+ assertArrayEquals(new byte[0], payload.notifyData);
+ }
+}