aboutsummaryrefslogtreecommitdiff
path: root/tests/iketests/src/java/com/android
diff options
context:
space:
mode:
Diffstat (limited to 'tests/iketests/src/java/com/android')
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/TunnelModeChildSessionOptionsTest.java48
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/crypto/IkeCombinedModeCipherTest.java160
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java26
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java71
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java235
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/testutils/CertUtils.java22
6 files changed, 524 insertions, 38 deletions
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/TunnelModeChildSessionOptionsTest.java b/tests/iketests/src/java/com/android/ike/ikev2/TunnelModeChildSessionOptionsTest.java
index a67d44f9..5ed6480c 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/TunnelModeChildSessionOptionsTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/TunnelModeChildSessionOptionsTest.java
@@ -20,8 +20,12 @@ import static android.system.OsConstants.AF_INET;
import static android.system.OsConstants.AF_INET6;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
+import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
+import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
+import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS;
+import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
@@ -52,6 +56,11 @@ public final class TunnelModeChildSessionOptionsTest {
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 ChildSaProposal mSaProposal;
@Before
@@ -130,4 +139,43 @@ public final class TunnelModeChildSessionOptionsTest {
}
}
+
+ @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> exptectedAttrCntMap = new SparseArray<>();
+ exptectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_DNS, 2);
+ exptectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_DNS, 2);
+
+ verifyAttrTypes(exptectedAttrCntMap, 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> exptectedAttrCntMap = new SparseArray<>();
+ exptectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_SUBNET, 1);
+ exptectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_SUBNET, 1);
+
+ verifyAttrTypes(exptectedAttrCntMap, childOptions);
+ }
}
+
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/crypto/IkeCombinedModeCipherTest.java b/tests/iketests/src/java/com/android/ike/ikev2/crypto/IkeCombinedModeCipherTest.java
new file mode 100644
index 00000000..a7ff2990
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/crypto/IkeCombinedModeCipherTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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 com.android.ike.ikev2.crypto;
+
+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 android.net.IpSecAlgorithm;
+
+import com.android.ike.TestUtils;
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.message.IkeMessage;
+import com.android.ike.ikev2.message.IkeSaPayload.EncryptionTransform;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.util.Arrays;
+import java.util.Random;
+
+import javax.crypto.AEADBadTagException;
+
+@RunWith(JUnit4.class)
+public final class IkeCombinedModeCipherTest {
+ private static final String IV = "fbd69d9de2dafc5e";
+ private static final String ENCRYPTED_PADDED_DATA_WITH_CHECKSUM =
+ "f4109834e9f3559758c05edf119917521b885f67f0d14ced43";
+ private static final String UNENCRYPTED_PADDED_DATA = "000000080000400f00";
+ private static final String ADDITIONAL_AUTH_DATA =
+ "77c708b4523e39a471dc683c1d4f21362e202508000000060000004129000025";
+ private static final String KEY =
+ "7C04513660DEC572D896105254EF92608054F8E6EE19E79CE52AB8697B2B5F2C2AA90C29";
+
+ private static final int AES_GCM_IV_LEN = 8;
+ private static final int AES_GCM_16_CHECKSUM_LEN = 128;
+
+ private IkeCombinedModeCipher mAesGcm16Cipher;
+
+ private byte[] mAesGcmKey;
+ private byte[] mIv;
+ private byte[] mEncryptedPaddedDataWithChecksum;
+ private byte[] mUnencryptedPaddedData;
+ private byte[] mAdditionalAuthData;
+
+ @Before
+ public void setUp() {
+ mAesGcm16Cipher =
+ (IkeCombinedModeCipher)
+ IkeCipher.create(
+ new EncryptionTransform(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ SaProposal.KEY_LEN_AES_256),
+ IkeMessage.getSecurityProvider());
+
+ mAesGcmKey = TestUtils.hexStringToByteArray(KEY);
+ mIv = TestUtils.hexStringToByteArray(IV);
+ mEncryptedPaddedDataWithChecksum =
+ TestUtils.hexStringToByteArray(ENCRYPTED_PADDED_DATA_WITH_CHECKSUM);
+ mUnencryptedPaddedData = TestUtils.hexStringToByteArray(UNENCRYPTED_PADDED_DATA);
+ mAdditionalAuthData = TestUtils.hexStringToByteArray(ADDITIONAL_AUTH_DATA);
+ }
+
+ @Test
+ public void testBuild() throws Exception {
+ assertTrue(mAesGcm16Cipher.isAead());
+ assertEquals(AES_GCM_IV_LEN, mAesGcm16Cipher.generateIv().length);
+ }
+
+ @Test
+ public void testGenerateRandomIv() throws Exception {
+ assertFalse(Arrays.equals(mAesGcm16Cipher.generateIv(), mAesGcm16Cipher.generateIv()));
+ }
+
+ @Test
+ public void testEncrypt() throws Exception {
+ byte[] calculatedData =
+ mAesGcm16Cipher.encrypt(
+ mUnencryptedPaddedData, mAdditionalAuthData, mAesGcmKey, mIv);
+
+ assertArrayEquals(mEncryptedPaddedDataWithChecksum, calculatedData);
+ }
+
+ @Test
+ public void testDecrypt() throws Exception {
+ byte[] calculatedData =
+ mAesGcm16Cipher.decrypt(
+ mEncryptedPaddedDataWithChecksum, mAdditionalAuthData, mAesGcmKey, mIv);
+
+ assertArrayEquals(mUnencryptedPaddedData, calculatedData);
+ }
+
+ @Test
+ public void testEncryptWithWrongKeyLen() throws Exception {
+ byte[] encryptionKey = TestUtils.hexStringToByteArray(KEY + "00");
+
+ try {
+ mAesGcm16Cipher.encrypt(
+ mUnencryptedPaddedData, mAdditionalAuthData, encryptionKey, mIv);
+ fail("Expected to fail because encryption key has wrong length.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+
+ @Test
+ public void testDecrypWithWrongKey() throws Exception {
+ byte[] encryptionKey = new byte[mAesGcmKey.length];
+ new Random().nextBytes(encryptionKey);
+
+ try {
+ mAesGcm16Cipher.decrypt(
+ mEncryptedPaddedDataWithChecksum, mAdditionalAuthData, encryptionKey, mIv);
+ fail("Expected to fail because decryption key is wrong");
+ } catch (AEADBadTagException expected) {
+
+ }
+ }
+
+ @Test
+ public void testBuildIpSecAlgorithm() throws Exception {
+ IpSecAlgorithm ipsecAlgorithm = mAesGcm16Cipher.buildIpSecAlgorithmWithKey(mAesGcmKey);
+
+ IpSecAlgorithm expectedIpSecAlgorithm =
+ new IpSecAlgorithm(
+ IpSecAlgorithm.AUTH_CRYPT_AES_GCM, mAesGcmKey, AES_GCM_16_CHECKSUM_LEN);
+
+ assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm));
+ }
+
+ @Test
+ public void buildIpSecAlgorithmWithInvalidKey() throws Exception {
+ byte[] encryptionKey = TestUtils.hexStringToByteArray(KEY + "00");
+
+ try {
+ mAesGcm16Cipher.buildIpSecAlgorithmWithKey(encryptionKey);
+ fail("Expected to fail because encryption key has wrong length.");
+ } catch (IllegalArgumentException expected) {
+
+ }
+ }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java
index 52f9259a..239bd504 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java
@@ -16,6 +16,8 @@
package com.android.ike.ikev2.message;
+import static com.android.ike.ikev2.message.IkeAuthDigitalSignPayload.SIGNATURE_ALGO_RSA_SHA2_256;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@@ -31,6 +33,7 @@ import com.android.ike.ikev2.testutils.CertUtils;
import org.junit.Before;
import org.junit.Test;
+import java.security.PrivateKey;
import java.security.cert.X509Certificate;
public final class IkeAuthDigitalSignPayloadTest {
@@ -92,9 +95,7 @@ public final class IkeAuthDigitalSignPayloadTest {
assertTrue(payload instanceof IkeAuthDigitalSignPayload);
IkeAuthDigitalSignPayload dsPayload = (IkeAuthDigitalSignPayload) payload;
- assertEquals(
- IkeAuthDigitalSignPayload.SIGNATURE_ALGO_RSA_SHA2_256,
- dsPayload.signatureAlgoAndHash);
+ assertEquals(SIGNATURE_ALGO_RSA_SHA2_256, dsPayload.signatureAlgoAndHash);
assertArrayEquals(dsPayload.signature, TestUtils.hexStringToByteArray(SIGNATURE));
}
@@ -136,7 +137,24 @@ public final class IkeAuthDigitalSignPayloadTest {
PRF_RESP_KEY);
fail("Expected to fail due to wrong certificate.");
} catch (AuthenticationFailedException expected) {
-
}
}
+
+ @Test
+ public void testGenerateSignature() throws Exception {
+ PrivateKey key = CertUtils.createRsaPrivateKeyFromKeyFile("end-cert-key-a.key");
+
+ IkeAuthDigitalSignPayload authPayload =
+ new IkeAuthDigitalSignPayload(
+ SIGNATURE_ALGO_RSA_SHA2_256,
+ key,
+ IKE_INIT_RESP_REQUEST,
+ NONCE_INIT_RESP,
+ ID_RESP_PAYLOAD_BODY,
+ mIkeHmacSha1Prf,
+ PRF_RESP_KEY);
+
+ assertEquals(SIGNATURE_ALGO_RSA_SHA2_256, authPayload.signatureAlgoAndHash);
+ assertArrayEquals(authPayload.signature, TestUtils.hexStringToByteArray(SIGNATURE));
+ }
}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
index 9ee6a620..e8a67d79 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeConfigPayloadTest.java
@@ -17,6 +17,7 @@
package com.android.ike.ikev2.message;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
+import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
import static com.android.ike.ikev2.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
@@ -47,6 +48,7 @@ import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttrIpv4AddressBase;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttrIpv6AddrRangeBase;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttribute;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttributeIpv4Address;
+import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttributeIpv4Dns;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
import com.android.ike.ikev2.message.IkeConfigPayload.ConfigAttributeIpv4Subnet;
@@ -104,6 +106,13 @@ public final class IkeConfigPayloadTest {
private static final byte[] IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE =
TestUtils.hexStringToByteArray("00030000");
+ private static final Inet4Address IPV4_DHCP =
+ (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
+ private static final byte[] IPV4_DHCP_ATTRIBUTE_WITH_VALUE =
+ TestUtils.hexStringToByteArray("00060004c00002c8");
+ private static final byte[] IPV4_DHCP_ATTRIBUTE_WITHOUT_VALUE =
+ TestUtils.hexStringToByteArray("00060000");
+
private static final byte[] IPV4_SUBNET_ATTRIBUTE_VALUE =
TestUtils.hexStringToByteArray("c0000264fffffff0");
private static final byte[] IPV4_SUBNET_ATTRIBUTE_WITH_VALUE =
@@ -420,6 +429,44 @@ public final class IkeConfigPayloadTest {
}
@Test
+ public void testDecodeIpv4DhcpWithValue() throws Exception {
+ ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp(IPV4_DHCP.getAddress());
+
+ assertEquals(CONFIG_ATTR_INTERNAL_IP4_DHCP, attribute.attributeType);
+ assertEquals(IPV4_DHCP, attribute.address);
+ }
+
+ @Test
+ public void testDecodeIpv4DhcpWithoutValue() throws Exception {
+ ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp(new byte[0]);
+
+ assertEquals(CONFIG_ATTR_INTERNAL_IP4_DHCP, attribute.attributeType);
+ assertNull(attribute.address);
+ }
+
+ @Test
+ public void testEncodeIpv4DhcpWithValue() throws Exception {
+ ConfigAttributeIpv4Dhcp attributeIp4Dhcp = new ConfigAttributeIpv4Dhcp(IPV4_DHCP);
+
+ verifyEncodeIpv4AddresBaseAttribute(
+ attributeIp4Dhcp,
+ CONFIG_ATTR_INTERNAL_IP4_DHCP,
+ IPV4_DHCP_ATTRIBUTE_WITH_VALUE,
+ IPV4_DHCP);
+ }
+
+ @Test
+ public void testEncodeIpv4DhcpWithoutValue() throws Exception {
+ ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp();
+
+ verifyEncodeIpv4AddresBaseAttribute(
+ attribute,
+ CONFIG_ATTR_INTERNAL_IP4_DHCP,
+ IPV4_DHCP_ATTRIBUTE_WITHOUT_VALUE,
+ null /*expectedAddress*/);
+ }
+
+ @Test
public void testDecodeIpv4SubnetWithValue() throws Exception {
ConfigAttributeIpv4Subnet attributeIp4Subnet =
new ConfigAttributeIpv4Subnet(IPV4_SUBNET_ATTRIBUTE_VALUE);
@@ -450,18 +497,6 @@ public final class IkeConfigPayloadTest {
}
@Test
- public void testEncodeIpv4SubnetWithValue() throws Exception {
- ConfigAttributeIpv4Subnet attributeIp4Subnet =
- new ConfigAttributeIpv4Subnet(IPV4_LINK_ADDRESS);
-
- verifyBuildAndEncodeAttributeCommon(
- attributeIp4Subnet,
- CONFIG_ATTR_INTERNAL_IP4_SUBNET,
- IPV4_SUBNET_ATTRIBUTE_WITH_VALUE);
- assertEquals(IPV4_LINK_ADDRESS, attributeIp4Subnet.linkAddress);
- }
-
- @Test
public void testEncodeIpv4SubnetWithoutValue() throws Exception {
ConfigAttributeIpv4Subnet attributeIp4Subnet = new ConfigAttributeIpv4Subnet();
@@ -559,18 +594,6 @@ public final class IkeConfigPayloadTest {
}
@Test
- public void testEncodeIpv6SubnetWithValue() throws Exception {
- ConfigAttributeIpv6Subnet attributeIp6Subnet =
- new ConfigAttributeIpv6Subnet(IPV6_LINK_ADDRESS);
-
- verifyEncodeIpv6RangeBaseAttribute(
- attributeIp6Subnet,
- CONFIG_ATTR_INTERNAL_IP6_SUBNET,
- IPV6_SUBNET_ATTRIBUTE_WITH_VALUE,
- IPV6_LINK_ADDRESS);
- }
-
- @Test
public void testEncodeIpv6SubnetWithoutValue() throws Exception {
ConfigAttributeIpv6Subnet attributeIp6Subnet = new ConfigAttributeIpv6Subnet();
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java
index 24e9e986..c43a8594 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.fail;
import com.android.ike.TestUtils;
import com.android.ike.ikev2.SaProposal;
import com.android.ike.ikev2.crypto.IkeCipher;
+import com.android.ike.ikev2.crypto.IkeCombinedModeCipher;
import com.android.ike.ikev2.crypto.IkeMacIntegrity;
import com.android.ike.ikev2.crypto.IkeNormalModeCipher;
import com.android.ike.ikev2.message.IkeSaPayload.EncryptionTransform;
@@ -34,7 +35,6 @@ import java.security.GeneralSecurityException;
import java.util.Arrays;
public final class IkeEncryptedPayloadBodyTest {
-
private static final String IKE_AUTH_INIT_REQUEST_HEADER =
"5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec";
private static final String IKE_AUTH_INIT_REQUEST_SK_HEADER = "230000d0";
@@ -83,6 +83,85 @@ public final class IkeEncryptedPayloadBodyTest {
private static final String HMAC_SHA1_3DES_MSG_INTE_KEY =
"867a0bd019108db856cf6984fc9fb62d70c0de74";
+ // TODO: b/142753861 Test IKE fragment protected by AES_CBC instead of 3DES
+
+ // Test vectors for IKE fragment protected by HmacSha1 and 3DES
+ private static final String HMAC_SHA1_3DES_FRAG_HEX_STRING =
+ "939ae1251d18eb9077a99551b15c6e933520232000000001"
+ + "000000c0000000a400050005fd7c7931705af184b7be76bb"
+ + "d45a8ecbb3ffd58b9438b93f67e9fe86b06229f80e9b52d2"
+ + "ff6afde3f2c13ae93ce55a801f62e1a818c9003880a36bbe"
+ + "986fe6979ba233b9f4f0ddc992d06dbad5a2b998be18fae9"
+ + "47e5ccfb37775d069344e711fbf499bb289cf4cca245bd45"
+ + "0ad89d18689207759507ba18d47247e920b9e000a25a7596"
+ + "e4130929e5cdc37d5c1b0d90bbaae946c260f4d3cf815f6d";
+ private static final String HMAC_SHA1_3DES_FRAG_DECRYPTED_BODY_HEX_STRING =
+ "54ebd95c572100002002000000000100040a0a0a01000300"
+ + "040808080800030004080804042c00002c00000028020304"
+ + "03cc86090a0300000c0100000c800e010003000008030000"
+ + "0200000008050000002d00001801000000070000100000ff"
+ + "ff0a0a0a010a0a0a010000001801000000070000100000ff"
+ + "ff00000000ffffffff";
+ private static final String HMAC_SHA1_3DES_FRAG_IV = "fd7c7931705af184";
+ private static final String HMAC_SHA1_3DES_FRAG_PADDING = "dcf0fa5e2b64";
+
+ private static final int HMAC_SHA1_3DES_FRAGMENT_NUM = 5;
+ private static final int HMAC_SHA1_3DES_TOTAL_FRAGMENTS = 5;
+
+ private static final String HMAC_SHA1_3DES_FRAG_ENCR_KEY =
+ "6BBF6CB3526D6492F4DA0AF45E9B9FD3E1FF534280352073";
+ private static final String HMAC_SHA1_3DES_FRAG_INTE_KEY =
+ "293449E8E518060780B9C06F15838A06EEF57814";
+
+ // Test vectors for IKE message protected by AES_GCM_16
+ private static final String AES_GCM_MSG_HEX_STRING =
+ "77c708b4523e39a471dc683c1d4f21362e20230800000005"
+ + "0000006127000045fbd69d9ee2dafc5e7c03a0106761065b2"
+ + "8fa8d11aed6046f7f8af117e44da7635be6e0dfafcb0a387c"
+ + "53fb46ba5d6fa9509161915929de97b7fbe23dc65723b0fe";
+ private static final String AES_GCM_MSG_DECRYPTED_BODY_HEX_STRING =
+ "000000280200000033233837e909ec805d56151bef5b1fa9b8e25b32419c9b3fc96ee699ec29d501";
+ private static final String AES_GCM_MSG_IV = "fbd69d9ee2dafc5e";
+ private static final String AES_GCM_MSG_ENCR_KEY =
+ "7C04513660DEC572D896105254EF92608054F8E6EE19E79CE52AB8697B2B5F2C2AA90C29";
+
+ // Test vectors for IKE fragment protected by AES_GCM_16
+ private static final String AES_GCM_FRAG_HEX_STRING =
+ "77c708b4523e39a471dc683c1d4f213635202320000000010"
+ + "0000113000000f7000200026faf9e5c04c67571871681d443"
+ + "01489f99fd78d318b0517a5a99bf6a3e1770f43d7d997c9e0"
+ + "d186038d16df3fd525eda821f80b3a40fc6bce397ac67539e"
+ + "40042919a5e9af38c70881d092a8571f0e131f594c0e8d6b8"
+ + "4ea116f0c95619439b0a267b35bc47dac72bbfb3d3776feb3"
+ + "86d7d4f819b0248f52f60bf4371ab6384e37819a9685c27d8"
+ + "e41abe30cd6f60905dd5c05c351ec0a1fcf9b99360161d2f3"
+ + "4dcf6401829df9392121d88e2201d279200e25d750678af6a"
+ + "7f4892a5c8d4a7358ec50cdf12cfa7652488f756ba6d07441"
+ + "e9a27aad3976ac8a705ff796857cb2df9ce360c3992e0285b"
+ + "34834255b06";
+ private static final String AES_GCM_FRAG_DECRYPTED_BODY_HEX_STRING =
+ "0fce6e996f4936ec8db8097339c371c686be75f4bed3f259c"
+ + "14d39c3ad90cb864085c6375f75b724d9f9daa8e7b22a106a"
+ + "488bc48c081997b7416fd33b146882e51ff6a640edf760212"
+ + "7f2454d502e92262ba3dd07cff52ee1bb1ea85f582db41a68"
+ + "aaf6dace362e5d8b10cfeb65eebc7572690e2c415a11cae57"
+ + "020810cf7aa56d9f2d5c2be3a633f8e4c6af5483a2b1f05bd"
+ + "4340ab551ddf7f51def57eaf5a37793ff6aa1e1ec288a2adf"
+ + "a647c369f15efa61a619966a320f24e1765c0e00c5ed394aa"
+ + "ef14512032b005827c000000090100000501";
+ private static final String AES_GCM_FRAG_IV = "6faf9e5c04c67571";
+
+ private static final int AES_GCM_FRAGMENT_NUM = 2;
+ private static final int AES_GCM_TOTAL_FRAGMENTS = 2;
+
+ private static final String AES_GCM_FRAG_ENCR_KEY =
+ "955ED949D6F18857220E97B17D9285C830A39F8D4DC46AB43943668093C62A3D66664F8C";
+
+ private static final int ENCRYPTED_BODY_SK_OFFSET =
+ IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH;
+ private static final int ENCRYPTED_BODY_SKF_OFFSET =
+ ENCRYPTED_BODY_SK_OFFSET + IkeSkfPayload.SKF_HEADER_LEN;
+
private IkeNormalModeCipher mAesCbcCipher;
private byte[] mAesCbcKey;
@@ -98,7 +177,18 @@ public final class IkeEncryptedPayloadBodyTest {
private byte[] mIv;
private byte[] mPadding;
- // TODO: Add tests for authenticating and decrypting received message.
+ private IkeNormalModeCipher m3DesCipher;
+
+ private IkeCombinedModeCipher mAesGcm16Cipher;
+
+ private byte[] mAesGcmMsgKey;
+ private byte[] mAesGcmMsg;
+ private byte[] mAesGcmUnencryptedData;
+
+ private byte[] mAesGcmFragKey;
+ private byte[] mAesGcmFragMsg;
+ private byte[] mAesGcmFragUnencryptedData;
+
@Before
public void setUp() throws Exception {
mDataToPadAndEncrypt =
@@ -123,6 +213,12 @@ public final class IkeEncryptedPayloadBodyTest {
mIv = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_IV);
mPadding = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_PADDING);
+ m3DesCipher =
+ (IkeNormalModeCipher)
+ IkeCipher.create(
+ new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES),
+ IkeMessage.getSecurityProvider());
+
mAesCbcCipher =
(IkeNormalModeCipher)
IkeCipher.create(
@@ -137,6 +233,24 @@ public final class IkeEncryptedPayloadBodyTest {
new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96),
IkeMessage.getSecurityProvider());
mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP);
+
+ mAesGcm16Cipher =
+ (IkeCombinedModeCipher)
+ IkeCipher.create(
+ new EncryptionTransform(
+ SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
+ SaProposal.KEY_LEN_AES_256),
+ IkeMessage.getSecurityProvider());
+
+ mAesGcmMsgKey = TestUtils.hexStringToByteArray(AES_GCM_MSG_ENCR_KEY);
+ mAesGcmMsg = TestUtils.hexStringToByteArray(AES_GCM_MSG_HEX_STRING);
+ mAesGcmUnencryptedData =
+ TestUtils.hexStringToByteArray(AES_GCM_MSG_DECRYPTED_BODY_HEX_STRING);
+
+ mAesGcmFragKey = TestUtils.hexStringToByteArray(AES_GCM_FRAG_ENCR_KEY);
+ mAesGcmFragMsg = TestUtils.hexStringToByteArray(AES_GCM_FRAG_HEX_STRING);
+ mAesGcmFragUnencryptedData =
+ TestUtils.hexStringToByteArray(AES_GCM_FRAG_DECRYPTED_BODY_HEX_STRING);
}
@Test
@@ -217,6 +331,7 @@ public final class IkeEncryptedPayloadBodyTest {
new IkeEncryptedPayloadBody(
ikeHeader,
IkePayload.PAYLOAD_TYPE_ID_INITIATOR,
+ new byte[0] /*skfHeader*/,
mDataToPadAndEncrypt,
mHmacSha1IntegrityMac,
mAesCbcCipher,
@@ -238,7 +353,7 @@ public final class IkeEncryptedPayloadBodyTest {
IkeEncryptedPayloadBody payloadBody =
new IkeEncryptedPayloadBody(
mIkeMessage,
- IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH,
+ ENCRYPTED_BODY_SK_OFFSET,
mHmacSha1IntegrityMac,
mAesCbcCipher,
mHmacSha1IntegrityKey,
@@ -252,20 +367,122 @@ public final class IkeEncryptedPayloadBodyTest {
byte[] message = TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_HEX_STRING);
byte[] expectedDecryptedData =
TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_DECRYPTED_BODY_HEX_STRING);
- IkeCipher tripleDesCipher =
- IkeCipher.create(
- new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES),
- IkeMessage.getSecurityProvider());
IkeEncryptedPayloadBody payloadBody =
new IkeEncryptedPayloadBody(
message,
- IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH,
+ ENCRYPTED_BODY_SK_OFFSET,
mHmacSha1IntegrityMac,
- tripleDesCipher,
+ m3DesCipher,
TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_INTE_KEY),
TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_ENCR_KEY));
assertArrayEquals(expectedDecryptedData, payloadBody.getUnencryptedData());
}
+
+ @Test
+ public void testBuildAndEncodeWithHmacSha13Des() throws Exception {
+ byte[] message = TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_HEX_STRING);
+ IkeHeader ikeHeader = new IkeHeader(message);
+
+ byte[] skfHeaderBytes =
+ IkeSkfPayload.encodeSkfHeader(
+ HMAC_SHA1_3DES_FRAGMENT_NUM, HMAC_SHA1_3DES_TOTAL_FRAGMENTS);
+
+ IkeEncryptedPayloadBody payloadBody =
+ new IkeEncryptedPayloadBody(
+ ikeHeader,
+ IkePayload.PAYLOAD_TYPE_NO_NEXT,
+ skfHeaderBytes,
+ TestUtils.hexStringToByteArray(
+ HMAC_SHA1_3DES_FRAG_DECRYPTED_BODY_HEX_STRING),
+ mHmacSha1IntegrityMac,
+ m3DesCipher,
+ TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_INTE_KEY),
+ TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_ENCR_KEY),
+ TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_IV),
+ TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_PADDING));
+
+ byte[] expectedEncodedData =
+ Arrays.copyOfRange(message, ENCRYPTED_BODY_SKF_OFFSET, message.length);
+
+ assertArrayEquals(expectedEncodedData, payloadBody.encode());
+ }
+
+ @Test
+ public void testAuthAndDecodeFullMsgWithAesGcm() throws Exception {
+ IkeEncryptedPayloadBody encryptedBody =
+ new IkeEncryptedPayloadBody(
+ mAesGcmMsg,
+ ENCRYPTED_BODY_SK_OFFSET,
+ null /*integrityMac*/,
+ mAesGcm16Cipher,
+ null /*integrityKey*/,
+ mAesGcmMsgKey);
+
+ assertArrayEquals(mAesGcmUnencryptedData, encryptedBody.getUnencryptedData());
+ }
+
+ @Test
+ public void testBuildAndEncodeMsgWithAesGcm() throws Exception {
+ IkeHeader ikeHeader = new IkeHeader(mAesGcmMsg);
+
+ IkeEncryptedPayloadBody payloadBody =
+ new IkeEncryptedPayloadBody(
+ ikeHeader,
+ IkePayload.PAYLOAD_TYPE_AUTH,
+ new byte[0],
+ mAesGcmUnencryptedData,
+ null /*integrityMac*/,
+ mAesGcm16Cipher,
+ null /*integrityKey*/,
+ mAesGcmMsgKey,
+ TestUtils.hexStringToByteArray(AES_GCM_MSG_IV),
+ new byte[0] /*padding*/);
+
+ byte[] expectedEncodedData =
+ Arrays.copyOfRange(mAesGcmMsg, ENCRYPTED_BODY_SK_OFFSET, mAesGcmMsg.length);
+
+ assertArrayEquals(expectedEncodedData, payloadBody.encode());
+ }
+
+ @Test
+ public void testAuthAndDecodeFragMsgWithAesGcm() throws Exception {
+ IkeEncryptedPayloadBody encryptedBody =
+ new IkeEncryptedPayloadBody(
+ mAesGcmFragMsg,
+ ENCRYPTED_BODY_SKF_OFFSET,
+ null /*integrityMac*/,
+ mAesGcm16Cipher,
+ null /*integrityKey*/,
+ mAesGcmFragKey);
+
+ assertArrayEquals(mAesGcmFragUnencryptedData, encryptedBody.getUnencryptedData());
+ }
+
+ @Test
+ public void testBuildAndEncodeFragMsgWithAesGcm() throws Exception {
+ IkeHeader ikeHeader = new IkeHeader(mAesGcmFragMsg);
+ byte[] skfHeaderBytes =
+ IkeSkfPayload.encodeSkfHeader(AES_GCM_FRAGMENT_NUM, AES_GCM_TOTAL_FRAGMENTS);
+
+ IkeEncryptedPayloadBody payloadBody =
+ new IkeEncryptedPayloadBody(
+ ikeHeader,
+ IkePayload.PAYLOAD_TYPE_NO_NEXT,
+ skfHeaderBytes,
+ mAesGcmFragUnencryptedData,
+ null /*integrityMac*/,
+ mAesGcm16Cipher,
+ null /*integrityKey*/,
+ mAesGcmFragKey,
+ TestUtils.hexStringToByteArray(AES_GCM_FRAG_IV),
+ new byte[0] /*padding*/);
+
+ byte[] expectedEncodedData =
+ Arrays.copyOfRange(
+ mAesGcmFragMsg, ENCRYPTED_BODY_SKF_OFFSET, mAesGcmFragMsg.length);
+
+ assertArrayEquals(expectedEncodedData, payloadBody.encode());
+ }
}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/testutils/CertUtils.java b/tests/iketests/src/java/com/android/ike/ikev2/testutils/CertUtils.java
index e44551a0..e42e5647 100644
--- a/tests/iketests/src/java/com/android/ike/ikev2/testutils/CertUtils.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/testutils/CertUtils.java
@@ -21,14 +21,21 @@ import android.content.Context;
import androidx.test.InstrumentationRegistry;
import com.android.ike.ikev2.message.IkeMessage;
+import com.android.org.bouncycastle.util.io.pem.PemObject;
+import com.android.org.bouncycastle.util.io.pem.PemReader;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.KeyFactory;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.spec.PKCS8EncodedKeySpec;
-/** CertUtils provides utility methods for creating X509 certificate. */
+/** CertUtils provides utility methods for creating X509 certificate and private key. */
public final class CertUtils {
private static final String PEM_FOLDER_NAME = "pem";
+ private static final String KEY_FOLDER_NAME = "key";
/** Creates an X509Certificate with a pem file */
public static X509Certificate createCertFromPemFile(String fileName) throws Exception {
@@ -40,4 +47,17 @@ public final class CertUtils {
CertificateFactory.getInstance("X.509", IkeMessage.getSecurityProvider());
return (X509Certificate) factory.generateCertificate(inputStream);
}
+
+ /** Creates an private key from a PKCS8 format key file */
+ public static RSAPrivateKey createRsaPrivateKeyFromKeyFile(String fileName) throws Exception {
+ Context context = InstrumentationRegistry.getContext();
+ InputStream inputStream =
+ context.getResources().getAssets().open(KEY_FOLDER_NAME + "/" + fileName);
+
+ PemObject pemObject = new PemReader(new InputStreamReader(inputStream)).readPemObject();
+
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return (RSAPrivateKey)
+ keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pemObject.getContent()));
+ }
}