| /* |
| * 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.test.ike; |
| |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_DPD_DELAY_SEC_DEFAULT; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_HARD_LIFETIME_SEC_DEFAULT; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_HARD_LIFETIME_SEC_MAXIMUM; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_HARD_LIFETIME_SEC_MINIMUM; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IKE_SOFT_LIFETIME_SEC_DEFAULT; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IkeAuthConfig; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IkeAuthDigitalSignLocalConfig; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IkeAuthDigitalSignRemoteConfig; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IkeAuthEapConfig; |
| import static android.net.ipsec.test.ike.IkeSessionParams.IkeAuthPskConfig; |
| import static android.system.OsConstants.AF_INET; |
| import static android.system.OsConstants.AF_INET6; |
| |
| import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_IP4_PCSCF; |
| import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_IP6_PCSCF; |
| import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.ConfigAttribute; |
| |
| 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.assertNotNull; |
| import static org.junit.Assert.assertNull; |
| import static org.junit.Assert.assertTrue; |
| import static org.junit.Assert.fail; |
| import static org.mockito.Mockito.doReturn; |
| import static org.mockito.Mockito.mock; |
| import static org.mockito.Mockito.when; |
| |
| import android.content.Context; |
| import android.net.ConnectivityManager; |
| import android.net.InetAddresses; |
| import android.net.Network; |
| import android.net.SocketKeepalive; |
| import android.net.eap.test.EapSessionConfig; |
| import android.net.ipsec.test.ike.ike3gpp.Ike3gppExtension; |
| import android.net.ipsec.test.ike.ike3gpp.Ike3gppExtension.Ike3gppDataListener; |
| import android.net.ipsec.test.ike.ike3gpp.Ike3gppParams; |
| import android.os.PersistableBundle; |
| import android.telephony.TelephonyManager; |
| import android.util.SparseArray; |
| |
| import com.android.internal.net.TestUtils; |
| import com.android.internal.net.ipsec.test.ike.testutils.CertUtils; |
| |
| import org.junit.Before; |
| import org.junit.Test; |
| |
| import java.net.Inet4Address; |
| import java.net.Inet6Address; |
| import java.security.PrivateKey; |
| import java.security.cert.X509Certificate; |
| import java.security.interfaces.DSAPrivateKey; |
| import java.security.interfaces.RSAKey; |
| import java.util.Arrays; |
| import java.util.concurrent.TimeUnit; |
| |
| public final class IkeSessionParamsTest { |
| private static final int IKE_OPTION_INVALID = -1; |
| private static final int SUB_ID = 0; |
| |
| private static final String PSK_HEX_STRING = "6A756E69706572313233"; |
| private static final byte[] PSK = TestUtils.hexStringToByteArray(PSK_HEX_STRING); |
| |
| private static final String LOCAL_IPV4_HOST_ADDRESS = "192.0.2.100"; |
| private static final String REMOTE_IPV4_HOST_ADDRESS = "192.0.2.100"; |
| private static final String REMOTE_HOSTNAME = "server.test.android.net"; |
| |
| private static final Inet4Address LOCAL_IPV4_ADDRESS = |
| (Inet4Address) InetAddresses.parseNumericAddress(LOCAL_IPV4_HOST_ADDRESS); |
| private static final Inet4Address REMOTE_IPV4_ADDRESS = |
| (Inet4Address) InetAddresses.parseNumericAddress(REMOTE_IPV4_HOST_ADDRESS); |
| |
| private static final Inet4Address PCSCF_IPV4_ADDRESS_1 = |
| (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.1"); |
| private static final Inet4Address PCSCF_IPV4_ADDRESS_2 = |
| (Inet4Address) InetAddresses.parseNumericAddress("192.0.2.2"); |
| private static final Inet6Address PCSCF_IPV6_ADDRESS_1 = |
| (Inet6Address) InetAddresses.parseNumericAddress("2001:DB8::1"); |
| private static final Inet6Address PCSCF_IPV6_ADDRESS_2 = |
| (Inet6Address) InetAddresses.parseNumericAddress("2001:DB8::2"); |
| |
| private static final String EAP_MSCHAP_V2_USERNAME = "username"; |
| private static final String EAP_MSCHAP_V2_PASSWORD = "password"; |
| |
| private Context mMockContext; |
| private ConnectivityManager mMockConnectManager; |
| private Network mMockDefaultNetwork; |
| private Network mMockUserConfigNetwork; |
| |
| private IkeSaProposal mIkeSaProposal; |
| private IkeIdentification mLocalIdentification; |
| private IkeIdentification mRemoteIdentification; |
| |
| private interface TestRSAPrivateKey extends PrivateKey, RSAKey {} |
| |
| private X509Certificate mMockServerCaCert; |
| private X509Certificate mMockClientEndCert; |
| private TestRSAPrivateKey mMockRsaPrivateKey; |
| |
| @Before |
| public void setUp() throws Exception { |
| mMockContext = mock(Context.class); |
| mMockConnectManager = mock(ConnectivityManager.class); |
| mMockDefaultNetwork = mock(Network.class); |
| mMockUserConfigNetwork = mock(Network.class); |
| |
| doReturn(Context.CONNECTIVITY_SERVICE) |
| .when(mMockContext) |
| .getSystemServiceName(ConnectivityManager.class); |
| doReturn(mMockConnectManager) |
| .when(mMockContext) |
| .getSystemService(Context.CONNECTIVITY_SERVICE); |
| when(mMockConnectManager.getActiveNetwork()).thenReturn(mMockDefaultNetwork); |
| |
| 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(TestRSAPrivateKey.class); |
| } |
| |
| private void verifyIkeParamsWithSeverIpAndDefaultValues(IkeSessionParams sessionParams) { |
| verifyIkeSessionParamsCommon(sessionParams); |
| |
| assertEquals(REMOTE_IPV4_HOST_ADDRESS, sessionParams.getServerHostname()); |
| assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); |
| assertEquals(IKE_DPD_DELAY_SEC_DEFAULT, sessionParams.getDpdDelaySeconds()); |
| assertArrayEquals( |
| IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT, |
| sessionParams.getRetransmissionTimeoutsMillis()); |
| } |
| |
| private void verifyIkeSessionParamsCommon(IkeSessionParams sessionParams) { |
| assertArrayEquals( |
| new SaProposal[] {mIkeSaProposal}, sessionParams.getSaProposalsInternal()); |
| |
| assertEquals(mLocalIdentification, sessionParams.getLocalIdentification()); |
| assertEquals(mRemoteIdentification, sessionParams.getRemoteIdentification()); |
| |
| assertTrue(sessionParams.isIkeFragmentationSupported()); |
| } |
| |
| private void verifyAuthPskConfig(IkeSessionParams sessionParams) { |
| IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); |
| assertTrue(localConfig instanceof IkeAuthPskConfig); |
| assertEquals(IkeSessionParams.IKE_AUTH_METHOD_PSK, localConfig.mAuthMethod); |
| assertArrayEquals(PSK, ((IkeAuthPskConfig) localConfig).mPsk); |
| |
| IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); |
| assertTrue(remoteConfig instanceof IkeAuthPskConfig); |
| assertEquals(IkeSessionParams.IKE_AUTH_METHOD_PSK, remoteConfig.mAuthMethod); |
| assertArrayEquals(PSK, ((IkeAuthPskConfig) remoteConfig).mPsk); |
| } |
| |
| private IkeSessionParams.Builder buildWithPskCommon(String hostname) { |
| return new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(hostname) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthPsk(PSK); |
| } |
| |
| @Test |
| public void testBuildWithPsk() throws Exception { |
| IkeSessionParams sessionParams = buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS).build(); |
| |
| verifyIkeParamsWithSeverIpAndDefaultValues(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| |
| assertEquals(mMockDefaultNetwork, sessionParams.getNetwork()); |
| assertNull(sessionParams.getConfiguredNetwork()); |
| |
| assertEquals(IKE_HARD_LIFETIME_SEC_DEFAULT, sessionParams.getHardLifetimeSeconds()); |
| assertEquals(IKE_SOFT_LIFETIME_SEC_DEFAULT, sessionParams.getSoftLifetimeSeconds()); |
| } |
| |
| @Test |
| public void testBuildWithPskAndLifetime() throws Exception { |
| int hardLifetimeSec = (int) TimeUnit.HOURS.toSeconds(20L); |
| int softLifetimeSec = (int) TimeUnit.HOURS.toSeconds(10L); |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setLifetimeSeconds(hardLifetimeSec, softLifetimeSec) |
| .build(); |
| |
| verifyIkeParamsWithSeverIpAndDefaultValues(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| |
| assertEquals(hardLifetimeSec, sessionParams.getHardLifetimeSeconds()); |
| assertEquals(softLifetimeSec, sessionParams.getSoftLifetimeSeconds()); |
| } |
| |
| @Test |
| public void testBuildWithPskAndHostname() throws Exception { |
| IkeSessionParams sessionParams = buildWithPskCommon(REMOTE_HOSTNAME).build(); |
| |
| verifyIkeSessionParamsCommon(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| |
| assertEquals(REMOTE_HOSTNAME, sessionParams.getServerHostname()); |
| } |
| |
| @Test |
| public void testAddIkeOption() throws Exception { |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) |
| .build(); |
| |
| verifyIkeSessionParamsCommon(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| |
| assertTrue(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); |
| } |
| |
| @Test |
| public void testAddAndRemoveIkeOption() throws Exception { |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) |
| .removeIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) |
| .build(); |
| |
| verifyIkeSessionParamsCommon(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| |
| assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); |
| } |
| |
| private IkeSessionParams.Builder createIkeParamsBuilderMinimum() { |
| return new IkeSessionParams.Builder() |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthPsk(PSK); |
| } |
| |
| @Test |
| public void testIkeSessionParamsEncodeDecodeIsLossLess() throws Exception { |
| IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); |
| |
| PersistableBundle bundle = sessionParams.toPersistableBundle(); |
| IkeSessionParams result = IkeSessionParams.fromPersistableBundle(bundle); |
| |
| assertEquals(sessionParams, result); |
| } |
| |
| @Test(expected = IllegalStateException.class) |
| public void testEncodeIkeSessionParamsWithConfiguredNetwork() throws Exception { |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setConfiguredNetwork(mMockUserConfigNetwork) |
| .build(); |
| |
| PersistableBundle bundle = sessionParams.toPersistableBundle(); |
| } |
| |
| @Test(expected = IllegalStateException.class) |
| public void testEncodeIkeSessionParamsWith3gppExtension() throws Exception { |
| Ike3gppExtension ike3gppExtension = |
| new Ike3gppExtension( |
| new Ike3gppParams.Builder().build(), mock(Ike3gppDataListener.class)); |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setIke3gppExtension(ike3gppExtension) |
| .build(); |
| |
| PersistableBundle bundle = sessionParams.toPersistableBundle(); |
| } |
| |
| @Test |
| public void testAddInvalidIkeOption() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager).addIkeOption(IKE_OPTION_INVALID); |
| fail("Expected to fail due to invalid ikeOption"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testRemoveInvalidIkeOption() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager).removeIkeOption(IKE_OPTION_INVALID); |
| fail("Expected to fail due to invalid ikeOption"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testCheckInvalidIkeOption() throws Exception { |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID) |
| .build(); |
| |
| try { |
| sessionParams.hasIkeOption(IKE_OPTION_INVALID); |
| fail("Expected to fail due to invalid ikeOption"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testBuildWithPskAndDpdDelay() throws Exception { |
| final int dpdDelaySec = 100; |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setDpdDelaySeconds(dpdDelaySec) |
| .build(); |
| |
| verifyIkeSessionParamsCommon(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| assertEquals(REMOTE_IPV4_HOST_ADDRESS, sessionParams.getServerHostname()); |
| |
| // Verify default values |
| assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); |
| assertArrayEquals( |
| IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT, |
| sessionParams.getRetransmissionTimeoutsMillis()); |
| |
| // Verify DPD delay |
| assertEquals(dpdDelaySec, sessionParams.getDpdDelaySeconds()); |
| } |
| |
| @Test |
| public void testBuildWithInvalidDpdDelay() throws Exception { |
| final int invalidDpdDelay = 1; |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager).setDpdDelaySeconds(invalidDpdDelay); |
| fail("Expected to fail due to invalid DPD delay"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testBuildWithPskAndNattKeepaliveDelay() throws Exception { |
| final int nattKeepaliveDelay = 100; |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setNattKeepAliveDelaySeconds(nattKeepaliveDelay) |
| .build(); |
| |
| // Verify NATT keepalive delay |
| assertEquals(nattKeepaliveDelay, sessionParams.getNattKeepAliveDelaySeconds()); |
| } |
| |
| @Test |
| public void testNattKeepaliveRange() { |
| assertTrue( |
| SocketKeepalive.MIN_INTERVAL_SEC |
| <= IkeSessionParams.IKE_NATT_KEEPALIVE_DELAY_SEC_MIN); |
| assertTrue( |
| SocketKeepalive.MAX_INTERVAL_SEC |
| >= IkeSessionParams.IKE_NATT_KEEPALIVE_DELAY_SEC_MAX); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testBuildWithNattKeepaliveDelayTooShort() throws Exception { |
| final int lowNattKeepaliveDelay = 1; |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setNattKeepAliveDelaySeconds(lowNattKeepaliveDelay); |
| } |
| |
| @Test(expected = IllegalArgumentException.class) |
| public void testBuildWithNattKeepaliveDelayTooLong() throws Exception { |
| final int highNattKeepaliveDelay = 9999; |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setNattKeepAliveDelaySeconds(highNattKeepaliveDelay); |
| } |
| |
| @Test |
| public void testBuildWithPskAndRetransmission() throws Exception { |
| final int[] retransmissionTimeoutList = new int[] {1000, 2000, 3000, 4000}; |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setRetransmissionTimeoutsMillis(retransmissionTimeoutList) |
| .build(); |
| |
| verifyIkeSessionParamsCommon(sessionParams); |
| verifyAuthPskConfig(sessionParams); |
| assertEquals(REMOTE_IPV4_HOST_ADDRESS, sessionParams.getServerHostname()); |
| |
| // Verify default values |
| assertEquals(IKE_DPD_DELAY_SEC_DEFAULT, sessionParams.getDpdDelaySeconds()); |
| assertFalse(sessionParams.hasIkeOption(IKE_OPTION_ACCEPT_ANY_REMOTE_ID)); |
| |
| // Verify retransmission configuration |
| assertEquals(retransmissionTimeoutList, sessionParams.getRetransmissionTimeoutsMillis()); |
| } |
| |
| @Test |
| public void testBuildWithInvalidRetransmissionTimeout() throws Exception { |
| final int[] invalidRetransTimeoutMsList = new int[] {1000, 2000, 3000, Integer.MAX_VALUE}; |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setRetransmissionTimeoutsMillis(invalidRetransTimeoutMsList); |
| fail("Expected to fail due to invalid retransmission timeout"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testBuildWithInvalidMaxRetransmissionAttempts() throws Exception { |
| final int[] invalidRetransTimeoutMsList = new int[20]; |
| for (int t : invalidRetransTimeoutMsList) t = 500; |
| |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setRetransmissionTimeoutsMillis(invalidRetransTimeoutMsList); |
| fail("Expected to fail due to invalid max retransmission times"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testBuildWithEap() throws Exception { |
| EapSessionConfig eapConfig = mock(EapSessionConfig.class); |
| |
| IkeSessionParams sessionParams = |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthEap(mMockServerCaCert, eapConfig) |
| .build(); |
| |
| verifyIkeParamsWithSeverIpAndDefaultValues(sessionParams); |
| assertEquals(mMockDefaultNetwork, sessionParams.getNetwork()); |
| assertNull(sessionParams.getConfiguredNetwork()); |
| |
| IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); |
| assertTrue(localConfig instanceof IkeAuthEapConfig); |
| assertEquals(IkeSessionParams.IKE_AUTH_METHOD_EAP, localConfig.mAuthMethod); |
| assertEquals(eapConfig, ((IkeAuthEapConfig) localConfig).mEapConfig); |
| |
| IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); |
| assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); |
| assertEquals(IkeSessionParams.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod); |
| assertEquals( |
| mMockServerCaCert, |
| ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert()); |
| } |
| |
| @Test |
| public void testBuildWithDigitalSignatureAuth() throws Exception { |
| IkeSessionParams sessionParams = |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .setNetwork(mMockUserConfigNetwork) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthDigitalSignature( |
| mMockServerCaCert, mMockClientEndCert, mMockRsaPrivateKey) |
| .build(); |
| |
| verifyIkeParamsWithSeverIpAndDefaultValues(sessionParams); |
| assertEquals(mMockUserConfigNetwork, sessionParams.getNetwork()); |
| assertEquals(mMockUserConfigNetwork, sessionParams.getConfiguredNetwork()); |
| |
| IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); |
| assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig); |
| |
| IkeAuthDigitalSignLocalConfig localAuthConfig = (IkeAuthDigitalSignLocalConfig) localConfig; |
| assertEquals( |
| IkeSessionParams.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, localAuthConfig.mAuthMethod); |
| assertEquals(mMockClientEndCert, localAuthConfig.mEndCert); |
| assertTrue(localAuthConfig.mIntermediateCerts.isEmpty()); |
| assertEquals(mMockRsaPrivateKey, localAuthConfig.mPrivateKey); |
| |
| IkeAuthConfig remoteConfig = sessionParams.getRemoteAuthConfig(); |
| assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig); |
| assertEquals(IkeSessionParams.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod); |
| assertEquals( |
| mMockServerCaCert, |
| ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert()); |
| } |
| |
| @Test |
| public void testBuildWithDsaDigitalSignatureAuth() throws Exception { |
| try { |
| IkeSessionParams sessionParams = |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .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) { |
| |
| } |
| } |
| |
| private void verifyAttrTypes(SparseArray expectedAttrCntMap, IkeSessionParams ikeParams) { |
| ConfigAttribute[] configAttributes = ikeParams.getConfigurationAttributesInternal(); |
| |
| 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 testBuildWithPcscfAddress() throws Exception { |
| IkeSessionParams sessionParams = |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthPsk(PSK) |
| .addPcscfServerRequest(AF_INET) |
| .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_1) |
| .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_2) |
| .addPcscfServerRequest(AF_INET6) |
| .addPcscfServerRequest(PCSCF_IPV4_ADDRESS_1) |
| .addPcscfServerRequest(PCSCF_IPV6_ADDRESS_2) |
| .build(); |
| |
| SparseArray<Integer> expectedAttrCounts = new SparseArray<>(); |
| expectedAttrCounts.put(CONFIG_ATTR_IP4_PCSCF, 3); |
| expectedAttrCounts.put(CONFIG_ATTR_IP6_PCSCF, 3); |
| |
| verifyAttrTypes(expectedAttrCounts, sessionParams); |
| } |
| |
| @Test |
| public void testBuildWithoutPcscfAddress() throws Exception { |
| IkeSessionParams sessionParams = |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .setAuthPsk(PSK) |
| .build(); |
| |
| SparseArray<Integer> expectedAttrCounts = new SparseArray<>(); |
| |
| verifyAttrTypes(expectedAttrCounts, sessionParams); |
| } |
| |
| @Test |
| public void testBuildWithoutSaProposal() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .build(); |
| fail("Expected to fail due to absence of SA proposal."); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testBuildWithoutLocalId() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .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 IkeSessionParams.Builder(mMockConnectManager) |
| .setServerHostname(REMOTE_IPV4_HOST_ADDRESS) |
| .addSaProposal(mIkeSaProposal) |
| .setLocalIdentification(mLocalIdentification) |
| .setRemoteIdentification(mRemoteIdentification) |
| .build(); |
| fail("Expected to fail because authentiction method is not set."); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testNonAsciiFqdnAuthentication() throws Exception { |
| try { |
| new IkeFqdnIdentification("¯\\_(ツ)_/¯"); |
| fail("Expected failure based on non-ASCII characters."); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testSetHardLifetimeTooLong() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setLifetimeSeconds( |
| IKE_HARD_LIFETIME_SEC_MAXIMUM + 1, IKE_SOFT_LIFETIME_SEC_DEFAULT); |
| fail("Expected failure because hard lifetime is too long"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testSetHardLifetimeTooShort() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setLifetimeSeconds( |
| IKE_HARD_LIFETIME_SEC_MINIMUM - 1, IKE_SOFT_LIFETIME_SEC_DEFAULT); |
| fail("Expected failure because hard lifetime is too short"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testSetSoftLifetimeTooLong() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setLifetimeSeconds( |
| IKE_HARD_LIFETIME_SEC_DEFAULT, IKE_HARD_LIFETIME_SEC_DEFAULT); |
| fail("Expected failure because soft lifetime is too long"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testSetSoftLifetimeTooShort() throws Exception { |
| try { |
| new IkeSessionParams.Builder(mMockConnectManager) |
| .setLifetimeSeconds(IKE_HARD_LIFETIME_SEC_DEFAULT, 0); |
| fail("Expected failure because soft lifetime is too short"); |
| } catch (IllegalArgumentException expected) { |
| } |
| } |
| |
| @Test |
| public void testExpceptionOnEapOnlyOptionWithoutEapAuth() throws Exception { |
| try { |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) |
| .build(); |
| fail("Expected failure because eap only option added without setting auth config"); |
| } catch (IllegalArgumentException expected) { |
| |
| } |
| } |
| |
| @Test |
| public void testExceptionOnEapOnlyOptionWithEapOnlyUnsafeMethod() throws Exception { |
| try { |
| EapSessionConfig eapSessionConfig = |
| new EapSessionConfig.Builder() |
| .setEapMsChapV2Config(EAP_MSCHAP_V2_USERNAME, EAP_MSCHAP_V2_PASSWORD) |
| .setEapAkaConfig(0, 0) |
| .build(); |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) |
| .setAuthEap(null, eapSessionConfig) |
| .build(); |
| fail("Expected failure because eap only option added without eap only safe method"); |
| } catch (IllegalArgumentException expected) { |
| |
| } |
| } |
| |
| @Test |
| public void testBuildWithEapOnlyOption() throws Exception { |
| EapSessionConfig eapSessionConfig = new EapSessionConfig.Builder() |
| .setEapAkaConfig(0, TelephonyManager.APPTYPE_ISIM) |
| .build(); |
| |
| IkeSessionParams sessionParams = buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) |
| .setAuthEap(null, eapSessionConfig) |
| .build(); |
| |
| assertNotNull(sessionParams); |
| verifyIkeSessionParamsCommon(sessionParams); |
| assertTrue(sessionParams.hasIkeOption(IKE_OPTION_EAP_ONLY_AUTH)); |
| IkeAuthConfig localConfig = sessionParams.getLocalAuthConfig(); |
| assertTrue(localConfig instanceof IkeAuthEapConfig); |
| } |
| |
| @Test |
| public void testBuildWithIke3gppExtension() throws Exception { |
| Ike3gppExtension ike3gppExtension = |
| new Ike3gppExtension( |
| new Ike3gppParams.Builder().build(), mock(Ike3gppDataListener.class)); |
| |
| IkeSessionParams sessionParams = |
| buildWithPskCommon(REMOTE_IPV4_HOST_ADDRESS) |
| .setIke3gppExtension(ike3gppExtension) |
| .build(); |
| assertEquals(ike3gppExtension, sessionParams.getIke3gppExtension()); |
| } |
| |
| private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeAuthConfig config) { |
| PersistableBundle bundle = config.toPersistableBundle(); |
| IkeAuthConfig result = IkeAuthConfig.fromPersistableBundle(bundle); |
| |
| assertEquals(config, result); |
| } |
| |
| @Test |
| public void testPersistableBundleEncodeDecodePskAuth() { |
| verifyPersistableBundleEncodeDecodeIsLossless(new IkeAuthPskConfig(PSK)); |
| } |
| |
| @Test |
| public void testPersistableBundleEncodeDecodeAuthDigitalSignRemote() throws Exception { |
| X509Certificate caCert = CertUtils.createCertFromPemFile("self-signed-ca-b.pem"); |
| verifyPersistableBundleEncodeDecodeIsLossless(new IkeAuthDigitalSignRemoteConfig(caCert)); |
| } |
| |
| @Test |
| public void testPersistableBundleEncodeDecodeAuthDigitalSignRemoteWithoutCaCert() |
| throws Exception { |
| verifyPersistableBundleEncodeDecodeIsLossless(new IkeAuthDigitalSignRemoteConfig(null)); |
| } |
| |
| @Test |
| public void testEqualsAuthConfigDigitalSignRemote() throws Exception { |
| X509Certificate caCert = CertUtils.createCertFromPemFile("self-signed-ca-b.pem"); |
| assertEquals( |
| new IkeAuthDigitalSignRemoteConfig(caCert), |
| new IkeAuthDigitalSignRemoteConfig(caCert)); |
| assertEquals( |
| new IkeAuthDigitalSignRemoteConfig(null), new IkeAuthDigitalSignRemoteConfig(null)); |
| assertNotEquals( |
| new IkeAuthDigitalSignRemoteConfig(caCert), |
| new IkeAuthDigitalSignRemoteConfig(null)); |
| } |
| |
| @Test |
| public void testPersistableBundleEncodeDecodeAuthDigitalSignLocal() throws Exception { |
| X509Certificate endCert = CertUtils.createCertFromPemFile("end-cert-b.pem"); |
| X509Certificate intermediateCertOne = |
| CertUtils.createCertFromPemFile("intermediate-ca-b-one.pem"); |
| X509Certificate intermediateCertTwo = |
| CertUtils.createCertFromPemFile("intermediate-ca-b-two.pem"); |
| PrivateKey key = CertUtils.createRsaPrivateKeyFromKeyFile("end-cert-key-a.key"); |
| |
| verifyPersistableBundleEncodeDecodeIsLossless( |
| new IkeAuthDigitalSignLocalConfig( |
| endCert, Arrays.asList(intermediateCertOne, intermediateCertTwo), key)); |
| } |
| |
| @Test |
| public void testPersistableBundleEncodeDecodeAuthEap() { |
| EapSessionConfig eapSessionConfig = |
| new EapSessionConfig.Builder() |
| .setEapAkaConfig(SUB_ID, TelephonyManager.APPTYPE_ISIM) |
| .build(); |
| verifyPersistableBundleEncodeDecodeIsLossless(new IkeAuthEapConfig(eapSessionConfig)); |
| } |
| |
| @Test |
| public void testConstructBuilderWithIkeSessionParams() throws Exception { |
| IkeSessionParams sessionParams = createIkeParamsBuilderMinimum().build(); |
| |
| IkeSessionParams result = new IkeSessionParams.Builder(sessionParams).build(); |
| assertEquals(sessionParams, result); |
| } |
| |
| @Test |
| public void testCreateCopyWithNetworkCleared() throws Exception { |
| IkeSessionParams sessionParams = |
| createIkeParamsBuilderMinimum() |
| .setConfiguredNetwork(mMockUserConfigNetwork) |
| .build(); |
| |
| IkeSessionParams result = |
| new IkeSessionParams.Builder(sessionParams).setConfiguredNetwork(null).build(); |
| assertNull(result.getConfiguredNetwork()); |
| } |
| } |