aboutsummaryrefslogtreecommitdiff
path: root/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java')
-rw-r--r--tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java181
1 files changed, 181 insertions, 0 deletions
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
new file mode 100644
index 00000000..1bb0b709
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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 com.android.ike.ikev2.message;
+
+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.ike.ikev2.IkeDhParams;
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.utils.BigIntegerUtils;
+
+import org.junit.Test;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import javax.crypto.spec.DHPrivateKeySpec;
+
+public final class IkeKePayloadTest {
+ private static final String KE_PAYLOAD_GENERIC_HEADER = "28000088";
+ private static final String KE_PAYLOAD_RAW_PACKET =
+ "00020000b4a2faf4bb54878ae21d638512ece55d9236fc50"
+ + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa"
+ + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd"
+ + "92f46bef84f0be7db860351843858f8acf87056e272377f7"
+ + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2"
+ + "6bbeb08214c7071376079587";
+
+ private static final boolean CRITICAL_BIT = false;
+
+ @IkePayload.PayloadType
+ private static final int NEXT_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_NONCE;
+
+ private static final int EXPECTED_DH_GROUP = SaProposal.DH_GROUP_1024_BIT_MODP;
+
+ private static final int EXPECTED_KE_DATA_LEN = 128;
+
+ private static final String KEY_EXCHANGE_DATA_RAW_PACKET =
+ "b4a2faf4bb54878ae21d638512ece55d9236fc5046ab6cef"
+ + "82220f421f3ce6361faf36564ecb6d28798a94aad7b2b4b6"
+ + "03ddeaaa5630adb9ece8ac37534036040610ebdd92f46bef"
+ + "84f0be7db860351843858f8acf87056e272377f70c9f2d81"
+ + "e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c26bbeb082"
+ + "14c7071376079587";
+
+ private static final String PRIME_1024_BIT_MODP_160_SUBGROUP =
+ "B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C6"
+ + "9A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C0"
+ + "13ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD70"
+ + "98488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0"
+ + "A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708"
+ + "DF1FB2BC2E4A4371";
+ private static final String GENERATOR_1024_BIT_MODP_160_SUBGROUP =
+ "A4D1CBD5C3FD34126765A442EFB99905F8104DD258AC507F"
+ + "D6406CFF14266D31266FEA1E5C41564B777E690F5504F213"
+ + "160217B4B01B886A5E91547F9E2749F4D7FBD7D3B9A92EE1"
+ + "909D0D2263F80A76A6A24C087A091F531DBF0A0169B6A28A"
+ + "D662A4D18E73AFA32D779D5918D08BC8858F4DCEF97C2A24"
+ + "855E6EEB22B3B2E5";
+ private static final String PRIVATE_KEY_LOCAL = "B9A3B3AE8FEFC1A2930496507086F8455D48943E";
+ private static final String PUBLIC_KEY_REMOTE =
+ "717A6CB053371FF4A3B932941C1E5663F861A1D6AD34AE66"
+ + "576DFB98F6C6CBF9DDD5A56C7833F6BCFDFF095582AD868E"
+ + "440E8D09FD769E3CECCDC3D3B1E4CFA057776CAAF9739B6A"
+ + "9FEE8E7411F8D6DAC09D6A4EDB46CC2B5D5203090EAE6126"
+ + "311E53FD2C14B574E6A3109A3DA1BE41BDCEAA186F5CE067"
+ + "16A2B6A07B3C33FE";
+ private static final String EXPECTED_SHARED_KEY =
+ "5C804F454D30D9C4DF85271F93528C91DF6B48AB5F80B3B5"
+ + "9CAAC1B28F8ACBA9CD3E39F3CB614525D9521D2E644C53B8"
+ + "07B810F340062F257D7D6FBFE8D5E8F072E9B6E9AFDA9413"
+ + "EAFB2E8B0699B1FB5A0CACEDDEAEAD7E9CFBB36AE2B42083"
+ + "5BD83A19FB0B5E96BF8FA4D09E345525167ECD9155416F46"
+ + "F408ED31B63C6E6D";
+ private static final String KEY_EXCHANGE_ALGORITHM = "DH";
+
+ @Test
+ public void testDecodeIkeKePayload() throws Exception {
+ byte[] inputPacket = TestUtils.hexStringToByteArray(KE_PAYLOAD_RAW_PACKET);
+
+ IkeKePayload payload = new IkeKePayload(CRITICAL_BIT, inputPacket);
+
+ assertFalse(payload.isOutbound);
+ assertEquals(EXPECTED_DH_GROUP, payload.dhGroup);
+
+ byte[] keyExchangeData = TestUtils.hexStringToByteArray(KEY_EXCHANGE_DATA_RAW_PACKET);
+ assertEquals(keyExchangeData.length, payload.keyExchangeData.length);
+ for (int i = 0; i < keyExchangeData.length; i++) {
+ assertEquals(keyExchangeData[i], payload.keyExchangeData[i]);
+ }
+ }
+
+ @Test
+ public void testDecodeIkeKePayloadWithInvalidKeData() throws Exception {
+ // Cut bytes of KE data from original KE payload
+ String badKeyPayloadPacket =
+ KE_PAYLOAD_RAW_PACKET.substring(0, KE_PAYLOAD_RAW_PACKET.length() - 2);
+ byte[] inputPacket = TestUtils.hexStringToByteArray(badKeyPayloadPacket);
+
+ try {
+ IkeKePayload payload = new IkeKePayload(CRITICAL_BIT, inputPacket);
+ fail("Expected InvalidSyntaxException: KE data length doesn't match its DH group type");
+ } catch (InvalidSyntaxException expected) {
+ }
+ }
+
+ @Test
+ public void testEncodeIkeKePayload() throws Exception {
+ byte[] inputPacket = TestUtils.hexStringToByteArray(KE_PAYLOAD_RAW_PACKET);
+ IkeKePayload payload = new IkeKePayload(CRITICAL_BIT, inputPacket);
+
+ ByteBuffer byteBuffer = ByteBuffer.allocate(payload.getPayloadLength());
+ payload.encodeToByteBuffer(NEXT_PAYLOAD_TYPE, byteBuffer);
+
+ byte[] expectedKePayload =
+ TestUtils.hexStringToByteArray(KE_PAYLOAD_GENERIC_HEADER + KE_PAYLOAD_RAW_PACKET);
+ assertArrayEquals(expectedKePayload, byteBuffer.array());
+ }
+
+ @Test
+ public void testGetIkeKePayload() throws Exception {
+ IkeKePayload payload = new IkeKePayload(SaProposal.DH_GROUP_1024_BIT_MODP);
+
+ // Test DHPrivateKeySpec
+ assertTrue(payload.isOutbound);
+ DHPrivateKeySpec privateKeySpec = payload.localPrivateKey;
+
+ BigInteger primeValue = privateKeySpec.getP();
+ BigInteger expectedPrimeValue = new BigInteger(IkeDhParams.PRIME_1024_BIT_MODP, 16);
+ assertEquals(0, expectedPrimeValue.compareTo(primeValue));
+
+ BigInteger genValue = privateKeySpec.getG();
+ BigInteger expectedGenValue = BigInteger.valueOf(IkeDhParams.BASE_GENERATOR_MODP);
+ assertEquals(0, expectedGenValue.compareTo(genValue));
+
+ // Test IkeKePayload
+ assertEquals(EXPECTED_DH_GROUP, payload.dhGroup);
+ assertEquals(EXPECTED_KE_DATA_LEN, payload.keyExchangeData.length);
+ }
+
+ // Since we didn't find test data for DH group types supported in current IKE library, we use
+ // test data for "1024-bit MODP Group with 160-bit Prime Order Subgroup" from RFC 5114. The main
+ // difference is that it uses weaker Prime and Generator values and requires more complicated
+ // recipient test in real Key Exchange process. But it is suitable for testing.
+ @Test
+ public void testGetSharedkey() throws Exception {
+ BigInteger primeValue =
+ BigIntegerUtils.unsignedHexStringToBigInteger(PRIME_1024_BIT_MODP_160_SUBGROUP);
+ BigInteger baseGenValue =
+ BigIntegerUtils.unsignedHexStringToBigInteger(GENERATOR_1024_BIT_MODP_160_SUBGROUP);
+ BigInteger privateKeyValue =
+ BigIntegerUtils.unsignedHexStringToBigInteger(PRIVATE_KEY_LOCAL);
+ byte[] remotePublicKey = TestUtils.hexStringToByteArray(PUBLIC_KEY_REMOTE);
+
+ DHPrivateKeySpec privateKeySpec =
+ new DHPrivateKeySpec(privateKeyValue, primeValue, baseGenValue);
+ byte[] sharedKeyBytes = IkeKePayload.getSharedKey(privateKeySpec, remotePublicKey);
+
+ byte[] expectedSharedKeyBytes = TestUtils.hexStringToByteArray(EXPECTED_SHARED_KEY);
+ assertTrue(Arrays.equals(expectedSharedKeyBytes, sharedKeyBytes));
+ }
+}