diff options
Diffstat (limited to 'tests/iketests/src/java/com/android/internal')
114 files changed, 0 insertions, 24037 deletions
diff --git a/tests/iketests/src/java/com/android/internal/net/TestUtils.java b/tests/iketests/src/java/com/android/internal/net/TestUtils.java deleted file mode 100644 index 6dd5ce5e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/TestUtils.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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.internal.net; - -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.spy; - -import com.android.internal.net.utils.Log; - -import java.nio.ByteBuffer; - -/** TestUtils provides utility methods for parsing Hex String and constructing testing Logger. */ -public class TestUtils { - public static byte[] hexStringToByteArray(String hexString) { - int len = hexString.length(); - if (len % 2 != 0) { - throw new IllegalArgumentException("Invalid Hex String"); - } - byte[] data = new byte[len / 2]; - for (int i = 0; i < len; i += 2) { - data[i / 2] = - (byte) - ((Character.digit(hexString.charAt(i), 16) << 4) - + Character.digit(hexString.charAt(i + 1), 16)); - } - return data; - } - - public static int hexStringToInt(String hexString) { - if (hexString.length() > 8) { - throw new IllegalArgumentException("Invalid hex string length for integer type"); - } - - for (int i = hexString.length(); i < 8; i++) { - hexString = "0" + hexString; - } - - return ByteBuffer.wrap(hexStringToByteArray(hexString)).getInt(); - } - - public static String stringToHexString(String s) { - // two hex characters for each char in s - StringBuilder sb = new StringBuilder(s.length() * 2); - char[] chars = s.toCharArray(); - for (char c : chars) { - sb.append(Integer.toHexString(c)); - } - return sb.toString(); - } - - public static Log makeSpyLogThrowExceptionForWtf(String tag) { - Log spyLog = spy(new Log(tag, true /*logSensitive*/)); - - doAnswer( - (invocation) -> { - throw new IllegalStateException((String) invocation.getArguments()[1]); - }) - .when(spyLog) - .wtf(anyString(), anyString()); - - doAnswer( - (invocation) -> { - throw (Throwable) invocation.getArguments()[2]; - }) - .when(spyLog) - .wtf(anyString(), anyString(), anyObject()); - - return spyLog; - } - - public static Log makeSpyLogDoLogErrorForWtf(String tag) { - Log spyLog = spy(new Log(tag, true /*logSensitive*/)); - - doAnswer( - (invocation) -> { - spyLog.e( - "Mock logging WTF: " + invocation.getArguments()[0], - (String) invocation.getArguments()[1]); - return null; - }) - .when(spyLog) - .wtf(anyString(), anyString()); - - doAnswer( - (invocation) -> { - spyLog.e( - "Mock logging WTF: " + invocation.getArguments()[0], - (String) invocation.getArguments()[1], - (Throwable) invocation.getArguments()[2]); - return null; - }) - .when(spyLog) - .wtf(anyString(), anyString(), anyObject()); - - return spyLog; - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java deleted file mode 100644 index 0872b67f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * 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.internal.net.eap; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.eap.EapSessionConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.statemachine.EapStateMachine; - -import org.junit.Before; -import org.junit.Test; - -public class EapAkaPrimeTest extends EapMethodEndToEndTest { - private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L; - - private static final int SUB_ID = 1; - private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI - - // EAP_IDENTITY = hex("test@android.net") - private static final byte[] EAP_IDENTITY = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = false; - private static final String PEER_NETWORK_NAME_1 = "foo:bar"; - private static final String PEER_NETWORK_NAME_2 = "bar"; - - // hex("foo:bar:buzz") - private static final String SERVER_NETWORK_NAME = "666F6F3A6261723A62757A7A"; - - // TODO(b/142667016): replace with externally generated test values - - // IK: 7320EE404E055EF2B5AB0F86E96C48BE - // CK: E9D1707652E13BF3E05975F601678E5C - // Server Network Name: 666F6F3A6261723A62757A7A - // SQN ^ AK: 35A9143ED9E1 - // IK': 79DC30692F3D2303D148549E5D50D0AA - // CK': BBD0A7AD3F14757BA604C4CBE70F9090 - // K_encr: 4c22c289bcf40367cf2bdb6a6e3fe56b - // K_aut: c64abd508ab628f842e9fb40a14fea769d2ccc67a8412794fe3b4c2556431e78 - // K_re: 5454ccf7ecc227f25c6cd1023e09394fa5cedc14a2f155e9d96a70dc404b4dca - private static final String RAND_1 = "D6A296F030A305601B311D38A004505C"; - private static final String RAND_2 = "000102030405060708090A0B0C0D0E0F"; - private static final String AUTN = "35A9143ED9E100011795E785DAFAAD9B"; - private static final String RES = "E5167A255FDCDE9248AF6B50ADA0D944"; - private static final String AUTS = "0102030405060708090A0B0C0D0E"; - private static final byte[] MSK = - hexStringToByteArray( - "695788d8f33af56b5b2fea065a0e8656" - + "7dc48120d6070d96056f9668614ec3e7" - + "feb4933a3aaab3587980a624998c8b5e" - + "a69d7295b824ef4a2201720be89d04df"); - private static final byte[] EMSK = - hexStringToByteArray( - "2db1f574d6e92cec294779defef5a7f0" - + "49319cc75367102815d0244087f23660" - + "0986b47a862c1aeeca418c84a2f9581b" - + "0738fdefd229a5f7a4ca76709379bf00"); - - // IK: 7320EE404E055EF2B5AB0F86E96C48BE - // CK: E9D1707652E13BF3E05975F601678E5C - // Server Network Name: 666F6F3A6261723A62757A7A - // SQN ^ AK: 35A9143ED9E1 - // IK': 6C45FB0B12FF8172223B6D0E599EAE20 - // CK': A01C894696BEB759ABE0340F71A20D7B - // K_encr: c039213c78fcf78a34bef30219a77822 - // K_aut: 95b014e569144eba71a387f91fb6b72e06781df12d61bfe88e5149477cd232aa - // K_re: 1000c2e2f01766a4d2581ac454e41fce1ee17bcccbc32dfad78815075d884c5e - private static final byte[] MSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "ad75a86586773134dcd9e78e3f75b282" - + "7a42435cb1be7235be58cddc60a0ba19" - + "dd5c30accfdb0db5ef065f46c3c25d7b" - + "9f8703d9493a2dc6fb6563dbdc854658"); - private static final byte[] EMSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "31a3f2bb0e3e831d991dc8666438297f" - + "4a5bc157fc1e31537e5a4927206d7b4b" - + "db830761eea3441d9b90da48aebb9734" - + "d3cbdec96072230a64043f54932a8841"); - - // Base 64 of: [Length][RAND_1][Length][AUTN] - private static final String BASE64_CHALLENGE_1 = - "ENailvAwowVgGzEdOKAEUFwQNakUPtnhAAEXleeF2vqtmw=="; - - // Base 64 of: ['DB'][Length][RES][Length][IK][Length][CK] - private static final String BASE_64_RESPONSE_SUCCESS = - "2xDlFnolX9zekkiva1CtoNlEEHMg7kBOBV7ytasPhulsSL4Q6dFwdlLhO/PgWXX2AWeOXA=="; - - // Base 64 of: [Length][RAND_2][Length][AUTN] - private static final String BASE64_CHALLENGE_2 = - "EAABAgMEBQYHCAkKCwwNDg8QNakUPtnhAAEXleeF2vqtmw=="; - - // Base 64 of: ['DC'][Length][AUTS] - private static final String BASE_64_RESPONSE_SYNC_FAIL = "3A4BAgMEBQYHCAkKCwwNDg=="; - - private static final String REQUEST_MAC = "9089f89b2f99bb85f2f2b529779f98db"; - private static final String RESPONSE_MAC = "48d7d6a80e1e2ff26a1e4148e0a2303e"; - private static final String REQUEST_MAC_WITHOUT_IDENTITY_REQ = - "59f680ede020a3d0156eef56affb6997"; - private static final String RESPONSE_MAC_WITHOUT_IDENTITY_REQ = - "e15322ff4abe51479c0fa92d00e343d7"; - - private static final byte[] EAP_AKA_PRIME_IDENTITY_REQUEST = - hexStringToByteArray( - "01CD000C" // EAP-Request | ID | length in bytes - + "32050000" // EAP-AKA' | Identity | 2B padding - + "0D010000"); // AT_ANY_ID_REQ attribute - private static final byte[] EAP_AKA_PRIME_IDENTITY_RESPONSE = - hexStringToByteArray( - "02CD001C" // EAP-Response | ID | length in bytes - + "32050000" // EAP-AKA' | Identity | 2B padding - + "0E05001036313233343536373839414243444546"); // AT_IDENTITY attribute - - private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "32010000" // EAP-AKA' | Challenge | 2B padding - + "01050000" + RAND_1 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute - + "18010001" // AT_KDF attribute - + "0B050000" + REQUEST_MAC); // AT_MAC attribute - private static final byte[] EAP_AKA_PRIME_CHALLENGE_RESPONSE = - hexStringToByteArray( - "02CE0030" // EAP-Response | ID | length in bytes - + "32010000" // EAP-AKA' | Challenge | 2B padding - + "03050080" + RES // AT_RES attribute - + "0B050000" + RESPONSE_MAC); // AT_MAC attribute - - private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "32010000" // EAP-AKA' | Challenge | 2B padding - + "01050000" + RAND_1 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute - + "18010001" // AT_KDF attribute - + "0B050000" + REQUEST_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute - private static final byte[] EAP_AKA_PRIME_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST = - hexStringToByteArray( - "02CE0030" // EAP-Response | ID | length in bytes - + "32010000" // EAP-AKA' | Challenge | 2B padding - + "03050080" + RES // AT_RES attribute - + "0B050000" + RESPONSE_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute - - private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST_SYNC_FAIL = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "32010000" // EAP-AKA' | Challenge | 2B padding - + "01050000" + RAND_2 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute - + "18010001" // AT_KDF attribute - + "0B050000" + REQUEST_MAC); // AT_MAC attribute - private static final byte[] EAP_AKA_PRIME_SYNC_FAIL_RESPONSE = - hexStringToByteArray( - "02CE0018" // EAP-Response | ID | length in bytes - + "32040000" // EAP-AKA' | Synchronization-Failure | 2B padding - + "0404" + AUTS); // AT_AUTS attribute - - private static final byte[] EAP_AKA_PRIME_AUTHENTICATION_REJECT = - hexStringToByteArray( - "02CE0008" // EAP-Response | ID | length in bytes - + "32020000"); // EAP-AKA' | Authentication-Reject | 2B padding - - private static final byte[] EAP_RESPONSE_NAK_PACKET = - hexStringToByteArray("021000060332"); // NAK with EAP-AKA' listed - - private TelephonyManager mMockTelephonyManager; - - @Before - @Override - public void setUp() { - super.setUp(); - - setUp(ALLOW_MISMATCHED_NETWORK_NAMES, PEER_NETWORK_NAME_1); - } - - private void setUp(boolean allowMismatchedNetworkNames, String peerNetworkName) { - mMockTelephonyManager = mock(TelephonyManager.class); - - mEapSessionConfig = - new EapSessionConfig.Builder() - .setEapIdentity(EAP_IDENTITY) - .setEapAkaPrimeConfig( - SUB_ID, APPTYPE_USIM, peerNetworkName, allowMismatchedNetworkNames) - .build(); - mEapAuthenticator = - new EapAuthenticator( - mTestLooper.getLooper(), - mMockCallback, - new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom), - (runnable) -> runnable.run(), - AUTHENTICATOR_TIMEOUT_MILLIS); - - when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)) - .thenReturn(mMockTelephonyManager); - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - } - - @Test - public void testEapAkaPrimeEndToEnd() { - verifyEapPrimeAkaIdentity(); - verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaPrimeEndToEndWithoutIdentityRequest() { - verifyEapAkaPrimeChallengeWithoutIdentityReq(); - verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ); - } - - @Test - public void testEapAkaPrimeWithEapNotifications() { - verifyEapNotification(1); - verifyEapPrimeAkaIdentity(); - - verifyEapNotification(2); - verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE); - - verifyEapNotification(3); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaPrimeUnsupportedType() { - verifyUnsupportedType(EAP_REQUEST_SIM_START_PACKET, EAP_RESPONSE_NAK_PACKET); - - verifyEapPrimeAkaIdentity(); - verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaPrimeSynchronizationFailure() { - verifyEapPrimeAkaIdentity(); - verifyEapAkaPrimeSynchronizationFailure(); - verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaPrimeAuthenticationReject() { - verifyEapPrimeAkaIdentity(); - - // return null from TelephonyManager to simluate rejection of AUTN - verifyEapAkaPrimeChallenge(null, EAP_AKA_PRIME_AUTHENTICATION_REJECT); - verifyEapFailure(); - } - - @Test - public void testEapAkaPrimeMismatchedNetworkNamesNotAllowed() { - // use mismatched peer network name - setUp(false, PEER_NETWORK_NAME_2); - verifyEapPrimeAkaIdentity(); - verifyEapAkaPrimeChallengeMismatchedNetworkNames(); - verifyEapFailure(); - } - - @Test - public void testEapAkaPrimeMismatchedNetworkNamesAllowed() { - setUp(true, PEER_NETWORK_NAME_2); - verifyEapPrimeAkaIdentity(); - verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - private void verifyEapPrimeAkaIdentity() { - // EAP-AKA'/Identity request - when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY); - - mEapAuthenticator.processEapMessage(EAP_AKA_PRIME_IDENTITY_REQUEST); - mTestLooper.dispatchAll(); - - // verify EAP-AKA'/Identity response - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - verify(mMockTelephonyManager).getSubscriberId(); - verify(mMockCallback).onResponse(eq(EAP_AKA_PRIME_IDENTITY_RESPONSE)); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaPrimeChallenge( - String challengeBase64, - String responseBase64, - byte[] incomingEapPacket, - byte[] outgoingEapPacket) { - // EAP-AKA'/Challenge request - when(mMockTelephonyManager.getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - challengeBase64)) - .thenReturn(responseBase64); - - mEapAuthenticator.processEapMessage(incomingEapPacket); - mTestLooper.dispatchAll(); - - // verify EAP-AKA'/Challenge response - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - challengeBase64); - verify(mMockCallback).onResponse(eq(outgoingEapPacket)); - } - - private void verifyEapAkaPrimeChallenge(String responseBase64, byte[] outgoingPacket) { - verifyEapAkaPrimeChallenge( - BASE64_CHALLENGE_1, - responseBase64, - EAP_AKA_PRIME_CHALLENGE_REQUEST, - outgoingPacket); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaPrimeChallengeWithoutIdentityReq() { - verifyEapAkaPrimeChallenge( - BASE64_CHALLENGE_1, - BASE_64_RESPONSE_SUCCESS, - EAP_AKA_PRIME_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ, - EAP_AKA_PRIME_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST); - - // also need to verify interactions with Context and TelephonyManager - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaPrimeSynchronizationFailure() { - verifyEapAkaPrimeChallenge( - BASE64_CHALLENGE_2, - BASE_64_RESPONSE_SYNC_FAIL, - EAP_AKA_PRIME_CHALLENGE_REQUEST_SYNC_FAIL, - EAP_AKA_PRIME_SYNC_FAIL_RESPONSE); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaPrimeChallengeMismatchedNetworkNames() { - // EAP-AKA'/Challenge request - mEapAuthenticator.processEapMessage(EAP_AKA_PRIME_CHALLENGE_REQUEST); - mTestLooper.dispatchAll(); - verify(mMockCallback).onResponse(eq(EAP_AKA_PRIME_AUTHENTICATION_REJECT)); - } - - @Override - protected void verifyEapSuccess(byte[] msk, byte[] emsk) { - super.verifyEapSuccess(msk, emsk); - - verifyNoMoreInteractions(mMockTelephonyManager); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java deleted file mode 100644 index e982a85d..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 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.internal.net.eap; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.eap.EapSessionConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.statemachine.EapStateMachine; - -import org.junit.Before; -import org.junit.Test; - -/** - * This test verifies that EAP-AKA is functional for an end-to-end implementation - */ -public class EapAkaTest extends EapMethodEndToEndTest { - private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L; - - private static final int SUB_ID = 1; - private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI - - // EAP_IDENTITY = hex("test@android.net") - private static final byte[] EAP_IDENTITY = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - // TODO(b/140797965): find valid AUTN/RAND values for the CTS test sim - // IK: 7320EE404E055EF2B5AB0F86E96C48BE - // CK: E9D1707652E13BF3E05975F601678E5C - // MK: 2AE8AD50432246E6ACED9AA0FC794A22CE9CE4BB - // K_encr: DB6F06910D5D19CC9DA5F2687F5C5737 - // K_aut: B20A586592796E08E7408FB53356E9B1 - private static final String RAND_1 = "D6A296F030A305601B311D38A004505C"; - private static final String RAND_2 = "000102030405060708090A0B0C0D0E0F"; - private static final String AUTN = "35A9143ED9E100011795E785DAFAAD9B"; - private static final String RES = "E5167A255FDCDE9248AF6B50ADA0D944"; - private static final String AUTS = "0102030405060708090A0B0C0D0E"; - private static final byte[] MSK = - hexStringToByteArray( - "EFC4FB9F54D99A3F4A04B756993CA813" - + "E463CA0ADBF3CB2A296519ED4C600FF5" - + "81898B1C425C20FE7471FC43A4BB3C00" - + "DDF80A7083972B660BC7153CBF2C9AA1"); - private static final byte[] EMSK = - hexStringToByteArray( - "5C95F3E2476ED4D6588CE6DE2618D808" - + "9ECA12A4636C8A1B0C678562CBFC31D3" - + "94B578DE0A3686E17F96F14D5341FE75" - + "2012944CA394E5288BA1B2C70CB65063"); - - // IK: 7320EE404E055EF2B5AB0F86E96C48BE - // CK: E9D1707652E13BF3E05975F601678E5C - // MK: 8183017CD8ADDB4617F4A2274DD5BCEA99354FB7 - // K_encr: 891D5DB8CACAF657D68BE72371F927A2 - // K_aut: E042A1CC5672358685EC012881EA02DE - private static final byte[] MSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "629DE03704E15EF1B8BADFF7FA5D84D5" - + "8574B6A3A46F274796346A86AE3455AC" - + "711E2D4D3F96EE71E664B1B947D7E9E7" - + "D227CBB6199A68BD7D43E6E4863D08D6"); - private static final byte[] EMSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "30A6638AE3AB5C5D29554D8256C3A287" - + "FDF6255E4D726C0622DDF89609C16A8D" - + "563768166A8111A083547DE4C8E280D6" - + "113A608DE9227FC7C02679A1E04DB3CF"); - - // Base 64 of: [Length][RAND_1][Length][AUTN] - private static final String BASE64_CHALLENGE_1 = - "ENailvAwowVgGzEdOKAEUFwQNakUPtnhAAEXleeF2vqtmw=="; - - // Base 64 of: ['DB'][Length][RES][Length][IK][Length][CK] - private static final String BASE_64_RESPONSE_SUCCESS = - "2xDlFnolX9zekkiva1CtoNlEEHMg7kBOBV7ytasPhulsSL4Q6dFwdlLhO/PgWXX2AWeOXA=="; - - // Base 64 of: [Length][RAND_2][Length][AUTN] - private static final String BASE64_CHALLENGE_2 = - "EAABAgMEBQYHCAkKCwwNDg8QNakUPtnhAAEXleeF2vqtmw=="; - - // Base 64 of: ['DC'][Length][AUTS] - private static final String BASE_64_RESPONSE_SYNC_FAIL = "3A4BAgMEBQYHCAkKCwwNDg=="; - - private static final String REQUEST_MAC = "90C3554783D49A18F9EAA231F3C261EC"; - private static final String RESPONSE_MAC = "D085987D3D15FA50A80D0CECFA2412EB"; - private static final String REQUEST_MAC_WITHOUT_IDENTITY_REQ = - "6AD7E3F43ED99384E751F55AB8EA48B4"; - private static final String RESPONSE_MAC_WITHOUT_IDENTITY_REQ = - "83E9F5B8B44BDE39B50538BF49864209"; - - private static final byte[] EAP_AKA_IDENTITY_REQUEST = - hexStringToByteArray( - "01CD000C" // EAP-Request | ID | length in bytes - + "17050000" // EAP-AKA | Identity | 2B padding - + "0D010000"); // AT_ANY_ID_REQ attribute - private static final byte[] EAP_AKA_IDENTITY_RESPONSE = - hexStringToByteArray( - "02CD001C" // EAP-Response | ID | length in bytes - + "17050000" // EAP-AKA | Identity | 2B padding - + "0E05001030313233343536373839414243444546"); // AT_IDENTITY attribute - - private static final byte[] EAP_AKA_CHALLENGE_REQUEST = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "01050000" + RAND_1 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "0B050000" + REQUEST_MAC); // AT_MAC attribute - private static final byte[] EAP_AKA_CHALLENGE_RESPONSE = - hexStringToByteArray( - "02CE0030" // EAP-Response | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "03050080" + RES // AT_RES attribute - + "0B050000" + RESPONSE_MAC); // AT_MAC attribute - - private static final byte[] EAP_AKA_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "01050000" + RAND_1 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "0B050000" + REQUEST_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute - private static final byte[] EAP_AKA_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST = - hexStringToByteArray( - "02CE0030" // EAP-Response | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "03050080" + RES // AT_RES attribute - + "0B050000" + RESPONSE_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute - - private static final byte[] EAP_AKA_CHALLENGE_REQUEST_SYNC_FAIL = - hexStringToByteArray( - "01CE0044" // EAP-Request | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "01050000" + RAND_2 // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "0B050000" + REQUEST_MAC); // AT_MAC attribute - private static final byte[] EAP_AKA_SYNC_FAIL_RESPONSE = - hexStringToByteArray( - "02CE0018" // EAP-Response | ID | length in bytes - + "17040000" // EAP-AKA | Synchronization-Failure | 2B padding - + "0404" + AUTS); // AT_AUTS attribute - - private static final byte[] EAP_AKA_AUTHENTICATION_REJECT = - hexStringToByteArray( - "02CE0008" // EAP-Response | ID | length in bytes - + "17020000"); // EAP-AKA | Authentication-Reject | 2B padding - - private static final byte[] EAP_RESPONSE_NAK_PACKET = - hexStringToByteArray("021000060317"); // NAK with EAP-AKA listed - - private TelephonyManager mMockTelephonyManager; - - @Before - @Override - public void setUp() { - super.setUp(); - - mMockTelephonyManager = mock(TelephonyManager.class); - - mEapSessionConfig = - new EapSessionConfig.Builder() - .setEapIdentity(EAP_IDENTITY) - .setEapAkaConfig(SUB_ID, APPTYPE_USIM) - .build(); - mEapAuthenticator = - new EapAuthenticator( - mTestLooper.getLooper(), - mMockCallback, - new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom), - (runnable) -> runnable.run(), - AUTHENTICATOR_TIMEOUT_MILLIS); - - when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)) - .thenReturn(mMockTelephonyManager); - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - } - - @Test - public void testEapAkaEndToEnd() { - verifyEapAkaIdentity(); - verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaEndToEndWithoutIdentityRequest() { - verifyEapAkaChallengeWithoutIdentityReq(); - verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ); - } - - @Test - public void testEapAkaWithEapNotifications() { - verifyEapNotification(1); - verifyEapAkaIdentity(); - - verifyEapNotification(2); - verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE); - - verifyEapNotification(3); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaUnsupportedType() { - verifyUnsupportedType(EAP_REQUEST_SIM_START_PACKET, EAP_RESPONSE_NAK_PACKET); - - verifyEapAkaIdentity(); - verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaSynchronizationFailure() { - verifyEapAkaIdentity(); - verifyEapAkaSynchronizationFailure(); - verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapAkaAuthenticationReject() { - verifyEapAkaIdentity(); - - // return null from TelephonyManager to simluate rejection of AUTN - verifyEapAkaChallenge(null, EAP_AKA_AUTHENTICATION_REJECT); - verifyEapFailure(); - } - - private void verifyEapAkaIdentity() { - // EAP-AKA/Identity request - when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY); - - mEapAuthenticator.processEapMessage(EAP_AKA_IDENTITY_REQUEST); - mTestLooper.dispatchAll(); - - // verify EAP-AKA/Identity response - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - verify(mMockTelephonyManager).getSubscriberId(); - verify(mMockCallback).onResponse(eq(EAP_AKA_IDENTITY_RESPONSE)); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaChallenge( - String challengeBase64, - String responseBase64, - byte[] incomingEapPacket, - byte[] outgoingEapPacket) { - // EAP-AKA/Challenge request - when(mMockTelephonyManager.getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - challengeBase64)) - .thenReturn(responseBase64); - - mEapAuthenticator.processEapMessage(incomingEapPacket); - mTestLooper.dispatchAll(); - - // verify EAP-AKA/Challenge response - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - challengeBase64); - verify(mMockCallback).onResponse(eq(outgoingEapPacket)); - } - - private void verifyEapAkaChallenge(String responseBase64, byte[] outgoingPacket) { - verifyEapAkaChallenge( - BASE64_CHALLENGE_1, responseBase64, EAP_AKA_CHALLENGE_REQUEST, outgoingPacket); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaChallengeWithoutIdentityReq() { - verifyEapAkaChallenge( - BASE64_CHALLENGE_1, - BASE_64_RESPONSE_SUCCESS, - EAP_AKA_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ, - EAP_AKA_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST); - - // also need to verify interactions with Context and TelephonyManager - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - private void verifyEapAkaSynchronizationFailure() { - verifyEapAkaChallenge( - BASE64_CHALLENGE_2, - BASE_64_RESPONSE_SYNC_FAIL, - EAP_AKA_CHALLENGE_REQUEST_SYNC_FAIL, - EAP_AKA_SYNC_FAIL_RESPONSE); - verifyNoMoreInteractions( - mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback); - } - - @Override - protected void verifyEapSuccess(byte[] msk, byte[] emsk) { - super.verifyEapSuccess(msk, emsk); - - verifyNoMoreInteractions(mMockTelephonyManager); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java deleted file mode 100644 index 4c868a03..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * 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.internal.net.eap; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.os.Looper; -import android.os.test.TestLooper; - -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.EapResult.EapSuccess; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.statemachine.EapStateMachine; - -import org.junit.Before; -import org.junit.Test; - -import java.util.concurrent.TimeoutException; - -public class EapAuthenticatorTest { - private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L; - private static final long TEST_TIMEOUT_MILLIS = 2 * AUTHENTICATOR_TIMEOUT_MILLIS; - private static final byte[] MSK = hexStringToByteArray( - "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF"); - private static final byte[] EMSK = hexStringToByteArray( - "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100"); - - private EapStateMachine mMockEapStateMachine; - - private TestLooper mTestLooper; - private boolean mCallbackFired; - - @Before - public void setUp() { - if (Looper.myLooper() == null) Looper.prepare(); - - mMockEapStateMachine = mock(EapStateMachine.class); - - mTestLooper = new TestLooper(); - mCallbackFired = false; - } - - @Test - public void testProcessEapMessageResponse() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onResponse(byte[] eapMsg) { - assertArrayEquals(EAP_SIM_RESPONSE_PACKET, eapMsg); - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - - EapResponse eapResponse = new EapResponse(EAP_SIM_RESPONSE_PACKET); - when(mMockEapStateMachine.process(eq(EAP_REQUEST_SIM_START_PACKET))) - .thenReturn(eapResponse); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(EAP_REQUEST_SIM_START_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - @Test - public void testProcessEapMessageError() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onError(Throwable cause) { - assertTrue(cause instanceof EapInvalidRequestException); - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - Exception cause = new EapInvalidRequestException("Error"); - EapError eapError = new EapError(cause); - when(mMockEapStateMachine.process(eq(REQUEST_UNSUPPORTED_TYPE_PACKET))) - .thenReturn(eapError); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(REQUEST_UNSUPPORTED_TYPE_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(REQUEST_UNSUPPORTED_TYPE_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - @Test - public void testProcessEapMessageSuccess() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onSuccess(byte[] msk, byte[] emsk) { - assertArrayEquals(MSK, msk); - assertArrayEquals(EMSK, emsk); - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - EapSuccess eapSuccess = new EapSuccess(MSK, EMSK); - when(mMockEapStateMachine.process(eq(EAP_SUCCESS_PACKET))) - .thenReturn(eapSuccess); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(EAP_SUCCESS_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(EAP_SUCCESS_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - @Test - public void testProcessEapMessageFailure() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onFail() { - // nothing to check here - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - when(mMockEapStateMachine.process(eq(EAP_FAILURE_PACKET))) - .thenReturn(new EapFailure()); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(EAP_FAILURE_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(EAP_FAILURE_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - @Test - public void testProcessEapMessageExceptionThrown() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onError(Throwable cause) { - assertTrue(cause instanceof NullPointerException); - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - when(mMockEapStateMachine.process(EAP_REQUEST_SIM_START_PACKET)) - .thenThrow(new NullPointerException()); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(EAP_REQUEST_SIM_START_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - @Test - public void testProcessEapMessageStateMachineTimeout() { - EapCallback eapCallback = new EapCallback() { - @Override - public void onError(Throwable cause) { - assertTrue(cause instanceof TimeoutException); - assertFalse("Callback has already been fired", mCallbackFired); - mCallbackFired = true; - } - }; - EapResponse eapResponse = new EapResponse(EAP_SIM_RESPONSE_PACKET); - when(mMockEapStateMachine.process(eq(EAP_REQUEST_SIM_START_PACKET))) - .then((invocation) -> { - // move time forward to trigger the timeout - mTestLooper.moveTimeForward(TEST_TIMEOUT_MILLIS); - return eapResponse; - }); - - getEapAuthenticatorWithCallback(eapCallback) - .processEapMessage(EAP_REQUEST_SIM_START_PACKET); - mTestLooper.dispatchAll(); - - assertTrue("Callback didn't fire", mCallbackFired); - verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET)); - verifyNoMoreInteractions(mMockEapStateMachine); - } - - private EapAuthenticator getEapAuthenticatorWithCallback(EapCallback eapCallback) { - return new EapAuthenticator( - mTestLooper.getLooper(), - eapCallback, - mMockEapStateMachine, - (runnable) -> runnable.run(), - AUTHENTICATOR_TIMEOUT_MILLIS); - } - - /** - * Default {@link IEapCallback} implementation that throws {@link UnsupportedOperationException} - * for all calls. - */ - private abstract static class EapCallback implements IEapCallback { - @Override - public void onSuccess(byte[] msk, byte[] emsk) { - throw new UnsupportedOperationException(); - } - - @Override - public void onFail() { - throw new UnsupportedOperationException(); - } - - @Override - public void onResponse(byte[] eapMsg) { - throw new UnsupportedOperationException(); - } - - @Override - public void onError(Throwable cause) { - throw new UnsupportedOperationException(); - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java deleted file mode 100644 index ce497635..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.internal.net.eap; - -import static org.junit.Assert.assertEquals; - -import com.android.internal.net.eap.EapResult.EapError; - -import org.junit.Test; - -public class EapErrorTest { - private static final RuntimeException EXPECTED_EXCEPTION = new RuntimeException("expected"); - - @Test - public void testEapErrorConstructor() { - EapError eapError = new EapError(EXPECTED_EXCEPTION); - assertEquals(EXPECTED_EXCEPTION, eapError.cause); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java deleted file mode 100644 index 412a4cf1..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.internal.net.eap; - -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.content.Context; -import android.net.eap.EapSessionConfig; -import android.os.test.TestLooper; - -import org.junit.Before; - -import java.security.SecureRandom; - -public class EapMethodEndToEndTest { - protected Context mMockContext; - protected SecureRandom mMockSecureRandom; - protected IEapCallback mMockCallback; - - protected TestLooper mTestLooper; - protected EapSessionConfig mEapSessionConfig; - protected EapAuthenticator mEapAuthenticator; - - @Before - public void setUp() { - mMockContext = mock(Context.class); - mMockSecureRandom = mock(SecureRandom.class); - mMockCallback = mock(IEapCallback.class); - - mTestLooper = new TestLooper(); - } - - protected void verifyUnsupportedType(byte[] invalidMessageType, byte[] nakResponse) { - mEapAuthenticator.processEapMessage(invalidMessageType); - mTestLooper.dispatchAll(); - - // verify EAP-Response/Nak returned - verify(mMockCallback).onResponse(eq(nakResponse)); - verifyNoMoreInteractions(mMockCallback); - } - - protected void verifyEapNotification(int callsToVerify) { - mEapAuthenticator.processEapMessage(EAP_REQUEST_NOTIFICATION_PACKET); - mTestLooper.dispatchAll(); - - verify(mMockCallback, times(callsToVerify)) - .onResponse(eq(EAP_RESPONSE_NOTIFICATION_PACKET)); - verifyNoMoreInteractions(mMockCallback); - } - - protected void verifyEapSuccess(byte[] msk, byte[] emsk) { - // EAP-Success - mEapAuthenticator.processEapMessage(EAP_SUCCESS); - mTestLooper.dispatchAll(); - - // verify that onSuccess callback made - verify(mMockCallback).onSuccess(eq(msk), eq(emsk)); - verifyNoMoreInteractions(mMockContext, mMockSecureRandom, mMockCallback); - } - - protected void verifyEapFailure() { - mEapAuthenticator.processEapMessage(EAP_FAILURE_PACKET); - mTestLooper.dispatchAll(); - - verify(mMockCallback).onFail(); - verifyNoMoreInteractions(mMockCallback); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java b/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java deleted file mode 100644 index 01264f9d..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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.internal.net.eap; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA_IDENTITY_PACKET; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; - -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.eap.statemachine.EapStateMachine; - -import org.junit.Before; -import org.junit.Test; - -public class EapMsChapV2Test extends EapMethodEndToEndTest { - private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L; - - private static final String USERNAME = "User"; - private static final String PASSWORD = "clientPass"; - - private static final byte[] PEER_CHALLENGE = - hexStringToByteArray("21402324255E262A28295F2B3A337C7E"); - private static final byte[] MSK = - hexStringToByteArray( - "D5F0E9521E3EA9589645E86051C822268B7CDC149B993A1BA118CB153F56DCCB"); - - // Server-Name = hex("authenticator@android.net") - private static final byte[] EAP_MSCHAP_V2_CHALLENGE_REQUEST = - hexStringToByteArray("01110033" // EAP-Request | ID | length in bytes - + "1A0142" // EAP-MSCHAPv2 | Request | MSCHAPv2 ID - + "002E10" // MS length | Value Size (0x10) - + "5B5D7C7D7B3F2F3E3C2C602132262628" // Authenticator-Challenge - + "61757468656E74696361746F7240616E64726F69642E6E6574"); // Server-Name - private static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE = - hexStringToByteArray("0211003F" // EAP-Response | ID | length in bytes - + "1A0242" // EAP-MSCHAPv2 | Response | MSCHAPv2 ID - + "003A31" // MS length | Value Size (0x31) - + "21402324255E262A28295F2B3A337C7E" // Peer-Challenge - + "0000000000000000" // 8B (reserved) - + "82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF" // NT-Response - + "00" // Flags - + "55736572"); // hex(USERNAME) - private static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST = - hexStringToByteArray("01120047" // EAP-Request | ID | length in bytes - + "1A03420042" // EAP-MSCHAPv2 | Success | MSCHAPv2 ID | MS length - + "533D" // hex("S=") - + "3430374135353839313135464430443632303946" - + "3531304645394330343536363933324344413536" // hex("<auth_string>") - + "204D3D" // hex(" M=") - + "7465737420416E64726F69642031323334"); // hex("test Android 1234") - private static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE = - hexStringToByteArray("02120006" // EAP-Response | ID | length in bytes - + "1A03"); // EAP-MSCHAPv2 | Success - private static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST = - hexStringToByteArray("01130049" // EAP-Request | ID | length in bytes - + "1A04420044" // EAP-MSCHAPv2 | Failure | MSCHAPv2 ID | MS length - + "453D363437" // hex("E=647") - + "20523D31" // hex(" R=1") - + "20433D" // hex(" C=") - + "30303031303230333034303530363037" - + "30383039304130423043304430453046" // hex("<authenticator challenge>") - + "20563D33" // hex(" V=3") - + "204D3D" // hex(" M=") - + "7465737420416E64726F69642031323334"); // hex("test Android 1234") - private static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE = - hexStringToByteArray("02130006" // EAP-Response | ID | length in bytes - + "1A04"); // EAP-MSCHAPv2 | Failure - - private static final byte[] EAP_RESPONSE_NAK_PACKET = hexStringToByteArray("02100006031A"); - - @Before - @Override - public void setUp() { - super.setUp(); - - mEapSessionConfig = - new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build(); - mEapAuthenticator = - new EapAuthenticator( - mTestLooper.getLooper(), - mMockCallback, - new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom), - (runnable) -> runnable.run(), - AUTHENTICATOR_TIMEOUT_MILLIS); - } - - @Test - public void testEapMsChapV2EndToEndSuccess() { - verifyEapMsChapV2Challenge(); - verifyEapMsChapV2SuccessRequest(); - verifyEapSuccess(MSK, new byte[0]); - } - - @Test - public void testEapMsChapV2EndToEndFailure() { - verifyEapMsChapV2Challenge(); - verifyEapMsChapV2FailureRequest(); - verifyEapFailure(); - } - - @Test - public void testEapMsChapV2UnsupportedType() { - verifyUnsupportedType(EAP_REQUEST_AKA_IDENTITY_PACKET, EAP_RESPONSE_NAK_PACKET); - - verifyEapMsChapV2Challenge(); - verifyEapMsChapV2SuccessRequest(); - verifyEapSuccess(MSK, new byte[0]); - } - - @Test - public void verifyEapMsChapV2WithEapNotifications() { - verifyEapNotification(1); - - verifyEapMsChapV2Challenge(); - verifyEapNotification(2); - - verifyEapMsChapV2SuccessRequest(); - verifyEapNotification(3); - - verifyEapSuccess(MSK, new byte[0]); - } - - private void verifyEapMsChapV2Challenge() { - doAnswer(invocation -> { - byte[] dst = invocation.getArgument(0); - System.arraycopy(PEER_CHALLENGE, 0, dst, 0, PEER_CHALLENGE.length); - return null; - }).when(mMockSecureRandom).nextBytes(eq(new byte[PEER_CHALLENGE.length])); - - mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_CHALLENGE_REQUEST); - mTestLooper.dispatchAll(); - - verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_CHALLENGE_RESPONSE)); - verify(mMockSecureRandom).nextBytes(any(byte[].class)); - verifyNoMoreInteractions(mMockCallback); - } - - private void verifyEapMsChapV2SuccessRequest() { - mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_SUCCESS_REQUEST); - mTestLooper.dispatchAll(); - - verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_SUCCESS_RESPONSE)); - verifyNoMoreInteractions(mMockCallback); - } - - private void verifyEapMsChapV2FailureRequest() { - mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_FAILURE_REQUEST); - mTestLooper.dispatchAll(); - - verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_FAILURE_RESPONSE)); - verifyNoMoreInteractions(mMockCallback); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java deleted file mode 100644 index 0c6dd52d..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.internal.net.eap; - -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.InvalidEapResponseException; -import com.android.internal.net.eap.message.EapMessage; - -import org.junit.Before; -import org.junit.Test; - -public class EapResponseTest { - private EapMessage mEapResponse; - private EapMessage mEapSuccess; - - @Before - public void setUp() throws Exception { - mEapResponse = EapMessage.decode(EAP_RESPONSE_NAK_PACKET); - mEapSuccess = EapMessage.decode(EAP_SUCCESS_PACKET); - } - - @Test - public void testGetEapResponse() { - EapResult eapResult = EapResponse.getEapResponse(mEapResponse); - assertTrue(eapResult instanceof EapResponse); - - EapResponse eapResponse = (EapResponse) eapResult; - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet); - } - - @Test - public void testGetEapResponseNullMessage() { - try { - EapResponse.getEapResponse(null); - fail("Expected IllegalArgumentException for null EapMessage"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testGetEapResponseNonRequestMessage() { - EapResult eapResult = EapResponse.getEapResponse(mEapSuccess); - assertTrue(eapResult instanceof EapError); - - EapError eapError = (EapError) eapResult; - assertTrue(eapError.cause instanceof InvalidEapResponseException); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java deleted file mode 100644 index 8b11d278..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * 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.internal.net.eap; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA_IDENTITY_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.eap.EapSessionConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.statemachine.EapStateMachine; - -import org.junit.Before; -import org.junit.Test; - -/** - * This test verifies that EAP-SIM is functional for an end-to-end implementation - */ -public class EapSimTest extends EapMethodEndToEndTest { - private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L; - - private static final byte[] NONCE = hexStringToByteArray("37f3ddd3954c4831a5ee08c574844398"); - private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI - - // EAP_IDENTITY = hex("test@android.net") - private static final byte[] EAP_IDENTITY = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - private static final int SUB_ID = 1; - - // Base 64 of: RAND - private static final String BASE64_RAND_1 = "EAEjRWeJq83vESNFZ4mrze8="; - private static final String BASE64_RAND_2 = "EBEjRWeJq83vESNFZ4mrze8="; - private static final String BASE64_RAND_3 = "ECEjRWeJq83vESNFZ4mrze8="; - - // BASE 64 of: "04" + SRES + "08" + KC - // SRES 1: 0ABCDEF0 KC 1: FEDCBA9876543210 - // SRES 2: 1ABCDEF1 KC 2: FEDCBA9876543211 - // SRES 3: 2ABCDEF2 KC 3: FEDCBA9876543212 - private static final String BASE64_RESP_1 = "BAq83vAI/ty6mHZUMhA="; - private static final String BASE64_RESP_2 = "BBq83vEI/ty6mHZUMhE="; - private static final String BASE64_RESP_3 = "BCq83vII/ty6mHZUMhI="; - - // MK: 202FC68A3335E8A939A33BC0A0EA8C435DC10060 - // K_encr: F63E152461391FF655C2632E35D076ED - // K_aut: 48E001C8DBA37120FD0465153A56F712 - private static final byte[] MSK = - hexStringToByteArray( - "9B1E2B6892BC113F6B6D0B5789DD8ADD" - + "B83BE2A84AA50FCAECD0003F92D8DA16" - + "4BF983C923695C309F1D7D68DB6992B0" - + "76EA8CE7129647A6F198F3A6AA8ADED9"); - private static final byte[] EMSK = hexStringToByteArray( - "88210b6724400313539c740f417076b0" - + "41da7e64658ec365bd2901a7cd7c2763" - + "dad1a0508b92a42fdf85ac53c6f7e756" - + "7f99b62bcaf467441b567f19b58d86ae"); - - // MK: ED275A588A4C1AEC15C55261DCCD851189E5C5FD - // K_encr: FED573CFA6FC81267C08E264F50A0BB9 - // K_aut: 277B5D6A68FE5156A387996510AC5D61 - private static final byte[] MSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "8023A49840433464DA1A4F2457FAB3D6" - + "B1A3CA6E5E1DB212FA1AEA17F0A5C933" - + "5541DE7448FE448AC3F09DC25BBAE1EE" - + "17DCE3D32099519CC75840F0E3FB612B"); - private static final byte[] EMSK_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "F7E213F0E8F14A21C87F9B5DFADA9A75" - + "A8EAF4AD718BF8C3ED6557BDB60E4671" - + "E6AE109448B2F32F9B984667AE6C2B3F" - + "2FDFE67F97AF4D4727A2EA37F06B7785"); - - private static final byte[] EAP_SIM_START_REQUEST = hexStringToByteArray( - "01850014120a0000" // EAP header - + "0f02000200010000" // AT_VERSION_LIST attribute - + "0d010000"); // AT_ANY_ID_REQ attribute - private static final byte[] EAP_SIM_START_RESPONSE = hexStringToByteArray( - "02850034120a0000" // EAP header - + "0705000037f3ddd3954c4831a5ee08c574844398" // AT_NONCE_MT attribute - + "10010001" // AT_SELECTED_VERSION attribute - + "0e05001031313233343536373839414243444546"); // AT_IDENTITY attribute - private static final byte[] EAP_SIM_CHALLENGE_REQUEST = hexStringToByteArray( - "01860050120b0000" // EAP header - + "010d0000" // AT_RAND attribute - + "0123456789abcdef1123456789abcdef" // Rand 1 - + "1123456789abcdef1123456789abcdef" // Rand 2 - + "2123456789abcdef1123456789abcdef" // Rand 3 - + "0b050000e4675b17fa7ba4d93db48d1af9ecbb01"); // AT_MAC attribute - private static final byte[] EAP_SIM_CHALLENGE_RESPONSE = - hexStringToByteArray( - "0286001c120b0000" // EAP header - + "0b050000e5df9cb1d935ea5f54d449a038bed061"); // AT_MAC attribute - - private static final byte[] EAP_SIM_START_REQUEST_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "01850010" // EAP-Request | ID | length in bytes - + "120a0000" // EAP-SIM | Start| 2B padding - + "0f02000200010000"); // AT_VERSION_LIST attribute - private static final byte[] EAP_SIM_START_RESPONSE_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "02850020" // EAP-Response | ID | length in bytes - + "120a0000" // EAP-SIM | Start | 2B padding - + "0705000037f3ddd3954c4831a5ee08c574844398" // AT_NONCE_MT attribute - + "10010001"); // AT_SELECTED_VERSION attribute - private static final byte[] EAP_SIM_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "01860050" // EAP-Request | ID | length in bytes - + "120b0000" // EAP-SIM | Challenge | 2B padding - + "010d0000" // AT_RAND attribute - + "0123456789abcdef1123456789abcdef" // Rand 1 - + "1123456789abcdef1123456789abcdef" // Rand 2 - + "2123456789abcdef1123456789abcdef" // Rand 3 - + "0b050000F2F8C10FCA946AAFE9555E2BD3693DF6"); // AT_MAC attribute - private static final byte[] EAP_SIM_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQ = - hexStringToByteArray( - "0286001c" // EAP-Response | ID | length in bytes - + "120b0000" // EAP-SIM | Challenge | 2B padding - + "0b050000DAC3C1B7D9DBFBC923464A94F186E410"); // AT_MAC attribute - - private TelephonyManager mMockTelephonyManager; - - @Before - @Override - public void setUp() { - super.setUp(); - - mMockTelephonyManager = mock(TelephonyManager.class); - - mEapSessionConfig = - new EapSessionConfig.Builder() - .setEapIdentity(EAP_IDENTITY) - .setEapSimConfig(SUB_ID, APPTYPE_USIM) - .build(); - mEapAuthenticator = - new EapAuthenticator( - mTestLooper.getLooper(), - mMockCallback, - new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom), - (runnable) -> runnable.run(), - AUTHENTICATOR_TIMEOUT_MILLIS); - } - - @Test - public void testEapSimEndToEnd() { - verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true); - verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void testEapSimEndToEndWithoutIdentityRequest() { - verifyEapSimStart( - EAP_SIM_START_REQUEST_WITHOUT_IDENTITY_REQ, - EAP_SIM_START_RESPONSE_WITHOUT_IDENTITY_REQ, - false); - verifyEapSimChallenge( - EAP_SIM_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ, - EAP_SIM_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQ); - verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ); - } - - @Test - public void testEapSimUnsupportedType() { - verifyUnsupportedType(EAP_REQUEST_AKA_IDENTITY_PACKET, EAP_RESPONSE_NAK_PACKET); - - verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true); - verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE); - verifyEapSuccess(MSK, EMSK); - } - - @Test - public void verifyEapSimWithEapNotifications() { - verifyEapNotification(1); - verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true); - - verifyEapNotification(2); - verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE); - verifyEapNotification(3); - verifyEapSuccess(MSK, EMSK); - } - - private void verifyEapSimStart( - byte[] incomingEapPacket, byte[] outgoingEapPacket, boolean expectIdentityRequest) { - // EAP-SIM/Start request - when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)) - .thenReturn(mMockTelephonyManager); - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY); - doAnswer(invocation -> { - byte[] dst = invocation.getArgument(0); - System.arraycopy(NONCE, 0, dst, 0, NONCE.length); - return null; - }).when(mMockSecureRandom).nextBytes(eq(new byte[NONCE.length])); - - mEapAuthenticator.processEapMessage(incomingEapPacket); - mTestLooper.dispatchAll(); - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - - if (expectIdentityRequest) { - verify(mMockTelephonyManager).getSubscriberId(); - } - - verify(mMockSecureRandom).nextBytes(any(byte[].class)); - - // verify EAP-SIM/Start response - verify(mMockCallback).onResponse(eq(outgoingEapPacket)); - verifyNoMoreInteractions( - mMockContext, - mMockTelephonyManager, - mMockSecureRandom, - mMockCallback); - } - - private void verifyEapSimChallenge(byte[] incomingEapPacket, byte[] outgoingEapPacket) { - // EAP-SIM/Challenge request - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE64_RAND_1)) - .thenReturn(BASE64_RESP_1); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE64_RAND_2)) - .thenReturn(BASE64_RESP_2); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE64_RAND_3)) - .thenReturn(BASE64_RESP_3); - - mEapAuthenticator.processEapMessage(incomingEapPacket); - mTestLooper.dispatchAll(); - - // verify EAP-SIM/Challenge response - verify(mMockTelephonyManager) - .getIccAuthentication( - eq(TelephonyManager.APPTYPE_USIM), - eq(TelephonyManager.AUTHTYPE_EAP_SIM), - eq(BASE64_RAND_1)); - verify(mMockTelephonyManager) - .getIccAuthentication( - eq(TelephonyManager.APPTYPE_USIM), - eq(TelephonyManager.AUTHTYPE_EAP_SIM), - eq(BASE64_RAND_2)); - verify(mMockTelephonyManager) - .getIccAuthentication( - eq(TelephonyManager.APPTYPE_USIM), - eq(TelephonyManager.AUTHTYPE_EAP_SIM), - eq(BASE64_RAND_3)); - verify(mMockCallback).onResponse(eq(outgoingEapPacket)); - verifyNoMoreInteractions( - mMockContext, - mMockTelephonyManager, - mMockSecureRandom, - mMockCallback); - } - - @Override - protected void verifyEapSuccess(byte[] msk, byte[] emsk) { - super.verifyEapSuccess(msk, emsk); - - verifyNoMoreInteractions(mMockTelephonyManager); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java deleted file mode 100644 index d7410540..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.internal.net.eap; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.fail; - -import com.android.internal.net.eap.EapResult.EapSuccess; - -import org.junit.Test; - -public class EapSuccessTest { - public static final byte[] MSK = new byte[] {(byte) 1, (byte) 2, (byte) 3}; - public static final byte[] EMSK = new byte[] {(byte) 4, (byte) 5, (byte) 6}; - - @Test - public void testEapSuccessConstructor() { - EapSuccess eapSuccess = new EapSuccess(MSK, EMSK); - assertArrayEquals(MSK, eapSuccess.msk); - assertArrayEquals(EMSK, eapSuccess.emsk); - } - - @Test - public void testEapSuccessConstructorNullMsk() { - try { - new EapSuccess(null, EMSK); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testEapSuccessConstructorNullEmsk() { - try { - new EapSuccess(MSK, null); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java b/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java deleted file mode 100644 index de058d15..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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.internal.net.eap; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import android.net.eap.EapSessionConfig; - -import java.util.HashMap; - -/** - * EapTestUtils is a util class for providing test-values of EAP-related objects. - */ -public class EapTestUtils { - /** - * Creates and returns a dummy EapSessionConfig instance. - * - * @return a new, empty EapSessionConfig instance - */ - public static EapSessionConfig getDummyEapSessionConfig() { - return new EapSessionConfig(new HashMap<>(), new byte[0]); - } - - /** - * Creates and returns a dummy EapSessionConfig instance with the given EAP-Identity. - * - * @param eapIdentity byte-array representing the EAP-Identity of the client - * @return a new, empty EapSessionConfig instance with the given EAP-Identity - */ - public static EapSessionConfig getDummyEapSessionConfig(byte[] eapIdentity) { - return new EapSessionConfig(new HashMap<>(), eapIdentity); - } - - /** - * Creates and returns a dummy EapSessionConfig instance with EAP-SIM configured. - * - * @return a new EapSessionConfig with EAP-SIM configs set - */ - public static EapSessionConfig getDummyEapSimSessionConfig() { - return new EapSessionConfig.Builder().setEapSimConfig(0, APPTYPE_USIM).build(); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java deleted file mode 100644 index 978f070f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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.internal.net.eap.crypto; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.fail; - -import com.android.internal.net.TestUtils; - -import org.junit.Before; -import org.junit.Test; - -/** - * The test vectors in this file come directly from NIST: - * - * <p>The original link to the test vectors was here: - * http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf - * - * <p>But has since been removed. A cached copy was found here: - * https://web.archive.org/web/20041031202951/http://www.csrc.nist.gov/CryptoToolkit/dss/Examples- - * 1024bit.pdf - */ -public final class Fips186_2PrfTest { - private static final String SEED = "bd029bbe7f51960bcf9edb2b61f06f0feb5a38b6"; - private static final String EXPECTED_RESULT = - "2070b3223dba372fde1c0ffc7b2e3b498b2606143c6c18bacb0f6c55babb13788e20d737a3275116"; - - private Fips186_2Prf mFipsPrf; - - @Before - public void setUp() { - mFipsPrf = new Fips186_2Prf(); - } - - @Test - public void testFips186_2Prf_Invalid_Seed() throws Exception { - try { - mFipsPrf.getRandom(new byte[0], 40); - fail("Expected exception for invalid length seed"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testFips186_2Prf() throws Exception { - byte[] seed = TestUtils.hexStringToByteArray(SEED); - byte[] actual = mFipsPrf.getRandom(seed, 40); - - assertArrayEquals(TestUtils.hexStringToByteArray(EXPECTED_RESULT), actual); - } - - // TODO: (b/136177143) Add more test vectors -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java deleted file mode 100644 index 355c1db1..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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.internal.net.eap.crypto; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -import static org.junit.Assert.assertArrayEquals; - -import org.junit.Before; -import org.junit.Test; - -/** - * HmacSha256ByteSignerTest tests that {@link HmacSha256ByteSigner} correctly signs data using the - * HMAC-SHA-256 algorithm. - * - * <p>These test vectors are defined in RFC 4231#4. - * - * @see <a href="https://tools.ietf.org/html/rfc4231#section-4">Test Vectors</a> - */ -public class HmacSha256ByteSignerTest { - private static final String[] KEYS = { - "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b", - "4a656665", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - "0102030405060708090a0b0c0d0e0f10111213141516171819", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaa", - "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" - + "aaaaaa" - }; - private static final String[] DATA = { - "4869205468657265", - "7768617420646f2079612077616e7420666f72206e6f7468696e673f", - "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd" - + "dddddddddddddddddddddddddddddddddddd", - "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd" - + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd", - "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a" - + "65204b6579202d2048617368204b6579204669727374", - "5468697320697320612074657374207573696e672061206c6172676572207468" - + "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074" - + "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565" - + "647320746f20626520686173686564206265666f7265206265696e6720757365" - + "642062792074686520484d414320616c676f726974686d2e" - }; - private static final String[] MACS = { - "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7", - "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843", - "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe", - "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b", - "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54", - "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2" - }; - - private HmacSha256ByteSigner mMacByteSigner; - - @Before - public void setUp() { - mMacByteSigner = HmacSha256ByteSigner.getInstance(); - } - - @Test - public void testSignBytes() { - for (int i = 0; i < KEYS.length; i++) { - byte[] key = hexStringToByteArray(KEYS[i]); - byte[] data = hexStringToByteArray(DATA[i]); - - byte[] expected = hexStringToByteArray(MACS[i]); - - assertArrayEquals(expected, mMacByteSigner.signBytes(key, data)); - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java deleted file mode 100644 index 7ba024e5..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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.internal.net.eap.crypto; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -/** - * Inputs taken from RFC 2759 Section 9.3. - * - * @see <a href="https://tools.ietf.org/html/rfc2759#section-9.3">RFC 2759 Section 9.3, Examples of - * DES Key Generation</a> - */ -public class ParityBitUtilTest { - private static final byte[] INPUT_BYTES = {(byte) 0xFC, (byte) 0x0E, (byte) 0x7E, (byte) 0x37}; - private static final byte[] OUTPUT_BYTES = {(byte) 0xFD, (byte) 0x0E, (byte) 0x7F, (byte) 0x37}; - - private static final String[] RAW_KEYS = {"FC156AF7EDCD6C", "0EDDE3337D427F"}; - private static final long[] RAW_KEY_LONGS = {0xFC156AF7EDCD6CL, 0xEDDE3337D427FL}; - private static final String[] PARITY_CORRECTED_KEYS = {"FD0B5B5E7F6E34D9", "0E6E796737EA08FE"}; - - @Test - public void testGetByteWithParityBit() { - for (int i = 0; i < INPUT_BYTES.length; i++) { - assertEquals(OUTPUT_BYTES[i], ParityBitUtil.getByteWithParityBit(INPUT_BYTES[i])); - } - } - - @Test - public void testByteArrayToLong() { - for (int i = 0; i < RAW_KEYS.length; i++) { - byte[] rawKey = hexStringToByteArray(RAW_KEYS[i]); - - assertEquals(RAW_KEY_LONGS[i], ParityBitUtil.byteArrayToLong(rawKey)); - } - } - - @Test - public void testAddParityBits() { - for (int i = 0; i < RAW_KEYS.length; i++) { - byte[] rawKey = hexStringToByteArray(RAW_KEYS[i]); - byte[] parityCorrectedKey = hexStringToByteArray(PARITY_CORRECTED_KEYS[i]); - - assertArrayEquals(parityCorrectedKey, ParityBitUtil.addParityBits(rawKey)); - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java deleted file mode 100644 index 9d4cc7ca..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 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.internal.net.eap.message; - -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.assertNotEquals; -import static org.junit.Assert.fail; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class EapDataTest { - private static final byte[] EXPECTED_EAP_DATA_BYTES = new byte[] { - EAP_TYPE_SIM, - (byte) 1, - (byte) 2, - (byte) 3 - }; - private static final byte[] EAP_TYPE_DATA = new byte[] {(byte) 1, (byte) 2, (byte) 3}; - private static final int UNSUPPORTED_EAP_TYPE = -1; - - @Test - public void testEapDataConstructor() { - new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - } - - @Test - public void testEapDataConstructorNullEapData() { - try { - new EapData(EAP_TYPE_SIM, null); - fail("IllegalArgumentException expected for null eapTypeData"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testEapDataConstructorUnsupportedType() { - try { - new EapData(UNSUPPORTED_EAP_TYPE, EAP_TYPE_DATA); - fail("Expected IllegalArgumentException"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testGetLength() { - EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - assertEquals(EAP_TYPE_DATA.length + 1, eapData.getLength()); - } - - @Test - public void testEquals() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - EapData eapDataCopy = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - assertEquals(eapData, eapDataCopy); - - EapData eapDataDifferent = new EapData(EAP_TYPE_SIM, new byte[0]); - assertNotEquals(eapData, eapDataDifferent); - } - - @Test - public void testHashCode() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - EapData eapDataCopy = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - assertNotEquals(0, eapData.hashCode()); - assertEquals(eapData.hashCode(), eapDataCopy.hashCode()); - } - - @Test - public void testEncodeToByteBuffer() { - EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA); - - ByteBuffer b = ByteBuffer.allocate(eapData.getLength()); - eapData.encodeToByteBuffer(b); - assertArrayEquals(EXPECTED_EAP_DATA_BYTES, b.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java deleted file mode 100644 index 813a30f7..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.internal.net.eap.message; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_NAK; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_RESPONSE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_TYPE_DATA; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INCOMPLETE_HEADER_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_CODE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.LONG_SUCCESS_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_MISSING_TYPE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidPacketLengthException; -import com.android.internal.net.eap.exceptions.InvalidEapCodeException; -import com.android.internal.net.eap.exceptions.UnsupportedEapTypeException; - -import org.junit.Test; - -import java.util.Arrays; - -public class EapMessageTest { - @Test - public void testConstructorRequestWithoutType() throws Exception { - try { - new EapMessage(EAP_CODE_REQUEST, ID_INT, null); - fail("Expected EapInvalidPacketLengthException for an EAP-Request without Type value"); - } catch (EapInvalidPacketLengthException expected) { - } - } - - @Test - public void testDecode() throws Exception { - EapMessage result = EapMessage.decode(EAP_SUCCESS_PACKET); - assertEquals(EAP_CODE_SUCCESS, result.eapCode); - assertEquals(ID_INT, result.eapIdentifier); - assertEquals(EAP_SUCCESS_PACKET.length, result.eapLength); - assertNull(result.eapData); - - EapData expectedEapData = new EapData(EAP_TYPE_SIM, - hexStringToByteArray(EAP_REQUEST_SIM_TYPE_DATA)); - result = EapMessage.decode(EAP_REQUEST_SIM_START_PACKET); - assertEquals(EAP_CODE_REQUEST, result.eapCode); - assertEquals(ID_INT, result.eapIdentifier); - assertEquals(EAP_REQUEST_SIM_START_PACKET.length, result.eapLength); - assertEquals(expectedEapData, result.eapData); - } - - @Test - public void testDecodeInvalidCode() throws Exception { - try { - EapMessage.decode(INVALID_CODE_PACKET); - fail("Expected InvalidEapCodeException"); - } catch (InvalidEapCodeException expected) { - } - } - - @Test - public void testDecodeIncompleteHeader() throws Exception { - try { - EapMessage.decode(INCOMPLETE_HEADER_PACKET); - fail("Expected EapInvalidPacketLengthException"); - } catch (EapInvalidPacketLengthException expected) { - } - } - - @Test - public void testDecodeShortPacket() throws Exception { - try { - EapMessage.decode(SHORT_PACKET); - fail("Expected EapInvalidPacketLengthException"); - } catch (EapInvalidPacketLengthException expected) { - } - } - - @Test - public void testDecodeSuccessIncorrectLength() throws Exception { - try { - EapMessage.decode(LONG_SUCCESS_PACKET); - fail("Expected EapInvalidPacketLengthException"); - } catch (EapInvalidPacketLengthException expected) { - } - } - - @Test - public void testDecodeMissingTypeData() throws Exception { - try { - EapMessage.decode(REQUEST_MISSING_TYPE_PACKET); - fail("Expected EapInvalidPacketLengthException"); - } catch (EapInvalidPacketLengthException expected) { - } - } - - @Test - public void testDecodeUnsupportedEapType() throws Exception { - try { - EapMessage.decode(REQUEST_UNSUPPORTED_TYPE_PACKET); - fail("Expected UnsupportedEapDataTypeException"); - } catch (UnsupportedEapTypeException expected) { - assertEquals(ID_INT, expected.eapIdentifier); - } - } - - @Test - public void testEncode() throws Exception { - EapMessage eapMessage = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - byte[] actualPacket = eapMessage.encode(); - assertArrayEquals(EAP_SUCCESS_PACKET, actualPacket); - - EapData nakData = new EapData(EAP_NAK, new byte[] {EAP_TYPE_SIM}); - eapMessage = new EapMessage(EAP_CODE_RESPONSE, ID_INT, nakData); - actualPacket = eapMessage.encode(); - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, actualPacket); - } - - @Test - public void testEncodeDecode() throws Exception { - EapMessage eapMessage = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - EapMessage result = EapMessage.decode(eapMessage.encode()); - - assertEquals(eapMessage.eapCode, result.eapCode); - assertEquals(eapMessage.eapIdentifier, result.eapIdentifier); - assertEquals(eapMessage.eapLength, result.eapLength); - assertEquals(eapMessage.eapData, result.eapData); - } - - @Test - public void testDecodeEncode() throws Exception { - byte[] result = EapMessage.decode(EAP_REQUEST_SIM_START_PACKET).encode(); - assertArrayEquals(EAP_REQUEST_SIM_START_PACKET, result); - } - - @Test - public void testGetNakResponse() { - EapResult nakResponse = EapMessage.getNakResponse(ID_INT, Arrays.asList(EAP_TYPE_SIM)); - - assertTrue(nakResponse instanceof EapResponse); - EapResponse eapResponse = (EapResponse) nakResponse; - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet); - } - - @Test - public void testGetNotificationResponse() { - EapResult notificationResponse = EapMessage.getNotificationResponse(ID_INT); - - assertTrue(notificationResponse instanceof EapResponse); - EapResponse eapResponse = (EapResponse) notificationResponse; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java deleted file mode 100644 index 20517583..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * 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.internal.net.eap.message; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST_DATA; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY_STRING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT_STRING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES; - -/** - * EapTestMessageDefinitions provides byte[] encodings of commonly used EAP Messages. - * - * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication - * Protocol (EAP)</a> - */ -public class EapTestMessageDefinitions { - public static final String ID = "10"; - public static final int ID_INT = Integer.parseInt(ID, 16 /* radix */); - - // EAP-AKA Identity request - public static final String EAP_REQUEST_TYPE_DATA = "0500000D010000"; - public static final byte[] EAP_AKA_IDENTITY_REQUEST = - hexStringToByteArray(EAP_REQUEST_TYPE_DATA); - - // EAP-AKA/Identity request with no attributes - public static final byte[] EAP_REQUEST_AKA = hexStringToByteArray("01" + ID + "000817050000"); - public static final byte[] EAP_REQUEST_AKA_IDENTITY_PACKET = - hexStringToByteArray("01" + ID + "000A17" + EAP_REQUEST_TYPE_DATA); - public static final byte[] EAP_REQUEST_IDENTITY_PACKET = - hexStringToByteArray("01" + ID + "000501"); - - // EAP-Identity: hex for ASCII in "test@android.net" - public static final String EAP_IDENTITY_STRING = "7465737440616E64726F69642E6E6574"; - public static final byte[] EAP_IDENTITY = hexStringToByteArray(EAP_IDENTITY_STRING); - public static final byte[] EAP_RESPONSE_IDENTITY_PACKET = - hexStringToByteArray("02" + ID + "001501" + EAP_IDENTITY_STRING); - public static final byte[] EAP_RESPONSE_IDENTITY_DEFAULT_PACKET = - hexStringToByteArray("02" + ID + "000501"); - public static final byte[] EAP_REQUEST_NOTIFICATION_PACKET = - hexStringToByteArray("01" + ID + "000802AABBCC"); - public static final byte[] EAP_SUCCESS_PACKET = hexStringToByteArray("03" + ID + "0004"); - public static final byte[] EAP_FAILURE_PACKET = hexStringToByteArray("04" + ID + "0004"); - public static final byte[] EAP_SIM_CLIENT_ERROR_RESPONSE = - hexStringToByteArray("02" + ID + "000C120E000016010001"); - public static final byte[] EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES = - hexStringToByteArray("02" + ID + "000C120E000016010002"); - public static final byte[] EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS = - hexStringToByteArray("02" + ID + "000C120E000016010000"); - public static final byte[] EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS = - hexStringToByteArray("02" + ID + "000C170E000016010000"); - - // EAP-SIM response containing SELECTED_VERSION (1) and IDENTITY attributes - public static final byte[] EAP_SIM_RESPONSE_PACKET = hexStringToByteArray( - "02" + ID + "0024120A0000100100010E060011" + IDENTITY_STRING + "000000"); - public static final byte[] EAP_SIM_RESPONSE_WITHOUT_IDENTITY = - hexStringToByteArray("02" + ID + "0020120A000007050000" + NONCE_MT_STRING + "10010001"); - public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE = hexStringToByteArray( - "02" + ID + "0008120C0000"); - public static final byte[] EAP_AKA_NOTIFICATION_RESPONSE = - hexStringToByteArray("02" + ID + "0008170C0000"); - - // Body of EapData is the list of supported methods - public static final byte[] EAP_RESPONSE_NAK_PACKET = - hexStringToByteArray("02" + ID + "00060312"); - public static final byte[] EAP_RESPONSE_NOTIFICATION_PACKET = - hexStringToByteArray("02" + ID + "000502"); - public static final byte[] EAP_REQUEST_MD5_CHALLENGE = - hexStringToByteArray("01" + ID + "000504"); - public static final byte[] EAP_REQUEST_NAK_PACKET = - hexStringToByteArray("01" + ID + "000503"); - public static final String EAP_REQUEST_SIM_TYPE_DATA = "0A00000F02000200010000"; - public static final byte[] EAP_REQUEST_SIM_START_PACKET = - hexStringToByteArray("01" + ID + "001012" + EAP_REQUEST_SIM_TYPE_DATA); - - public static final byte[] REQUEST_UNSUPPORTED_TYPE_PACKET = - hexStringToByteArray("01" + ID + "0005FF"); - public static final byte[] REQUEST_MISSING_TYPE_PACKET = - hexStringToByteArray("01" + ID + "0004"); - public static final byte[] LONG_SUCCESS_PACKET = hexStringToByteArray("03" + ID + "000500"); - public static final byte[] SHORT_PACKET = hexStringToByteArray("01" + ID + "0005"); - public static final byte[] INCOMPLETE_HEADER_PACKET = hexStringToByteArray("03" + ID); - public static final byte[] INVALID_CODE_PACKET = hexStringToByteArray("F0" + ID + "0004"); - - // Attributes - public static final String SKIPPABLE_DATA = "112233445566"; - public static final byte[] SKIPPABLE_DATA_BYTES = hexStringToByteArray(SKIPPABLE_DATA); - public static final byte[] SKIPPABLE_INVALID_ATTRIBUTE = - hexStringToByteArray("FF02" + SKIPPABLE_DATA); - public static final byte[] NON_SKIPPABLE_INVALID_ATTRIBUTE = - hexStringToByteArray("7F010000"); - - // Type-Data - public static final byte[] EAP_SIM_START_SUBTYPE = - hexStringToByteArray("0A00000F02" + AT_VERSION_LIST_DATA + "0A010000"); - public static final byte[] INVALID_SUBTYPE = hexStringToByteArray("FF"); - public static final byte[] TYPE_DATA_INVALID_AT_RAND = - hexStringToByteArray("0A000001050000" + RAND_1); - public static final byte[] SHORT_TYPE_DATA = hexStringToByteArray("0A"); - public static final byte[] TYPE_DATA_INVALID_ATTRIBUTE = - hexStringToByteArray("0A00007F01"); - public static final byte[] EAP_SIM_START_DUPLICATE_ATTRIBUTES = - hexStringToByteArray("0A00000F02" + "0A010000" + "0A010000"); - - // RAND Challenge Results - public static final String SRES_1 = "11223344"; - public static final byte[] SRES_1_BYTES = hexStringToByteArray(SRES_1); - public static final String SRES_2 = "44332211"; - public static final byte[] SRES_2_BYTES = hexStringToByteArray(SRES_2); - public static final byte[] SRES_BYTES = hexStringToByteArray(SRES_1 + SRES_2); - public static final String KC_1 = "0102030405060708"; - public static final byte[] KC_1_BYTES = hexStringToByteArray(KC_1); - public static final String KC_2 = "0807060504030201"; - public static final byte[] KC_2_BYTES = hexStringToByteArray(KC_2); - public static final byte[] VALID_CHALLENGE_RESPONSE = - hexStringToByteArray("04" + SRES_1 + "08" + KC_1); - public static final byte[] CHALLENGE_RESPONSE_INVALID_SRES = hexStringToByteArray("03"); - public static final byte[] CHALLENGE_RESPONSE_INVALID_KC = - hexStringToByteArray("04" + SRES_1 + "04"); - - public static final String IMSI = "123456789012345"; - public static final String EAP_SIM_IDENTITY = "1" + IMSI; - public static final byte[] EAP_SIM_IDENTITY_BYTES = hexStringToByteArray(EAP_SIM_IDENTITY); - - // ASCII hex for "0" + IMSI (EAP-AKA identity format) - public static final String EAP_AKA_IDENTITY_BYTES = "30313233343536373839303132333435"; - - // Master Key generation - public static final String MK_STRING = "0123456789ABCDEF0123456789ABCDEF01234567"; - public static final byte[] MK = hexStringToByteArray(MK_STRING); - public static final String K_ENCR_STRING = "000102030405060708090A0B0C0D0E0F"; - public static final byte[] K_ENCR = hexStringToByteArray(K_ENCR_STRING); - public static final String K_AUT_STRING = "0F0E0D0C0B0A09080706050403020100"; - public static final byte[] K_AUT = hexStringToByteArray(K_AUT_STRING); - public static final String MSK_STRING = - "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF" - + "00112233445566778899AABBCCDDEEFF"; - public static final byte[] MSK = hexStringToByteArray(MSK_STRING); - public static final String EMSK_STRING = - "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100" - + "FFEEDDCCBBAA99887766554433221100"; - public static final byte[] EMSK = hexStringToByteArray(EMSK_STRING); - - // MAC computation - public static final String ORIGINAL_MAC_STRING = "112233445566778899AABBCCDDEEFF11"; - public static final byte[] ORIGINAL_MAC = hexStringToByteArray(ORIGINAL_MAC_STRING); - public static final String COMPUTED_MAC_STRING = "FFEEDDCCBBAA998877665544332211FF"; - public static final byte[] COMPUTED_MAC = hexStringToByteArray(COMPUTED_MAC_STRING); - public static final String EAP_SIM_CHALLENGE_REQUEST_STRING = - "01" + ID + "0040" // EAP-Request | ID | length in bytes - + "120b0000" // EAP-SIM | Challenge | 2B padding - + "01090000" + RAND_1 + RAND_2 // EAP-SIM AT_RAND attribute - + "0B05000000000000000000000000000000000000"; // AT_MAC attribute with no MAC - public static final byte[] MAC_INPUT = - hexStringToByteArray(EAP_SIM_CHALLENGE_REQUEST_STRING + NONCE_MT_STRING); - - // Response Message with MAC - public static final String EAP_SIM_CHALLENGE_RESPONSE_EMPTY_MAC = - "02" + ID + "001C" // EAP-Response | ID | length in bytes - + "120b0000" // EAP-SIM | Challenge | 2B padding - + "0B05000000000000000000000000000000000000"; // AT_MAC attribute with no MAC - public static final byte[] EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT = - hexStringToByteArray(EAP_SIM_CHALLENGE_RESPONSE_EMPTY_MAC + SRES_1 + SRES_2); - public static final byte[] EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC = hexStringToByteArray( - "02" + ID + "001C" // EAP-Response | ID | length in bytes - + "120b0000" // EAP-SIM | Challenge | 2B padding - + "0B050000" + COMPUTED_MAC_STRING); // AT_MAC attribute - public static final byte[] EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC = hexStringToByteArray( - "01" + ID + "0020" // EAP-Request | ID | length in bytes - + "120C0000" // EAP-SIM | Notification | 2B padding - + "0C010000" // AT_NOTIFICATION attribute - + "0B05000000000000000000000000000000000000"); // empty AT_MAC attribute - public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC = hexStringToByteArray( - "02" + ID + "001C" // EAP-Response | ID | length in bytes - + "120C0000" // EAP-SIM | Notification | 2B padding - + "0B05000000000000000000000000000000000000"); // empty AT_MAC attribute - public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC = hexStringToByteArray( - "02" + ID + "001C" // EAP-Response | ID | length in bytes - + "120C0000" // EAP-SIM | Notification | 2B padding - + "0B050000" + COMPUTED_MAC_STRING); // AT_MAC attribute - - public static final byte[] EAP_AKA_IDENTITY_RESPONSE = - hexStringToByteArray("02" + ID + "001C" // EAP-Response | ID | length in bytes - + "17050000" // EAP-AKA | Identity | 2B padding - + "0E050010" + EAP_AKA_IDENTITY_BYTES); // AT_IDENTITY ("0" + IMSI) - - // Base64 of: FF0111 - public static final String EAP_AKA_UICC_RESP_INVALID_TAG = "/wER"; - - // Base64 of: DC0E112233445566778899AABBCCDDEE - public static final String EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64 = "3A4RIjNEVWZ3iJmqu8zd7g=="; - - public static final byte[] EAP_AKA_SYNCHRONIZATION_FAILURE = - hexStringToByteArray("02" + ID + "0018" // EAP-Response | ID | length in bytes - + "17040000" // EAP-SIM | Synchronization-Failure | 2B padding - + "0404112233445566778899AABBCCDDEE"); // AT_AUTS attribute - - public static final String IK = "00112233445566778899AABBCCDDEEFF"; - public static final byte[] IK_BYTES = hexStringToByteArray(IK); - public static final String CK = "FFEEDDCCBBAA99887766554433221100"; - public static final byte[] CK_BYTES = hexStringToByteArray(CK); - - // Base-64 of: 'DB05' + RES_BYTES + '10' + IK + '10' + CK - // 'DB0511223344551000112233445566778899AABBCCDDEEFF10FFEEDDCCBBAA99887766554433221100' - public static final String EAP_AKA_UICC_RESP_SUCCESS_BASE_64 = - "2wURIjNEVRAAESIzRFVmd4iZqrvM3e7/EP/u3cy7qpmId2ZVRDMiEQA="; - - public static final byte[] EAP_AKA_AUTHENTICATION_REJECT = - hexStringToByteArray("02" + ID + "000817020000"); - public static final String EAP_AKA_CHALLENGE_RESPONSE_MAC = "C70366512D9C5EBA8E3484509A25DCE4"; - public static final byte[] EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES = - hexStringToByteArray(EAP_AKA_CHALLENGE_RESPONSE_MAC); - public static final byte[] EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA = - hexStringToByteArray( - "01000003030028" + RES + "0000000B050000" + EAP_AKA_CHALLENGE_RESPONSE_MAC); - public static final byte[] EAP_AKA_CHALLENGE_RESPONSE = - hexStringToByteArray( - "02100028" // EAP-Response | ID | length in bytes - + "17010000" // EAP-AKA | Challenge | 2B padding - + "03030028" + RES + "000000" // AT_RES attribute - + "0B050000" + EAP_AKA_CHALLENGE_RESPONSE_MAC); // AT_MAC attribute - - public static final byte[] EAP_SUCCESS = hexStringToByteArray("03860004"); - - public static final byte[] EAP_REQUEST_MSCHAP_V2 = - hexStringToByteArray("01" + ID + "00061A01"); - - // MSCHAPv2 Test vectors taken from RFC 2759#9.2 and RFC 3079#3.5.3 - public static final String MSCHAP_V2_USERNAME = "User"; - public static final String MSCHAP_V2_USERNAME_HEX = "55736572"; - public static final byte[] MSCHAP_V2_USERNAME_ASCII_BYTES = - hexStringToByteArray(MSCHAP_V2_USERNAME_HEX); - public static final String MSCHAP_V2_PASSWORD = "clientPass"; - public static final byte[] MSCHAP_V2_PASSWORD_UTF_BYTES = - hexStringToByteArray("63006C00690065006E0074005000610073007300"); - public static final String MSCHAP_V2_AUTHENTICATOR_CHALLENGE_STRING = - "5B5D7C7D7B3F2F3E3C2C602132262628"; - public static final byte[] MSCHAP_V2_AUTHENTICATOR_CHALLENGE = - hexStringToByteArray(MSCHAP_V2_AUTHENTICATOR_CHALLENGE_STRING); - public static final String MSCHAP_V2_PEER_CHALLENGE_STRING = "21402324255E262A28295F2B3A337C7E"; - public static final byte[] MSCHAP_V2_PEER_CHALLENGE = - hexStringToByteArray(MSCHAP_V2_PEER_CHALLENGE_STRING); - public static final byte[] MSCHAP_V2_CHALLENGE = hexStringToByteArray("D02E4386BCE91226"); - public static final byte[] MSCHAP_V2_PASSWORD_HASH = - hexStringToByteArray("44EBBA8D5312B8D611474411F56989AE"); - public static final byte[] MSCHAP_V2_PASSWORD_HASH_HASH = - hexStringToByteArray("41C00C584BD2D91C4017A2A12FA59F3F"); - public static final String MSCHAP_V2_NT_RESPONSE_STRING = - "82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF"; - public static final byte[] MSCHAP_V2_NT_RESPONSE = - hexStringToByteArray(MSCHAP_V2_NT_RESPONSE_STRING); - public static final byte[] MSCHAP_V2_AUTHENTICATOR_RESPONSE = - hexStringToByteArray("407A5589115FD0D6209F510FE9C04566932CDA56"); - public static final byte[] MSCHAP_V2_MASTER_KEY = - hexStringToByteArray("FDECE3717A8C838CB388E527AE3CDD31"); - - // generated based on RFC 3079#3.5.3 params - public static final String SEND_KEY = "D5F0E9521E3EA9589645E86051C82226"; - public static final byte[] MSCHAP_V2_SEND_START_KEY = hexStringToByteArray(SEND_KEY); - - // This value is labeled 'send key' in RFC 3079#3.5.3. However, it's used as 'receive key' here, - // because send and receive keys are swapped for peers relative to authenticators. - public static final String RECEIVE_KEY = "8B7CDC149B993A1BA118CB153F56DCCB"; - public static final byte[] MSCHAP_V2_RECEIVE_START_KEY = hexStringToByteArray(RECEIVE_KEY); - - // MSK: MSCHAP_V2_SEND_START_KEY + MSCHAP_V2_RECEIVE_START_KEY - public static final byte[] MSCHAP_V2_MSK = hexStringToByteArray(SEND_KEY + RECEIVE_KEY); - - public static final String MSCHAP_V2_ID = "42"; - public static final int MSCHAP_V2_ID_INT = Integer.parseInt(MSCHAP_V2_ID, 16 /* radix */); - public static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE = - hexStringToByteArray("02" + ID + "003F" // EAP-Response | ID | length in bytes - + "1A02" + MSCHAP_V2_ID // EAP-MSCHAPv2 | Response | MSCHAPv2 ID - + "003A31" // MS length | Value Size (0x31) - + MSCHAP_V2_PEER_CHALLENGE_STRING - + "0000000000000000" // 8B (reserved) - + MSCHAP_V2_NT_RESPONSE_STRING - + "00" // Flags (always 0) - + MSCHAP_V2_USERNAME_HEX); - - public static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE = - hexStringToByteArray("02" + ID + "0006" // EAP-Response | ID | length in bytes - + "1A03"); // EAP-MSCHAPv2 | Success - - public static final byte[] INVALID_AUTHENTICATOR_RESPONSE = new byte[20]; - - public static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE = - hexStringToByteArray("02" + ID + "0006" // EAP-Response | ID | length in bytes - + "1A04"); // EAP-MSCHAPv2 | Failure - - public static final byte[] EAP_AKA_PRIME_REQUEST = - hexStringToByteArray("01" + ID + "000832050000"); - public static final byte[] EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS = - hexStringToByteArray("02" + ID + "000C320E000016010000"); - public static final String EAP_AKA_PRIME_IDENTITY = "36313233343536373839303132333435"; - public static final byte[] EAP_AKA_PRIME_IDENTITY_BYTES = - hexStringToByteArray(EAP_AKA_PRIME_IDENTITY); - public static final byte[] EAP_AKA_PRIME_IDENTITY_RESPONSE = - hexStringToByteArray( - "02" + ID + "001C" // EAP-Response | ID | length in bytes - + "32050000" // EAP-AKA' | Identity | 2B padding - + "0E050010" + EAP_AKA_PRIME_IDENTITY); // AT_IDENTITY ("6" + IMSI) - public static final byte[] EAP_AKA_PRIME_AUTHENTICATION_REJECT = - hexStringToByteArray( - "02" + ID + "0008" // EAP-Response | ID | length in bytes - + "32020000"); // EAP-AKA' | Authentication Reject | 2B padding -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java deleted file mode 100644 index 45a86735..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_LONG_MS_LENGTH; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_SHORT_CHALLENGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_SHORT_MS_LENGTH; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_WRONG_OP_CODE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_CHALLENGE_REQUEST; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_CHALLENGE; - -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.eap.EapResult.EapError; -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.BufferUnderflowException; - -public class EapMsChapV2ChallengeRequestTest { - private static final String TAG = EapMsChapV2ChallengeRequestTest.class.getSimpleName(); - - private EapMsChapV2TypeDataDecoder mTypeDataDecoder; - - @Before - public void setUp() { - mTypeDataDecoder = new EapMsChapV2TypeDataDecoder(); - } - - @Test - public void testDecodeChallengeRequest() { - DecodeResult<EapMsChapV2ChallengeRequest> result = - mTypeDataDecoder.decodeChallengeRequest(TAG, EAP_MSCHAP_V2_CHALLENGE_REQUEST); - assertTrue(result.isSuccessfulDecode()); - EapMsChapV2ChallengeRequest challengeRequest = result.eapTypeData; - - assertEquals(EAP_MSCHAP_V2_CHALLENGE, challengeRequest.opCode); - assertEquals(ID_INT, challengeRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_CHALLENGE_REQUEST.length, challengeRequest.msLength); - assertArrayEquals(CHALLENGE_BYTES, challengeRequest.challenge); - assertArrayEquals(SERVER_NAME_BYTES, challengeRequest.name); - } - - @Test - public void testDecodeChallengeRequestWrongOpCode() { - DecodeResult<EapMsChapV2ChallengeRequest> result = - mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_WRONG_OP_CODE); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeChallengeRequestShortChallenge() { - DecodeResult<EapMsChapV2ChallengeRequest> result = - mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_SHORT_CHALLENGE); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeChallengeRequestShortMsLength() { - DecodeResult<EapMsChapV2ChallengeRequest> result = - mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_SHORT_MS_LENGTH); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeChallengeRequestLongMsLength() { - DecodeResult<EapMsChapV2ChallengeRequest> result = - mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_LONG_MS_LENGTH); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof BufferUnderflowException); - } - - @Test - public void testEncodeChallengeRequestFails() throws Exception { - EapMsChapV2ChallengeRequest challengeRequest = - new EapMsChapV2ChallengeRequest( - ID_INT, - EAP_MSCHAP_V2_CHALLENGE_REQUEST.length, - CHALLENGE_BYTES, - SERVER_NAME_BYTES); - try { - challengeRequest.encode(); - fail("Expected UnsupportedOperationException for encoding a Challenge Request"); - } catch (UnsupportedOperationException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java deleted file mode 100644 index 3e243a98..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_CHALLENGE_RESPONSE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.NT_RESPONSE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PEER_CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PEER_NAME_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SHORT_CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SHORT_NT_RESPONSE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_RESPONSE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeResponse; - -import org.junit.Test; - -public class EapMsChapV2ChallengeResponseTest { - private static final int FLAGS = 0; - private static final int INVALID_FLAGS = 0xFF; - - @Test - public void testConstructor() throws Exception { - EapMsChapV2ChallengeResponse challengeResponse = - new EapMsChapV2ChallengeResponse( - ID_INT, PEER_CHALLENGE_BYTES, NT_RESPONSE_BYTES, FLAGS, PEER_NAME_BYTES); - assertEquals(EAP_MSCHAP_V2_RESPONSE, challengeResponse.opCode); - assertEquals(ID_INT, challengeResponse.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE.length, challengeResponse.msLength); - assertArrayEquals(PEER_CHALLENGE_BYTES, challengeResponse.peerChallenge); - assertArrayEquals(NT_RESPONSE_BYTES, challengeResponse.ntResponse); - assertEquals(FLAGS, challengeResponse.flags); - assertArrayEquals(PEER_NAME_BYTES, challengeResponse.name); - } - - @Test - public void testConstructorInvalidChallenge() { - try { - EapMsChapV2ChallengeResponse challengeResponse = - new EapMsChapV2ChallengeResponse( - ID_INT, - SHORT_CHALLENGE_BYTES, - NT_RESPONSE_BYTES, - FLAGS, - PEER_NAME_BYTES); - fail("Expected EapMsChapV2ParsingException for invalid Peer Challenge length"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testConstructorInvalidNtResponse() { - try { - EapMsChapV2ChallengeResponse challengeResponse = - new EapMsChapV2ChallengeResponse( - ID_INT, - PEER_CHALLENGE_BYTES, - SHORT_NT_RESPONSE, - FLAGS, - PEER_NAME_BYTES); - fail("Expected EapMsChapV2ParsingException for invalid NT-Response length"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testConstructorInvalidFlags() { - try { - EapMsChapV2ChallengeResponse challengeResponse = - new EapMsChapV2ChallengeResponse( - ID_INT, - PEER_CHALLENGE_BYTES, - NT_RESPONSE_BYTES, - INVALID_FLAGS, - PEER_NAME_BYTES); - fail("Expected EapMsChapV2ParsingException for non-zero Flags value"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testEncode() throws Exception { - EapMsChapV2ChallengeResponse challengeResponse = - new EapMsChapV2ChallengeResponse( - ID_INT, PEER_CHALLENGE_BYTES, NT_RESPONSE_BYTES, FLAGS, PEER_NAME_BYTES); - byte[] encodedChallengeResponse = challengeResponse.encode(); - - assertArrayEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE, encodedChallengeResponse); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java deleted file mode 100644 index ead8022a..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java +++ /dev/null @@ -1,172 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ERROR_CODE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_EXTRA_ATTRIBUTE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_CHALLENGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_ERROR_CODE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_SHORT_CHALLENGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PASSWORD_CHANGE_PROTOCOL; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.RETRY_BIT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE; - -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 com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; - -import org.junit.Before; -import org.junit.Test; - -public class EapMsChapV2FailureRequestTest { - private static final String TAG = EapMsChapV2FailureRequestTest.class.getSimpleName(); - - private EapMsChapV2TypeDataDecoder mTypeDataDecoder; - - @Before - public void setUp() { - mTypeDataDecoder = new EapMsChapV2TypeDataDecoder(); - } - - @Test - public void testDecodeFailureRequest() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest(TAG, EAP_MSCHAP_V2_FAILURE_REQUEST); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2FailureRequest failureRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode); - assertEquals(ID_INT, failureRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_FAILURE_REQUEST.length, failureRequest.msLength); - assertEquals(ERROR_CODE, failureRequest.errorCode); - assertEquals(RETRY_BIT, failureRequest.isRetryable); - assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge); - assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol); - assertEquals(MESSAGE, failureRequest.message); - } - - @Test - public void testDecodeFailureRequestMissingMessage() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest( - TAG, EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2FailureRequest failureRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode); - assertEquals(ID_INT, failureRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE.length, failureRequest.msLength); - assertEquals(ERROR_CODE, failureRequest.errorCode); - assertEquals(RETRY_BIT, failureRequest.isRetryable); - assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge); - assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol); - assertEquals(MESSAGE_MISSING_TEXT, failureRequest.message); - } - - @Test - public void testDecodeFailureRequestMissingMessageWithSpace() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest( - TAG, EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2FailureRequest failureRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode); - assertEquals(ID_INT, failureRequest.msChapV2Id); - assertEquals( - EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE.length, - failureRequest.msLength); - assertEquals(ERROR_CODE, failureRequest.errorCode); - assertEquals(RETRY_BIT, failureRequest.isRetryable); - assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge); - assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol); - assertEquals(MESSAGE_MISSING_TEXT, failureRequest.message); - } - - @Test - public void testDecodeFailureRequestInvalidErrorCode() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_INVALID_ERROR_CODE); - assertTrue(!result.isSuccessfulDecode()); - assertTrue(result.eapError.cause instanceof NumberFormatException); - } - - @Test - public void testDecodeFailureRequestInvalidChallenge() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_INVALID_CHALLENGE); - assertTrue(!result.isSuccessfulDecode()); - assertTrue(result.eapError.cause instanceof NumberFormatException); - } - - @Test - public void testDecodeFailureRequestShortChallenge() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_SHORT_CHALLENGE); - assertTrue(!result.isSuccessfulDecode()); - assertTrue(result.eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeFailureRequestInvalidPasswordChangeProtocol() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest( - TAG, FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL); - assertTrue(!result.isSuccessfulDecode()); - assertTrue(result.eapError.cause instanceof NumberFormatException); - } - - @Test - public void testDecodeFailureExtraAttribute() { - DecodeResult<EapMsChapV2FailureRequest> result = - mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_EXTRA_ATTRIBUTE); - assertTrue(!result.isSuccessfulDecode()); - assertTrue(result.eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testEncodeFails() throws Exception { - EapMsChapV2FailureRequest failureRequest = - new EapMsChapV2FailureRequest( - ID_INT, - EAP_MSCHAP_V2_FAILURE_REQUEST.length, - ERROR_CODE, - RETRY_BIT, - CHALLENGE_BYTES, - PASSWORD_CHANGE_PROTOCOL, - MESSAGE); - try { - failureRequest.encode(); - fail("Expected UnsupportedOperationException for encoding a request"); - } catch (UnsupportedOperationException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java deleted file mode 100644 index 261ddb28..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_RESPONSE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureResponse; - -import org.junit.Test; - -public class EapMsChapV2FailureResponseTest { - @Test - public void testGetEapMsChapV2FailureResponse() { - EapMsChapV2FailureResponse failureResponse = - EapMsChapV2FailureResponse.getEapMsChapV2FailureResponse(); - assertEquals(EAP_MSCHAP_V2_FAILURE, failureResponse.opCode); - } - - @Test - public void testEncode() { - EapMsChapV2FailureResponse failureResponse = - EapMsChapV2FailureResponse.getEapMsChapV2FailureResponse(); - assertArrayEquals(EAP_MSCHAP_V2_FAILURE_RESPONSE, failureResponse.encode()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java deleted file mode 100644 index e70c2a2f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java +++ /dev/null @@ -1,284 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -public class EapMsChapV2PacketDefinitions { - public static final String ID = "1F"; - public static final int ID_INT = Integer.parseInt(ID, 16 /* radix */); - - public static final String CHALLENGE = "000102030405060708090A0B0C0D0E0F"; - public static final byte[] CHALLENGE_BYTES = hexStringToByteArray(CHALLENGE); - - // server name is the ASCII hex for "authenticator@android.net" - public static final String SERVER_NAME = "61757468656E74696361746F7240616E64726F69642E6E6574"; - public static final byte[] SERVER_NAME_BYTES = hexStringToByteArray(SERVER_NAME); - public static final byte[] EAP_MSCHAP_V2_CHALLENGE_REQUEST = - hexStringToByteArray("01" + ID + "002E10" + CHALLENGE + SERVER_NAME); - - public static final byte[] CHALLENGE_REQUEST_WRONG_OP_CODE = hexStringToByteArray("02"); - public static final String SHORT_CHALLENGE = "001122334455"; - public static final byte[] SHORT_CHALLENGE_BYTES = hexStringToByteArray(SHORT_CHALLENGE); - public static final byte[] CHALLENGE_REQUEST_SHORT_CHALLENGE = - hexStringToByteArray("01" + ID + "002406" + SHORT_CHALLENGE + SERVER_NAME); - public static final byte[] CHALLENGE_REQUEST_SHORT_MS_LENGTH = - hexStringToByteArray("01" + ID + "000110" + CHALLENGE + SERVER_NAME); - public static final byte[] CHALLENGE_REQUEST_LONG_MS_LENGTH = - hexStringToByteArray("01" + ID + "00FF10" + CHALLENGE + SERVER_NAME); - - public static final String PEER_CHALLENGE = "00112233445566778899AABBCCDDEEFF"; - public static final byte[] PEER_CHALLENGE_BYTES = hexStringToByteArray(PEER_CHALLENGE); - public static final String NT_RESPONSE = "FFEEDDCCBBAA998877665544332211000011223344556677"; - public static final byte[] NT_RESPONSE_BYTES = hexStringToByteArray(NT_RESPONSE); - - // peer name is the ASCII hex for "peer@android.net" - public static final String PEER_NAME = "7065657240616E64726F69642E6E6574"; - public static final byte[] PEER_NAME_BYTES = hexStringToByteArray(PEER_NAME); - public static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE = - hexStringToByteArray( - "02" - + ID - + "004631" - + PEER_CHALLENGE - + "0000000000000000" - + NT_RESPONSE - + "00" - + PEER_NAME); - - public static final byte[] SHORT_NT_RESPONSE = hexStringToByteArray("0011223344"); - - public static final String AUTH_STRING = "00112233445566778899AABBCCDDEEFF00112233"; - - // ASCII hex for AUTH_STRING - public static final String AUTH_STRING_HEX = - "30303131323233333434353536363737383839394141424243434444454546463030313132323333"; - public static final byte[] AUTH_BYTES = hexStringToByteArray(AUTH_STRING); - - // hex("S=") + AUTH_STRING_HEX - public static final String FORMATTED_AUTH_STRING = "533D" + AUTH_STRING_HEX; - - public static final String SPACE_HEX = "20"; - - // ASCII hex for: "test Android 1234" - public static final String MESSAGE = "test Android 1234"; - public static final String MESSAGE_HEX = "7465737420416E64726F69642031323334"; - - // hex("M=") + MESSAGE_HEX - public static final String FORMATTED_MESSAGE = "4D3D" + MESSAGE_HEX; - - public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST = - hexStringToByteArray( - "03" + ID + "0042" + FORMATTED_AUTH_STRING + SPACE_HEX + FORMATTED_MESSAGE); - public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE = - hexStringToByteArray("03" + ID + "0031" + FORMATTED_AUTH_STRING + SPACE_HEX + "4D3D"); - public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE = - hexStringToByteArray("03" + ID + "002E" + FORMATTED_AUTH_STRING); - public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE = - hexStringToByteArray("03" + ID + "002F" + FORMATTED_AUTH_STRING + SPACE_HEX); - public static final String MESSAGE_MISSING_TEXT = "<omitted by authenticator>"; - - public static final String SHORT_AUTH_STRING = "001122334455"; - - public static final byte[] SUCCESS_REQUEST_WRONG_OP_CODE = hexStringToByteArray("02"); - - // message format: hex("M=") + AUTH_STRING_HEX + hex("M=") + MESSAGE_HEX - public static final byte[] SUCCESS_REQUEST_WRONG_PREFIX = - hexStringToByteArray("03" + ID + "00314D3D" + AUTH_STRING_HEX + SPACE_HEX + "4D3D"); - - // message format: hex("S=") + SHORT_AUTH_STRING + hex("M=") + MESSAGE_HEX - public static final byte[] SUCCESS_REQUEST_SHORT_AUTH_STRING = - hexStringToByteArray("03" + ID + "0031533D" + SHORT_AUTH_STRING + SPACE_HEX + "4D3D"); - - public static final String INVALID_AUTH_HEX = - "3030313132323333343435353636373738383939414142424343444445454646303031317A7A7979"; - public static final byte[] SUCCESS_REQUEST_INVALID_AUTH_STRING = - hexStringToByteArray("03" + ID + "0031533D" + INVALID_AUTH_HEX + SPACE_HEX + "4D3D"); - - // extra key-value: hex("N=12") - public static final String EXTRA_KEY = "4E3D3132"; - public static final byte[] SUCCESS_REQUEST_EXTRA_ATTRIBUTE = - hexStringToByteArray( - "03" - + ID - + "0042" - + FORMATTED_AUTH_STRING - + SPACE_HEX - + EXTRA_KEY - + SPACE_HEX - + FORMATTED_MESSAGE); - - public static final String SUCCESS_REQUEST = "S=" + AUTH_STRING + " M=" + MESSAGE; - public static final String EXTRA_M_MESSAGE = "M=" + MESSAGE; - public static final String SUCCESS_REQUEST_EXTRA_M = - "S=" + AUTH_STRING + " M=" + EXTRA_M_MESSAGE; - public static final String SUCCESS_REQUEST_MISSING_M = "S=" + AUTH_STRING; - public static final String SUCCESS_REQUEST_INVALID_FORMAT = - "S==" + AUTH_STRING + "M=" + MESSAGE; - public static final String SUCCESS_REQUEST_DUPLICATE_KEY = - "S=" + AUTH_STRING + " S=" + AUTH_STRING + " M=" + MESSAGE; - - public static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE = hexStringToByteArray("03"); - - public static final int ERROR_CODE = 647; // account disabled - - // formatted error code: hex("E=" + ERROR_CODE) - public static final String FORMATTED_ERROR_CODE = "453D363437"; - public static final boolean RETRY_BIT = true; - - // formatted retry bit: hex("R=1") - public static final String FORMATTED_RETRY_BIT = "523D31"; - - // challenge hex: hex(CHALLENGE) - public static final String CHALLENGE_HEX = - "3030303130323033303430353036303730383039304130423043304430453046"; - - // formatted challenge: hex("C=") + CHALLENGE_HEX - public static final String FORMATTED_CHALLENGE = "433D" + CHALLENGE_HEX; - - public static final int PASSWORD_CHANGE_PROTOCOL = 3; - - // formatted password change protocol: hex("V=3") - public static final String FORMATTED_PASSWORD_CHANGE_PROTOCOL = "563D33"; - - public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST = - hexStringToByteArray( - "04" - + ID - + "0048" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + FORMATTED_MESSAGE); - public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE = - hexStringToByteArray( - "04" - + ID - + "0034" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL); - public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE = - hexStringToByteArray( - "04" - + ID - + "0035" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX); - - // invalid error code: hex("E=abc") - public static final String INVALID_ERROR_CODE = "453D616263"; - public static final byte[] FAILURE_REQUEST_INVALID_ERROR_CODE = - hexStringToByteArray( - "04" - + ID - + "0048" - + INVALID_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + FORMATTED_MESSAGE); - - // invalid challenge: hex("C=zyxd") - public static final String INVALID_CHALLENGE = "433D7A797864"; - public static final byte[] FAILURE_REQUEST_INVALID_CHALLENGE = - hexStringToByteArray( - "04" - + ID - + "0032" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + INVALID_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + FORMATTED_MESSAGE); - - // short challenge: hex("C=" + SHORT_CHALLENGE) - public static final String FORMATTED_SHORT_CHALLENGE = "433D303031313232333334343535"; - public static final byte[] FAILURE_REQUEST_SHORT_CHALLENGE = - hexStringToByteArray( - "04" - + ID - + "0034" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_SHORT_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + FORMATTED_MESSAGE); - - // invalid password change protocol: hex("V=d") - public static final String INVALID_PASSWORD_CHANGE_PROTOCOL = "563D64"; - public static final byte[] FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL = - hexStringToByteArray( - "04" - + ID - + "0048" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + INVALID_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + FORMATTED_MESSAGE); - - public static final byte[] FAILURE_REQUEST_EXTRA_ATTRIBUTE = - hexStringToByteArray( - "04" - + ID - + "0048" - + FORMATTED_ERROR_CODE - + SPACE_HEX - + FORMATTED_RETRY_BIT - + SPACE_HEX - + FORMATTED_CHALLENGE - + SPACE_HEX - + FORMATTED_PASSWORD_CHANGE_PROTOCOL - + SPACE_HEX - + EXTRA_KEY - + SPACE_HEX - + FORMATTED_MESSAGE); - - public static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE = hexStringToByteArray("04"); -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java deleted file mode 100644 index 1e0909ed..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_EXTRA_ATTRIBUTE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_INVALID_AUTH_STRING; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_SHORT_AUTH_STRING; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_WRONG_OP_CODE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_WRONG_PREFIX; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS; - -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.eap.EapResult.EapError; -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.BufferUnderflowException; - -public class EapMsChapV2SuccessRequestTest { - private static final String TAG = EapMsChapV2SuccessRequestTest.class.getSimpleName(); - - private EapMsChapV2TypeDataDecoder mTypeDataDecoder; - - @Before - public void setUp() { - mTypeDataDecoder = new EapMsChapV2TypeDataDecoder(); - } - - @Test - public void testDecodeSuccessRequest() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2SuccessRequest successRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode); - assertEquals(ID_INT, successRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST.length, successRequest.msLength); - assertArrayEquals(AUTH_BYTES, successRequest.authBytes); - assertEquals(MESSAGE, successRequest.message); - } - - @Test - public void testDecodeSuccessRequestEmptyMessage() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest( - TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2SuccessRequest successRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode); - assertEquals(ID_INT, successRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE.length, successRequest.msLength); - assertArrayEquals(AUTH_BYTES, successRequest.authBytes); - assertTrue(successRequest.message.isEmpty()); - } - - @Test - public void testDecodeSuccessRequestMissingMessage() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest( - TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2SuccessRequest successRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode); - assertEquals(ID_INT, successRequest.msChapV2Id); - assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE.length, successRequest.msLength); - assertArrayEquals(AUTH_BYTES, successRequest.authBytes); - assertEquals(MESSAGE_MISSING_TEXT, successRequest.message); - } - - @Test - public void testDecodeSuccessRequestMissingMessageWithSpace() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest( - TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE); - assertTrue(result.isSuccessfulDecode()); - - EapMsChapV2SuccessRequest successRequest = result.eapTypeData; - assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode); - assertEquals(ID_INT, successRequest.msChapV2Id); - assertEquals( - EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE.length, - successRequest.msLength); - assertArrayEquals(AUTH_BYTES, successRequest.authBytes); - assertEquals(MESSAGE_MISSING_TEXT, successRequest.message); - } - - @Test - public void testDecodeSuccessRequestWrongOpCode() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_WRONG_OP_CODE); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeSuccessRequestShortMessage() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, new byte[0]); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof BufferUnderflowException); - } - - @Test - public void testDecodeSuccessRequestInvalidPrefix() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_WRONG_PREFIX); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeSuccessRequestShortAuthString() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_SHORT_AUTH_STRING); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testDecodeSuccessRequestInvalidAuthString() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_INVALID_AUTH_STRING); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof NumberFormatException); - } - - @Test - public void testDecodeSuccessRequestExtraAttribute() { - DecodeResult<EapMsChapV2SuccessRequest> result = - mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_EXTRA_ATTRIBUTE); - assertFalse(result.isSuccessfulDecode()); - EapError eapError = result.eapError; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - } - - @Test - public void testEncodeFails() throws Exception { - EapMsChapV2SuccessRequest successRequest = - new EapMsChapV2SuccessRequest( - ID_INT, EAP_MSCHAP_V2_SUCCESS_REQUEST.length, AUTH_BYTES, MESSAGE); - try { - successRequest.encode(); - fail("Expected UnsupportedOperationException for encoding a request"); - } catch (UnsupportedOperationException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java deleted file mode 100644 index 524b3ecf..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_RESPONSE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; - -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessResponse; - -import org.junit.Test; - -public class EapMsChapV2SuccessResponseTest { - @Test - public void testGetEapMsChapV2SuccessResponse() { - EapMsChapV2SuccessResponse successResponse = - EapMsChapV2SuccessResponse.getEapMsChapV2SuccessResponse(); - assertEquals(EAP_MSCHAP_V2_SUCCESS, successResponse.opCode); - } - - @Test - public void testEncode() { - EapMsChapV2SuccessResponse successResponse = - EapMsChapV2SuccessResponse.getEapMsChapV2SuccessResponse(); - assertArrayEquals(EAP_MSCHAP_V2_SUCCESS_RESPONSE, successResponse.encode()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java deleted file mode 100644 index 45f1c641..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.internal.net.eap.message.mschapv2; - -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_STRING; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EXTRA_M_MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_DUPLICATE_KEY; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_EXTRA_M; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_INVALID_FORMAT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_MISSING_M; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_CHALLENGE; - -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.eap.EapResult.EapError; -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2VariableTypeData; - -import org.junit.Test; - -import java.util.HashMap; -import java.util.Map; - -public class EapMsChapV2TypeDataTest { - private static final int INVALID_OPCODE = -1; - private static final int MSCHAP_V2_ID = 1; - private static final int MS_LENGTH = 32; - private static final String HEX_STRING_INVALID_LENGTH = "00112"; - private static final String HEX_STRING_INVALID_CHARS = "001122z-+x"; - - @Test - public void testEapMsChapV2TypeDataConstructor() throws Exception { - EapMsChapV2TypeData typeData = new EapMsChapV2TypeData(EAP_MSCHAP_V2_CHALLENGE) {}; - assertEquals(EAP_MSCHAP_V2_CHALLENGE, typeData.opCode); - - try { - new EapMsChapV2TypeData(INVALID_OPCODE) {}; - fail("ExpectedEapMsChapV2ParsingException for invalid OpCode"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testEapMsChapV2VariableTypeDataConstructor() throws Exception { - EapMsChapV2VariableTypeData typeData = - new EapMsChapV2VariableTypeData( - EAP_MSCHAP_V2_CHALLENGE, MSCHAP_V2_ID, MS_LENGTH) {}; - assertEquals(EAP_MSCHAP_V2_CHALLENGE, typeData.opCode); - assertEquals(MSCHAP_V2_ID, typeData.msChapV2Id); - assertEquals(MS_LENGTH, typeData.msLength); - - try { - new EapMsChapV2VariableTypeData(INVALID_OPCODE, MSCHAP_V2_ID, MS_LENGTH) {}; - fail("ExpectedEapMsChapV2ParsingException for invalid OpCode"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testDecodeResultIsSuccessfulDecode() throws Exception { - DecodeResult<EapMsChapV2TypeData> result = - new DecodeResult(new EapMsChapV2TypeData(EAP_MSCHAP_V2_CHALLENGE) {}); - assertTrue(result.isSuccessfulDecode()); - - result = new DecodeResult(new EapError(new Exception())); - assertFalse(result.isSuccessfulDecode()); - } - - @Test - public void testGetMessageMappings() throws Exception { - Map<String, String> expectedMappings = new HashMap<>(); - expectedMappings.put("S", AUTH_STRING); - expectedMappings.put("M", MESSAGE); - assertEquals(expectedMappings, EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST)); - - expectedMappings = new HashMap<>(); - expectedMappings.put("S", AUTH_STRING); - expectedMappings.put("M", EXTRA_M_MESSAGE); - assertEquals( - expectedMappings, EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_EXTRA_M)); - - expectedMappings = new HashMap<>(); - expectedMappings.put("S", AUTH_STRING); - expectedMappings.put("M", MESSAGE_MISSING_TEXT); - assertEquals( - expectedMappings, - EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_MISSING_M)); - } - - @Test - public void testGetMessageMappingsInvalidFormat() { - try { - EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_INVALID_FORMAT); - fail("Expected EapMsChapV2ParsingException for extra '='s in message"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testGetMessageMappingDuplicateKey() { - try { - EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_DUPLICATE_KEY); - fail("Expected EapMsChapV2ParsingException for duplicate key in message"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testHexStringToByteArray() throws Exception { - byte[] result = EapMsChapV2TypeData.hexStringToByteArray(AUTH_STRING); - assertArrayEquals(AUTH_BYTES, result); - } - - @Test - public void testHexStringToByteArrayInvalidLength() { - try { - EapMsChapV2TypeData.hexStringToByteArray(HEX_STRING_INVALID_LENGTH); - fail("Expected EapMsChapV2ParsingException for invalid hex string length"); - } catch (EapMsChapV2ParsingException expected) { - } - } - - @Test - public void testHexStringToByteArrayInvalidChars() throws Exception { - try { - EapMsChapV2TypeData.hexStringToByteArray(HEX_STRING_INVALID_CHARS); - fail("Expected NumberFormatException for invalid hex chars"); - } catch (NumberFormatException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java deleted file mode 100644 index 6a9e517f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.KDF_VERSION; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_HEX; - -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 com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map.Entry; - -public class EapAkaPrimeTypeDataTest { - private static final String RAND = "7A1FCDC0034BA1227E7B9FCEAFD47D53"; - private static final byte[] RAND_BYTES = hexStringToByteArray(RAND); - private static final String AUTN = "000102030405060708090A0B0C0D0E0F"; - private static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN); - private static final String MAC = "95FEB9E70427F34B4FAC8F2C7A65A302"; - private static final byte[] MAC_BYTES = hexStringToByteArray(MAC); - private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST = - hexStringToByteArray( - "010000" // Challenge | 2B padding - + "01050000" + RAND // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT - + "18010001" // AT_KDF - + "0B050000" + MAC); // AT_MAC attribute - private static final byte[] EAP_AKA_PRIME_MULTIPLE_AT_KDF = - hexStringToByteArray( - "010000" // Challenge | 2B padding - + "01050000" + RAND // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT - + "18010001" // AT_KDF - + "18010002" // AT_KDF - + "0B050000" + MAC); // AT_MAC attribute - - private EapAkaPrimeTypeDataDecoder mTypeDataDecoder; - - @Before - public void setUp() { - mTypeDataDecoder = EapAkaPrimeTypeData.getEapAkaPrimeTypeDataDecoder(); - } - - @Test - public void testDecode() { - DecodeResult<EapAkaTypeData> result = - mTypeDataDecoder.decode(EAP_AKA_PRIME_CHALLENGE_REQUEST); - - assertTrue(result.isSuccessfulDecode()); - EapAkaPrimeTypeData eapAkaPrimeTypeData = (EapAkaPrimeTypeData) result.eapTypeData; - assertEquals(EAP_AKA_CHALLENGE, eapAkaPrimeTypeData.eapSubtype); - - // also check Map entries (needs to match input order) - Iterator<Entry<Integer, EapSimAkaAttribute>> itr = - eapAkaPrimeTypeData.attributeMap.entrySet().iterator(); - Entry<Integer, EapSimAkaAttribute> entry = itr.next(); - assertEquals(EAP_AT_RAND, (int) entry.getKey()); - assertArrayEquals(RAND_BYTES, ((AtRandAka) entry.getValue()).rand); - - entry = itr.next(); - assertEquals(EAP_AT_AUTN, (int) entry.getKey()); - assertArrayEquals(AUTN_BYTES, ((AtAutn) entry.getValue()).autn); - - entry = itr.next(); - assertEquals(EAP_AT_KDF_INPUT, (int) entry.getKey()); - assertArrayEquals(NETWORK_NAME_BYTES, ((AtKdfInput) entry.getValue()).networkName); - - entry = itr.next(); - assertEquals(EAP_AT_KDF, (int) entry.getKey()); - assertEquals(KDF_VERSION, ((AtKdf) entry.getValue()).kdf); - - entry = itr.next(); - assertEquals(EAP_AT_MAC, (int) entry.getKey()); - assertArrayEquals(MAC_BYTES, ((AtMac) entry.getValue()).mac); - - assertFalse(itr.hasNext()); - } - - @Test - public void testDecodeMultipleAtKdfAttributes() { - DecodeResult<EapAkaTypeData> result = - mTypeDataDecoder.decode(EAP_AKA_PRIME_MULTIPLE_AT_KDF); - - assertFalse(result.isSuccessfulDecode()); - assertEquals(AtClientErrorCode.UNABLE_TO_PROCESS, result.atClientErrorCode); - } - - @Test - public void testEncode() throws Exception { - LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>(); - attributes.put(EAP_AT_RAND, new AtRandAka(RAND_BYTES)); - attributes.put(EAP_AT_AUTN, new AtAutn(AUTN_BYTES)); - attributes.put(EAP_AT_KDF_INPUT, new AtKdfInput(AT_KDF_INPUT.length, NETWORK_NAME_BYTES)); - attributes.put(EAP_AT_KDF, new AtKdf(KDF_VERSION)); - attributes.put(EAP_AT_MAC, new AtMac(MAC_BYTES)); - EapAkaPrimeTypeData eapAkaPrimeTypeData = - new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, attributes); - - byte[] result = eapAkaPrimeTypeData.encode(); - assertArrayEquals(EAP_AKA_PRIME_CHALLENGE_REQUEST, result); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java deleted file mode 100644 index b2d89d16..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_IDENTITY_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_CHECKCODE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES; - -import static junit.framework.TestCase.fail; - -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 com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map.Entry; - -public class EapAkaTypeDataTest { - private static final int UNABLE_TO_PROCESS_CODE = 0; - private static final int INVALID_SUBTYPE_INT = -1; - - private static final int EAP_AT_TRUST_IND = 139; - private static final String RAND = "7A1FCDC0034BA1227E7B9FCEAFD47D53"; - private static final byte[] RAND_BYTES = hexStringToByteArray(RAND); - private static final String AUTN = "000102030405060708090A0B0C0D0E0F"; - private static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN); - private static final String MAC = "95FEB9E70427F34B4FAC8F2C7A65A302"; - private static final byte[] MAC_BYTES = hexStringToByteArray(MAC); - private static final byte[] EAP_AKA_REQUEST = - hexStringToByteArray( - "010000" // Challenge | 2B padding - + "01050000" + RAND // AT_RAND attribute - + "02050000" + AUTN // AT_AUTN attribute - + "8B010002" // AT_RESULT_IND attribute (TS 124 302#8.2.3.1) - + "0B050000" + MAC // AT_MAC attribute - + "86010000"); // AT_CHECKCODE attribute - - private EapAkaTypeDataDecoder mEapAkaTypeDataDecoder; - - @Before - public void setUp() { - mEapAkaTypeDataDecoder = EapAkaTypeData.getEapAkaTypeDataDecoder(); - } - - @Test - public void testDecode() { - DecodeResult<EapAkaTypeData> result = - mEapAkaTypeDataDecoder.decode(EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA); - - assertTrue(result.isSuccessfulDecode()); - EapAkaTypeData eapAkaTypeData = result.eapTypeData; - assertEquals(EAP_AKA_CHALLENGE, eapAkaTypeData.eapSubtype); - - // also check Map entries (needs to match input order) - Iterator<Entry<Integer, EapSimAkaAttribute>> itr = - eapAkaTypeData.attributeMap.entrySet().iterator(); - Entry<Integer, EapSimAkaAttribute> entry = itr.next(); - assertEquals(EAP_AT_RES, (int) entry.getKey()); - assertArrayEquals(RES_BYTES, ((AtRes) entry.getValue()).res); - - entry = itr.next(); - assertEquals(EAP_AT_MAC, (int) entry.getKey()); - assertArrayEquals(EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES, ((AtMac) entry.getValue()).mac); - - assertFalse(itr.hasNext()); - } - - @Test - public void testDecodeWithOptionalAttributes() { - DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(EAP_AKA_REQUEST); - - assertTrue(result.isSuccessfulDecode()); - EapAkaTypeData eapAkaTypeData = result.eapTypeData; - assertEquals(EAP_AKA_CHALLENGE, eapAkaTypeData.eapSubtype); - - // also check Map entries (needs to match input order) - Iterator<Entry<Integer, EapSimAkaAttribute>> itr = - eapAkaTypeData.attributeMap.entrySet().iterator(); - Entry<Integer, EapSimAkaAttribute> entry = itr.next(); - assertEquals(EAP_AT_RAND, (int) entry.getKey()); - assertArrayEquals(RAND_BYTES, ((AtRandAka) entry.getValue()).rand); - - entry = itr.next(); - assertEquals(EAP_AT_AUTN, (int) entry.getKey()); - assertArrayEquals(AUTN_BYTES, ((AtAutn) entry.getValue()).autn); - - entry = itr.next(); - assertEquals(EAP_AT_TRUST_IND, (int) entry.getKey()); - assertTrue(entry.getValue() instanceof EapSimAkaUnsupportedAttribute); - - entry = itr.next(); - assertEquals(EAP_AT_MAC, (int) entry.getKey()); - assertArrayEquals(MAC_BYTES, ((AtMac) entry.getValue()).mac); - - entry = itr.next(); - assertEquals(EAP_AT_CHECKCODE, (int) entry.getKey()); - assertTrue(entry.getValue() instanceof EapSimAkaUnsupportedAttribute); - - assertFalse(itr.hasNext()); - } - - @Test - public void testDecodeInvalidSubtype() { - DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(INVALID_SUBTYPE); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testEncode() throws Exception { - LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>(); - attributes.put(EAP_AT_ANY_ID_REQ, new AtAnyIdReq()); - EapAkaTypeData eapAkaTypeData = new EapAkaTypeData(EAP_AKA_IDENTITY, attributes); - - byte[] result = eapAkaTypeData.encode(); - assertArrayEquals(EAP_AKA_IDENTITY_REQUEST, result); - } - - @Test - public void testConstructorInvalidSubtype() throws Exception { - try { - new EapAkaTypeData(INVALID_SUBTYPE_INT, Arrays.asList(new AtAnyIdReq())); - fail("Expected IllegalArgumentException for invalid subtype"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testConstructorDuplicateAttributes() throws Exception { - try { - new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq(), new AtAnyIdReq())); - fail("Expected IllegalArgumentException for duplicate attributes"); - } catch (IllegalArgumentException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java deleted file mode 100644 index 5b6f5d60..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_DATA; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_DATA_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_INVALID_ATTRIBUTE; - -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 com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class EapSimAkaAttributeFactoryTest { - private static final int SKIPPABLE_ATTRIBUTE_TYPE = 0xFF; - private static final int SKIPPABLE_EXPECTED_LENGTH = 8; - - private static final int NON_SKIPPABLE_ATTRIBUTE_TYPE = 0x7F; - private static final int NON_SKIPPABLE_ATTRIBUTE_LENGTH = 4; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecodeInvalidSkippable() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.wrap(SKIPPABLE_DATA_BYTES); - - EapSimAkaAttribute result = mAttributeFactory.getAttribute( - SKIPPABLE_ATTRIBUTE_TYPE, - SKIPPABLE_EXPECTED_LENGTH, - byteBuffer); - assertTrue(result instanceof EapSimAkaUnsupportedAttribute); - EapSimAkaUnsupportedAttribute unsupportedAttribute = (EapSimAkaUnsupportedAttribute) result; - assertEquals(SKIPPABLE_ATTRIBUTE_TYPE, unsupportedAttribute.attributeType); - assertEquals(SKIPPABLE_EXPECTED_LENGTH, unsupportedAttribute.lengthInBytes); - assertArrayEquals(hexStringToByteArray(SKIPPABLE_DATA), unsupportedAttribute.data); - } - - @Test - public void testEncodeInvalidSkippable() throws Exception { - EapSimAkaUnsupportedAttribute unsupportedAttribute = new EapSimAkaUnsupportedAttribute( - SKIPPABLE_ATTRIBUTE_TYPE, - SKIPPABLE_EXPECTED_LENGTH, - hexStringToByteArray(SKIPPABLE_DATA)); - - ByteBuffer result = ByteBuffer.allocate(SKIPPABLE_EXPECTED_LENGTH); - unsupportedAttribute.encode(result); - assertArrayEquals(SKIPPABLE_INVALID_ATTRIBUTE, result.array()); - } - - @Test - public void testDecodeInvalidNonSkippable() throws Exception { - // Unskippable type + length + byte[] represent shortest legitimate attribute: "7F040000" - ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[2]); - - try { - mAttributeFactory.getAttribute( - NON_SKIPPABLE_ATTRIBUTE_TYPE, - NON_SKIPPABLE_ATTRIBUTE_LENGTH, - byteBuffer); - fail("Expected EapSimAkaUnsupportedAttributeException for decoding invalid" - + " non-skippable Attribute"); - } catch (EapSimAkaUnsupportedAttributeException expected) { - } - } - -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java deleted file mode 100644 index 678a812b..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka; - -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_DUPLICATE_ATTRIBUTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_SUBTYPE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_TYPE_DATA; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.TYPE_DATA_INVALID_ATTRIBUTE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.TYPE_DATA_INVALID_AT_RAND; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST; - -import static junit.framework.TestCase.fail; - -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 com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map.Entry; - -public class EapSimTypeDataTest { - private static final int UNABLE_TO_PROCESS_CODE = 0; - private static final int INSUFFICIENT_CHALLENGES_CODE = 2; - private static final int EAP_SIM_START = 10; - private static final int INVALID_SUBTYPE_INT = -1; - - private EapSimTypeDataDecoder mEapSimTypeDataDecoder; - - @Before - public void setUp() { - mEapSimTypeDataDecoder = EapSimTypeData.getEapSimTypeDataDecoder(); - } - - @Test - public void testConstructor() throws Exception { - List<EapSimAkaAttribute> attributes = Arrays.asList( - new AtVersionList(8, 1), new AtPermanentIdReq()); - - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, attributes); - assertEquals(EAP_SIM_START, eapSimTypeData.eapSubtype); - - // check order of entries in EapSimTypeData.attributeMap - Iterator<Entry<Integer, EapSimAkaAttribute>> itr = - eapSimTypeData.attributeMap.entrySet().iterator(); - Entry<Integer, EapSimAkaAttribute> pair = itr.next(); - assertEquals(EAP_AT_VERSION_LIST, (int) pair.getKey()); - assertEquals(Arrays.asList(1), ((AtVersionList) pair.getValue()).versions); - - pair = itr.next(); - assertEquals(EAP_AT_PERMANENT_ID_REQ, (int) pair.getKey()); - assertTrue(pair.getValue() instanceof AtPermanentIdReq); - } - - @Test - public void testDecode() { - DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(EAP_SIM_START_SUBTYPE); - - assertTrue(result.isSuccessfulDecode()); - EapSimTypeData eapSimTypeData = result.eapTypeData; - assertEquals(EAP_SIM_START, eapSimTypeData.eapSubtype); - assertTrue(eapSimTypeData.attributeMap.containsKey(EAP_AT_VERSION_LIST)); - AtVersionList atVersionList = (AtVersionList) - eapSimTypeData.attributeMap.get(EAP_AT_VERSION_LIST); - assertEquals(Arrays.asList(1), atVersionList.versions); - assertTrue(eapSimTypeData.attributeMap.containsKey(EAP_AT_PERMANENT_ID_REQ)); - - // also check order of Map entries (needs to match input order) - Iterator<Integer> itr = eapSimTypeData.attributeMap.keySet().iterator(); - assertEquals(EAP_AT_VERSION_LIST, (int) itr.next()); - assertEquals(EAP_AT_PERMANENT_ID_REQ, (int) itr.next()); - assertFalse(itr.hasNext()); - } - - @Test - public void testDecodeNullTypeData() { - DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(null); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testDecodeInvalidSubtype() { - DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(INVALID_SUBTYPE); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testDecodeInvalidAtRand() { - DecodeResult<EapSimTypeData> result = - mEapSimTypeDataDecoder.decode(TYPE_DATA_INVALID_AT_RAND); - assertFalse(result.isSuccessfulDecode()); - assertEquals(INSUFFICIENT_CHALLENGES_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testDecodeShortPacket() { - DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(SHORT_TYPE_DATA); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testDecodeInvalidEapAttribute() { - DecodeResult<EapSimTypeData> result = - mEapSimTypeDataDecoder.decode(TYPE_DATA_INVALID_ATTRIBUTE); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testEncode() throws Exception { - LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>(); - attributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - attributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, attributes); - - byte[] result = eapSimTypeData.encode(); - assertArrayEquals(EAP_SIM_START_SUBTYPE, result); - } - - @Test - public void testDecodeDuplicateAttributes() { - DecodeResult<EapSimTypeData> result = - mEapSimTypeDataDecoder.decode(EAP_SIM_START_DUPLICATE_ATTRIBUTES); - assertFalse(result.isSuccessfulDecode()); - assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode); - } - - @Test - public void testConstructorInvalidSubtype() throws Exception { - try { - new EapSimTypeData(INVALID_SUBTYPE_INT, Arrays.asList(new AtPermanentIdReq())); - fail("Expected IllegalArgumentException for invalid subtype"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testConstructorDuplicateAttributes() throws Exception { - try { - new EapSimTypeData( - EAP_SIM_START, Arrays.asList(new AtPermanentIdReq(), new AtPermanentIdReq())); - fail("Expected IllegalArgumentException for duplicate attributes"); - } catch (IllegalArgumentException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java deleted file mode 100644 index ebf22e4f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTN; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTN_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES; - -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 com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtAutnTest { - private EapAkaAttributeFactory mEapAkaAttributeFactory; - - @Before - public void setUp() { - mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_AUTN); - EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtAutn atAutn = (AtAutn) result; - assertEquals(EAP_AT_AUTN, atAutn.attributeType); - assertEquals(AT_AUTN.length, atAutn.lengthInBytes); - assertArrayEquals(AUTN_BYTES, atAutn.autn); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_AUTN_INVALID_LENGTH); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtAutn atAutn = new AtAutn(AUTN_BYTES); - - ByteBuffer result = ByteBuffer.allocate(AT_AUTN.length); - atAutn.encode(result); - assertArrayEquals(AT_AUTN, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java deleted file mode 100644 index d65a735f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTS; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTS; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTS_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTS_BYTES; - -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 com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAuts; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtAutsTest { - private EapAkaAttributeFactory mEapAkaAttributeFactory; - - @Before - public void setUp() { - mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_AUTS); - EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtAuts atAuts = (AtAuts) result; - assertEquals(EAP_AT_AUTS, atAuts.attributeType); - assertEquals(AT_AUTS.length, atAuts.lengthInBytes); - assertArrayEquals(AUTS_BYTES, atAuts.auts); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_AUTS_INVALID_LENGTH); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtAuts atAuts = new AtAuts(AUTS_BYTES); - - ByteBuffer result = ByteBuffer.allocate(AT_AUTS.length); - atAuts.encode(result); - assertArrayEquals(AT_AUTS, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java deleted file mode 100644 index efdfcc2e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_BIDDING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_SUPPORTS_AKA_PRIME; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtBiddingTest { - private EapAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = EapAkaAttributeFactory.getInstance(); - } - - @Test - public void testDecodeServerSupportsAkaPrime() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_SUPPORTS_AKA_PRIME); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtBidding atBidding = (AtBidding) result; - assertEquals(EAP_AT_BIDDING, atBidding.attributeType); - assertEquals(AT_BIDDING_SUPPORTS_AKA_PRIME.length, atBidding.lengthInBytes); - assertTrue(atBidding.doesServerSupportEapAkaPrime); - } - - @Test - public void testDecodeDoesNotSupportAkaPrime() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtBidding atBidding = (AtBidding) result; - assertEquals(EAP_AT_BIDDING, atBidding.attributeType); - assertEquals(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME.length, atBidding.lengthInBytes); - assertFalse(atBidding.doesServerSupportEapAkaPrime); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeServerSupportsAkaPrime() throws Exception { - AtBidding atBidding = new AtBidding(true); - - ByteBuffer result = ByteBuffer.allocate(AT_BIDDING_SUPPORTS_AKA_PRIME.length); - atBidding.encode(result); - assertArrayEquals(AT_BIDDING_SUPPORTS_AKA_PRIME, result.array()); - } - - @Test - public void testEncodeDoesNotSupportAkaPrime() throws Exception { - AtBidding atBidding = new AtBidding(false); - - ByteBuffer result = ByteBuffer.allocate(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME.length); - atBidding.encode(result); - assertArrayEquals(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java deleted file mode 100644 index 2051414c..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToInt; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_CLIENT_ERROR_CODE; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_CLIENT_ERROR_CODE; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_CLIENT_ERROR_CODE_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.ERROR_CODE; - -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.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; - -public class AtClientErrorCodeTest { - private static final int EXPECTED_LENGTH = 4; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_CLIENT_ERROR_CODE); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtClientErrorCode); - AtClientErrorCode atClientErrorCode = (AtClientErrorCode) result; - assertEquals(EAP_AT_CLIENT_ERROR_CODE, atClientErrorCode.attributeType); - assertEquals(EXPECTED_LENGTH, atClientErrorCode.lengthInBytes); - assertEquals(hexStringToInt(ERROR_CODE), atClientErrorCode.errorCode); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_CLIENT_ERROR_CODE_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected BufferUnderflowException for invalid attribute length"); - } catch (BufferUnderflowException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtClientErrorCode atNotification = new AtClientErrorCode( - EXPECTED_LENGTH, hexStringToInt(ERROR_CODE)); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atNotification.encode(result); - assertArrayEquals(AT_CLIENT_ERROR_CODE, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java deleted file mode 100644 index eb1086d5..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER_TOO_SMALL; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_TOO_SMALL; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_TOO_SMALL_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.COUNTER_INT; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounter; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounterTooSmall; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtCounterTest { - private static final int EXPECTED_LENGTH = 4; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecodeAtCounter() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_COUNTER); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtCounter); - AtCounter atCounter = (AtCounter) result; - assertEquals(EAP_AT_COUNTER, atCounter.attributeType); - assertEquals(EXPECTED_LENGTH, atCounter.lengthInBytes); - assertEquals(COUNTER_INT, atCounter.counter); - } - - @Test - public void testDecodeAtCounterInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeAtCounter() throws Exception { - AtCounter atCounter = new AtCounter(COUNTER_INT); - - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - atCounter.encode(result); - assertArrayEquals(AT_COUNTER, result.array()); - } - - @Test - public void testAtCounterTooSmallConstructor() throws Exception { - AtCounterTooSmall atCounterTooSmall = new AtCounterTooSmall(); - assertEquals(EAP_AT_COUNTER_TOO_SMALL, atCounterTooSmall.attributeType); - assertEquals(EXPECTED_LENGTH, atCounterTooSmall.lengthInBytes); - } - - @Test - public void testDecodeAtCounterTooSmall() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_TOO_SMALL); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtCounterTooSmall); - AtCounterTooSmall atCounterTooSmall = (AtCounterTooSmall) result; - assertEquals(EAP_AT_COUNTER_TOO_SMALL, atCounterTooSmall.attributeType); - assertEquals(EXPECTED_LENGTH, atCounterTooSmall.lengthInBytes); - } - - @Test - public void testDecodeAtCounterTooSmallInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_TOO_SMALL_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeAtCounterTooSmall() throws Exception { - AtCounterTooSmall atCounterTooSmall = new AtCounterTooSmall(); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - atCounterTooSmall.encode(result); - assertArrayEquals(AT_COUNTER_TOO_SMALL, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java deleted file mode 100644 index d006053e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.ANY_ID_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_ANY_ID_REQ; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_FULL_AUTH_ID_REQ; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PERMANENT_ID_REQ; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.FULL_AUTH_ID_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.PERMANENT_ID_INVALID_LENGTH; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtFullauthIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtIdReqTest { - private static final int EXPECTED_LENGTH = 4; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecodeAtPermanentIdReq() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_PERMANENT_ID_REQ); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtPermanentIdReq); - AtPermanentIdReq atPermanentIdReq = (AtPermanentIdReq) result; - assertEquals(EAP_AT_PERMANENT_ID_REQ, atPermanentIdReq.attributeType); - assertEquals(EXPECTED_LENGTH, atPermanentIdReq.lengthInBytes); - } - - @Test - public void testDecodeAtPermanentIdReqInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(PERMANENT_ID_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeAtPermanentIdReq() throws Exception { - AtPermanentIdReq atPermanentIdReq = new AtPermanentIdReq(); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atPermanentIdReq.encode(result); - assertArrayEquals(AT_PERMANENT_ID_REQ, result.array()); - } - - @Test - public void testDecodeAtAnyIdReq() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_ANY_ID_REQ); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtAnyIdReq); - AtAnyIdReq atAnyIdReq = (AtAnyIdReq) result; - assertEquals(EAP_AT_ANY_ID_REQ, atAnyIdReq.attributeType); - assertEquals(EXPECTED_LENGTH, atAnyIdReq.lengthInBytes); - } - - @Test - public void testDecodeAtAnyIdReqInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(ANY_ID_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeAtAnyIdReq() throws Exception { - AtAnyIdReq atPermanentIdReq = new AtAnyIdReq(); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atPermanentIdReq.encode(result); - assertArrayEquals(AT_ANY_ID_REQ, result.array()); - } - - @Test - public void testDecodeAtFullauthIdReq() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_FULL_AUTH_ID_REQ); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtFullauthIdReq); - AtFullauthIdReq atFullauthIdReq = (AtFullauthIdReq) result; - assertEquals(EAP_AT_FULLAUTH_ID_REQ, atFullauthIdReq.attributeType); - assertEquals(EXPECTED_LENGTH, atFullauthIdReq.lengthInBytes); - } - - @Test - public void testDecodeAtFullauthIdReqInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(FULL_AUTH_ID_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncodeAtFullauthIdReq() throws Exception { - AtFullauthIdReq atPermanentIdReq = new AtFullauthIdReq(); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atPermanentIdReq.encode(result); - assertArrayEquals(AT_FULL_AUTH_ID_REQ, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java deleted file mode 100644 index cf8e8803..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY; - -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 com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtIdentityTest { - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_IDENTITY); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtIdentity); - AtIdentity atIdentity = (AtIdentity) result; - assertEquals(EAP_AT_IDENTITY, atIdentity.attributeType); - assertEquals(AT_IDENTITY.length, atIdentity.lengthInBytes); - assertArrayEquals(IDENTITY, atIdentity.identity); - } - - @Test - public void testEncode() throws Exception { - AtIdentity atIdentity = new AtIdentity(AT_IDENTITY.length, IDENTITY); - ByteBuffer result = ByteBuffer.allocate(AT_IDENTITY.length); - atIdentity.encode(result); - - assertArrayEquals(AT_IDENTITY, result.array()); - } - - @Test - public void testGetAtIdentity() throws Exception { - AtIdentity atIdentity = AtIdentity.getAtIdentity(IDENTITY); - - assertArrayEquals(IDENTITY, atIdentity.identity); - - ByteBuffer buffer = ByteBuffer.allocate(atIdentity.lengthInBytes); - atIdentity.encode(buffer); - buffer.rewind(); - - EapSimAkaAttribute eapSimAkaAttribute = - EapSimAttributeFactory.getInstance().getAttribute(buffer); - assertTrue(eapSimAkaAttribute instanceof AtIdentity); - AtIdentity newAtIdentity = (AtIdentity) eapSimAkaAttribute; - assertEquals(atIdentity.lengthInBytes, newAtIdentity.lengthInBytes); - assertArrayEquals(atIdentity.identity, newAtIdentity.identity); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java deleted file mode 100644 index 51ea3f14..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT_EMPTY_NETWORK_NAME; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_BYTES; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; - -import com.android.internal.net.eap.message.simaka.EapAkaPrimeAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtKdfInputTest { - private EapAkaPrimeAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = EapAkaPrimeAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_KDF_INPUT); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtKdfInput atKdfInput = (AtKdfInput) result; - assertEquals(EAP_AT_KDF_INPUT, atKdfInput.attributeType); - assertEquals(AT_KDF_INPUT.length, atKdfInput.lengthInBytes); - assertArrayEquals(NETWORK_NAME_BYTES, atKdfInput.networkName); - } - - @Test - public void testDecodeEmptyNetworkName() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_KDF_INPUT_EMPTY_NETWORK_NAME); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtKdfInput atKdfInput = (AtKdfInput) result; - assertEquals(EAP_AT_KDF_INPUT, atKdfInput.attributeType); - assertEquals(AT_KDF_INPUT_EMPTY_NETWORK_NAME.length, atKdfInput.lengthInBytes); - assertArrayEquals(new byte[0], atKdfInput.networkName); - } - - @Test - public void testEncode() throws Exception { - AtKdfInput atKdfInput = new AtKdfInput(AT_KDF_INPUT.length, NETWORK_NAME_BYTES); - ByteBuffer result = ByteBuffer.allocate(AT_KDF_INPUT.length); - - atKdfInput.encode(result); - assertArrayEquals(AT_KDF_INPUT, result.array()); - assertFalse(result.hasRemaining()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java deleted file mode 100644 index 0bb07326..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.KDF_VERSION; - -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 com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaPrimeAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtKdfTest { - private EapAkaPrimeAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = EapAkaPrimeAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_KDF); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtKdf atKdf = (AtKdf) result; - assertEquals(EAP_AT_KDF, atKdf.attributeType); - assertEquals(AT_KDF.length, atKdf.lengthInBytes); - assertEquals(KDF_VERSION, atKdf.kdf); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_KDF_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtKdf atKdf = new AtKdf(KDF_VERSION); - ByteBuffer result = ByteBuffer.allocate(AT_KDF.length); - - atKdf.encode(result); - assertArrayEquals(AT_KDF, result.array()); - assertFalse(result.hasRemaining()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java deleted file mode 100644 index 82b066d5..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_MAC; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_MAC_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.MAC; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtMacTest { - private static final int EXPECTED_LENGTH = 20; - private static final int MAC_LENGTH = 16; - private static final byte[] MAC_BYTES = hexStringToByteArray(MAC); - private static final byte[] INVALID_MAC = {(byte) 1, (byte) 2, (byte) 3}; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testConstructor() throws Exception { - AtMac atMac = new AtMac(); - assertEquals(EAP_AT_MAC, atMac.attributeType); - assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes); - assertArrayEquals(new byte[MAC_LENGTH], atMac.mac); - } - - @Test - public void testParameterizedConstructor() throws Exception { - AtMac atMac = new AtMac(MAC_BYTES); - assertEquals(EAP_AT_MAC, atMac.attributeType); - assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes); - assertArrayEquals(MAC_BYTES, atMac.mac); - } - - @Test - public void testParameterizedConstructorInvalidMac() { - try { - AtMac atMac = new AtMac(INVALID_MAC); - fail("Expected EapSimAkaInvalidAttributeException for invalid MAC length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_MAC); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtMac); - AtMac atMac = (AtMac) result; - assertEquals(EAP_AT_MAC, atMac.attributeType); - assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes); - assertArrayEquals(MAC_BYTES, atMac.mac); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_MAC_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtMac atMac = new AtMac(MAC_BYTES); - - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - atMac.encode(result); - assertArrayEquals(AT_MAC, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java deleted file mode 100644 index 751908a2..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_MT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_MT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt; -import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtNonceMtTest { - private static final byte[] INVALID_NONCE = new byte[10]; - private static final int EXPECTED_LENGTH = 20; - - private EapSimAttributeFactory mEapSimAttributeFactory; - - @Before - public void setUp() { - mEapSimAttributeFactory = EapSimAttributeFactory.getInstance(); - } - - @Test - public void testConstructorInvalidNonceLength() { - try { - new AtNonceMt(INVALID_NONCE); - fail("Expected EapSimAkaInvalidAttributeException for invalid NonceMt length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NONCE_MT); - EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtNonceMt); - AtNonceMt atNonceMt = (AtNonceMt) result; - assertEquals(EAP_AT_NONCE_MT, atNonceMt.attributeType); - assertEquals(EXPECTED_LENGTH, atNonceMt.lengthInBytes); - assertArrayEquals(NONCE_MT, atNonceMt.nonceMt); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NONCE_INVALID_LENGTH); - try { - mEapSimAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws EapSimAkaInvalidAttributeException { - AtNonceMt atNonceMt = new AtNonceMt(NONCE_MT); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atNonceMt.encode(result); - assertArrayEquals(AT_NONCE_MT, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java deleted file mode 100644 index 1ad64669..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_S; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_S; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_S_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_S; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceS; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtNonceSTest { - private static final byte[] INVALID_NONCE = new byte[10]; - private static final int EXPECTED_LENGTH = 20; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testConstructorInvalidNonceLength() { - try { - new AtNonceS(INVALID_NONCE); - fail("Expected EapSimAkaInvalidAttributeException for invalid NonceMt length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NONCE_S); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtNonceS); - AtNonceS atNonceS = (AtNonceS) result; - assertEquals(EAP_AT_NONCE_S, atNonceS.attributeType); - assertEquals(EXPECTED_LENGTH, atNonceS.lengthInBytes); - assertArrayEquals(hexStringToByteArray(NONCE_S), atNonceS.nonceS); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NONCE_S_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtNonceS atNonceS = new AtNonceS(hexStringToByteArray(NONCE_S)); - - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - atNonceS.encode(result); - assertArrayEquals(AT_NONCE_S, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java deleted file mode 100644 index 2db3cbb2..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToInt; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_POST_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION_INVALID_STATE; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NOTIFICATION_CODE; - -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.assertTrue; -import static org.junit.Assert.fail; - -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtNotificationTest { - private static final int EXPECTED_LENGTH = 4; - private static final int UNKNOWN_CODE = 0xA0FF; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtNotification); - AtNotification atNotification = (AtNotification) result; - assertEquals(EAP_AT_NOTIFICATION, atNotification.attributeType); - assertEquals(EXPECTED_LENGTH, atNotification.lengthInBytes); - assertTrue(atNotification.isSuccessCode); - assertFalse(atNotification.isPreSuccessfulChallenge); - assertEquals(hexStringToInt(NOTIFICATION_CODE), atNotification.notificationCode); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION_INVALID_LENGTH); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecodeInvalidState() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION_INVALID_STATE); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid state"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtNotification atNotification = new AtNotification(hexStringToInt(NOTIFICATION_CODE)); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atNotification.encode(result); - assertArrayEquals(AT_NOTIFICATION, result.array()); - } - - @Test - public void testToString() throws Exception { - AtNotification knownCode = new AtNotification(GENERAL_FAILURE_POST_CHALLENGE); - AtNotification unknownCode = new AtNotification(UNKNOWN_CODE); - - assertNotNull(knownCode.toString()); - assertNotNull(unknownCode.toString()); - assertNotEquals(knownCode.toString(), unknownCode.toString()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java deleted file mode 100644 index d310d504..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PADDING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PADDING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PADDING_INVALID_PADDING; - -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.eap.exceptions.simaka.EapSimAkaInvalidAtPaddingException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPadding; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtPaddingTest { - private static final int EXPECTED_LENGTH = 8; - - private EapSimAkaAttributeFactory mAttributeFactory; - - @Before - public void setUp() { - mAttributeFactory = new EapSimAkaAttributeFactory() {}; - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_PADDING); - EapSimAkaAttribute result = mAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtPadding); - AtPadding atPadding = (AtPadding) result; - assertEquals(EAP_AT_PADDING, atPadding.attributeType); - assertEquals(EXPECTED_LENGTH, atPadding.lengthInBytes); - } - - @Test - public void testDecodeInvalidPadding() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_PADDING_INVALID_PADDING); - try { - mAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAtPaddingException for nonzero padding bytes"); - } catch (EapSimAkaInvalidAtPaddingException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtPadding atPadding = new AtPadding(EXPECTED_LENGTH); - - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - atPadding.encode(result); - - assertFalse(result.hasRemaining()); - assertArrayEquals(AT_PADDING, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java deleted file mode 100644 index bdffdda9..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_AKA; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_AKA_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES; - -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 com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtRandAkaTest { - private EapAkaAttributeFactory mEapAkaAttributeFactory; - - @Before - public void setUp() { - mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RAND_AKA); - EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtRandAka atRandAka = (AtRandAka) result; - assertEquals(EAP_AT_RAND, atRandAka.attributeType); - assertEquals(AT_RAND_AKA.length, atRandAka.lengthInBytes); - assertArrayEquals(RAND_1_BYTES, atRandAka.rand); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RAND_AKA_INVALID_LENGTH); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - - ByteBuffer result = ByteBuffer.allocate(AT_RAND_AKA.length); - atRandAka.encode(result); - assertArrayEquals(AT_RAND_AKA, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java deleted file mode 100644 index 7456be6c..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM_DUPLICATE_RANDS; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM_INVALID_NUM_RANDS; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.exceptions.simaka.EapSimInvalidAtRandException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim; -import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtRandSimTest { - private static final int EXPECTED_NUM_RANDS = 2; - - private EapSimAttributeFactory mEapSimAttributeFactory; - - @Before - public void setUp() { - mEapSimAttributeFactory = EapSimAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM); - EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtRandSim); - AtRandSim atRandSim = (AtRandSim) result; - assertEquals(EAP_AT_RAND, atRandSim.attributeType); - assertEquals(AT_RAND_SIM.length, atRandSim.lengthInBytes); - assertEquals(EXPECTED_NUM_RANDS, atRandSim.rands.size()); - assertArrayEquals(hexStringToByteArray(RAND_1), atRandSim.rands.get(0)); - assertArrayEquals(hexStringToByteArray(RAND_2), atRandSim.rands.get(1)); - } - - @Test - public void testDecodeInvalidNumRands() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM_INVALID_NUM_RANDS); - try { - mEapSimAttributeFactory.getAttribute(input); - fail("Expected EapSimInvalidAtRandException for invalid number of RANDs"); - } catch (EapSimInvalidAtRandException expected) { - } - } - - @Test - public void testDecodeDuplicateRands() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM_DUPLICATE_RANDS); - try { - mEapSimAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for duplicate RANDs"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - byte[][] expectedRands = new byte[][] { - hexStringToByteArray(RAND_1), - hexStringToByteArray(RAND_2) - }; - AtRandSim atRandSim = new AtRandSim(AT_RAND_SIM.length, expectedRands); - - ByteBuffer result = ByteBuffer.allocate(AT_RAND_SIM.length); - atRandSim.encode(result); - assertArrayEquals(AT_RAND_SIM, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java deleted file mode 100644 index 34c2ff39..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_INVALID_RES_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_LONG_RES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_SHORT_RES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtResTest { - private EapAkaAttributeFactory mEapAkaAttributeFactory; - - @Before - public void setUp() { - mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RES); - EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - AtRes atRes = (AtRes) result; - assertEquals(EAP_AT_RES, atRes.attributeType); - assertEquals(AT_RES.length, atRes.lengthInBytes); - assertArrayEquals(RES_BYTES, atRes.res); - } - - @Test - public void testDecodeInvalidResLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RES_INVALID_RES_LENGTH); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid RES length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecodeShortResLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RES_SHORT_RES); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for too short RES"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testDecodeLongResLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_RES_LONG_RES); - try { - mEapAkaAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for too long RES"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtRes atRes = new AtRes(AT_RES.length, RES_BYTES); - - ByteBuffer result = ByteBuffer.allocate(AT_RES.length); - atRes.encode(result); - assertArrayEquals(AT_RES, result.array()); - } - - @Test - public void testGetAtRes() throws Exception { - AtRes atRes = AtRes.getAtRes(RES_BYTES); - - ByteBuffer result = ByteBuffer.allocate(AT_RES.length); - atRes.encode(result); - assertArrayEquals(AT_RES, result.array()); - } - - @Test - public void testIsValidResLen() { - // valid RES length: 4 <= RES length <= 16 - assertTrue(AtRes.isValidResLen(5)); - assertFalse(AtRes.isValidResLen(0)); - assertFalse(AtRes.isValidResLen(20)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java deleted file mode 100644 index 659fe9a8..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_SELECTED_VERSION; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_SELECTED_VERSION; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_SELECTED_VERSION_INVALID_LENGTH; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion; -import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class AtSelectedVersionTest { - private static final int EXPECTED_LENGTH = 4; - private static final int EXPECTED_VERSION = 1; - - private EapSimAttributeFactory mEapSimAttributeFactory; - - @Before - public void setUp() { - mEapSimAttributeFactory = EapSimAttributeFactory.getInstance(); - } - - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_SELECTED_VERSION); - EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtSelectedVersion); - AtSelectedVersion atSelectedVersion = (AtSelectedVersion) result; - assertEquals(EAP_AT_SELECTED_VERSION, atSelectedVersion.attributeType); - assertEquals(EXPECTED_LENGTH, atSelectedVersion.lengthInBytes); - assertEquals(EXPECTED_VERSION, atSelectedVersion.selectedVersion); - } - - @Test - public void testDecodeInvalidLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_SELECTED_VERSION_INVALID_LENGTH); - try { - mEapSimAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid actual list length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtSelectedVersion atSelectedVersion = new AtSelectedVersion( - EXPECTED_LENGTH, EXPECTED_VERSION); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atSelectedVersion.encode(result); - assertArrayEquals(AT_SELECTED_VERSION, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java deleted file mode 100644 index 96bb7ca3..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToInt; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST_INVALID_LENGTH; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.VERSION; - -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.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList; -import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.List; - -public class AtVersionListTest { - private static final int EXPECTED_LENGTH = 8; - private static final List<Integer> EXPECTED_VERSIONS = Arrays.asList(1); - - private EapSimAttributeFactory mEapSimAttributeFactory; - - @Before - public void setUp() { - mEapSimAttributeFactory = EapSimAttributeFactory.getInstance(); - } - - @Test - public void testDecode() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_VERSION_LIST); - EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input); - - assertFalse(input.hasRemaining()); - assertTrue(result instanceof AtVersionList); - AtVersionList atVersionList = (AtVersionList) result; - assertEquals(EAP_AT_VERSION_LIST, atVersionList.attributeType); - assertEquals(EXPECTED_LENGTH, atVersionList.lengthInBytes); - assertEquals(EXPECTED_VERSIONS, atVersionList.versions); - } - - @Test - public void testDecodeInvalidActualLength() throws Exception { - ByteBuffer input = ByteBuffer.wrap(AT_VERSION_LIST_INVALID_LENGTH); - try { - mEapSimAttributeFactory.getAttribute(input); - fail("Expected EapSimAkaInvalidAttributeException for invalid actual list length"); - } catch (EapSimAkaInvalidAttributeException expected) { - } - } - - @Test - public void testEncode() throws Exception { - AtVersionList atVersionList = new AtVersionList(EXPECTED_LENGTH, hexStringToInt(VERSION)); - ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH); - - atVersionList.encode(result); - assertArrayEquals(AT_VERSION_LIST, result.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java deleted file mode 100644 index 98ea222c..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; - -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class EapSimAkaAttributeTest { - private static final int EXPECTED_ATTRIBUTE_TYPE = 1; - private static final int EXPECTED_LENGTH_IN_BYTES = 4; - private static final int BUFFER_LENGTH = 2; - private static final int EXPECTED_LENGTH_ENCODED = 1; - private static final byte[] EXPECTED_ENCODING = { - (byte) EXPECTED_ATTRIBUTE_TYPE, - (byte) EXPECTED_LENGTH_ENCODED - }; - - @Test - public void testEncode() throws Exception { - EapSimAkaAttribute eapSimAkaAttribute = new EapSimAkaAttribute( - EXPECTED_ATTRIBUTE_TYPE, - EXPECTED_LENGTH_IN_BYTES) { - public void encode(ByteBuffer byteBuffer) { - encodeAttributeHeader(byteBuffer); - } - }; - - ByteBuffer result = ByteBuffer.allocate(BUFFER_LENGTH); - eapSimAkaAttribute.encode(result); - assertArrayEquals(EXPECTED_ENCODING, result.array()); - assertFalse(result.hasRemaining()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java deleted file mode 100644 index 60397e1f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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.internal.net.eap.message.simaka.attributes; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -/** - * EapTestAttributeDefinitions provides byte[] encodings of commonly used EAP Messages. - * - * @ee <a href="https://tools.ietf.org/html/rfc4186#section-10">RFC 4186, EAP-SIM Authentication, - * Section 10</a> - * @see <a href="https://tools.ietf.org/html/rfc4187#section-10">RFC 4187, EAP-AKA Authentication, - * Section 10</a> - */ -public class EapTestAttributeDefinitions { - public static final String VERSION = "0001"; - public static final String AT_VERSION_LIST_DATA = "0002" + VERSION + "0000"; - public static final byte[] AT_VERSION_LIST = - hexStringToByteArray("0F02" + AT_VERSION_LIST_DATA); - public static final byte[] AT_SELECTED_VERSION = hexStringToByteArray("10010001"); - public static final String NONCE_MT_STRING = "0123456789ABCDEFFEDCBA9876543210"; - public static final byte[] NONCE_MT = hexStringToByteArray(NONCE_MT_STRING); - public static final byte[] AT_NONCE_MT = hexStringToByteArray("07050000" + NONCE_MT_STRING); - public static final byte[] AT_PERMANENT_ID_REQ = hexStringToByteArray("0A010000"); - public static final byte[] AT_ANY_ID_REQ = hexStringToByteArray("0D010000"); - public static final byte[] AT_FULL_AUTH_ID_REQ = hexStringToByteArray("11010000"); - - // Identity = "test1@android.net" - public static final String IDENTITY_STRING = "746573743140616E64726F69642E6E6574"; - public static final byte[] IDENTITY = hexStringToByteArray(IDENTITY_STRING); - public static final byte[] AT_IDENTITY = - hexStringToByteArray("0E060011" + IDENTITY_STRING + "000000"); - public static final String RAND_1 = "00112233445566778899AABBCCDDEEFF"; - public static final byte[] RAND_1_BYTES = hexStringToByteArray(RAND_1); - public static final String RAND_2 = "FFEEDDCCBBAA99887766554433221100"; - public static final byte[] RAND_2_BYTES = hexStringToByteArray(RAND_2); - public static final byte[] AT_RAND_SIM = hexStringToByteArray("01090000" + RAND_1 + RAND_2); - public static final byte[] AT_RAND_AKA = hexStringToByteArray("01050000" + RAND_1); - public static final byte[] AT_PADDING = hexStringToByteArray("0602000000000000"); - public static final String MAC = "112233445566778899AABBCCDDEEFF11"; - public static final byte[] MAC_BYTES = hexStringToByteArray(MAC); - public static final byte[] AT_MAC = hexStringToByteArray("0B050000" + MAC); - public static final String COUNTER = "000A"; - public static final int COUNTER_INT = Integer.parseInt(COUNTER, 16 /* radix */); - public static final byte[] AT_COUNTER = hexStringToByteArray("1301" + COUNTER); - public static final byte[] AT_COUNTER_TOO_SMALL = hexStringToByteArray("14010000"); - public static final String NONCE_S = "0123456789ABCDEFFEDCBA9876543210"; - public static final byte[] AT_NONCE_S = hexStringToByteArray("15050000" + NONCE_S); - public static final String NOTIFICATION_CODE = "8000"; - public static final byte[] AT_NOTIFICATION = hexStringToByteArray("0C01" + NOTIFICATION_CODE); - public static final String ERROR_CODE = "0001"; - public static final byte[] AT_CLIENT_ERROR_CODE = hexStringToByteArray("1601" + ERROR_CODE); - public static final String AUTN = "0123456789ABCDEFFEDCBA9876543210"; - public static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN); - public static final byte[] AT_AUTN = hexStringToByteArray("02050000" + AUTN); - public static final String RES = "1122334455"; - public static final byte[] RES_BYTES = hexStringToByteArray(RES); - public static final byte[] AT_RES = hexStringToByteArray("03030028" + RES + "000000"); - public static final String AUTS = "112233445566778899AABBCCDDEE"; - public static final byte[] AUTS_BYTES = hexStringToByteArray(AUTS); - public static final byte[] AT_AUTS = hexStringToByteArray("0404" + AUTS); - public static final byte[] AT_BIDDING_SUPPORTS_AKA_PRIME = hexStringToByteArray("88018000"); - public static final byte[] AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME = - hexStringToByteArray("88010000"); - - // Network Name = "android.net" - public static final String NETWORK_NAME_HEX = "616E64726F69642E6E6574"; - public static final byte[] NETWORK_NAME_BYTES = hexStringToByteArray(NETWORK_NAME_HEX); - public static final byte[] AT_KDF_INPUT = - hexStringToByteArray("1704000B" + NETWORK_NAME_HEX + "00"); - public static final byte[] AT_KDF_INPUT_EMPTY_NETWORK_NAME = hexStringToByteArray("17010000"); - public static final int KDF_VERSION = 1; - public static final byte[] AT_KDF = hexStringToByteArray("18010001"); - - public static final byte[] AT_VERSION_LIST_INVALID_LENGTH = hexStringToByteArray("0F020003"); - public static final byte[] AT_SELECTED_VERSION_INVALID_LENGTH = - hexStringToByteArray("10020001"); - public static final byte[] AT_NONCE_INVALID_LENGTH = - hexStringToByteArray("07060000" + NONCE_MT_STRING); - public static final byte[] PERMANENT_ID_INVALID_LENGTH = hexStringToByteArray("0A020000"); - public static final byte[] ANY_ID_INVALID_LENGTH = hexStringToByteArray("0D020000"); - public static final byte[] FULL_AUTH_ID_INVALID_LENGTH = hexStringToByteArray("11020000"); - public static final byte[] AT_RAND_SIM_INVALID_NUM_RANDS = - hexStringToByteArray("01050000" + RAND_1); - public static final byte[] AT_RAND_SIM_DUPLICATE_RANDS = - hexStringToByteArray("01090000" + RAND_1 + RAND_1); - public static final byte[] AT_RAND_AKA_INVALID_LENGTH = hexStringToByteArray("01010000"); - public static final byte[] AT_PADDING_INVALID_PADDING = hexStringToByteArray("0601FFFF"); - public static final byte[] AT_MAC_INVALID_LENGTH = hexStringToByteArray("0B06"); - public static final byte[] AT_COUNTER_INVALID_LENGTH = hexStringToByteArray("1302"); - public static final byte[] AT_COUNTER_TOO_SMALL_INVALID_LENGTH = hexStringToByteArray("1402"); - public static final byte[] AT_NONCE_S_INVALID_LENGTH = hexStringToByteArray("1506"); - public static final byte[] AT_NOTIFICATION_INVALID_LENGTH = hexStringToByteArray("0C02"); - public static final byte[] AT_NOTIFICATION_INVALID_STATE = hexStringToByteArray("0C01C000"); - public static final byte[] AT_CLIENT_ERROR_CODE_INVALID_LENGTH = hexStringToByteArray("1602"); - public static final byte[] AT_AUTN_INVALID_LENGTH = hexStringToByteArray("02010000"); - public static final byte[] AT_RES_INVALID_RES_LENGTH = - hexStringToByteArray("030300241122334450000000"); - public static final byte[] AT_RES_SHORT_RES = - hexStringToByteArray("0302000811000000"); - public static final byte[] AT_RES_LONG_RES = - hexStringToByteArray("0306008800112233445566778899AABBCCDDEEFF11000000"); - public static final byte[] AT_AUTS_INVALID_LENGTH = hexStringToByteArray("03010000"); - public static final byte[] AT_KDF_INVALID_LENGTH = hexStringToByteArray("18020001"); - public static final byte[] AT_BIDDING_INVALID_LENGTH = hexStringToByteArray("88020000"); -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java deleted file mode 100644 index a452fa6f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.statemachine.EapStateMachine.IdentityState; -import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState; - -import org.junit.Before; -import org.junit.Test; - -public class CreatedStateTest extends EapStateTest { - private EapStateMachine mEapStateMachineSpy; - - @Before - @Override - public void setUp() { - super.setUp(); - - mEapStateMachineSpy = spy(mEapStateMachine); - mEapState = mEapStateMachineSpy.new CreatedState(); - } - - @Test - public void testProcessIdentityRequest() { - mEapState.process(EAP_REQUEST_IDENTITY_PACKET); - - verify(mEapStateMachineSpy).transitionAndProcess( - any(IdentityState.class), eq(EAP_REQUEST_IDENTITY_PACKET)); - } - - @Test - public void testProcessNotificationRequest() { - EapResult eapResult = mEapState.process(EAP_REQUEST_NOTIFICATION_PACKET); - - // state shouldn't change after Notification request - assertTrue(eapResult instanceof EapResponse); - EapResponse eapResponse = (EapResponse) eapResult; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any()); - } - - @Test - public void testProcessSimStart() { - mEapState.process(EAP_REQUEST_SIM_START_PACKET); - - // EapStateMachine should change to MethodState for method-type packet - verify(mEapStateMachineSpy).transitionAndProcess( - any(MethodState.class), eq(EAP_REQUEST_SIM_START_PACKET)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java deleted file mode 100644 index b07d1ff3..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java +++ /dev/null @@ -1,430 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CK_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_AUTHENTICATION_REJECT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_SYNCHRONIZATION_FAILURE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_INVALID_TAG; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_SUCCESS_BASE_64; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IK_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTS_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.EapResult.EapSuccess; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.exceptions.simaka.EapAkaInvalidAuthenticationResponse; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState.RandChallengeResult; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; - -public class EapAkaChallengeStateTest extends EapAkaStateTest { - private ChallengeState mChallengeState; - - // '10' + RAND_1_BYTES + '10' + AUTN_BYTES - private static final String BASE_64_CHALLENGE = - "EAARIjNEVWZ3iJmqu8zd7v8QASNFZ4mrze/+3LqYdlQyEA=="; - - /** - * Process to generate MAC: - * - * message = 01100044 | EAP-Request, ID, length in bytes - * 17010000 | EAP-AKA, AKA-Challenge, padding - * 0105000000112233445566778899AABBCCDDEEFF | AT_RAND - * 020500000123456789ABCDEFFEDCBA9876543210 | AT_AUTN - * 0B05000000000000000000000000000000000000 | AT_MAC (zeroed out) - * - * MK = SHA-1(Identity | IK | CK) - * K_encr, K_aut, MSK, EMSK = PRF(MK) - * MAC = HMAC-SHA-1(K_aut, message) - */ - private static final byte[] REQUEST_MAC_BYTES = - hexStringToByteArray("3EB97A1D0E62894FD0DA384D24D8983C"); - - /** - * message = 01100048 | EAP-Request, ID, length in bytes - * 17010000 | EAP-AKA, AKA-Challenge, padding - * 0105000000112233445566778899AABBCCDDEEFF | AT_RAND - * 020500000123456789ABCDEFFEDCBA9876543210 | AT_AUTN - * 88018000 | AT_BIDDING - * 0B05000000000000000000000000000000000000 | AT_MAC (zeroed out) - */ - private static final byte[] BIDDING_DOWN_MAC = - hexStringToByteArray("9CB543894A5EFDC32DF6A6CE1AB0E01A"); - - @Before - public void setUp() { - super.setUp(); - - mChallengeState = mEapAkaMethodStateMachine.new ChallengeState(IDENTITY); - mEapAkaMethodStateMachine.transitionTo(mChallengeState); - } - - @Test - public void testProcessIncorrectEapMethodType() throws Exception { - EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapResult result = mChallengeState.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessSuccess() throws Exception { - System.arraycopy(MSK, 0, mEapAkaMethodStateMachine.mMsk, 0, MSK.length); - System.arraycopy(EMSK, 0, mEapAkaMethodStateMachine.mEmsk, 0, EMSK.length); - - mChallengeState.mHadSuccessfulChallenge = true; - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - - EapSuccess eapSuccess = (EapSuccess) mEapAkaMethodStateMachine.process(input); - assertArrayEquals(MSK, eapSuccess.msk); - assertArrayEquals(EMSK, eapSuccess.emsk); - assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState); - } - - @Test - public void testProcessInvalidSuccess() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - - EapError eapError = (EapError) mEapAkaMethodStateMachine.process(input); - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessFailure() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null); - EapResult result = mEapAkaMethodStateMachine.process(input); - assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState); - - assertTrue(result instanceof EapFailure); - } - - @Test - public void testProcessMissingAtRand() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atAutn, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessMissingAtAutn() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessMissingAtMac() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testRandChallengeResultConstructor() throws Exception { - RandChallengeResult result = - mChallengeState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES); - assertArrayEquals(RES_BYTES, result.res); - assertArrayEquals(IK_BYTES, result.ik); - assertArrayEquals(CK_BYTES, result.ck); - assertNull(result.auts); - - result = mChallengeState.new RandChallengeResult(AUTS_BYTES); - assertArrayEquals(AUTS_BYTES, result.auts); - assertNull(result.res); - assertNull(result.ik); - assertNull(result.ck); - - try { - mChallengeState.new RandChallengeResult(new byte[0], IK_BYTES, CK_BYTES); - fail("Expected EapSimAkaInvalidLengthException for invalid RES length"); - } catch (EapSimAkaInvalidLengthException ex) { - } - - try { - mChallengeState.new RandChallengeResult(RES_BYTES, new byte[0], CK_BYTES); - fail("Expected EapSimAkaInvalidLengthException for invalid IK length"); - } catch (EapSimAkaInvalidLengthException ex) { - } - - try { - mChallengeState.new RandChallengeResult(RES_BYTES, IK_BYTES, new byte[0]); - fail("Expected EapSimAkaInvalidLengthException for invalid CK length"); - } catch (EapSimAkaInvalidLengthException ex) { - } - - try { - mChallengeState.new RandChallengeResult(new byte[0]); - fail("Expected EapSimAkaInvalidLengthException for invalid AUTS length"); - } catch (EapSimAkaInvalidLengthException ex) { - } - } - - @Test - public void testProcessIccAuthenticationNullResponse() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)) - .thenReturn(null); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_AUTHENTICATION_REJECT, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessIccAuthenticationInvalidTag() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)) - .thenReturn(EAP_AKA_UICC_RESP_INVALID_TAG); - - EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage); - assertTrue(eapError.cause instanceof EapAkaInvalidAuthenticationResponse); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessIccAuthenticationSynchronizeTag() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)) - .thenReturn(EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_SYNCHRONIZATION_FAILURE, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessValidChallenge() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(REQUEST_MAC_BYTES); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)) - .thenReturn(EAP_AKA_UICC_RESP_SUCCESS_BASE_64); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CHALLENGE_RESPONSE, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessBiddingDownAttack() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtBidding atBidding = new AtBidding(true); - AtMac atMac = new AtMac(BIDDING_DOWN_MAC); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atBidding, atMac))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)) - .thenReturn(EAP_AKA_UICC_RESP_SUCCESS_BASE_64); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_AUTHENTICATION_REJECT, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java deleted file mode 100644 index 6e100dbf..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.IdentityState; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; - -import org.junit.Test; - -import java.util.LinkedHashMap; - -public class EapAkaCreatedStateTest extends EapAkaStateTest { - @Test - public void testProcessTransitionToIdentityState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaTypeData(EAP_AKA_IDENTITY, new LinkedHashMap<>())); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mEapAkaMethodStateMachine.process(eapMessage); - - assertTrue(mEapAkaMethodStateMachine.getState() instanceof IdentityState); - - // decoded in CreatedState and IdentityState - verify(mMockEapAkaTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - } - - @Test - public void testProcessTransitionToChallengeState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaTypeData(EAP_AKA_CHALLENGE, new LinkedHashMap<>())); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mEapAkaMethodStateMachine.process(eapMessage); - - ChallengeState challengeState = (ChallengeState) mEapAkaMethodStateMachine.getState(); - assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity); - - // decoded in CreatedState and ChallengeState - verify(mMockEapAkaTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - } - - @Test - public void testProcessSuccess() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - EapResult result = mEapAkaMethodStateMachine.process(input); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessFailure() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null); - EapResult result = mEapAkaMethodStateMachine.process(input); - assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState); - - assertTrue(result instanceof EapFailure); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java deleted file mode 100644 index 20175f95..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_IDENTITY_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.IdentityState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.LinkedHashMap; - -public class EapAkaIdentityStateTest extends EapAkaStateTest { - private IdentityState mIdentityState; - - @Before - public void setUp() { - super.setUp(); - - mIdentityState = mEapAkaMethodStateMachine.new IdentityState(); - mEapAkaMethodStateMachine.transitionTo(mIdentityState); - } - - @Test - public void testProcessIdentityRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq()))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_IDENTITY_RESPONSE, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager).getSubscriberId(); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessWithoutIdentityRequestAttributes() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaTypeData(EAP_AKA_IDENTITY, new LinkedHashMap<>())); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessMultipleIdentityRequestAttributes() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData( - EAP_AKA_IDENTITY, - Arrays.asList(new AtAnyIdReq(), new AtPermanentIdReq()))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessImsiUnavailable() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq()))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(null); - - EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage); - assertTrue(eapError.cause instanceof EapSimAkaIdentityUnavailableException); - - verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager).getSubscriberId(); - verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessTransitionToChallengeState() throws Exception { - // transition to IdentityState so we can verify the transition to ChallengeState - IdentityState identityState = mEapAkaMethodStateMachine.new IdentityState(); - mEapAkaMethodStateMachine.transitionTo(identityState); - - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaTypeData(EAP_AKA_CHALLENGE, new LinkedHashMap<>())); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mEapAkaMethodStateMachine.process(eapMessage); - - assertTrue(mEapAkaMethodStateMachine.getState() instanceof ChallengeState); - - // decoded in IdentityState and ChallengeState - verify(mMockEapAkaTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java deleted file mode 100644 index db2899b6..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_NOTIFICATION_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE; - -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.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig.EapAkaConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.CreatedState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; - -public class EapAkaMethodStateMachineTest { - private static final int SUB_ID = 1; - private static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566"); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - protected TelephonyManager mMockTelephonyManager; - private EapAkaTypeDataDecoder mMockEapAkaTypeDataDecoder; - - private EapAkaConfig mEapAkaConfig = new EapAkaConfig(SUB_ID, APPTYPE_USIM); - private EapAkaMethodStateMachine mEapAkaMethodStateMachine; - - @Before - public void setUp() { - mMockTelephonyManager = mock(TelephonyManager.class); - mMockEapAkaTypeDataDecoder = mock(EapAkaTypeDataDecoder.class); - - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - - mEapAkaMethodStateMachine = - new EapAkaMethodStateMachine( - mMockTelephonyManager, - EAP_IDENTITY_BYTES, - mEapAkaConfig, - mMockEapAkaTypeDataDecoder, - false); - - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - } - - @Test - public void testEapAkaMethodStateMachineStartState() { - assertTrue(mEapAkaMethodStateMachine.getState() instanceof CreatedState); - } - - @Test - public void testGetEapMethod() { - assertEquals(EAP_TYPE_AKA, mEapAkaMethodStateMachine.getEapMethod()); - } - - @Test - public void testEapAkaFailsOnMultipleAkaNotifications() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // First EAP-AKA/Notification - EapAkaTypeData notificationTypeData = - new EapAkaTypeData( - EAP_AKA_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(notificationTypeData); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_NOTIFICATION_RESPONSE, eapResponse.packet); - verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - - // Transition to IdentityState - decodeResult = - new DecodeResult<>( - new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq()))); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI); - - eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertFalse( - "EAP-Request/AKA-Identity returned a Client-Error response", - Arrays.equals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet)); - - // decoded in: previous 1 time + in CreatedState and IdentityState - verify(mMockEapAkaTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager).getSubscriberId(); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - - // Second EAP-AKA/Notification - decodeResult = new DecodeResult<>(notificationTypeData); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage); - assertTrue(eapError.cause instanceof EapInvalidRequestException); - - // decoded previous 3 times + 1 - verify(mMockEapAkaTypeDataDecoder, times(4)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java deleted file mode 100644 index 731eb6bd..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java +++ /dev/null @@ -1,354 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CK_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_AUTHENTICATION_REJECT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IK_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.MAC_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState.RandChallengeResult; -import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; - -public class EapAkaPrimeChallengeStateTest extends EapAkaPrimeStateTest { - private static final String SERVER_NETWORK_NAME_STRING = "foo:bar:buzz"; - private static final byte[] SERVER_NETWORK_NAME = - SERVER_NETWORK_NAME_STRING.getBytes(StandardCharsets.UTF_8); - private static final String INCORRECT_NETWORK_NAME = "foo:buzz"; - private static final byte[] INCORRECT_SERVER_NETWORK_NAME = - INCORRECT_NETWORK_NAME.getBytes(StandardCharsets.UTF_8); - private static final int VALID_KDF = 1; - private static final int INVALID_KDF = 10; - - private static final byte[] EXPECTED_CK_IK_PRIME = - hexStringToByteArray( - "A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6"); - private static final byte[] K_ENCR = hexStringToByteArray("15a5bb098528210cde9e8d4a1bd63850"); - private static final byte[] K_AUT = - hexStringToByteArray( - "957b3d518ac9ff028f2cc5177fedad841f5f812cb06e2b88aceaa98129680f35"); - private static final byte[] K_RE = - hexStringToByteArray( - "3c15cf7112935a8170d0904622ecbb67c49dcba5d50814bdd81958e045e42f9c"); - private static final byte[] MSK = - hexStringToByteArray( - "1dcca0351a58d2b858e6cf2380551470d67cc8749d1915409793171abd360118" - + "e3ae271bf088ca5a41bb1b9b8f7028bcba888298bfbf64d7b8a4f53a6c2cdf18"); - private static final byte[] EMSK = - hexStringToByteArray( - "a5e6b66a9cb2daa9fe3867d41145848e7bf50d749bfd1bb0d090257402e6a555" - + "da6d538e76b71e9f80afe60709965a63a355bdccc4e3a8b358e098e41545fa67"); - - private ChallengeState mState; - - @Before - public void setUp() { - super.setUp(); - - mState = mStateMachine.new ChallengeState(); - mStateMachine.transitionTo(mState); - } - - @Test - public void testTransitionWithEapIdentity() throws Exception { - mStateMachine.transitionTo(mStateMachine.new CreatedState()); - - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>())); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mStateMachine.process(eapMessage); - - ChallengeState challengeState = (ChallengeState) mStateMachine.getState(); - assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity); - - // decode() is called in CreatedState and ChallengeState - verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testTransitionWithEapAkaPrimeIdentity() throws Exception { - mStateMachine.transitionTo(mStateMachine.new CreatedState()); - - // Process AKA' Identity Request - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq()))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_IDENTITY_RESPONSE, eapResponse.packet); - - // decode() is called in CreatedState and IdentityState - verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager).getSubscriberId(); - - // Process AKA' Challenge Request - decodeResult = - new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>())); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mStateMachine.process(eapMessage); - - ChallengeState challengeState = (ChallengeState) mStateMachine.getState(); - assertArrayEquals(EAP_AKA_PRIME_IDENTITY_BYTES, challengeState.mIdentity); - - // decode() called again in IdentityState and ChallengeState - verify(mMockTypeDataDecoder, times(4)).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testProcessMissingAtKdf() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdfInput atKdfInput = new AtKdfInput(0, SERVER_NETWORK_NAME); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac, atKdfInput))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet); - verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testProcessMissingAtKdfInput() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdf atKdf = new AtKdf(VALID_KDF); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn, atMac, atKdf))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet); - verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testProcessUnsupportedKdf() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdfInput atKdfInput = new AtKdfInput(0, SERVER_NETWORK_NAME); - AtKdf atKdf = new AtKdf(INVALID_KDF); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet); - verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testProcessIncorrectNetworkName() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdfInput atKdfInput = new AtKdfInput(0, INCORRECT_SERVER_NETWORK_NAME); - AtKdf atKdf = new AtKdf(VALID_KDF); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet); - verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - } - - @Test - public void testProcessIncorrectNetworkNameIsIgnored() throws Exception { - // Create state machine with configs allowing invalid network name to be ignored - mStateMachine = - new EapAkaPrimeMethodStateMachine( - mMockContext, - EAP_IDENTITY_BYTES, - new EapSessionConfig.EapAkaPrimeConfig( - SUB_ID, APPTYPE_USIM, PEER_NETWORK_NAME, true), - mMockTypeDataDecoder); - mState = mStateMachine.new ChallengeState(); - mStateMachine.transitionTo(mState); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdfInput atKdfInput = new AtKdfInput(0, INCORRECT_SERVER_NETWORK_NAME); - AtKdf atKdf = new AtKdf(VALID_KDF); - - EapAkaPrimeTypeData eapAkaPrimeTypeData = - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf)); - assertTrue( - "Incorrect network names should be ignored", - mState.isValidChallengeAttributes(eapAkaPrimeTypeData)); - } - - @Test - public void testHasMatchingNetworkNames() { - // "" should match anything - assertTrue(mState.hasMatchingNetworkNames("", SERVER_NETWORK_NAME_STRING)); - assertTrue(mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, "")); - - // "foo:bar" should match "foo:bar:buzz" - assertTrue(mState.hasMatchingNetworkNames(PEER_NETWORK_NAME, SERVER_NETWORK_NAME_STRING)); - assertTrue(mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, PEER_NETWORK_NAME)); - - // "foo:buzz" shouldn't match "foo:bar:buzz" - assertFalse( - mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, INCORRECT_NETWORK_NAME)); - assertFalse( - mState.hasMatchingNetworkNames(INCORRECT_NETWORK_NAME, SERVER_NETWORK_NAME_STRING)); - } - - @Test - public void testDeriveCkIkPrime() throws Exception { - RandChallengeResult randChallengeResult = - mState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES); - AtKdfInput atKdfInput = - new AtKdfInput(0, PEER_NETWORK_NAME.getBytes(StandardCharsets.UTF_8)); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - - // S = FC | Network Name | len(Network Name) | SQN ^ AK | len(SQN ^ AK) - // = 20666F6F3A62617200070123456789AB0006 - // K = CK | IK - // = FFEEDDCCBBAA9988776655443322110000112233445566778899AABBCCDDEEFF - // CK' | IK' = HMAC-SHA256(K, S) - // = A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6 - byte[] result = mState.deriveCkIkPrime(randChallengeResult, atKdfInput, atAutn); - assertArrayEquals(EXPECTED_CK_IK_PRIME, result); - } - - @Test - public void testGenerateAndPersistEapAkaKeys() throws Exception { - RandChallengeResult randChallengeResult = - mState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES); - - AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES); - AtAutn atAutn = new AtAutn(AUTN_BYTES); - AtMac atMac = new AtMac(MAC_BYTES); - AtKdfInput atKdfInput = - new AtKdfInput(0, PEER_NETWORK_NAME.getBytes(StandardCharsets.UTF_8)); - AtKdf atKdf = new AtKdf(VALID_KDF); - - EapAkaPrimeTypeData eapAkaPrimeTypeData = - new EapAkaPrimeTypeData( - EAP_AKA_CHALLENGE, - Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf)); - - // CK' | IK' = A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6 - // data = "EAP-AKA'" | Identity - // = 4541502D414B41277465737440616E64726F69642E6E6574 - // prf+(CK' | IK', data) = T1 | T2 | T3 | T4 | T5 | T6 | T7 - // T1 = 15a5bb098528210cde9e8d4a1bd63850957b3d518ac9ff028f2cc5177fedad84 - // T2 = 1f5f812cb06e2b88aceaa98129680f353c15cf7112935a8170d0904622ecbb67 - // T3 = c49dcba5d50814bdd81958e045e42f9c1dcca0351a58d2b858e6cf2380551470 - // T4 = d67cc8749d1915409793171abd360118e3ae271bf088ca5a41bb1b9b8f7028bc - // T5 = ba888298bfbf64d7b8a4f53a6c2cdf18a5e6b66a9cb2daa9fe3867d41145848e - // T6 = 7bf50d749bfd1bb0d090257402e6a555da6d538e76b71e9f80afe60709965a63 - // T7 = a355bdccc4e3a8b358e098e41545fa677897d8341c4a107a2343f393ec966181 - // K_encr | K_aut | K_re | MSK | EMSK = prf+(CK' | IK', data) - assertNull( - mState.generateAndPersistEapAkaKeys(randChallengeResult, 0, eapAkaPrimeTypeData)); - assertArrayEquals(K_ENCR, mStateMachine.mKEncr); - assertArrayEquals(K_AUT, mStateMachine.mKAut); - assertArrayEquals(K_RE, mStateMachine.mKRe); - assertArrayEquals(MSK, mStateMachine.mMsk); - assertArrayEquals(EMSK, mStateMachine.mEmsk); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java deleted file mode 100644 index 90d0bf66..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState; - -import org.junit.Test; - -import java.util.ArrayList; - -public class EapAkaPrimeCreatedStateTest extends EapAkaPrimeStateTest { - @Test - public void testProcessTransitionToIdentityState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, new ArrayList<>())); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mStateMachine.process(eapMessage); - - assertTrue(mStateMachine.getState() instanceof EapAkaMethodStateMachine.IdentityState); - - // decoded in CreatedState and IdentityState - verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder); - } - - @Test - public void testProcessTransitionToChallengeState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>())); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mStateMachine.process(eapMessage); - - ChallengeState challengeState = (ChallengeState) mStateMachine.getState(); - assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity); - - // decoded in CreatedState and ChallengeState - verify(mMockTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java deleted file mode 100644 index 73191fb0..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.ArrayList; -import java.util.Arrays; - -public class EapAkaPrimeIdentityStateTest extends EapAkaPrimeStateTest { - @Before - public void setUp() { - super.setUp(); - - mStateMachine.transitionTo(mStateMachine.new IdentityState()); - } - - @Test - public void testProcessIdentityRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>( - new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq()))); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI); - - EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_PRIME_IDENTITY_RESPONSE, eapResponse.packet); - - verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager).getSubscriberId(); - verifyNoMoreInteractions(mMockTypeDataDecoder, mMockTelephonyManager); - } - - @Test - public void testProcessTransitionToChallengeState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // Don't actually need any attributes in the attributeMap, since we only care about the - // state transition here. - DecodeResult<EapAkaTypeData> decodeResult = - new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>())); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mStateMachine.process(eapMessage); - - assertTrue(mStateMachine.getState() instanceof ChallengeState); - - // decoded in IdentityState and ChallengeState - verify(mMockTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java deleted file mode 100644 index 125b3235..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE; -import static com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.K_AUT_LEN; -import static com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.K_RE_LEN; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.KEY_LEN; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.SESSION_KEY_LENGTH; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.CreatedState; - -import org.junit.Test; - -import java.util.Arrays; - -public class EapAkaPrimeMethodStateMachineTest extends EapAkaPrimeTest { - private static final String TAG = EapAkaPrimeMethodStateMachineTest.class.getSimpleName(); - private static final byte[] K_AUT = - hexStringToByteArray( - "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F"); - private static final byte[] MAC = hexStringToByteArray("0322b08b59cae2df8f766162ac76f30b"); - - @Test - public void testEapAkaPrimeMethodStateMachineStartState() { - assertTrue(mStateMachine.getState() instanceof CreatedState); - } - - @Test - public void testKeyLengths() { - assertEquals(KEY_LEN, mStateMachine.getKEncrLength()); - assertEquals(K_AUT_LEN, mStateMachine.getKAutLength()); - assertEquals(K_RE_LEN, mStateMachine.getKReLen()); - assertEquals(SESSION_KEY_LENGTH, mStateMachine.getMskLength()); - assertEquals(SESSION_KEY_LENGTH, mStateMachine.getEmskLength()); - } - - @Test - public void testIsValidMacUsesHmacSha256() throws Exception { - System.arraycopy(K_AUT, 0, mStateMachine.mKAut, 0, K_AUT.length); - - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, new byte[0]); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapAkaPrimeTypeData eapAkaPrimeTypeData = - new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, Arrays.asList(new AtMac(MAC))); - - assertTrue(mStateMachine.isValidMac(TAG, eapMessage, eapAkaPrimeTypeData, new byte[0])); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java deleted file mode 100644 index 18fce265..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; - -import org.junit.Test; - -public class EapAkaPrimeStateTest extends EapAkaPrimeTest { - protected static final String NOTIFICATION_MESSAGE = "test"; - - @Test - public void testProcessNotification() throws Exception { - EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes()); - EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preNotification = (EapMethodState) mStateMachine.getState(); - - EapResult result = mStateMachine.process(notification); - assertEquals(preNotification, mStateMachine.getState()); - verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - } - - @Test - public void testProcessInvalidDecodeResult() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preProcess = (EapMethodState) mStateMachine.getState(); - - AtClientErrorCode atClientErrorCode = AtClientErrorCode.UNABLE_TO_PROCESS; - DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(atClientErrorCode); - when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResult result = mStateMachine.process(eapMessage); - assertEquals(preProcess, mStateMachine.getState()); - verify(mMockTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - } - - @Test - public void testHandleEapFailure() throws Exception { - EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_FAILURE, ID_INT, null)); - assertTrue(result instanceof EapFailure); - assertTrue(mStateMachine.getState() instanceof FinalState); - } - - @Test - public void testHandleEapSuccess() throws Exception { - EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null)); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java deleted file mode 100644 index 48371bbd..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.eap.EapSessionConfig.EapAkaPrimeConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData; - -import org.junit.Before; - -public class EapAkaPrimeTest { - - // newtork name example in RFC 5448#3.1 - protected static final int SUB_ID = 1; - protected static final String PEER_NETWORK_NAME = "foo:bar"; - protected static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = false; - protected static final EapAkaPrimeConfig EAP_AKA_PRIME_CONFIG = - new EapAkaPrimeConfig( - SUB_ID, APPTYPE_USIM, PEER_NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES); - protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566"); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - protected Context mMockContext; - protected TelephonyManager mMockTelephonyManager; - protected EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder mMockTypeDataDecoder; - - protected EapAkaPrimeMethodStateMachine mStateMachine; - - @Before - public void setUp() { - mMockContext = mock(Context.class); - mMockTelephonyManager = mock(TelephonyManager.class); - mMockTypeDataDecoder = mock(EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder.class); - - when(mMockContext.getSystemService(eq(Context.TELEPHONY_SERVICE))) - .thenReturn(mMockTelephonyManager); - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - - mStateMachine = - new EapAkaPrimeMethodStateMachine( - mMockContext, - EAP_IDENTITY_BYTES, - EAP_AKA_PRIME_CONFIG, - mMockTypeDataDecoder); - - verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE)); - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java deleted file mode 100644 index 23b240b9..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_NOTIFICATION_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig.EapAkaConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; - -public class EapAkaStateTest { - protected static final int SUB_ID = 1; - protected static final String NOTIFICATION_MESSAGE = "test"; - protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566"); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - protected TelephonyManager mMockTelephonyManager; - protected EapAkaTypeDataDecoder mMockEapAkaTypeDataDecoder; - - protected EapAkaConfig mEapAkaConfig = new EapAkaConfig(SUB_ID, APPTYPE_USIM); - protected EapAkaMethodStateMachine mEapAkaMethodStateMachine; - - @Before - public void setUp() { - mMockTelephonyManager = mock(TelephonyManager.class); - mMockEapAkaTypeDataDecoder = mock(EapAkaTypeDataDecoder.class); - - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - - mEapAkaMethodStateMachine = - new EapAkaMethodStateMachine( - mMockTelephonyManager, - EAP_IDENTITY_BYTES, - mEapAkaConfig, - mMockEapAkaTypeDataDecoder, - true); - - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - } - - @Test - public void testProcessNotification() throws Exception { - EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes()); - EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preNotification = (EapMethodState) mEapAkaMethodStateMachine.getState(); - - EapResult result = mEapAkaMethodStateMachine.process(notification); - assertEquals(preNotification, mEapAkaMethodStateMachine.getState()); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - - assertTrue(result instanceof EapResult.EapResponse); - EapResult.EapResponse eapResponse = (EapResult.EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - } - - @Test - public void testProcessEapAkaNotification() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preProcess = (EapMethodState) mEapAkaMethodStateMachine.getState(); - EapAkaTypeData typeData = - new EapAkaTypeData( - EAP_AKA_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - - DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(typeData); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_AKA_NOTIFICATION_RESPONSE, eapResponse.packet); - assertEquals(preProcess, mEapAkaMethodStateMachine.getState()); - verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - } - - @Test - public void testProcessInvalidDecodeResult() throws Exception { - EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preProcess = (EapMethodState) mEapAkaMethodStateMachine.getState(); - - AtClientErrorCode atClientErrorCode = AtClientErrorCode.UNABLE_TO_PROCESS; - DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(atClientErrorCode); - when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResult result = mEapAkaMethodStateMachine.process(eapMessage); - assertEquals(preProcess, mEapAkaMethodStateMachine.getState()); - verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java deleted file mode 100644 index 1dd60c0c..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import org.junit.Before; - -public class EapMsChapV2AwaitingEapFailureStateTest extends EapMsChapV2StateTest { - @Before - @Override - public void setUp() { - super.setUp(); - - mStateMachine.transitionTo(mStateMachine.new AwaitingEapFailureState()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java deleted file mode 100644 index d4377cb6..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapSuccess; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; - -import org.junit.Before; -import org.junit.Test; - -public class EapMsChapV2AwaitingEapSuccessStateTest extends EapMsChapV2StateTest { - @Before - @Override - public void setUp() { - super.setUp(); - - mStateMachine.transitionTo( - mStateMachine.new AwaitingEapSuccessState(MSCHAP_V2_NT_RESPONSE)); - } - - @Test - @Override - public void testHandleEapSuccess() throws Exception { - EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null)); - EapSuccess eapSuccess = (EapSuccess) result; - assertArrayEquals(MSCHAP_V2_MSK, eapSuccess.msk); - assertArrayEquals(new byte[0], eapSuccess.emsk); - assertTrue(mStateMachine.getState() instanceof FinalState); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java deleted file mode 100644 index ec442dab..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_CHALLENGE_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest.TYPE_DATA_HEADER_SIZE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest.VALUE_SIZE; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; -import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.ValidateAuthenticatorState; - -import org.junit.Before; -import org.junit.Test; - -public class EapMsChapV2ChallengeStateTest extends EapMsChapV2StateTest { - @Before - @Override - public void setUp() { - super.setUp(); - - mStateMachine.transitionTo(mStateMachine.new ChallengeState()); - } - - @Test - public void testProcessChallenge() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapMsChapV2ChallengeRequest challengeRequest = - new EapMsChapV2ChallengeRequest( - MSCHAP_V2_ID_INT, - TYPE_DATA_HEADER_SIZE + VALUE_SIZE + SERVER_NAME_BYTES.length, - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - SERVER_NAME_BYTES); - when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn(new DecodeResult<>(challengeRequest)); - - doAnswer(invocation -> { - byte[] dst = invocation.getArgument(0); - System.arraycopy(MSCHAP_V2_PEER_CHALLENGE, 0, dst, 0, MSCHAP_V2_PEER_CHALLENGE.length); - return null; - }).when(mMockSecureRandom).nextBytes(eq(new byte[MSCHAP_V2_PEER_CHALLENGE.length])); - - EapResult result = mStateMachine.process(eapMessage); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE, eapResponse.packet); - assertTrue(mStateMachine.getState() instanceof ValidateAuthenticatorState); - verify(mMockSecureRandom).nextBytes(any(byte[].class)); - verify(mMockTypeDataDecoder).decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } - - @Test - public void testIncorrectTypeData() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn( - new DecodeResult<>( - new EapError( - new EapMsChapV2ParsingException("incorrect type data")))); - - EapResult result = mStateMachine.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - verify(mMockTypeDataDecoder).decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java deleted file mode 100644 index 633e0ebd..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES; - -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; -import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.ValidateAuthenticatorState; - -import org.junit.Test; - -public class EapMsChapV2CreatedStateTest extends EapMsChapV2StateTest { - @Test - public void testProcessChallengeRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn( - new DecodeResult<>( - new EapMsChapV2ChallengeRequest( - 0, 0, CHALLENGE_BYTES, SERVER_NAME_BYTES))); - - mStateMachine.process(eapMessage); - - assertTrue(mStateMachine.getState() instanceof ValidateAuthenticatorState); - verify(mMockTypeDataDecoder, times(2)) - .decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } - - @Test - public void testIncorrectTypeData() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - when(mMockTypeDataDecoder.decodeChallengeRequest( - eq(CREATED_STATE_TAG), eq(DUMMY_TYPE_DATA))) - .thenReturn( - new DecodeResult<>( - new EapError( - new EapMsChapV2ParsingException("incorrect type data")))); - - EapResult result = mStateMachine.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapMsChapV2ParsingException); - verify(mMockTypeDataDecoder) - .decodeChallengeRequest(eq(CREATED_STATE_TAG), eq(DUMMY_TYPE_DATA)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java deleted file mode 100644 index b24c3f82..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MASTER_KEY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_HASH; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_HASH_HASH; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_UTF_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_RECEIVE_START_KEY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_SEND_START_KEY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME_ASCII_BYTES; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import android.net.eap.EapSessionConfig.EapMsChapV2Config; - -import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.CreatedState; -import com.android.internal.net.utils.Log; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; - -public class EapMsChapV2MethodStateMachineTest { - private EapMsChapV2Config mEapMsChapV2Config; - private EapMsChapV2MethodStateMachine mStateMachine; - - @Before - public void setUp() { - mEapMsChapV2Config = new EapMsChapV2Config(MSCHAP_V2_USERNAME, MSCHAP_V2_PASSWORD); - mStateMachine = new EapMsChapV2MethodStateMachine(mEapMsChapV2Config, new SecureRandom()); - } - - @Test - public void testGetEapMethod() { - assertEquals(EAP_TYPE_MSCHAP_V2, mStateMachine.getEapMethod()); - } - - @Test - public void testStartsOnCreatedState() { - assertTrue(mStateMachine.getState() instanceof CreatedState); - } - - // Tests for MS CHAPv2 authentication utils. Test vectors from RFC 2759#9.2. - - @Test - public void testUsernameToBytes() { - assertArrayEquals( - MSCHAP_V2_USERNAME_ASCII_BYTES, - EapMsChapV2MethodStateMachine.usernameToBytes(MSCHAP_V2_USERNAME)); - } - - @Test - public void testPasswordToBytes() { - assertArrayEquals( - MSCHAP_V2_PASSWORD_UTF_BYTES, - EapMsChapV2MethodStateMachine.passwordToBytes(MSCHAP_V2_PASSWORD)); - } - - @Test - public void testGenerateNtResponse() throws Exception { - byte[] ntResponse = - EapMsChapV2MethodStateMachine.generateNtResponse( - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - MSCHAP_V2_PEER_CHALLENGE, - MSCHAP_V2_USERNAME, - MSCHAP_V2_PASSWORD); - assertArrayEquals(MSCHAP_V2_NT_RESPONSE, ntResponse); - } - - @Test - public void testChallengeHash() throws Exception { - byte[] challenge = - EapMsChapV2MethodStateMachine.challengeHash( - MSCHAP_V2_PEER_CHALLENGE, - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - MSCHAP_V2_USERNAME); - assertArrayEquals(MSCHAP_V2_CHALLENGE, challenge); - } - - @Test - public void testNtPasswordHash() { - byte[] passwordHash = EapMsChapV2MethodStateMachine.ntPasswordHash(MSCHAP_V2_PASSWORD); - assertArrayEquals(MSCHAP_V2_PASSWORD_HASH, passwordHash); - } - - @Test - public void testHashNtPasswordHash() { - byte[] passwordHashHash = - EapMsChapV2MethodStateMachine.hashNtPasswordHash(MSCHAP_V2_PASSWORD_HASH); - assertArrayEquals(MSCHAP_V2_PASSWORD_HASH_HASH, passwordHashHash); - } - - @Test - public void testChallengeResponse() throws Exception { - byte[] challengeResponse = - EapMsChapV2MethodStateMachine.challengeResponse( - MSCHAP_V2_CHALLENGE, MSCHAP_V2_PASSWORD_HASH); - assertArrayEquals(MSCHAP_V2_NT_RESPONSE, challengeResponse); - } - - @Test - public void testGenerateAuthenticatorResponse() throws Exception { - byte[] authenticatorResponse = - EapMsChapV2MethodStateMachine.generateAuthenticatorResponse( - MSCHAP_V2_PASSWORD, - MSCHAP_V2_NT_RESPONSE, - MSCHAP_V2_PEER_CHALLENGE, - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - MSCHAP_V2_USERNAME); - assertArrayEquals(MSCHAP_V2_AUTHENTICATOR_RESPONSE, authenticatorResponse); - } - - @Test - public void testCheckAuthenticatorResponse() throws Exception { - assertTrue( - "AuthenticatorResponse didn't match computed response", - EapMsChapV2MethodStateMachine.checkAuthenticatorResponse( - MSCHAP_V2_PASSWORD, - MSCHAP_V2_NT_RESPONSE, - MSCHAP_V2_PEER_CHALLENGE, - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - MSCHAP_V2_USERNAME, - MSCHAP_V2_AUTHENTICATOR_RESPONSE)); - } - - @Test - public void testGetMasterKey() throws Exception { - byte[] masterKey = - EapMsChapV2MethodStateMachine.getMasterKey( - MSCHAP_V2_PASSWORD_HASH_HASH, MSCHAP_V2_NT_RESPONSE); - assertArrayEquals(MSCHAP_V2_MASTER_KEY, masterKey); - } - - @Test - public void testGetAsymmetricStartKeySendKey() throws Exception { - byte[] startKey = - EapMsChapV2MethodStateMachine.getAsymmetricStartKey(MSCHAP_V2_MASTER_KEY, true); - assertArrayEquals(Log.byteArrayToHexString(startKey), MSCHAP_V2_SEND_START_KEY, startKey); - } - - @Test - public void testGetAsymmetricStartKeyReceiveKey() throws Exception { - byte[] receiveKey = - EapMsChapV2MethodStateMachine.getAsymmetricStartKey(MSCHAP_V2_MASTER_KEY, false); - assertArrayEquals(MSCHAP_V2_RECEIVE_START_KEY, receiveKey); - } - - @Test - public void testGenerateMsk() throws Exception { - byte[] msk = - EapMsChapV2MethodStateMachine.generateMsk( - MSCHAP_V2_PASSWORD, MSCHAP_V2_NT_RESPONSE); - assertArrayEquals(MSCHAP_V2_MSK, msk); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java deleted file mode 100644 index 1e4a0c58..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; - -import android.net.eap.EapSessionConfig.EapMsChapV2Config; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; - -public class EapMsChapV2StateTest { - protected static final String CREATED_STATE_TAG = "CreatedState"; - protected static final String NOTIFICATION_MESSAGE = "test"; - protected static final byte[] DUMMY_TYPE_DATA = hexStringToByteArray("00112233"); - - protected SecureRandom mMockSecureRandom; - protected EapMsChapV2TypeDataDecoder mMockTypeDataDecoder; - - protected EapMsChapV2Config mEapMsChapV2Config; - protected EapMsChapV2MethodStateMachine mStateMachine; - - @Before - public void setUp() { - mMockSecureRandom = mock(SecureRandom.class); - mMockTypeDataDecoder = mock(EapMsChapV2TypeDataDecoder.class); - - mEapMsChapV2Config = new EapMsChapV2Config(MSCHAP_V2_USERNAME, MSCHAP_V2_PASSWORD); - mStateMachine = - new EapMsChapV2MethodStateMachine( - mEapMsChapV2Config, mMockSecureRandom, mMockTypeDataDecoder); - } - - @Test - public void testHandleEapFailure() throws Exception { - EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_FAILURE, ID_INT, null)); - assertTrue(result instanceof EapFailure); - assertTrue(mStateMachine.getState() instanceof FinalState); - } - - @Test - public void testHandleEapSuccess() throws Exception { - EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null)); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testHandleEapNotification() throws Exception { - EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes()); - EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preNotification = (EapMethodState) mStateMachine.getState(); - - EapResult result = mStateMachine.process(notification); - assertEquals(preNotification, mStateMachine.getState()); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java deleted file mode 100644 index dda7d5bc..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_FAILURE_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_SUCCESS_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_AUTHENTICATOR_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ERROR_CODE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PASSWORD_CHANGE_PROTOCOL; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.RETRY_BIT; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE; -import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessRequest; -import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; -import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.AwaitingEapFailureState; -import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.AwaitingEapSuccessState; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.BufferUnderflowException; - -public class EapMsChapV2ValidateAuthenticatorStateTest extends EapMsChapV2StateTest { - private static final int INVALID_OP_CODE = -1; - - @Before - @Override - public void setUp() { - super.setUp(); - - mStateMachine.transitionTo( - mStateMachine.new ValidateAuthenticatorState( - MSCHAP_V2_AUTHENTICATOR_CHALLENGE, - MSCHAP_V2_PEER_CHALLENGE, - MSCHAP_V2_NT_RESPONSE)); - } - - @Test - public void testProcessSuccessRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapMsChapV2SuccessRequest successRequest = - new EapMsChapV2SuccessRequest( - MSCHAP_V2_ID_INT, 0, MSCHAP_V2_AUTHENTICATOR_RESPONSE, MESSAGE); - - when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_SUCCESS); - when(mMockTypeDataDecoder.decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn(new DecodeResult<>(successRequest)); - - EapResult result = mStateMachine.process(eapMessage); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_MSCHAP_V2_SUCCESS_RESPONSE, eapResponse.packet); - assertTrue(mStateMachine.getState() instanceof AwaitingEapSuccessState); - verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA)); - verify(mMockTypeDataDecoder).decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } - - @Test - public void testProcessInvalidSuccessRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapMsChapV2SuccessRequest successRequest = - new EapMsChapV2SuccessRequest( - MSCHAP_V2_ID_INT, 0, INVALID_AUTHENTICATOR_RESPONSE, MESSAGE); - - when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_SUCCESS); - when(mMockTypeDataDecoder.decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn(new DecodeResult<>(successRequest)); - - EapResult result = mStateMachine.process(eapMessage); - assertTrue(result instanceof EapFailure); - assertTrue(mStateMachine.getState() instanceof FinalState); - verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA)); - verify(mMockTypeDataDecoder).decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } - - @Test - public void testProcessFailureRequest() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapMsChapV2FailureRequest failureRequest = - new EapMsChapV2FailureRequest( - MSCHAP_V2_ID_INT, - 0, - ERROR_CODE, - RETRY_BIT, - CHALLENGE_BYTES, - PASSWORD_CHANGE_PROTOCOL, - MESSAGE); - - when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_FAILURE); - when(mMockTypeDataDecoder.decodeFailureRequest(any(String.class), eq(DUMMY_TYPE_DATA))) - .thenReturn(new DecodeResult<>(failureRequest)); - - EapResult result = mStateMachine.process(eapMessage); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_MSCHAP_V2_FAILURE_RESPONSE, eapResponse.packet); - assertTrue(mStateMachine.getState() instanceof AwaitingEapFailureState); - verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA)); - verify(mMockTypeDataDecoder).decodeFailureRequest(any(String.class), eq(DUMMY_TYPE_DATA)); - } - - @Test - public void testProcessEmptyTypeData() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, new byte[0]); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - when(mMockTypeDataDecoder.getOpCode(eq(new byte[0]))) - .thenThrow(new BufferUnderflowException()); - - EapResult result = mStateMachine.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof BufferUnderflowException); - verify(mMockTypeDataDecoder).getOpCode(eq(new byte[0])); - } - - @Test - public void testProcessInvalidPacket() throws Exception { - EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(INVALID_OP_CODE); - - EapResult result = mStateMachine.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java deleted file mode 100644 index 7adc9f75..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.COMPUTED_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK_STRING; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_1; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_2; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_AUT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_AUT_STRING; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_ENCR; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_ENCR_STRING; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MAC_INPUT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK_STRING; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ORIGINAL_MAC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_1; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_BYTES; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_POST_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CLIENT_ERROR; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT_STRING; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2_BYTES; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.KEY_LEN; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.MAC_ALGORITHM_STRING; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.MASTER_KEY_GENERATION_ALG; -import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.SESSION_KEY_LENGTH; - -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.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig.EapSimConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.crypto.Fips186_2Prf; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.MessageDigest; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; - -public class EapSimAkaMethodStateMachineTest { - private static final String TAG = EapSimAkaMethodStateMachineTest.class.getSimpleName(); - private static final int SUB_ID = 1; - private static final int AT_RAND_LEN = 36; - private static final String VERSIONS_STRING = "0001"; - private static final String SELECTED_VERSION = "0001"; - private static final byte[] SHA_1_INPUT = hexStringToByteArray("0123456789ABCDEF"); - private static final byte[] FORMATTED_UICC_CHALLENGE = - hexStringToByteArray("1000112233445566778899AABBCCDDEEFF"); - private static final String BASE_64_CHALLENGE = "EAARIjNEVWZ3iJmqu8zd7v8="; - private static final String BASE_64_RESPONSE = "BBEiM0QIAQIDBAUGBwg="; - private static final byte[] UICC_RESPONSE = - hexStringToByteArray("04" + SRES_1 + "08" + KC_1); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - // K_encr + K_aut + MSK + EMSK - private static final int PRF_OUTPUT_BYTES = (2 * KEY_LEN) + (2 * SESSION_KEY_LENGTH); - - private TelephonyManager mMockTelephonyManager; - private EapSimConfig mEapSimConfig; - private EapSimAkaMethodStateMachine mStateMachine; - - @Before - public void setUp() { - mMockTelephonyManager = mock(TelephonyManager.class); - mEapSimConfig = new EapSimConfig(SUB_ID, TelephonyManager.APPTYPE_USIM); - - mStateMachine = - new EapSimAkaMethodStateMachine( - mMockTelephonyManager, EAP_IDENTITY_BYTES, mEapSimConfig) { - @Override - EapSimAkaTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) { - return new EapSimTypeData( - EAP_SIM_CLIENT_ERROR, Arrays.asList(clientErrorCode)); - } - - @Override - EapSimAkaTypeData getEapSimAkaTypeData( - int eapSubtype, List<EapSimAkaAttribute> attributes) { - return new EapSimTypeData(eapSubtype, attributes); - } - - @Override - int getEapMethod() { - return EAP_TYPE_SIM; - } - }; - mStateMachine = spy(mStateMachine); - } - - @Test - public void testBuildClientErrorResponse() { - AtClientErrorCode errorCode = AtClientErrorCode.UNSUPPORTED_VERSION; - - EapResult result = - mStateMachine.buildClientErrorResponse(ID_INT, EAP_TYPE_SIM, errorCode); - assertTrue(result instanceof EapResult.EapResponse); - EapResult.EapResponse eapResponse = (EapResult.EapResponse) result; - assertArrayEquals(EAP_SIM_CLIENT_ERROR_RESPONSE, eapResponse.packet); - } - - @Test - public void testBuildResponseMessage() throws Exception { - List<EapSimAkaAttribute> attributes = new ArrayList<>(); - attributes.add(new AtSelectedVersion(1)); - attributes.add(new AtIdentity(AT_IDENTITY.length, IDENTITY)); - int identifier = ID_INT; - - EapResult result = - mStateMachine.buildResponseMessage( - EAP_TYPE_SIM, - EAP_SIM_START, - identifier, - attributes); - assertTrue(result instanceof EapResult); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_SIM_RESPONSE_PACKET, eapResponse.packet); - } - - @Test - public void testGenerateAndPersistKeys() { - byte[] mkInput = hexStringToByteArray( - EAP_SIM_IDENTITY - + KC_1 - + KC_2 - + NONCE_MT_STRING - + VERSIONS_STRING - + SELECTED_VERSION); - MessageDigest mockSha1 = mock(MessageDigest.class); - when(mockSha1.digest(eq(mkInput))).thenReturn(MK); - - byte[] keys = hexStringToByteArray(K_ENCR_STRING + K_AUT_STRING + MSK_STRING + EMSK_STRING); - Fips186_2Prf mockFips186_2Prf = mock(Fips186_2Prf.class); - when(mockFips186_2Prf.getRandom(eq(MK), eq(PRF_OUTPUT_BYTES))).thenReturn(keys); - - mStateMachine.generateAndPersistKeys(TAG, mockSha1, mockFips186_2Prf, mkInput); - assertArrayEquals(K_ENCR, mStateMachine.mKEncr); - assertArrayEquals(K_AUT, mStateMachine.mKAut); - assertArrayEquals(MSK, mStateMachine.mMsk); - assertArrayEquals(EMSK, mStateMachine.mEmsk); - - verify(mockSha1).digest(eq(mkInput)); - verify(mockFips186_2Prf).getRandom(eq(MK), eq(PRF_OUTPUT_BYTES)); - verifyNoMoreInteractions(mockSha1, mockFips186_2Prf); - } - - /** - * Test that we can actually instantiate and use the SHA-1algorithm. - */ - @Test - public void testCreateSha1() throws Exception { - MessageDigest sha1 = MessageDigest.getInstance(MASTER_KEY_GENERATION_ALG); - byte[] sha1Result = sha1.digest(SHA_1_INPUT); - assertFalse(Arrays.equals(SHA_1_INPUT, sha1Result)); - } - - /** - * Test that we can actually instantiate and use the HMAC-SHA-1 algorithm. - */ - @Test - public void testCreateHmacSha1() throws Exception { - Mac macAlgorithm = Mac.getInstance(MAC_ALGORITHM_STRING); - macAlgorithm.init(new SecretKeySpec(K_AUT, MAC_ALGORITHM_STRING)); - byte[] mac = macAlgorithm.doFinal(MAC_INPUT); - assertFalse(Arrays.equals(MAC_INPUT, mac)); - } - - @Test - public void testProcessUiccAuthentication() throws Exception { - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)).thenReturn(BASE_64_RESPONSE); - - byte[] result = - mStateMachine.processUiccAuthentication( - TAG, - TelephonyManager.AUTHTYPE_EAP_AKA, - FORMATTED_UICC_CHALLENGE); - - assertArrayEquals(UICC_RESPONSE, result); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testProcessUiccAuthenticationNullResponse() throws Exception { - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE)).thenReturn(null); - - try { - mStateMachine.processUiccAuthentication( - TAG, - TelephonyManager.AUTHTYPE_EAP_AKA, - FORMATTED_UICC_CHALLENGE); - fail("EapSimAkaAuthenticationFailureException expected for null TelMan response"); - } catch (EapSimAkaAuthenticationFailureException expected) { - } - - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_AKA, - BASE_64_CHALLENGE); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testGetMac() throws Exception { - AtMac atMac = new AtMac(ORIGINAL_MAC); - AtRandSim atRandSim = new AtRandSim(AT_RAND_LEN, RAND_1_BYTES, RAND_2_BYTES); - EapSimTypeData eapSimTypeData = - new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(atRandSim, atMac)); - - Mac mockMac = mock(Mac.class); - when(mockMac.doFinal(eq(MAC_INPUT))).thenReturn(COMPUTED_MAC); - mStateMachine.mMacAlgorithm = mockMac; - - byte[] mac = mStateMachine.getMac(EAP_CODE_REQUEST, ID_INT, eapSimTypeData, NONCE_MT); - assertArrayEquals(COMPUTED_MAC, mac); - AtMac postCalculationAtMac = (AtMac) eapSimTypeData.attributeMap.get(EAP_AT_MAC); - assertArrayEquals(ORIGINAL_MAC, postCalculationAtMac.mac); - - verify(mockMac).doFinal(eq(MAC_INPUT)); - verifyNoMoreInteractions(mockMac); - } - - @Test - public void testGetMacNoMacAlgorithm() throws Exception { - try { - mStateMachine.getMac(EAP_CODE_REQUEST, ID_INT, null, null); - fail("Expected IllegalStateException if Mac not set"); - } catch (IllegalStateException expected) { - } - } - - @Test - public void testReceivedValidMac() throws Exception { - AtMac atMac = new AtMac(ORIGINAL_MAC); - AtRandSim atRandSim = new AtRandSim(AT_RAND_LEN, RAND_1_BYTES, RAND_2_BYTES); - EapSimTypeData eapSimTypeData = - new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(atRandSim, atMac)); - EapData eapData = new EapData(EAP_TYPE_SIM, new byte[0]); - EapMessage message = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - doReturn(ORIGINAL_MAC) - .when(mStateMachine) - .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT)); - - assertTrue(mStateMachine.isValidMac(TAG, message, eapSimTypeData, NONCE_MT)); - - doReturn(new byte[0]) - .when(mStateMachine) - .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT)); - - assertFalse(mStateMachine.isValidMac(TAG, message, eapSimTypeData, NONCE_MT)); - - verify(mStateMachine, times(2)) - .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT)); - } - - @Test - public void testBuildResponseMessageWithMac() { - Mac mockMac = mock(Mac.class); - when(mockMac.doFinal(eq(EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT))).thenReturn(COMPUTED_MAC); - mStateMachine.mMacAlgorithm = mockMac; - - EapResult result = - mStateMachine.buildResponseMessageWithMac(ID_INT, EAP_SIM_CHALLENGE, SRES_BYTES); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC, eapResponse.packet); - verify(mockMac).doFinal(eq(EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT)); - verifyNoMoreInteractions(mockMac); - } - - @Test - public void testHandleEapSimNotificationPreChallenge() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - - EapResponse eapResponse = - (EapResponse) - mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData); - assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet); - assertTrue(mStateMachine.mHasReceivedSimAkaNotification); - verify(mStateMachine, never()).transitionTo(any(EapMethodState.class)); - } - - @Test - public void testHandleEapSimNotificationPreChallengeInvalidPBit() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_POST_CHALLENGE))); - - EapResponse eapResponse = - (EapResponse) - mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData); - assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - verify(mStateMachine, never()) - .transitionTo(any(EapMethodStateMachine.EapMethodState.class)); - } - - @Test - public void testHandleEapSimNotificationMultipleNotifications() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - - mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData); - - EapError eapError = - (EapError) mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData); - assertTrue(eapError.cause instanceof EapInvalidRequestException); - assertTrue(mStateMachine.mHasReceivedSimAkaNotification); - verify(mStateMachine, never()) - .transitionTo(any(EapMethodStateMachine.EapMethodState.class)); - } - - @Test - public void testHandleEapSimNotificationInvalidAtMac() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList( - new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE), new AtMac())); - - EapResponse eapResponse = - (EapResponse) - mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData); - assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - verify(mStateMachine, never()) - .transitionTo(any(EapMethodStateMachine.EapMethodState.class)); - } - - @Test - public void testHandleEapSimNotificationPostChallenge() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList( - new AtNotification(GENERAL_FAILURE_POST_CHALLENGE), - new AtMac(ORIGINAL_MAC))); - - Mac mockMac = mock(Mac.class); - when(mockMac.doFinal(eq(EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC))) - .thenReturn(ORIGINAL_MAC); - when(mockMac.doFinal(eq(EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC))) - .thenReturn(COMPUTED_MAC); - mStateMachine.mMacAlgorithm = mockMac; - - EapResponse eapResponse = - (EapResponse) - mStateMachine.handleEapSimAkaNotification(TAG, false, ID_INT, typeData); - assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC, eapResponse.packet); - assertTrue(mStateMachine.mHasReceivedSimAkaNotification); - verify(mStateMachine, never()).transitionTo(any(EapMethodState.class)); - - verify(mockMac).doFinal(eq(EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC)); - verify(mockMac).doFinal(eq(EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC)); - verifyNoMoreInteractions(mockMac); - } - - @Test - public void testHandleEapSimNotificationPostChallengeInvalidAtMac() throws Exception { - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_POST_CHALLENGE))); - - EapResponse eapResponse = - (EapResponse) - mStateMachine.handleEapSimAkaNotification(TAG, false, ID_INT, typeData); - assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet); - verify(mStateMachine, never()).transitionTo(any(EapMethodState.class)); - } - - @Test - public void testKeyLengths() { - assertEquals(KEY_LEN, mStateMachine.getKEncrLength()); - assertEquals(KEY_LEN, mStateMachine.getKAutLength()); - assertEquals(SESSION_KEY_LENGTH, mStateMachine.getMskLength()); - assertEquals(SESSION_KEY_LENGTH, mStateMachine.getEmskLength()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java deleted file mode 100644 index bffc03ab..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CHALLENGE_RESPONSE_INVALID_KC; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CHALLENGE_RESPONSE_INVALID_SRES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_1_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_2_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_1_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_2_BYTES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.VALID_CHALLENGE_RESPONSE; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2_BYTES; - -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 static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapSuccess; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState.RandChallengeResult; - -import org.junit.Test; - -import java.nio.BufferUnderflowException; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.List; - -public class EapSimChallengeStateTest extends EapSimStateTest { - private static final int VALID_SRES_LENGTH = 4; - private static final int INVALID_SRES_LENGTH = 5; - private static final int VALID_KC_LENGTH = 8; - private static final int INVALID_KC_LENGTH = 9; - private static final int AT_RAND_LENGTH = 36; - private static final List<Integer> VERSIONS = Arrays.asList(1); - - // Base64 of {@link EapTestAttributeDefinitions#RAND_1} - private static final String BASE_64_RAND_1 = "EAARIjNEVWZ3iJmqu8zd7v8="; - - // Base64 of {@link EapTestAttributeDefinitions#RAND_2} - private static final String BASE_64_RAND_2 = "EP/u3cy7qpmId2ZVRDMiEQA="; - - // Base64 of "04" + SRES_1 + "08" + KC_1 - private static final String BASE_64_RESP_1 = "BBEiM0QIAQIDBAUGBwg="; - - // Base64 of "04" + SRES_2 + "08" + KC_2 - private static final String BASE_64_RESP_2 = "BEQzIhEICAcGBQQDAgE="; - - // Base64 of "04" + SRES_1 + '081122" - private static final String BASE_64_INVALID_RESP = "BBEiM0QIESI="; - - private AtNonceMt mAtNonceMt; - private ChallengeState mChallengeState; - - @Override - public void setUp() { - super.setUp(); - - try { - mAtNonceMt = new AtNonceMt(NONCE_MT); - } catch (EapSimAkaInvalidAttributeException ex) { - // this will never happen - } - mChallengeState = mEapSimMethodStateMachine - .new ChallengeState(VERSIONS, mAtNonceMt, EAP_SIM_IDENTITY_BYTES); - mEapSimMethodStateMachine.transitionTo(mChallengeState); - } - - @Test - public void testProcessIncorrectEapMethodType() throws Exception { - EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapResult result = mChallengeState.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessSuccess() throws Exception { - System.arraycopy(MSK, 0, mEapSimMethodStateMachine.mMsk, 0, MSK.length); - System.arraycopy(EMSK, 0, mEapSimMethodStateMachine.mEmsk, 0, EMSK.length); - - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - EapResult result = mEapSimMethodStateMachine.process(input); - assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState); - - EapSuccess eapSuccess = (EapSuccess) result; - assertArrayEquals(MSK, eapSuccess.msk); - assertArrayEquals(EMSK, eapSuccess.emsk); - } - - @Test - public void testProcessFailure() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null); - EapResult result = mEapSimMethodStateMachine.process(input); - assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState); - - assertTrue(result instanceof EapFailure); - } - - @Test - public void testIsValidChallengeAttributes() { - LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap = new LinkedHashMap<>(); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap); - assertFalse(mChallengeState.isValidChallengeAttributes(eapSimTypeData)); - - attributeMap.put(EAP_AT_RAND, null); // value doesn't matter, just need key - eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap); - assertFalse(mChallengeState.isValidChallengeAttributes(eapSimTypeData)); - - attributeMap.put(EAP_AT_MAC, null); // value doesn't matter, just need key - eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap); - assertTrue(mChallengeState.isValidChallengeAttributes(eapSimTypeData)); - } - - @Test - public void testRandChallengeResultConstructor() { - try { - mChallengeState.new RandChallengeResult( - new byte[VALID_SRES_LENGTH], new byte[INVALID_KC_LENGTH]); - fail("EapSimAkaInvalidLengthException expected for invalid SRES lengths"); - } catch (EapSimAkaInvalidLengthException expected) { - } - - try { - mChallengeState.new RandChallengeResult( - new byte[INVALID_SRES_LENGTH], new byte[VALID_KC_LENGTH]); - fail("EapSimAkaInvalidLengthException expected for invalid Kc lengths"); - } catch (EapSimAkaInvalidLengthException expected) { - } - } - - @Test - public void testRandChallengeResultEquals() throws Exception { - RandChallengeResult resultA = - mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES); - RandChallengeResult resultB = - mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES); - RandChallengeResult resultC = - mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES); - - assertEquals(resultA, resultB); - assertNotEquals(resultA, resultC); - } - - @Test - public void testRandChallengeResultHashCode() throws Exception { - RandChallengeResult resultA = - mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES); - RandChallengeResult resultB = - mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES); - RandChallengeResult resultC = - mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES); - - assertEquals(resultA.hashCode(), resultB.hashCode()); - assertNotEquals(resultA.hashCode(), resultC.hashCode()); - } - - @Test - public void testGetRandChallengeResultFromResponse() throws Exception { - RandChallengeResult result = - mChallengeState.getRandChallengeResultFromResponse(VALID_CHALLENGE_RESPONSE); - - assertArrayEquals(SRES_1_BYTES, result.sres); - assertArrayEquals(KC_1_BYTES, result.kc); - } - - @Test - public void testGetRandChallengeResultFromResponseInvalidSres() { - try { - mChallengeState.getRandChallengeResultFromResponse(CHALLENGE_RESPONSE_INVALID_SRES); - fail("EapSimAkaInvalidLengthException expected for invalid SRES_1 length"); - } catch (EapSimAkaInvalidLengthException expected) { - } - } - - @Test - public void testGetRandChallengeResultFromResponseInvalidKc() { - try { - mChallengeState.getRandChallengeResultFromResponse(CHALLENGE_RESPONSE_INVALID_KC); - fail("EapSimAkaInvalidLengthException expected for invalid KC length"); - } catch (EapSimAkaInvalidLengthException expected) { - } - } - - @Test - public void testGetRandChallengeResults() throws Exception { - EapSimTypeData eapSimTypeData = - new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList( - new AtRandSim(AT_RAND_LENGTH, - hexStringToByteArray(RAND_1), - hexStringToByteArray(RAND_2)))); - - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1)) - .thenReturn(BASE_64_RESP_1); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_2)) - .thenReturn(BASE_64_RESP_2); - - List<RandChallengeResult> actualResult = - mChallengeState.getRandChallengeResults(eapSimTypeData); - - List<RandChallengeResult> expectedResult = Arrays.asList( - mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES), - mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES)); - assertEquals(expectedResult, actualResult); - - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_2); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testGetRandChallengeResultsBufferUnderflow() throws Exception { - EapSimTypeData eapSimTypeData = - new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList( - new AtRandSim(AT_RAND_LENGTH, - hexStringToByteArray(RAND_1), - hexStringToByteArray(RAND_2)))); - - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1)) - .thenReturn(BASE_64_RESP_1); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_2)) - .thenReturn(BASE_64_INVALID_RESP); - - try { - mChallengeState.getRandChallengeResults(eapSimTypeData); - fail("BufferUnderflowException expected for short Kc value"); - } catch (BufferUnderflowException ex) { - } - - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_2); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testProcessUiccAuthenticationNullResponse() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - AtRandSim atRandSim = new AtRandSim(AT_RAND_LENGTH, RAND_1_BYTES, RAND_2_BYTES); - - DecodeResult<EapSimTypeData> decodeResult = - new DecodeResult<>( - new EapSimTypeData( - EAP_SIM_CHALLENGE, - Arrays.asList(atRandSim, new AtMac()))); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - when(mMockTelephonyManager - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1)) - .thenReturn(null); - - EapError eapError = (EapError) mEapSimMethodStateMachine.process(eapMessage); - assertTrue(eapError.cause instanceof EapSimAkaAuthenticationFailureException); - - verify(mMockEapSimTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - verify(mMockTelephonyManager) - .getIccAuthentication( - TelephonyManager.APPTYPE_USIM, - TelephonyManager.AUTHTYPE_EAP_SIM, - BASE_64_RAND_1); - verifyNoMoreInteractions(mMockEapSimTypeDataDecoder, mMockTelephonyManager); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java deleted file mode 100644 index bdd19201..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; - -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.CreatedState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.StartState; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.List; - -public class EapSimCreatedStateTest extends EapSimStateTest { - private static final int EAP_SIM_START = 10; - - private CreatedState mCreatedState; - - @Before - public void setUp() { - super.setUp(); - mCreatedState = mEapSimMethodStateMachine.new CreatedState(); - } - - @Test - public void testProcessSuccess() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - EapResult result = mCreatedState.process(input); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessFailure() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null); - EapResult result = mCreatedState.process(input); - assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState); - - assertTrue(result instanceof EapFailure); - } - - @Test - public void testTransitionToStartState() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - List<EapSimAkaAttribute> attributes = Arrays.asList( - new AtVersionList(8, 1), new AtPermanentIdReq()); - DecodeResult<EapSimTypeData> decodeResult = - new DecodeResult<>(new EapSimTypeData(EAP_SIM_START, attributes)); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - mEapSimMethodStateMachine.process(eapMessage); - assertTrue(mEapSimMethodStateMachine.getState() instanceof StartState); - - // decoded in CreatedState and StartState - verify(mMockEapSimTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockEapSimTypeDataDecoder); - } - - @Test - public void testProcessIncorrectEapMethodType() throws Exception { - EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapResult result = mEapSimMethodStateMachine.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java deleted file mode 100644 index ac1d01ca..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START; - -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.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig.EapSimConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.CreatedState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; -import java.util.Arrays; - -public class EapSimMethodStateMachineTest { - private static final int SUB_ID = 1; - private static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566"); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - private TelephonyManager mMockTelephonyManager; - private EapSimTypeDataDecoder mMockEapSimTypeDataDecoder; - - private EapSimConfig mEapSimConfig = new EapSimConfig(SUB_ID, APPTYPE_USIM); - private EapSimMethodStateMachine mEapSimMethodStateMachine; - - - @Before - public void setUp() { - mMockTelephonyManager = mock(TelephonyManager.class); - mMockEapSimTypeDataDecoder = mock(EapSimTypeDataDecoder.class); - - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - - mEapSimMethodStateMachine = - new EapSimMethodStateMachine( - mMockTelephonyManager, - EAP_IDENTITY_BYTES, - mEapSimConfig, - new SecureRandom(), - mMockEapSimTypeDataDecoder); - - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - } - - @Test - public void testEapSimMethodStateMachineStartState() { - assertTrue(mEapSimMethodStateMachine.getState() instanceof CreatedState); - } - - @Test - public void testGetMethod() { - assertEquals(EAP_TYPE_SIM, mEapSimMethodStateMachine.getEapMethod()); - } - - @Test - public void testEapSimFailsOnMultipleSimNotifications() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - // First EAP-SIM/Notification - EapSimTypeData notificationTypeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(notificationTypeData); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet); - verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - - // Transition to StartState - decodeResult = - new DecodeResult<>( - new EapSimTypeData(EAP_SIM_START, Arrays.asList(new AtVersionList(8, 1)))); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage); - assertFalse( - "EAP-Request/SIM-Start returned a Client-Error response", - Arrays.equals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet)); - - // decoded in: previous 1 time + in CreatedState and StartState - verify(mMockEapSimTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA)); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - - // Second EAP-SIM/Notification - decodeResult = new EapSimAkaTypeData.DecodeResult<>(notificationTypeData); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapError eapError = (EapError) mEapSimMethodStateMachine.process(eapMessage); - assertTrue(eapError.cause instanceof EapInvalidRequestException); - - // decoded previous 3 times + 1 - verify(mMockEapSimTypeDataDecoder, times(4)).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java deleted file mode 100644 index ccb746ab..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_WITHOUT_IDENTITY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ENCR_DATA; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IV; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START; -import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState; -import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.StartState; -import com.android.internal.net.utils.Log; - -import org.junit.Before; -import org.junit.Test; - -import java.util.Arrays; -import java.util.LinkedHashMap; - -public class EapSimStartStateTest extends EapSimStateTest { - - private StartState mStartState; - private LinkedHashMap<Integer, EapSimAkaAttribute> mAttributes; - - @Before - public void setUp() { - super.setUp(); - - AtNonceMt atNonceMt = null; - try { - atNonceMt = new AtNonceMt(NONCE_MT); - } catch (Exception e) { - fail("Failed to create AtNonceMt attribute in setUp()"); - } - - mStartState = mEapSimMethodStateMachine.new StartState(atNonceMt); - mEapSimMethodStateMachine.transitionTo(mStartState); - - mAttributes = new LinkedHashMap<>(); - } - - @Test - public void testProcessSuccess() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null); - EapResult result = mStartState.process(input); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessFailure() throws Exception { - EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null); - EapResult result = mStartState.process(input); - assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState); - - assertTrue(result instanceof EapFailure); - } - - @Test - public void testProcessIncorrectEapMethodType() throws Exception { - EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - - EapResult result = mStartState.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testIsValidStartAttributes() throws Exception { - mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertTrue(mStartState.isValidStartAttributes(eapSimTypeData)); - } - - @Test - public void testIsValidStartAttributesMissingVersionList() throws Exception { - mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertFalse(mStartState.isValidStartAttributes(eapSimTypeData)); - } - - @Test - public void testIsValidStartAttributesMultipleIdRequests() throws Exception { - mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - mAttributes.put(EAP_AT_ANY_ID_REQ, new AtAnyIdReq()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertFalse(mStartState.isValidStartAttributes(eapSimTypeData)); - } - - @Test - public void testIsValidStartAttributesInvalidAttributes() throws Exception { - mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - mAttributes.put(EAP_AT_MAC, new AtMac()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertFalse(mStartState.isValidStartAttributes(eapSimTypeData)); - - mAttributes.remove(EAP_AT_MAC); - mAttributes.put(EAP_AT_IV, null); // just need <K, V> pair in the map - eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertFalse(mStartState.isValidStartAttributes(eapSimTypeData)); - - mAttributes.remove(EAP_AT_IV); - mAttributes.put(EAP_AT_ENCR_DATA, null); // just need <K, V> pair in the map - eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - assertFalse(mStartState.isValidStartAttributes(eapSimTypeData)); - } - - @Test - public void testAddIdentityAttributeToResponse() throws Exception { - EapSimTypeData eapSimTypeData = new EapSimTypeData( - EAP_SIM_START, Arrays.asList(new AtPermanentIdReq())); - - when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI); - - AtIdentity atIdentity = mStartState.getIdentityResponse(eapSimTypeData); - assertArrayEquals(EAP_SIM_IDENTITY.getBytes(), mStartState.mIdentity); - verify(mMockTelephonyManager).getSubscriberId(); - assertArrayEquals(EAP_SIM_IDENTITY.getBytes(), atIdentity.identity); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testAddIdentityAttributeToResponseImsiUnavailable() throws Exception { - EapMessage eapMessage = new EapMessage( - EAP_CODE_REQUEST, - ID_INT, - new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA)); - mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq()); - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes); - DecodeResult decodeResult = new DecodeResult(eapSimTypeData); - - when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA)).thenReturn(decodeResult); - when(mMockTelephonyManager.getSubscriberId()).thenReturn(null); - - EapResult result = mStartState.process(eapMessage); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapSimAkaIdentityUnavailableException); - - verify(mMockTelephonyManager).getSubscriberId(); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testAddIdentityAttributeToResponseNoIdRequest() throws Exception { - EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, Arrays.asList()); - - AtIdentity atIdentity = mStartState.getIdentityResponse(eapSimTypeData); - assertNull(atIdentity); - verifyNoMoreInteractions(mMockTelephonyManager); - } - - @Test - public void testProcessWithoutIdentityRequest() throws Exception { - EapMessage eapMessage = - new EapMessage( - EAP_CODE_REQUEST, ID_INT, new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA)); - - // Send EAP-SIM/Start message without Identity request - mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1)); - DecodeResult eapSimStartDecodeResult = - new DecodeResult(new EapSimTypeData(EAP_SIM_START, mAttributes)); - when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA)) - .thenReturn(eapSimStartDecodeResult); - - EapResult result = mEapSimMethodStateMachine.process(eapMessage); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals( - Log.byteArrayToHexString(eapResponse.packet), - EAP_SIM_RESPONSE_WITHOUT_IDENTITY, - eapResponse.packet); - - verify(mMockEapSimTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA)); - - // Send EAP-SIM/Challenge message - DecodeResult eapSimChallengeDecodeResult = - new DecodeResult(new EapSimTypeData(EAP_SIM_CHALLENGE, new LinkedHashMap<>())); - when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA)) - .thenReturn(eapSimChallengeDecodeResult); - - // We only care about the transition to ChallengeState - the response doesn't matter - mEapSimMethodStateMachine.process(eapMessage); - ChallengeState challengeState = (ChallengeState) mEapSimMethodStateMachine.getState(); - assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity); - - // verify decode called 3x times: - // 1. decode in EAP-SIM/Start test above - // 2. decode in EAP-SIM/Challenge test for StartState - // 3. decode in EAP-SIM/Challenge test for ChallengeState - verify(mMockEapSimTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java deleted file mode 100644 index d8d18416..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; -import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION; -import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE; -import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig.EapSimConfig; -import android.telephony.TelephonyManager; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.message.EapData; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode; -import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification; -import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult; -import com.android.internal.net.eap.message.simaka.EapSimTypeData; -import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder; -import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; -import java.util.Arrays; - -public class EapSimStateTest { - protected static final int SUB_ID = 1; - protected static final String NOTIFICATION_MESSAGE = "test"; - protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566"); - - // EAP-Identity = hex("test@android.net") - protected static final byte[] EAP_IDENTITY_BYTES = - hexStringToByteArray("7465737440616E64726F69642E6E6574"); - - protected TelephonyManager mMockTelephonyManager; - protected EapSimTypeDataDecoder mMockEapSimTypeDataDecoder; - - protected EapSimConfig mEapSimConfig = new EapSimConfig(SUB_ID, APPTYPE_USIM); - protected EapSimMethodStateMachine mEapSimMethodStateMachine; - - @Before - public void setUp() { - mMockTelephonyManager = mock(TelephonyManager.class); - mMockEapSimTypeDataDecoder = mock(EapSimTypeDataDecoder.class); - - when(mMockTelephonyManager.createForSubscriptionId(SUB_ID)) - .thenReturn(mMockTelephonyManager); - - mEapSimMethodStateMachine = - new EapSimMethodStateMachine( - mMockTelephonyManager, - EAP_IDENTITY_BYTES, - mEapSimConfig, - new SecureRandom(), - mMockEapSimTypeDataDecoder); - - verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID); - } - - @Test - public void testProcessNotification() throws Exception { - EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes()); - EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preNotification = (EapMethodState) mEapSimMethodStateMachine.getState(); - - EapResult result = mEapSimMethodStateMachine.process(notification); - assertEquals(preNotification, mEapSimMethodStateMachine.getState()); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - - assertTrue(result instanceof EapResponse); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - } - - @Test - public void testProcessEapSimNotification() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preProcess = (EapMethodState) mEapSimMethodStateMachine.getState(); - EapSimTypeData typeData = - new EapSimTypeData( - EAP_SIM_NOTIFICATION, - Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE))); - - DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(typeData); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResponse eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage); - assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet); - assertEquals(preProcess, mEapSimMethodStateMachine.getState()); - verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - } - - @Test - public void testProcessInvalidDecodeResult() throws Exception { - EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA); - EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData); - EapMethodState preProcess = (EapMethodState) mEapSimMethodStateMachine.getState(); - - AtClientErrorCode atClientErrorCode = AtClientErrorCode.INSUFFICIENT_CHALLENGES; - DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(atClientErrorCode); - when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult); - - EapResult result = mEapSimMethodStateMachine.process(eapMessage); - assertEquals(preProcess, mEapSimMethodStateMachine.getState()); - verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA); - verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder); - - assertTrue(result instanceof EapResponse); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES, eapResponse.packet); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java deleted file mode 100644 index 288fc85f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static androidx.test.InstrumentationRegistry.getInstrumentation; - -import static com.android.internal.net.eap.EapTestUtils.getDummyEapSessionConfig; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET; - -import static org.junit.Assert.assertTrue; - -import android.content.Context; -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.statemachine.EapStateMachine.CreatedState; -import com.android.internal.net.eap.statemachine.EapStateMachine.FailureState; -import com.android.internal.net.eap.statemachine.EapStateMachine.SuccessState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; - -public class EapStateMachineTest { - private Context mContext; - private EapSessionConfig mEapSessionConfig; - - @Before - public void setUp() { - mContext = getInstrumentation().getContext(); - mEapSessionConfig = getDummyEapSessionConfig(); - } - - @Test - public void testEapStateMachineStartState() { - EapStateMachine eapStateMachine = - new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom()); - assertTrue(eapStateMachine.getState() instanceof CreatedState); - } - - @Test - public void testSuccessStateProcessFails() { - SuccessState successState = - new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom()) - .new SuccessState(); - EapResult result = successState.process(EAP_SUCCESS_PACKET); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testFailureStateProcessFails() { - FailureState failureState = - new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom()) - .new FailureState(); - EapResult result = failureState.process(EAP_SUCCESS_PACKET); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java deleted file mode 100644 index 0193cb4e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static androidx.test.InstrumentationRegistry.getInstrumentation; - -import static com.android.internal.net.eap.EapTestUtils.getDummyEapSimSessionConfig; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_MD5_CHALLENGE; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NAK_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; - -import android.content.Context; -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.exceptions.EapInvalidPacketLengthException; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.statemachine.EapStateMachine.EapState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; - -/** - * EapStateTest is a test template for testing EapState implementations. - * - * <p>Specifically, testing for CreatedState, IdentityState, and MethodState should subclass - * EapStateTest - */ -public class EapStateTest { - protected Context mContext; - protected EapSessionConfig mEapSessionConfig; - protected EapStateMachine mEapStateMachine; - protected EapState mEapState; - - @Before - public void setUp() { - mContext = getInstrumentation().getContext(); - mEapSessionConfig = getDummyEapSimSessionConfig(); - mEapStateMachine = new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom()); - - // this EapState definition is used to make sure all non-Success/Failure EAP states - // produce the same results for error cases. - mEapState = mEapStateMachine.new EapState() { - @Override - public EapResult process(byte[] msg) { - return decode(msg).eapResult; - } - }; - } - - @Test - public void testProcessNullPacket() { - EapResult result = mEapState.process(null); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof IllegalArgumentException); - } - - @Test - public void testProcessUnsupportedEapDataType() { - EapResult result = mEapState.process(REQUEST_UNSUPPORTED_TYPE_PACKET); - assertTrue(result instanceof EapResponse); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet); - } - - @Test - public void testProcessDecodeFailure() { - EapResult result = mEapState.process(SHORT_PACKET); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidPacketLengthException); - } - - @Test - public void testProcessResponse() { - EapResult result = mEapState.process(EAP_RESPONSE_NOTIFICATION_PACKET); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessNakRequest() { - EapResult result = mEapState.process(EAP_REQUEST_NAK_PACKET); - assertTrue(result instanceof EapError); - - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - } - - @Test - public void testProcessMd5Challenge() { - EapResult result = mEapState.process(EAP_REQUEST_MD5_CHALLENGE); - assertTrue(result instanceof EapResponse); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java deleted file mode 100644 index abe4e824..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static com.android.internal.net.eap.EapTestUtils.getDummyEapSessionConfig; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_IDENTITY; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_IDENTITY_DEFAULT_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_IDENTITY_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState; - -import org.junit.Before; -import org.junit.Test; - -import java.security.SecureRandom; - -public class IdentityStateTest extends EapStateTest { - private EapStateMachine mEapStateMachineSpy; - - @Before - @Override - public void setUp() { - super.setUp(); - - mEapStateMachineSpy = spy(mEapStateMachine); - mEapState = mEapStateMachineSpy.new IdentityState(); - } - - @Test - public void testProcess() { - mEapSessionConfig = getDummyEapSessionConfig(EAP_IDENTITY); - mEapStateMachineSpy = spy( - new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom())); - mEapState = mEapStateMachineSpy.new IdentityState(); - - EapResult eapResult = mEapState.process(EAP_REQUEST_IDENTITY_PACKET); - - assertTrue(eapResult instanceof EapResponse); - EapResponse eapResponse = (EapResponse) eapResult; - assertArrayEquals(EAP_RESPONSE_IDENTITY_PACKET, eapResponse.packet); - verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any()); - } - - @Test - public void testProcessDefaultIdentity() { - EapResult eapResult = mEapState.process(EAP_REQUEST_IDENTITY_PACKET); - - assertTrue(eapResult instanceof EapResponse); - EapResponse eapResponse = (EapResponse) eapResult; - assertArrayEquals(EAP_RESPONSE_IDENTITY_DEFAULT_PACKET, eapResponse.packet); - verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any()); - } - - @Test - public void testProcessNotificationRequest() { - EapResult eapResult = mEapState.process(EAP_REQUEST_NOTIFICATION_PACKET); - - // state shouldn't change after Notification request - assertTrue(eapResult instanceof EapResponse); - EapResponse eapResponse = (EapResponse) eapResult; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any()); - } - - @Test - public void testProcessSimStart() { - mEapState.process(EAP_REQUEST_SIM_START_PACKET); - - // EapStateMachine should change to MethodState for method-type packet - verify(mEapStateMachineSpy).transitionAndProcess( - any(MethodState.class), eq(EAP_REQUEST_SIM_START_PACKET)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java deleted file mode 100644 index 9df06e56..00000000 --- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * 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.internal.net.eap.statemachine; - -import static android.telephony.TelephonyManager.APPTYPE_USIM; - -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE; -import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS; -import static com.android.internal.net.eap.message.EapMessage.EAP_HEADER_LENGTH; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_REQUEST; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_MSCHAP_V2; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT; -import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.net.eap.EapSessionConfig; - -import com.android.internal.net.eap.EapResult; -import com.android.internal.net.eap.EapResult.EapError; -import com.android.internal.net.eap.EapResult.EapFailure; -import com.android.internal.net.eap.EapResult.EapResponse; -import com.android.internal.net.eap.EapResult.EapSuccess; -import com.android.internal.net.eap.exceptions.EapInvalidRequestException; -import com.android.internal.net.eap.message.EapMessage; -import com.android.internal.net.eap.statemachine.EapStateMachine.FailureState; -import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState; -import com.android.internal.net.eap.statemachine.EapStateMachine.SuccessState; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentMatcher; - -import java.security.SecureRandom; - -public class MethodStateTest extends EapStateTest { - private static final String USERNAME = "username"; - private static final String PASSWORD = "password"; - private static final String NETWORK_NAME = "android.net"; - private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = true; - - @Before - @Override - public void setUp() { - super.setUp(); - mEapState = mEapStateMachine.new MethodState(); - mEapStateMachine.transitionTo(mEapState); - } - - @Test - public void testProcessUnsupportedEapType() { - mEapState = mEapStateMachine.new MethodState(); - EapResult result = mEapState.process(EAP_REQUEST_IDENTITY_PACKET); - - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet); - } - - @Test - public void testProcessTransitionsToEapSim() { - mEapStateMachine.process(EAP_REQUEST_SIM_START_PACKET); - - assertTrue(mEapStateMachine.getState() instanceof MethodState); - MethodState methodState = (MethodState) mEapStateMachine.getState(); - assertTrue(methodState.mEapMethodStateMachine instanceof EapSimMethodStateMachine); - } - - @Test - public void testProcessTransitionToEapAka() { - // make EapStateMachine with EAP-AKA configurations - EapSessionConfig eapSessionConfig = new EapSessionConfig.Builder() - .setEapAkaConfig(0, APPTYPE_USIM).build(); - mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom()); - - mEapStateMachine.process(EAP_REQUEST_AKA); - - assertTrue(mEapStateMachine.getState() instanceof MethodState); - MethodState methodState = (MethodState) mEapStateMachine.getState(); - assertTrue(methodState.mEapMethodStateMachine instanceof EapAkaMethodStateMachine); - } - - @Test - public void testProcessTransitionToEapAkaPrime() { - // make EapStateMachine with EAP-AKA' configurations - EapSessionConfig eapSessionConfig = - new EapSessionConfig.Builder() - .setEapAkaPrimeConfig( - 0, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES) - .build(); - mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom()); - - mEapStateMachine.process(EAP_AKA_PRIME_REQUEST); - - assertTrue(mEapStateMachine.getState() instanceof MethodState); - MethodState methodState = (MethodState) mEapStateMachine.getState(); - assertTrue(methodState.mEapMethodStateMachine instanceof EapAkaPrimeMethodStateMachine); - } - - @Test - public void testProcessTransitionToEapMsChapV2() { - // make EapStateMachine with EAP MSCHAPv2 configurations - EapSessionConfig eapSessionConfig = - new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build(); - mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom()); - - mEapStateMachine.process(EAP_REQUEST_MSCHAP_V2); - - assertTrue(mEapStateMachine.getState() instanceof MethodState); - MethodState methodState = (MethodState) mEapStateMachine.getState(); - assertTrue(methodState.mEapMethodStateMachine instanceof EapMsChapV2MethodStateMachine); - } - - @Test - public void testProcessTransitionToSuccessState() { - EapSuccess eapSuccess = new EapSuccess(MSK, EMSK); - - ArgumentMatcher<EapMessage> eapSuccessMatcher = msg -> - msg.eapCode == EAP_CODE_SUCCESS - && msg.eapIdentifier == ID_INT - && msg.eapLength == EAP_HEADER_LENGTH - && msg.eapData == null; - - EapMethodStateMachine mockEapMethodStateMachine = mock(EapMethodStateMachine.class); - when(mockEapMethodStateMachine.process(argThat(eapSuccessMatcher))).thenReturn(eapSuccess); - ((MethodState) mEapState).mEapMethodStateMachine = mockEapMethodStateMachine; - - mEapState.process(EAP_SUCCESS_PACKET); - verify(mockEapMethodStateMachine).process(argThat(eapSuccessMatcher)); - assertTrue(mEapStateMachine.getState() instanceof SuccessState); - verifyNoMoreInteractions(mockEapMethodStateMachine); - } - - @Test - public void testProcessTransitionToFailureState() { - EapFailure eapFailure = new EapFailure(); - - ArgumentMatcher<EapMessage> eapSuccessMatcher = msg -> - msg.eapCode == EAP_CODE_FAILURE - && msg.eapIdentifier == ID_INT - && msg.eapLength == EAP_HEADER_LENGTH - && msg.eapData == null; - - EapMethodStateMachine mockEapMethodStateMachine = mock(EapMethodStateMachine.class); - when(mockEapMethodStateMachine.process(argThat(eapSuccessMatcher))).thenReturn(eapFailure); - ((MethodState) mEapState).mEapMethodStateMachine = mockEapMethodStateMachine; - - mEapState.process(EAP_FAILURE_PACKET); - verify(mockEapMethodStateMachine).process(argThat(eapSuccessMatcher)); - assertTrue(mEapStateMachine.getState() instanceof FailureState); - verifyNoMoreInteractions(mockEapMethodStateMachine); - } - - @Test - public void testProcessEapFailureWithNoEapMethodState() { - EapResult result = mEapStateMachine.process(EAP_FAILURE_PACKET); - assertTrue(result instanceof EapFailure); - assertTrue(mEapStateMachine.getState() instanceof FailureState); - } - - @Test - public void testProcessEapSuccessWithNoEapMethodState() { - EapResult result = mEapStateMachine.process(EAP_SUCCESS_PACKET); - EapError eapError = (EapError) result; - assertTrue(eapError.cause instanceof EapInvalidRequestException); - assertTrue(mEapStateMachine.getState() instanceof MethodState); - } - - @Test - public void testProcessEapNotificationWithNoEapMethodState() { - EapResult result = mEapStateMachine.process(EAP_REQUEST_NOTIFICATION_PACKET); - EapResponse eapResponse = (EapResponse) result; - assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet); - assertTrue(mEapStateMachine.getState() instanceof MethodState); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java deleted file mode 100644 index f6c32eef..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java +++ /dev/null @@ -1,1646 +0,0 @@ -/* - * 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.internal.net.ipsec.ike; - -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; -import static android.system.OsConstants.AF_INET; - -import static com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CMD_FORCE_TRANSITION; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS; -import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA; -import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; -import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_DELETE; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_KE; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NONCE; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_INITIATOR; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_RESPONDER; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_ESP; - -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.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.argThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyLong; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.IpSecManager; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.IpSecTransform; -import android.net.LinkAddress; -import android.net.ipsec.ike.ChildSaProposal; -import android.net.ipsec.ike.ChildSessionCallback; -import android.net.ipsec.ike.ChildSessionConfiguration; -import android.net.ipsec.ike.ChildSessionOptions; -import android.net.ipsec.ike.IkeManager; -import android.net.ipsec.ike.IkeTrafficSelector; -import android.net.ipsec.ike.SaProposal; -import android.net.ipsec.ike.TunnelModeChildSessionOptions; -import android.net.ipsec.ike.exceptions.IkeException; -import android.net.ipsec.ike.exceptions.IkeInternalException; -import android.os.test.TestLooper; - -import androidx.test.InstrumentationRegistry; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CreateChildSaHelper; -import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest; -import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecord; -import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecordConfig; -import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper; -import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException; -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.IkeDeletePayload; -import com.android.internal.net.ipsec.ike.message.IkeKePayload; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.message.IkeNoncePayload; -import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload; -import com.android.internal.net.ipsec.ike.message.IkePayload; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload; -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.IkeTestUtils; -import com.android.internal.net.ipsec.ike.message.IkeTsPayload; -import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils; -import com.android.internal.net.utils.Log; -import com.android.server.IpSecService; - -import libcore.net.InetAddressUtils; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.ArgumentMatcher; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.security.GeneralSecurityException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Executor; - -public final class ChildSessionStateMachineTest { - private static final String TAG = "ChildSessionStateMachineTest"; - - private static final Inet4Address LOCAL_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200")); - private static final Inet4Address REMOTE_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100")); - private static final Inet4Address INTERNAL_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("203.0.113.100")); - - private static final int IPV4_PREFIX_LEN = 32; - - private static final String IKE_AUTH_RESP_SA_PAYLOAD = - "2c00002c0000002801030403cae7019f0300000c0100000c800e0080" - + "03000008030000020000000805000000"; - private static final String REKEY_CHILD_RESP_SA_PAYLOAD = - "2800002c0000002801030403cd1736b30300000c0100000c800e0080" - + "03000008030000020000000805000000"; - private static final String REKEY_CHILD_REQ_SA_PAYLOAD = - "2800002c0000002801030403c88336490300000c0100000c800e0080" - + "03000008030000020000000805000000"; - private static final String REKEY_CHILD_UNACCEPTABLE_REQ_SA_PAYLOAD = - "2800002c0000002801030403c88336490300000c0100000c800e00c0" - + "03000008030000020000000805000000"; - - private static final int CURRENT_CHILD_SA_SPI_IN = 0x2ad4c0a2; - private static final int CURRENT_CHILD_SA_SPI_OUT = 0xcae7019f; - - private static final int LOCAL_INIT_NEW_CHILD_SA_SPI_IN = 0x57a09b0f; - private static final int LOCAL_INIT_NEW_CHILD_SA_SPI_OUT = 0xcd1736b3; - - private static final int REMOTE_INIT_NEW_CHILD_SA_SPI_IN = 0xd2d01795; - private static final int REMOTE_INIT_NEW_CHILD_SA_SPI_OUT = 0xc8833649; - - private static final String IKE_SK_D_HEX_STRING = "C86B56EFCF684DCC2877578AEF3137167FE0EBF6"; - private static final byte[] SK_D = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING); - - private static final int KEY_LEN_IKE_SKD = 20; - - private IkeMacPrf mIkePrf; - - private Context mContext; - private IpSecService mMockIpSecService; - private IpSecManager mMockIpSecManager; - private UdpEncapsulationSocket mMockUdpEncapSocket; - - private TestLooper mLooper; - private ChildSessionStateMachine mChildSessionStateMachine; - - private List<IkePayload> mFirstSaReqPayloads = new LinkedList<>(); - private List<IkePayload> mFirstSaRespPayloads = new LinkedList<>(); - - private ChildSaRecord mSpyCurrentChildSaRecord; - private ChildSaRecord mSpyLocalInitNewChildSaRecord; - private ChildSaRecord mSpyRemoteInitNewChildSaRecord; - - private Log mSpyIkeLog; - - private ISaRecordHelper mMockSaRecordHelper; - - private ChildSessionOptions mChildSessionOptions; - private EncryptionTransform mChildEncryptionTransform; - private IntegrityTransform mChildIntegrityTransform; - private DhGroupTransform mChildDhGroupTransform; - - private ChildSaProposal mMockNegotiatedProposal; - - private Executor mSpyUserCbExecutor; - private ChildSessionCallback mMockChildSessionCallback; - private IChildSessionSmCallback mMockChildSessionSmCallback; - - private ArgumentCaptor<ChildSaRecordConfig> mChildSaRecordConfigCaptor = - ArgumentCaptor.forClass(ChildSaRecordConfig.class); - private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor = - ArgumentCaptor.forClass(List.class); - private ArgumentCaptor<ChildSessionConfiguration> mChildConfigCaptor = - ArgumentCaptor.forClass(ChildSessionConfiguration.class); - - private ArgumentMatcher<ChildLocalRequest> mRekeyChildLocalReqMatcher = - (argument) -> { - return CMD_LOCAL_REQUEST_REKEY_CHILD == argument.procedureType - && mMockChildSessionCallback == argument.childSessionCallback; - }; - - public ChildSessionStateMachineTest() { - mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class); - mMockChildSessionSmCallback = mock(IChildSessionSmCallback.class); - - mChildEncryptionTransform = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128); - mChildIntegrityTransform = - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); - - mChildDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP); - } - - @Before - public void setup() throws Exception { - mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG); - IkeManager.setIkeLog(mSpyIkeLog); - - mIkePrf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - - mContext = InstrumentationRegistry.getContext(); - mMockIpSecService = mock(IpSecService.class); - mMockIpSecManager = new IpSecManager(mContext, mMockIpSecService); - mMockUdpEncapSocket = mock(UdpEncapsulationSocket.class); - - mMockNegotiatedProposal = mock(ChildSaProposal.class); - - mSpyUserCbExecutor = - spy( - (command) -> { - command.run(); - }); - - mMockChildSessionCallback = mock(ChildSessionCallback.class); - mChildSessionOptions = buildChildSessionOptions(); - - // Setup thread and looper - mLooper = new TestLooper(); - mChildSessionStateMachine = - new ChildSessionStateMachine( - mLooper.getLooper(), - mContext, - mMockIpSecManager, - mChildSessionOptions, - mSpyUserCbExecutor, - mMockChildSessionCallback, - mMockChildSessionSmCallback); - mChildSessionStateMachine.setDbg(true); - SaRecord.setSaRecordHelper(mMockSaRecordHelper); - - setUpFirstSaNegoPayloadLists(); - setUpChildSaRecords(); - - mChildSessionStateMachine.start(); - } - - @After - public void tearDown() { - mChildSessionStateMachine.setDbg(false); - IkeManager.resetIkeLog(); - SaRecord.setSaRecordHelper(new SaRecordHelper()); - } - - private ChildSaProposal buildSaProposal() throws Exception { - return new ChildSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) - .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) - .build(); - } - - private ChildSessionOptions buildChildSessionOptions() throws Exception { - return new TunnelModeChildSessionOptions.Builder() - .addSaProposal(buildSaProposal()) - .addInternalAddressRequest(AF_INET, 1) - .addInternalAddressRequest(INTERNAL_ADDRESS, IPV4_PREFIX_LEN) - .build(); - } - - private void setUpChildSaRecords() { - mSpyCurrentChildSaRecord = - makeSpyChildSaRecord(CURRENT_CHILD_SA_SPI_IN, CURRENT_CHILD_SA_SPI_OUT); - mSpyLocalInitNewChildSaRecord = - makeSpyChildSaRecord( - LOCAL_INIT_NEW_CHILD_SA_SPI_IN, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT); - mSpyRemoteInitNewChildSaRecord = - makeSpyChildSaRecord( - REMOTE_INIT_NEW_CHILD_SA_SPI_IN, REMOTE_INIT_NEW_CHILD_SA_SPI_OUT); - } - - private void setUpSpiResource(InetAddress address, int spiRequested) throws Exception { - when(mMockIpSecService.allocateSecurityParameterIndex( - eq(address.getHostAddress()), anyInt(), anyObject())) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(spiRequested)); - } - - private void setUpFirstSaNegoPayloadLists() throws Exception { - // Build locally generated SA payload that has its SPI resource allocated. - setUpSpiResource(LOCAL_ADDRESS, CURRENT_CHILD_SA_SPI_IN); - IkeSaPayload reqSaPayload = - IkeSaPayload.createChildSaRequestPayload( - mChildSessionOptions.getSaProposals(), mMockIpSecManager, LOCAL_ADDRESS); - mFirstSaReqPayloads.add(reqSaPayload); - - // Build a remotely generated SA payload whoes SPI resource has not been allocated. - setUpSpiResource(REMOTE_ADDRESS, CURRENT_CHILD_SA_SPI_OUT); - IkeSaPayload respSaPayload = - (IkeSaPayload) - (IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_SA, true, IKE_AUTH_RESP_SA_PAYLOAD)); - mFirstSaRespPayloads.add(respSaPayload); - - // Build TS Payloads - IkeTsPayload tsInitPayload = - new IkeTsPayload( - true /*isInitiator*/, mChildSessionOptions.getLocalTrafficSelectors()); - IkeTsPayload tsRespPayload = - new IkeTsPayload( - false /*isInitiator*/, mChildSessionOptions.getRemoteTrafficSelectors()); - - mFirstSaReqPayloads.add(tsInitPayload); - mFirstSaReqPayloads.add(tsRespPayload); - mFirstSaRespPayloads.add(tsInitPayload); - mFirstSaRespPayloads.add(tsRespPayload); - - // Build Nonce Payloads - mFirstSaReqPayloads.add(new IkeNoncePayload()); - mFirstSaRespPayloads.add(new IkeNoncePayload()); - - // Build Config Request Payload - List<ConfigAttribute> attrReqList = new LinkedList<>(); - attrReqList.add(new ConfigAttributeIpv4Address(INTERNAL_ADDRESS)); - attrReqList.add(new ConfigAttributeIpv4Netmask()); - mFirstSaReqPayloads.add(new IkeConfigPayload(false /*isReply*/, attrReqList)); - - // Build Config Reply Payload - List<ConfigAttribute> attrRespList = new LinkedList<>(); - attrRespList.add(new ConfigAttributeIpv4Address(INTERNAL_ADDRESS)); - mFirstSaRespPayloads.add(new IkeConfigPayload(true /*isReply*/, attrRespList)); - } - - private ChildSaRecord makeSpyChildSaRecord(int inboundSpi, int outboundSpi) { - ChildSaRecord child = - spy( - new ChildSaRecord( - inboundSpi, - outboundSpi, - true /*localInit*/, - null, - null, - null, - null, - null, - null, - mock(IpSecTransform.class), - mock(IpSecTransform.class), - mock(ChildLocalRequest.class))); - doNothing().when(child).close(); - return child; - } - - private void quitAndVerify() { - mChildSessionStateMachine.mCurrentChildSaRecord = null; - mChildSessionStateMachine.mLocalInitNewChildSaRecord = null; - mChildSessionStateMachine.mRemoteInitNewChildSaRecord = null; - - reset(mMockChildSessionSmCallback); - mChildSessionStateMachine.quit(); - mLooper.dispatchAll(); - - verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onChildSessionClosed(mMockChildSessionCallback); - } - - private void verifyChildSaRecordConfig( - ChildSaRecordConfig childSaRecordConfig, - int initSpi, - int respSpi, - boolean isLocalInit) { - assertEquals(mContext, childSaRecordConfig.context); - assertEquals(initSpi, childSaRecordConfig.initSpi.getSpi()); - assertEquals(respSpi, childSaRecordConfig.respSpi.getSpi()); - - if (isLocalInit) { - assertEquals(LOCAL_ADDRESS, childSaRecordConfig.initAddress); - assertEquals(REMOTE_ADDRESS, childSaRecordConfig.respAddress); - } else { - assertEquals(REMOTE_ADDRESS, childSaRecordConfig.initAddress); - assertEquals(LOCAL_ADDRESS, childSaRecordConfig.respAddress); - } - - assertEquals(mMockUdpEncapSocket, childSaRecordConfig.udpEncapSocket); - assertEquals(mIkePrf, childSaRecordConfig.ikePrf); - assertArrayEquals(SK_D, childSaRecordConfig.skD); - assertFalse(childSaRecordConfig.isTransport); - assertEquals(isLocalInit, childSaRecordConfig.isLocalInit); - assertTrue(childSaRecordConfig.hasIntegrityAlgo); - assertEquals( - CMD_LOCAL_REQUEST_REKEY_CHILD, childSaRecordConfig.futureRekeyEvent.procedureType); - assertEquals( - mMockChildSessionCallback, - childSaRecordConfig.futureRekeyEvent.childSessionCallback); - } - - private void verifyNotifyUsersCreateIpSecSa( - ChildSaRecord childSaRecord, boolean expectInbound) { - IpSecTransform transform = - expectInbound - ? childSaRecord.getInboundIpSecTransform() - : childSaRecord.getOutboundIpSecTransform(); - int direction = expectInbound ? IpSecManager.DIRECTION_IN : IpSecManager.DIRECTION_OUT; - - verify(mMockChildSessionCallback).onIpSecTransformCreated(eq(transform), eq(direction)); - } - - private void verifyInitCreateChildResp( - List<IkePayload> reqPayloads, List<IkePayload> respPayloads) throws Exception { - verify(mMockChildSessionSmCallback) - .onChildSaCreated( - mSpyCurrentChildSaRecord.getRemoteSpi(), mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - // Validate negotiated SA proposal. - ChildSaProposal negotiatedProposal = mChildSessionStateMachine.mSaProposal; - assertNotNull(negotiatedProposal); - assertEquals( - new EncryptionTransform[] {mChildEncryptionTransform}, - negotiatedProposal.getEncryptionTransforms()); - assertEquals( - new IntegrityTransform[] {mChildIntegrityTransform}, - negotiatedProposal.getIntegrityTransforms()); - - // Validate current ChildSaRecord - verify(mMockSaRecordHelper) - .makeChildSaRecord( - eq(reqPayloads), eq(respPayloads), mChildSaRecordConfigCaptor.capture()); - ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue(); - - verifyChildSaRecordConfig( - childSaRecordConfig, - CURRENT_CHILD_SA_SPI_IN, - CURRENT_CHILD_SA_SPI_OUT, - true /*isLocalInit*/); - - assertEquals(mSpyCurrentChildSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord); - - verify(mMockChildSessionSmCallback) - .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); - verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - // Verify users have been notified - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verifyNotifyUsersCreateIpSecSa(mSpyCurrentChildSaRecord, true /*expectInbound*/); - verifyNotifyUsersCreateIpSecSa(mSpyCurrentChildSaRecord, false /*expectInbound*/); - verify(mMockChildSessionCallback).onOpened(mChildConfigCaptor.capture()); - - // Verify Child Session Configuration - ChildSessionConfiguration sessionConfig = mChildConfigCaptor.getValue(); - verifyTsList( - Arrays.asList(mChildSessionOptions.getLocalTrafficSelectors()), - sessionConfig.getInboundTrafficSelectors()); - verifyTsList( - Arrays.asList(mChildSessionOptions.getRemoteTrafficSelectors()), - sessionConfig.getOutboundTrafficSelectors()); - - List<LinkAddress> addrList = sessionConfig.getInternalAddressList(); - assertEquals(1, addrList.size()); - assertEquals(INTERNAL_ADDRESS, addrList.get(0).getAddress()); - assertEquals(IPV4_PREFIX_LEN, addrList.get(0).getPrefixLength()); - } - - 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 testCreateFirstChild() throws Exception { - when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any())) - .thenReturn(mSpyCurrentChildSaRecord); - - mChildSessionStateMachine.handleFirstChildExchange( - mFirstSaReqPayloads, - mFirstSaRespPayloads, - LOCAL_ADDRESS, - REMOTE_ADDRESS, - mMockUdpEncapSocket, - mIkePrf, - SK_D); - mLooper.dispatchAll(); - - verifyInitCreateChildResp(mFirstSaReqPayloads, mFirstSaRespPayloads); - - quitAndVerify(); - } - - private void verifyOutboundCreatePayloadTypes( - List<IkePayload> outboundPayloads, boolean isRekey) { - assertNotNull( - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_SA, IkeSaPayload.class, outboundPayloads)); - assertNotNull( - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class, outboundPayloads)); - assertNotNull( - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class, outboundPayloads)); - assertNotNull( - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_NONCE, IkeNoncePayload.class, outboundPayloads)); - assertNull( - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_KE, IkeKePayload.class, outboundPayloads)); - - IkeConfigPayload configPayload = - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_CP, IkeConfigPayload.class, outboundPayloads); - if (isRekey) { - assertNull(configPayload); - } else { - assertNotNull(configPayload); - assertEquals(IkeConfigPayload.CONFIG_TYPE_REQUEST, configPayload.configType); - } - } - - @Test - public void testCreateChild() throws Exception { - when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any())) - .thenReturn(mSpyCurrentChildSaRecord); - - mChildSessionStateMachine.createChildSession( - LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D); - mLooper.dispatchAll(); - - // Validate outbound payload list - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_CREATE_CHILD_SA), - eq(false), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - - List<IkePayload> reqPayloadList = mPayloadListCaptor.getValue(); - verifyOutboundCreatePayloadTypes(reqPayloadList, false /*isRekey*/); - assertTrue( - IkePayload.getPayloadListForTypeInProvidedList( - PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, reqPayloadList) - .isEmpty()); - - mChildSessionStateMachine.receiveResponse( - EXCHANGE_TYPE_CREATE_CHILD_SA, mFirstSaRespPayloads); - mLooper.dispatchAll(); - - verifyInitCreateChildResp(reqPayloadList, mFirstSaRespPayloads); - - quitAndVerify(); - } - - private <T extends IkeException> void verifyHandleFatalErrorAndQuit(Class<T> exceptionClass) { - assertNull(mChildSessionStateMachine.getCurrentState()); - verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onChildSessionClosed(mMockChildSessionCallback); - - verify(mMockChildSessionCallback).onClosedExceptionally(any(exceptionClass)); - } - - @Test - public void testCreateChildHandlesErrorNotifyResp() throws Exception { - // Send out Create request - mChildSessionStateMachine.createChildSession( - LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D); - mLooper.dispatchAll(); - - // Receive error notification in Create response - IkeNotifyPayload notifyPayload = new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN); - List<IkePayload> respPayloads = new LinkedList<>(); - respPayloads.add(notifyPayload); - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads); - mLooper.dispatchAll(); - - // Verify no SPI for provisional Child was registered. - verify(mMockChildSessionSmCallback, never()) - .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine)); - - // Verify user was notified and state machine has quit. - verifyHandleFatalErrorAndQuit(NoValidProposalChosenException.class); - } - - @Test - public void testCreateChildHandlesRespWithMissingPayload() throws Exception { - // Send out Create request - mChildSessionStateMachine.createChildSession( - LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D); - mLooper.dispatchAll(); - - // Receive response with no Nonce Payload - List<IkePayload> respPayloads = new LinkedList<>(); - for (IkePayload payload : mFirstSaRespPayloads) { - if (IkePayload.PAYLOAD_TYPE_NONCE == payload.payloadType) continue; - respPayloads.add(payload); - } - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads); - mLooper.dispatchAll(); - - // Verify SPI for provisional Child was registered and unregistered. - verify(mMockChildSessionSmCallback) - .onChildSaCreated(CURRENT_CHILD_SA_SPI_OUT, mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onChildSaDeleted(CURRENT_CHILD_SA_SPI_OUT); - - // Verify user was notified and state machine has quit. - verifyHandleFatalErrorAndQuit(InvalidSyntaxException.class); - } - - @Test - public void testCreateChildHandlesKeyCalculationFail() throws Exception { - // Throw exception when building ChildSaRecord - when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any())) - .thenThrow( - new GeneralSecurityException("testCreateChildHandlesKeyCalculationFail")); - - // Send out and receive Create Child message - mChildSessionStateMachine.createChildSession( - LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D); - mLooper.dispatchAll(); - mChildSessionStateMachine.receiveResponse( - EXCHANGE_TYPE_CREATE_CHILD_SA, mFirstSaRespPayloads); - mLooper.dispatchAll(); - - // Verify SPI for provisional Child was registered and unregistered. - verify(mMockChildSessionSmCallback) - .onChildSaCreated(CURRENT_CHILD_SA_SPI_OUT, mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onChildSaDeleted(CURRENT_CHILD_SA_SPI_OUT); - - // Verify user was notified and state machine has quit. - verifyHandleFatalErrorAndQuit(IkeInternalException.class); - } - - private void setupIdleStateMachine() throws Exception { - mChildSessionStateMachine.mLocalAddress = LOCAL_ADDRESS; - mChildSessionStateMachine.mRemoteAddress = REMOTE_ADDRESS; - mChildSessionStateMachine.mUdpEncapSocket = mMockUdpEncapSocket; - mChildSessionStateMachine.mIkePrf = mIkePrf; - mChildSessionStateMachine.mSkD = SK_D; - - mChildSessionStateMachine.mSaProposal = buildSaProposal(); - mChildSessionStateMachine.mChildCipher = mock(IkeCipher.class); - mChildSessionStateMachine.mChildIntegrity = mock(IkeMacIntegrity.class); - mChildSessionStateMachine.mLocalTs = mChildSessionOptions.getLocalTrafficSelectors(); - mChildSessionStateMachine.mRemoteTs = mChildSessionOptions.getRemoteTrafficSelectors(); - - mChildSessionStateMachine.mCurrentChildSaRecord = mSpyCurrentChildSaRecord; - - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mIdle); - mLooper.dispatchAll(); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - } - - private List<IkePayload> makeDeletePayloads(int spi) { - List<IkePayload> inboundPayloads = new ArrayList<>(1); - inboundPayloads.add(new IkeDeletePayload(new int[] {spi})); - return inboundPayloads; - } - - private void verifyOutboundDeletePayload(int expectedSpi, boolean isResp) { - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_INFORMATIONAL), - eq(isResp), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - - List<IkePayload> outPayloadList = mPayloadListCaptor.getValue(); - assertEquals(1, outPayloadList.size()); - - List<IkeDeletePayload> deletePayloads = - IkePayload.getPayloadListForTypeInProvidedList( - PAYLOAD_TYPE_DELETE, IkeDeletePayload.class, outPayloadList); - assertEquals(1, deletePayloads.size()); - IkeDeletePayload deletePayload = deletePayloads.get(0); - assertEquals(expectedSpi, deletePayload.spisToDelete[0]); - } - - private void verifyNotifyUserDeleteChildSa(ChildSaRecord childSaRecord) { - verify(mMockChildSessionCallback) - .onIpSecTransformDeleted( - eq(childSaRecord.getInboundIpSecTransform()), - eq(IpSecManager.DIRECTION_IN)); - verify(mMockChildSessionCallback) - .onIpSecTransformDeleted( - eq(childSaRecord.getOutboundIpSecTransform()), - eq(IpSecManager.DIRECTION_OUT)); - } - - private void verifyNotifyUsersDeleteSession() { - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockChildSessionCallback).onClosed(); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - } - - @Test - public void testDeleteChildLocal() throws Exception { - setupIdleStateMachine(); - - // Test initiating Delete request - mChildSessionStateMachine.deleteChildSession(); - mLooper.dispatchAll(); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.DeleteChildLocalDelete); - verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), false /*isResp*/); - - // Test receiving Delete response - mChildSessionStateMachine.receiveResponse( - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - - verifyNotifyUsersDeleteSession(); - } - - @Test - public void testDeleteChildLocalHandlesInvalidResp() throws Exception { - setupIdleStateMachine(); - - // Test initiating Delete request - mChildSessionStateMachine.deleteChildSession(); - mLooper.dispatchAll(); - - // Test receiving response with no Delete Payload - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_INFORMATIONAL, new LinkedList<>()); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - verify(mMockChildSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - } - - @Test - public void testDeleteChildLocalInInitial() throws Exception { - mChildSessionStateMachine.deleteChildSession(); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockChildSessionCallback).onClosed(); - } - - @Test - public void testSimultaneousDeleteChild() throws Exception { - setupIdleStateMachine(); - - mChildSessionStateMachine.deleteChildSession(); - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_INFORMATIONAL), - eq(true), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - List<IkePayload> respPayloadList = mPayloadListCaptor.getValue(); - assertTrue(respPayloadList.isEmpty()); - - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_INFORMATIONAL, new LinkedList<>()); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - - verifyNotifyUsersDeleteSession(); - } - - @Test - public void testReplyRekeyRequestDuringDeletion() throws Exception { - setupIdleStateMachine(); - - mChildSessionStateMachine.deleteChildSession(); - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, mock(List.class)); - mLooper.dispatchAll(); - - // Verify outbound response to Rekey Child request - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_INFORMATIONAL), - eq(true), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - List<IkePayload> respPayloadList = mPayloadListCaptor.getValue(); - assertEquals(1, respPayloadList.size()); - - IkeNotifyPayload notifyPayload = (IkeNotifyPayload) respPayloadList.get(0); - assertEquals(ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType); - assertEquals(0, notifyPayload.notifyData.length); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.DeleteChildLocalDelete); - } - - @Test - public void testDeleteChildRemote() throws Exception { - setupIdleStateMachine(); - - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - // Verify response - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_INFORMATIONAL), - eq(true), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - List<IkePayload> respPayloadList = mPayloadListCaptor.getValue(); - - assertEquals(1, respPayloadList.size()); - assertArrayEquals( - new int[] {mSpyCurrentChildSaRecord.getLocalSpi()}, - ((IkeDeletePayload) respPayloadList.get(0)).spisToDelete); - - verifyNotifyUsersDeleteSession(); - } - - private void verifyOutboundRekeySaPayload(List<IkePayload> outboundPayloads, boolean isResp) { - IkeSaPayload saPayload = - IkePayload.getPayloadForTypeInProvidedList( - PAYLOAD_TYPE_SA, IkeSaPayload.class, outboundPayloads); - assertEquals(isResp, saPayload.isSaResponse); - assertEquals(1, saPayload.proposalList.size()); - - IkeSaPayload.ChildProposal proposal = - (IkeSaPayload.ChildProposal) saPayload.proposalList.get(0); - assertEquals(1, proposal.number); // Must be 1-indexed - assertEquals(mChildSessionStateMachine.mSaProposal, proposal.saProposal); - } - - private void verifyOutboundRekeyNotifyPayload(List<IkePayload> outboundPayloads) { - List<IkeNotifyPayload> notifyPayloads = - IkePayload.getPayloadListForTypeInProvidedList( - PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, outboundPayloads); - assertEquals(1, notifyPayloads.size()); - IkeNotifyPayload notifyPayload = notifyPayloads.get(0); - assertEquals(NOTIFY_TYPE_REKEY_SA, notifyPayload.notifyType); - assertEquals(PROTOCOL_ID_ESP, notifyPayload.protocolId); - assertEquals(mSpyCurrentChildSaRecord.getLocalSpi(), notifyPayload.spi); - } - - @Test - public void testRekeyChildLocalCreateSendsRequest() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mChildSessionStateMachine.rekeyChildSession(); - mLooper.dispatchAll(); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildLocalCreate); - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_CREATE_CHILD_SA), - eq(false), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - - // Verify outbound payload list - List<IkePayload> reqPayloadList = mPayloadListCaptor.getValue(); - verifyOutboundCreatePayloadTypes(reqPayloadList, true /*isRekey*/); - - verifyOutboundRekeySaPayload(reqPayloadList, false /*isResp*/); - verifyOutboundRekeyNotifyPayload(reqPayloadList); - } - - private List<IkePayload> makeInboundRekeyChildPayloads( - int remoteSpi, String inboundSaHexString, boolean isLocalInitRekey) throws Exception { - List<IkePayload> inboundPayloads = new LinkedList<>(); - - IkeSaPayload saPayload = - (IkeSaPayload) - (IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_SA, true, inboundSaHexString)); - inboundPayloads.add(saPayload); - - // Build TS Payloads - IkeTrafficSelector[] initTs = - isLocalInitRekey - ? mChildSessionStateMachine.mLocalTs - : mChildSessionStateMachine.mRemoteTs; - IkeTrafficSelector[] respTs = - isLocalInitRekey - ? mChildSessionStateMachine.mRemoteTs - : mChildSessionStateMachine.mLocalTs; - inboundPayloads.add(new IkeTsPayload(true /*isInitiator*/, initTs)); - inboundPayloads.add(new IkeTsPayload(false /*isInitiator*/, respTs)); - - // Build Nonce Payloads - inboundPayloads.add(new IkeNoncePayload()); - - if (isLocalInitRekey) { - // Rekey-Create response without Notify-Rekey payload is valid. - return inboundPayloads; - } - - // Build Rekey-Notification - inboundPayloads.add( - new IkeNotifyPayload( - PROTOCOL_ID_ESP, - mSpyCurrentChildSaRecord.getRemoteSpi(), - NOTIFY_TYPE_REKEY_SA, - new byte[0])); - - return inboundPayloads; - } - - @Test - public void testRekeyChildLocalCreateValidatesResponse() throws Exception { - setupIdleStateMachine(); - setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN); - setUpSpiResource(REMOTE_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT); - - // Send Rekey-Create request - mChildSessionStateMachine.rekeyChildSession(); - mLooper.dispatchAll(); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildLocalCreate); - - // Prepare "rekeyed" SA and receive Rekey response - List<IkePayload> rekeyRespPayloads = - makeInboundRekeyChildPayloads( - LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_RESP_SA_PAYLOAD, - true /*isLocalInitRekey*/); - when(mMockSaRecordHelper.makeChildSaRecord( - any(List.class), eq(rekeyRespPayloads), any(ChildSaRecordConfig.class))) - .thenReturn(mSpyLocalInitNewChildSaRecord); - - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyRespPayloads); - mLooper.dispatchAll(); - - // Verify state transition - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildLocalDelete); - - // Verify newly created ChildSaRecord - assertEquals( - mSpyLocalInitNewChildSaRecord, - mChildSessionStateMachine.mLocalInitNewChildSaRecord); - verify(mMockChildSessionSmCallback) - .onChildSaCreated( - eq(mSpyLocalInitNewChildSaRecord.getRemoteSpi()), - eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); - - verify(mMockSaRecordHelper) - .makeChildSaRecord( - any(List.class), - eq(rekeyRespPayloads), - mChildSaRecordConfigCaptor.capture()); - ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue(); - verifyChildSaRecordConfig( - childSaRecordConfig, - LOCAL_INIT_NEW_CHILD_SA_SPI_IN, - LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, - true /*isLocalInit*/); - - // Verify users have been notified - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verifyNotifyUsersCreateIpSecSa(mSpyLocalInitNewChildSaRecord, true /*expectInbound*/); - verifyNotifyUsersCreateIpSecSa(mSpyLocalInitNewChildSaRecord, false /*expectInbound*/); - } - - @Test - public void testRekeyLocalCreateHandlesErrorNotifyResp() throws Exception { - setupIdleStateMachine(); - setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN); - - // Send Rekey-Create request - mChildSessionStateMachine.rekeyChildSession(); - mLooper.dispatchAll(); - - // Receive error notification in Create response - IkeNotifyPayload notifyPayload = new IkeNotifyPayload(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE); - List<IkePayload> respPayloads = new LinkedList<>(); - respPayloads.add(notifyPayload); - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads); - mLooper.dispatchAll(); - - // Verify rekey has been rescheduled and Child Session is alive - verify(mMockChildSessionSmCallback) - .scheduleRetryLocalRequest( - (ChildLocalRequest) mSpyCurrentChildSaRecord.getFutureRekeyEvent()); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - // Verify no SPI for provisional Child was registered. - verify(mMockChildSessionSmCallback, never()) - .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine)); - } - - @Test - public void testRekeyLocalCreateHandlesRespWithMissingPayload() throws Exception { - setupIdleStateMachine(); - setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN); - reset(mMockChildSessionSmCallback); - - // Send Rekey-Create request - mChildSessionStateMachine.rekeyChildSession(); - mLooper.dispatchAll(); - - // Receive response with no SA Payload - List<IkePayload> validRekeyRespPayloads = - makeInboundRekeyChildPayloads( - LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_RESP_SA_PAYLOAD, - true /*isLocalInitRekey*/); - List<IkePayload> respPayloads = new LinkedList<>(); - for (IkePayload payload : validRekeyRespPayloads) { - if (IkePayload.PAYLOAD_TYPE_SA == payload.payloadType) continue; - respPayloads.add(payload); - } - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads); - mLooper.dispatchAll(); - - // Verify user was notified and state machine has quit. - verifyHandleFatalErrorAndQuit(InvalidSyntaxException.class); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - - // Verify no SPI for provisional Child was registered. - verify(mMockChildSessionSmCallback, never()) - .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine)); - - // Verify retry was not scheduled - verify(mMockChildSessionSmCallback, never()).scheduleRetryLocalRequest(any()); - } - - @Test - public void testRekeyLocalCreateChildHandlesKeyCalculationFail() throws Exception { - // Throw exception when building ChildSaRecord - when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any())) - .thenThrow( - new GeneralSecurityException( - "testRekeyCreateChildHandlesKeyCalculationFail")); - - // Setup for rekey negotiation - setupIdleStateMachine(); - setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN); - setUpSpiResource(REMOTE_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT); - reset(mMockChildSessionSmCallback); - - // Send Rekey-Create request - mChildSessionStateMachine.rekeyChildSession(); - mLooper.dispatchAll(); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildLocalCreate); - - // Receive Rekey response - List<IkePayload> rekeyRespPayloads = - makeInboundRekeyChildPayloads( - LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_RESP_SA_PAYLOAD, - true /*isLocalInitRekey*/); - mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyRespPayloads); - mLooper.dispatchAll(); - - // Verify user was notified and state machine has quit. - verifyHandleFatalErrorAndQuit(IkeInternalException.class); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - - // Verify SPI for provisional Child was registered and unregistered. - verify(mMockChildSessionSmCallback) - .onChildSaCreated(LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, mChildSessionStateMachine); - verify(mMockChildSessionSmCallback).onChildSaDeleted(LOCAL_INIT_NEW_CHILD_SA_SPI_OUT); - - // Verify retry was not scheduled - verify(mMockChildSessionSmCallback, never()).scheduleRetryLocalRequest(any()); - } - - @Test - public void testRekeyChildLocalDeleteSendsRequest() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildLocalDelete - mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete); - mLooper.dispatchAll(); - - // Verify outbound delete request - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildLocalDelete); - verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), false /*isResp*/); - - assertEquals(mSpyCurrentChildSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord); - assertEquals( - mSpyLocalInitNewChildSaRecord, mChildSessionStateMachine.mChildSaRecordSurviving); - } - - void verifyChildSaUpdated(ChildSaRecord oldSaRecord, ChildSaRecord newSaRecord) { - verify(mMockChildSessionSmCallback).onChildSaDeleted(oldSaRecord.getRemoteSpi()); - verify(oldSaRecord).close(); - - assertNull(mChildSessionStateMachine.mChildSaRecordSurviving); - assertEquals(newSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord); - } - - @Test - public void testRekeyChildLocalDeleteValidatesResponse() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildLocalDelete - mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete); - mLooper.dispatchAll(); - - // Test receiving Delete response - mChildSessionStateMachine.receiveResponse( - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - // First invoked in #setupIdleStateMachine - verify(mMockChildSessionSmCallback, times(2)) - .onProcedureFinished(mChildSessionStateMachine); - - verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyLocalInitNewChildSaRecord); - - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockChildSessionCallback, never()).onClosed(); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - } - - @Test - public void testRekeyChildLocalDeleteHandlesInvalidResp() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildLocalDelete - mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete); - mLooper.dispatchAll(); - - // Test receiving Delete response with missing Delete payload - mChildSessionStateMachine.receiveResponse( - EXCHANGE_TYPE_INFORMATIONAL, new ArrayList<IkePayload>()); - mLooper.dispatchAll(); - - // Verify rekey has finished - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyLocalInitNewChildSaRecord); - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - - // First invoked in #setupIdleStateMachine - verify(mMockChildSessionSmCallback, times(2)) - .onProcedureFinished(mChildSessionStateMachine); - } - - @Test - public void testRekeyChildRemoteCreate() throws Exception { - setupIdleStateMachine(); - - // Setup for new Child SA negotiation. - setUpSpiResource(LOCAL_ADDRESS, REMOTE_INIT_NEW_CHILD_SA_SPI_IN); - setUpSpiResource(REMOTE_ADDRESS, REMOTE_INIT_NEW_CHILD_SA_SPI_OUT); - - List<IkePayload> rekeyReqPayloads = - makeInboundRekeyChildPayloads( - REMOTE_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_REQ_SA_PAYLOAD, - false /*isLocalInitRekey*/); - when(mMockSaRecordHelper.makeChildSaRecord( - eq(rekeyReqPayloads), any(List.class), any(ChildSaRecordConfig.class))) - .thenReturn(mSpyRemoteInitNewChildSaRecord); - - // Receive rekey Child request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads); - mLooper.dispatchAll(); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildRemoteDelete); - - // Verify outbound rekey response - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(EXCHANGE_TYPE_CREATE_CHILD_SA), - eq(true), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - List<IkePayload> respPayloadList = mPayloadListCaptor.getValue(); - verifyOutboundCreatePayloadTypes(respPayloadList, true /*isRekey*/); - - verifyOutboundRekeySaPayload(respPayloadList, true /*isResp*/); - verifyOutboundRekeyNotifyPayload(respPayloadList); - - // Verify new Child SA - assertEquals( - mSpyRemoteInitNewChildSaRecord, - mChildSessionStateMachine.mRemoteInitNewChildSaRecord); - - verify(mMockChildSessionSmCallback) - .onChildSaCreated( - eq(mSpyRemoteInitNewChildSaRecord.getRemoteSpi()), - eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); - - verify(mMockSaRecordHelper) - .makeChildSaRecord( - eq(rekeyReqPayloads), - any(List.class), - mChildSaRecordConfigCaptor.capture()); - ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue(); - verifyChildSaRecordConfig( - childSaRecordConfig, - REMOTE_INIT_NEW_CHILD_SA_SPI_OUT, - REMOTE_INIT_NEW_CHILD_SA_SPI_IN, - false /*isLocalInit*/); - - // Verify that users are notified the creation of new inbound IpSecTransform - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, true /*expectInbound*/); - } - - private void verifyOutboundErrorNotify(int exchangeType, int errorCode) { - verify(mMockChildSessionSmCallback) - .onOutboundPayloadsReady( - eq(exchangeType), - eq(true), - mPayloadListCaptor.capture(), - eq(mChildSessionStateMachine)); - List<IkePayload> respPayloadList = mPayloadListCaptor.getValue(); - - assertEquals(1, respPayloadList.size()); - IkePayload payload = respPayloadList.get(0); - assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); - assertEquals(errorCode, ((IkeNotifyPayload) payload).notifyType); - } - - @Test - public void testRekeyChildRemoteCreateHandlesInvalidReq() throws Exception { - setupIdleStateMachine(); - - List<IkePayload> rekeyReqPayloads = - makeInboundRekeyChildPayloads( - REMOTE_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_UNACCEPTABLE_REQ_SA_PAYLOAD, - false /*isLocalInitRekey*/); - - // Receive rekey Child request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads); - mLooper.dispatchAll(); - - // Verify error notification was sent and state machind was back to Idle - verifyOutboundErrorNotify(EXCHANGE_TYPE_CREATE_CHILD_SA, ERROR_TYPE_NO_PROPOSAL_CHOSEN); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - } - - @Test - public void testRekeyChildRemoteCreateSaCreationFail() throws Exception { - // Throw exception when building ChildSaRecord - when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any())) - .thenThrow( - new GeneralSecurityException("testRekeyChildRemoteCreateSaCreationFail")); - - setupIdleStateMachine(); - - List<IkePayload> rekeyReqPayloads = - makeInboundRekeyChildPayloads( - REMOTE_INIT_NEW_CHILD_SA_SPI_OUT, - REKEY_CHILD_REQ_SA_PAYLOAD, - false /*isLocalInitRekey*/); - - // Receive rekey Child request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads); - mLooper.dispatchAll(); - - // Verify error notification was sent and state machind was back to Idle - verifyOutboundErrorNotify(EXCHANGE_TYPE_CREATE_CHILD_SA, ERROR_TYPE_NO_PROPOSAL_CHOSEN); - - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - } - - @Test - public void testRekeyChildRemoteDelete() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildRemoteDelete - mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete); - - // Test receiving Delete request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - // Verify outbound Delete response - verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), true /*isResp*/); - - // Verify Child SA has been updated - verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyRemoteInitNewChildSaRecord); - - // Verify procedure has been finished. #onProcedureFinished was first invoked in - // #setupIdleStateMachine - verify(mMockChildSessionSmCallback, times(2)) - .onProcedureFinished(mChildSessionStateMachine); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/); - verify(mMockChildSessionCallback, never()).onClosed(); - } - - @Test - public void testRekeyChildLocalDeleteWithReqForNewSa() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildLocalDelete - mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete); - mLooper.dispatchAll(); - - // Test receiving Delete new Child SA request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyLocalInitNewChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - // Verify outbound Delete response on new Child SA - verifyOutboundDeletePayload(mSpyLocalInitNewChildSaRecord.getLocalSpi(), true /*isResp*/); - verify(mMockChildSessionSmCallback) - .onChildSaDeleted(mSpyLocalInitNewChildSaRecord.getRemoteSpi()); - verify(mSpyLocalInitNewChildSaRecord).close(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - - verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUserDeleteChildSa(mSpyLocalInitNewChildSaRecord); - - verify(mMockChildSessionCallback).onClosed(); - } - - @Test - public void testRekeyChildRemoteDeleteWithReqForNewSa() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildRemoteDelete - mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete); - mLooper.dispatchAll(); - - // Test receiving Delete new Child SA request - mChildSessionStateMachine.receiveRequest( - IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, - EXCHANGE_TYPE_INFORMATIONAL, - makeDeletePayloads(mSpyRemoteInitNewChildSaRecord.getRemoteSpi())); - mLooper.dispatchAll(); - - // Verify outbound Delete response on new Child SA - verifyOutboundDeletePayload(mSpyRemoteInitNewChildSaRecord.getLocalSpi(), true /*isResp*/); - verify(mMockChildSessionSmCallback) - .onChildSaDeleted(mSpyRemoteInitNewChildSaRecord.getRemoteSpi()); - verify(mSpyRemoteInitNewChildSaRecord).close(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - - verify(mSpyUserCbExecutor, times(3)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUserDeleteChildSa(mSpyRemoteInitNewChildSaRecord); - verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/); - - verify(mMockChildSessionCallback).onClosed(); - } - - @Test - public void testRekeyChildRemoteDeleteTimeout() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildRemoteDelete - mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete); - mLooper.dispatchAll(); - - mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS); - mLooper.dispatchAll(); - - // Verify no response sent. - verify(mMockChildSessionSmCallback, never()) - .onOutboundPayloadsReady(anyInt(), anyBoolean(), any(List.class), anyObject()); - - // Verify Child SA has been renewed - verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyRemoteInitNewChildSaRecord); - - // Verify procedure has been finished. #onProcedureFinished was first invoked in - // #setupIdleStateMachine - verify(mMockChildSessionSmCallback, times(2)) - .onProcedureFinished(mChildSessionStateMachine); - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.Idle); - - verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/); - - verify(mMockChildSessionCallback, never()).onClosed(); - } - - @Test - public void testRekeyChildRemoteDeleteExitAndRenter() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildRemoteDelete - mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete); - mLooper.dispatchAll(); - - // Trigger a timeout, and immediately re-enter remote-delete - mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS / 2 + 1); - mChildSessionStateMachine.sendMessage(ChildSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE); - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete); - mLooper.dispatchAll(); - - // Shift time forward - mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS / 2 + 1); - mLooper.dispatchAll(); - - // Verify final state has not changed - timeout was not triggered. - assertTrue( - mChildSessionStateMachine.getCurrentState() - instanceof ChildSessionStateMachine.RekeyChildRemoteDelete); - - verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/); - - verify(mMockChildSessionCallback, never()).onClosed(); - } - - @Test - public void testCloseSessionNow() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyChildLocalDelete - mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord; - mChildSessionStateMachine.sendMessage( - CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete); - - mChildSessionStateMachine.killSession(); - mLooper.dispatchAll(); - - assertNull(mChildSessionStateMachine.getCurrentState()); - - verify(mSpyUserCbExecutor, times(3)).execute(any(Runnable.class)); - - verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord); - verifyNotifyUserDeleteChildSa(mSpyLocalInitNewChildSaRecord); - - verify(mMockChildSessionCallback).onClosed(); - } - - @Test - public void testValidateExpectKeExistCase() throws Exception { - when(mMockNegotiatedProposal.getDhGroupTransforms()) - .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform}); - List<IkePayload> payloadList = new LinkedList<>(); - payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_1024_BIT_MODP)); - - CreateChildSaHelper.validateKePayloads( - payloadList, true /*isResp*/, mMockNegotiatedProposal); - CreateChildSaHelper.validateKePayloads( - payloadList, false /*isResp*/, mMockNegotiatedProposal); - } - - @Test - public void testValidateExpectNoKeExistCase() throws Exception { - when(mMockNegotiatedProposal.getDhGroupTransforms()).thenReturn(new DhGroupTransform[0]); - List<IkePayload> payloadList = new LinkedList<>(); - - CreateChildSaHelper.validateKePayloads( - payloadList, true /*isResp*/, mMockNegotiatedProposal); - CreateChildSaHelper.validateKePayloads( - payloadList, false /*isResp*/, mMockNegotiatedProposal); - } - - @Test - public void testThrowWhenKeMissing() throws Exception { - when(mMockNegotiatedProposal.getDhGroupTransforms()) - .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform}); - List<IkePayload> payloadList = new LinkedList<>(); - - try { - CreateChildSaHelper.validateKePayloads( - payloadList, true /*isResp*/, mMockNegotiatedProposal); - fail("Expected to fail due to the absence of KE Payload"); - } catch (InvalidSyntaxException expected) { - } - - try { - CreateChildSaHelper.validateKePayloads( - payloadList, false /*isResp*/, mMockNegotiatedProposal); - fail("Expected to fail due to the absence of KE Payload"); - } catch (InvalidKeException expected) { - } - } - - @Test - public void testThrowWhenKeHasMismatchedDhGroup() throws Exception { - when(mMockNegotiatedProposal.getDhGroupTransforms()) - .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform}); - List<IkePayload> payloadList = new LinkedList<>(); - payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_2048_BIT_MODP)); - - try { - CreateChildSaHelper.validateKePayloads( - payloadList, true /*isResp*/, mMockNegotiatedProposal); - fail("Expected to fail due to mismatched DH Group"); - } catch (InvalidSyntaxException expected) { - } - - try { - CreateChildSaHelper.validateKePayloads( - payloadList, false /*isResp*/, mMockNegotiatedProposal); - fail("Expected to fail due to mismatched DH Group"); - } catch (InvalidKeException expected) { - } - } - - @Test - public void testThrowForUnexpectedKe() throws Exception { - DhGroupTransform noneGroup = new DhGroupTransform(SaProposal.DH_GROUP_NONE); - when(mMockNegotiatedProposal.getDhGroupTransforms()) - .thenReturn(new DhGroupTransform[] {noneGroup}); - List<IkePayload> payloadList = new LinkedList<>(); - payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_2048_BIT_MODP)); - - try { - CreateChildSaHelper.validateKePayloads( - payloadList, true /*isResp*/, mMockNegotiatedProposal); - fail("Expected to fail due to unexpected KE payload."); - } catch (InvalidSyntaxException expected) { - } - - CreateChildSaHelper.validateKePayloads( - payloadList, false /*isResp*/, mMockNegotiatedProposal); - } - - @Test - public void testHandleUnexpectedException() throws Exception { - Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); - IkeManager.setIkeLog(spyIkeLog); - - mChildSessionStateMachine.createChildSession( - null /*localAddress*/, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D); - mLooper.dispatchAll(); - - verifyHandleFatalErrorAndQuit(IkeInternalException.class); - verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java deleted file mode 100644 index 3406d014..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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.internal.net.ipsec.ike; - -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE; - -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.inOrder; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IProcedureConsumer; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.InOrder; - -public final class IkeLocalRequestSchedulerTest { - private IkeLocalRequestScheduler mScheduler; - - private IProcedureConsumer mMockConsumer; - private LocalRequest[] mMockRequestArray; - - private ArgumentCaptor<LocalRequest> mLocalRequestCaptor = - ArgumentCaptor.forClass(LocalRequest.class); - - @Before - public void setUp() { - mMockConsumer = mock(IProcedureConsumer.class); - mScheduler = new IkeLocalRequestScheduler(mMockConsumer); - - mMockRequestArray = new LocalRequest[10]; - for (int i = 0; i < mMockRequestArray.length; i++) { - mMockRequestArray[i] = mock(LocalRequest.class); - } - } - - @Test - public void testAddMultipleRequestProcessOnlyOne() { - for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r); - - // Verify that no procedure was preemptively pulled from the queue - verify(mMockConsumer, never()).onNewProcedureReady(any()); - - // Check that the onNewPrcedureReady called exactly once, on the first item - mScheduler.readyForNextProcedure(); - verify(mMockConsumer, times(1)).onNewProcedureReady(any()); - verify(mMockConsumer, times(1)).onNewProcedureReady(mMockRequestArray[0]); - for (int i = 1; i < mMockRequestArray.length; i++) { - verify(mMockConsumer, never()).onNewProcedureReady(mMockRequestArray[i]); - } - } - - @Test - public void testProcessOrder() { - InOrder inOrder = inOrder(mMockConsumer); - - for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r); - for (int i = 0; i < mMockRequestArray.length; i++) mScheduler.readyForNextProcedure(); - - for (LocalRequest r : mMockRequestArray) { - inOrder.verify(mMockConsumer).onNewProcedureReady(r); - } - } - - @Test - public void testAddRequestToFrontProcessOrder() { - InOrder inOrder = inOrder(mMockConsumer); - - LocalRequest[] mockHighPriorityRequestArray = new LocalRequest[10]; - for (int i = 0; i < mockHighPriorityRequestArray.length; i++) { - mockHighPriorityRequestArray[i] = mock(LocalRequest.class); - } - - for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r); - for (LocalRequest r : mockHighPriorityRequestArray) mScheduler.addRequestAtFront(r); - - for (int i = 0; i < mockHighPriorityRequestArray.length + mMockRequestArray.length; i++) { - mScheduler.readyForNextProcedure(); - } - - // Verify processing order. mockHighPriorityRequestArray is processed in reverse order - for (int i = mockHighPriorityRequestArray.length - 1; i >= 0; i--) { - inOrder.verify(mMockConsumer).onNewProcedureReady(mockHighPriorityRequestArray[i]); - } - for (LocalRequest r : mMockRequestArray) { - inOrder.verify(mMockConsumer).onNewProcedureReady(r); - } - } - - @Test - public void testDoNotProcessCanceledRequest() { - LocalRequest[] requestArray = new LocalRequest[4]; - - for (int i = 0; i < requestArray.length; i++) { - requestArray[i] = new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE); - mScheduler.addRequest(requestArray[i]); - } - - mScheduler.readyForNextProcedure(); - verify(mMockConsumer).onNewProcedureReady(eq(requestArray[0])); - - requestArray[1].cancel(); - mScheduler.readyForNextProcedure(); - verify(mMockConsumer, never()).onNewProcedureReady(eq(requestArray[1])); - verify(mMockConsumer).onNewProcedureReady(eq(requestArray[2])); - - mScheduler.readyForNextProcedure(); - verify(mMockConsumer).onNewProcedureReady(eq(requestArray[3])); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java deleted file mode 100644 index 94f4d622..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java +++ /dev/null @@ -1,4036 +0,0 @@ -/* - * 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.internal.net.ipsec.ike; - -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD; - -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.RETRY_INTERVAL_MS; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.SA_SOFT_LIFETIME_MS; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS; -import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA; -import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; -import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED; -import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP; -import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_AUTH; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA; - -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.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Matchers.argThat; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.doThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.IpSecManager; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.eap.EapSessionConfig; -import android.net.ipsec.ike.ChildSaProposal; -import android.net.ipsec.ike.ChildSessionCallback; -import android.net.ipsec.ike.ChildSessionOptions; -import android.net.ipsec.ike.IkeIpv4AddrIdentification; -import android.net.ipsec.ike.IkeManager; -import android.net.ipsec.ike.IkeSaProposal; -import android.net.ipsec.ike.IkeSessionCallback; -import android.net.ipsec.ike.IkeSessionOptions; -import android.net.ipsec.ike.SaProposal; -import android.net.ipsec.ike.TransportModeChildSessionOptions; -import android.net.ipsec.ike.exceptions.IkeException; -import android.net.ipsec.ike.exceptions.IkeInternalException; -import android.net.ipsec.ike.exceptions.IkeProtocolException; -import android.os.test.TestLooper; -import android.telephony.TelephonyManager; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.eap.EapAuthenticator; -import com.android.internal.net.eap.IEapCallback; -import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback; -import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.ChildSessionFactoryHelper; -import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.IChildSessionFactoryHelper; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest; -import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex; -import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.ReceivedIkePacket; -import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper; -import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord; -import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecordConfig; -import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -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.IkeAuthDigitalSignPayload; -import com.android.internal.net.ipsec.ike.message.IkeAuthPayload; -import com.android.internal.net.ipsec.ike.message.IkeAuthPskPayload; -import com.android.internal.net.ipsec.ike.message.IkeCertX509CertPayload; -import com.android.internal.net.ipsec.ike.message.IkeDeletePayload; -import com.android.internal.net.ipsec.ike.message.IkeEapPayload; -import com.android.internal.net.ipsec.ike.message.IkeHeader; -import com.android.internal.net.ipsec.ike.message.IkeIdPayload; -import com.android.internal.net.ipsec.ike.message.IkeInformationalPayload; -import com.android.internal.net.ipsec.ike.message.IkeKePayload; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultProtectedError; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultUnprotectedError; -import com.android.internal.net.ipsec.ike.message.IkeMessage.IIkeMessageHelper; -import com.android.internal.net.ipsec.ike.message.IkeMessage.IkeMessageHelper; -import com.android.internal.net.ipsec.ike.message.IkeNoncePayload; -import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload; -import com.android.internal.net.ipsec.ike.message.IkePayload; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload; -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.IkeSkfPayload; -import com.android.internal.net.ipsec.ike.message.IkeTestUtils; -import com.android.internal.net.ipsec.ike.message.IkeTsPayload; -import com.android.internal.net.ipsec.ike.testutils.CertUtils; -import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils; -import com.android.internal.net.ipsec.ike.utils.Retransmitter; -import com.android.internal.net.ipsec.ike.utils.Retransmitter.IBackoffTimeoutCalculator; -import com.android.internal.net.utils.Log; -import com.android.internal.util.State; - -import libcore.net.InetAddressUtils; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; -import org.mockito.invocation.InvocationOnMock; - -import java.io.IOException; -import java.net.Inet4Address; -import java.security.GeneralSecurityException; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.Executor; - -public final class IkeSessionStateMachineTest { - private static final String TAG = "IkeSessionStateMachineTest"; - - 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 static final String IKE_INIT_RESP_HEX_STRING = - "5f54bf6d8b48e6e1909232b3d1edcb5c21202220000000000000014c220000300000" - + "002c010100040300000c0100000c800e008003000008030000020300000802000002" - + "00000008040000022800008800020000fe014fefed55a4229928bfa3dad1ea6ffaca" - + "abfb5f5bdd71790e99a192530e3f849d3a3d96dc6e0a7a10ff6f72a6162103ac573c" - + "acd41d08b7a034cad8f5eab09c14ced5a9e4af5692dff028f21c1119dd75226b6af6" - + "b2f009245369c9892cc5742e5c94a254ebff052470771fb2cb4f29a35d8953e18a1a" - + "6c6fbc56acc188a5290000249756112ca539f5c25abacc7ee92b73091942a9c06950" - + "f98848f1af1694c4ddff2900001c00004004c53f054b976a25d75fde72dbf1c7b6c8" - + "c9aa9ca12900001c00004005b16d79b21c1bc89ca7350f42de805be0227e2ed62b00" - + "00080000401400000014882fe56d6fd20dbc2251613b2ebe5beb"; - private static final String IKE_SA_PAYLOAD_HEX_STRING = - "220000300000002c010100040300000c0100000c800e00800300000803000002030" - + "00008020000020000000804000002"; - private static final String IKE_REKEY_SA_PAYLOAD_HEX_STRING = - "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" - + "000080300000203000008020000020000000804000002"; - private static final String IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING = - "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" - + "00008030000020300000802000002000000080400000e"; - private static final int IKE_REKEY_SA_INITIATOR_SPI = 0xff; - private static final String KE_PAYLOAD_HEX_STRING = - "2800008800020000b4a2faf4bb54878ae21d638512ece55d9236fc50" - + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa" - + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd" - + "92f46bef84f0be7db860351843858f8acf87056e272377f7" - + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" - + "6bbeb08214c7071376079587"; - private static final String NONCE_INIT_PAYLOAD_HEX_STRING = - "29000024c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; - private static final String NONCE_RESP_PAYLOAD_HEX_STRING = - "290000249756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; - private static final String NONCE_INIT_HEX_STRING = - "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; - private static final String NONCE_RESP_HEX_STRING = - "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; - private static final String NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING = - "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0"; - private static final String NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING = - "2b00001c00004005d915368ca036004cb578ae3e3fb268509aeab190"; - private static final String FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING = "290000080000402e"; - private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000"; - private static final String NOTIFY_REKEY_IKE_PAYLOAD_HEX_STRING = "2100000800004009"; - private static final String ID_PAYLOAD_INITIATOR_HEX_STRING = - "290000180200000031313233343536373839414243444546"; - private static final String ID_PAYLOAD_RESPONDER_HEX_STRING = "2700000c010000007f000001"; - private static final String PSK_AUTH_RESP_PAYLOAD_HEX_STRING = - "2100001c0200000058f36412e9b7b38df817a9f7779b7a008dacdd25"; - private static final String GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING = - "300000580e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d413" - + "6b9f69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8e" - + "12c5d982aa4efdaeac36a02b222aa96242cc424"; - private static final String CHILD_SA_PAYLOAD_HEX_STRING = - "2c00002c0000002801030403cae7019f0300000c0100000c800e008003000008030" - + "000020000000805000000"; - private static final String TS_INIT_PAYLOAD_HEX_STRING = - "2d00001801000000070000100000ffff00000000ffffffff"; - private static final String TS_RESP_PAYLOAD_HEX_STRING = - "2900001801000000070000100000ffff000000000fffffff"; - - private static final String PSK_HEX_STRING = "6A756E69706572313233"; - - private static final String PRF_KEY_INIT_HEX_STRING = - "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String PRF_KEY_RESP_HEX_STRING = - "A30E6B08BE56C0E6BFF4744143C75219299E1BEB"; - - private static final byte[] EAP_DUMMY_MSG = "EAP Message".getBytes(); - - private static final int KEY_LEN_IKE_INTE = 20; - private static final int KEY_LEN_IKE_ENCR = 16; - private static final int KEY_LEN_IKE_PRF = 20; - private static final int KEY_LEN_IKE_SKD = KEY_LEN_IKE_PRF; - - private static final int CHILD_SPI_LOCAL = 0x2ad4c0a2; - private static final int CHILD_SPI_REMOTE = 0xcae7019f; - - private static final int DUMMY_UDP_ENCAP_RESOURCE_ID = 0x3234; - private static final int UDP_ENCAP_PORT = 34567; - - private static final int EAP_SIM_SUB_ID = 1; - - private static final int PAYLOAD_TYPE_UNSUPPORTED = 127; - - private static final long RETRANSMIT_BACKOFF_TIMEOUT_MS = 5000L; - - private MockIpSecTestUtils mMockIpSecTestUtils; - private Context mContext; - private IpSecManager mIpSecManager; - private UdpEncapsulationSocket mUdpEncapSocket; - - private IkeSocket mSpyIkeSocket; - - private TestLooper mLooper; - private IkeSessionStateMachine mIkeSessionStateMachine; - - private byte[] mPsk; - - private ChildSessionOptions mChildSessionOptions; - - private Executor mSpyUserCbExecutor; - private IkeSessionCallback mMockIkeSessionCallback; - private ChildSessionCallback mMockChildSessionCallback; - - private EncryptionTransform mIkeEncryptionTransform; - private IntegrityTransform mIkeIntegrityTransform; - private PrfTransform mIkePrfTransform; - private DhGroupTransform mIkeDhGroupTransform; - - private IIkeMessageHelper mMockIkeMessageHelper; - private ISaRecordHelper mMockSaRecordHelper; - private IBackoffTimeoutCalculator mMockBackoffTimeoutCalculator; - - private ChildSessionStateMachine mMockChildSessionStateMachine; - private IChildSessionFactoryHelper mMockChildSessionFactoryHelper; - private IChildSessionSmCallback mDummyChildSmCallback; - - private IkeSaRecord mSpyCurrentIkeSaRecord; - private IkeSaRecord mSpyLocalInitIkeSaRecord; - private IkeSaRecord mSpyRemoteInitIkeSaRecord; - - private Log mSpyIkeLog; - - private int mExpectedCurrentSaLocalReqMsgId; - private int mExpectedCurrentSaRemoteReqMsgId; - - private EapSessionConfig mEapSessionConfig; - private IkeEapAuthenticatorFactory mMockEapAuthenticatorFactory; - private EapAuthenticator mMockEapAuthenticator; - - private X509Certificate mRootCertificate; - private X509Certificate mServerEndCertificate; - - private ArgumentCaptor<IkeMessage> mIkeMessageCaptor = - ArgumentCaptor.forClass(IkeMessage.class); - private ArgumentCaptor<IkeSaRecordConfig> mIkeSaRecordConfigCaptor = - ArgumentCaptor.forClass(IkeSaRecordConfig.class); - private ArgumentCaptor<IChildSessionSmCallback> mChildSessionSmCbCaptor = - ArgumentCaptor.forClass(IChildSessionSmCallback.class); - private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor = - ArgumentCaptor.forClass(List.class); - - private ReceivedIkePacket makeDummyReceivedIkeInitRespPacket( - long initiatorSpi, - long responderSpi, - @IkeHeader.ExchangeType int eType, - boolean isResp, - boolean fromIkeInit, - List<Integer> payloadTypeList, - List<String> payloadHexStringList) - throws Exception { - - List<IkePayload> payloadList = - hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); - // Build a remotely generated NAT_DETECTION_SOURCE_IP payload to mock a remote node's - // network that is not behind NAT. - IkePayload sourceNatPayload = - new IkeNotifyPayload( - NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP, - IkeNotifyPayload.generateNatDetectionData( - initiatorSpi, - responderSpi, - REMOTE_ADDRESS, - IkeSocket.IKE_SERVER_PORT)); - payloadList.add(sourceNatPayload); - return makeDummyUnencryptedReceivedIkePacket( - initiatorSpi, responderSpi, eType, isResp, fromIkeInit, payloadList); - } - - private ReceivedIkePacket makeDummyUnencryptedReceivedIkePacket( - long initiatorSpi, - long responderSpi, - @IkeHeader.ExchangeType int eType, - boolean isResp, - boolean fromIkeInit, - List<IkePayload> payloadList) - throws Exception { - IkeMessage dummyIkeMessage = - makeDummyIkeMessageForTest( - initiatorSpi, - responderSpi, - eType, - isResp, - fromIkeInit, - 0, - false /*isEncrypted*/, - payloadList); - - byte[] dummyIkePacketBytes = new byte[0]; - when(mMockIkeMessageHelper.decode(0, dummyIkeMessage.ikeHeader, dummyIkePacketBytes)) - .thenReturn(new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)); - - return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); - } - - private ReceivedIkePacket makeDummyEncryptedReceivedIkePacket( - IkeSaRecord ikeSaRecord, - @IkeHeader.ExchangeType int eType, - boolean isResp, - List<Integer> payloadTypeList, - List<String> payloadHexStringList) - throws Exception { - List<IkePayload> payloadList = - hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - ikeSaRecord, eType, isResp, payloadList); - } - - private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( - IkeSaRecord ikeSaRecord, - @IkeHeader.ExchangeType int eType, - boolean isResp, - List<IkePayload> payloadList) - throws Exception { - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - ikeSaRecord, - eType, - isResp, - isResp - ? ikeSaRecord.getLocalRequestMessageId() - : ikeSaRecord.getRemoteRequestMessageId(), - payloadList, - new byte[0] /*dummyIkePacketBytes*/); - } - - private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( - IkeSaRecord ikeSaRecord, - @IkeHeader.ExchangeType int eType, - boolean isResp, - int msgId, - List<IkePayload> payloadList, - byte[] dummyIkePacketBytes) - throws Exception { - boolean fromIkeInit = !ikeSaRecord.isLocalInit; - IkeMessage dummyIkeMessage = - makeDummyIkeMessageForTest( - ikeSaRecord.getInitiatorSpi(), - ikeSaRecord.getResponderSpi(), - eType, - isResp, - fromIkeInit, - msgId, - true /*isEncyprted*/, - payloadList); - - setDecodeEncryptedPacketResult( - ikeSaRecord, - dummyIkeMessage.ikeHeader, - null /*collectedFrags*/, - new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)); - - return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); - } - - private ReceivedIkePacket makeDummyReceivedIkePacketWithInvalidSyntax( - IkeSaRecord ikeSaRecord, boolean isResp, int eType) { - return makeDummyReceivedIkePacketWithDecodingError( - ikeSaRecord, isResp, eType, new InvalidSyntaxException("IkeStateMachineTest")); - } - - private ReceivedIkePacket makeDummyReceivedIkePacketWithDecodingError( - IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception) { - IkeHeader header = - makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); - byte[] dummyPacket = new byte[0]; - when(mMockIkeMessageHelper.decode( - anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any())) - .thenReturn(new DecodeResultProtectedError(exception, dummyPacket)); - - return new ReceivedIkePacket(header, dummyPacket); - } - - private ReceivedIkePacket makeDummyReceivedIkePacketWithUnprotectedError( - IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception) { - IkeHeader header = - makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); - byte[] dummyPacket = new byte[0]; - when(mMockIkeMessageHelper.decode( - anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any())) - .thenReturn(new DecodeResultUnprotectedError(exception)); - - return new ReceivedIkePacket(header, dummyPacket); - } - - private ReceivedIkePacket makeDummyReceivedIkeFragmentPacket( - IkeSaRecord ikeSaRecord, - boolean isResp, - int eType, - IkeSkfPayload skfPayload, - int nextPayloadType, - DecodeResultPartial collectedFrags) { - IkeHeader header = - makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); - - byte[] dummyPacket = new byte[0]; - DecodeResultPartial resultFrags = - new DecodeResultPartial( - header, dummyPacket, skfPayload, nextPayloadType, collectedFrags); - setDecodeEncryptedPacketResult(ikeSaRecord, header, collectedFrags, resultFrags); - - return new ReceivedIkePacket(header, dummyPacket); - } - - private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketOk( - IkeSaRecord ikeSaRecord, - boolean isResp, - int eType, - DecodeResultPartial collectedFrags, - List<IkePayload> payloadList, - byte[] firstFragBytes) { - IkeHeader header = - makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); - - IkeMessage completeMessage = new IkeMessage(header, payloadList); - - setDecodeEncryptedPacketResult( - ikeSaRecord, - header, - collectedFrags, - new DecodeResultOk(completeMessage, firstFragBytes)); - - return new ReceivedIkePacket(header, new byte[0] /*dummyIkePacketBytes*/); - } - - private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketError( - IkeSaRecord ikeSaRecord, - boolean isResp, - int eType, - DecodeResultPartial collectedFrags, - IkeException exception) { - IkeHeader header = - makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); - - byte[] dummyIkePacketBytes = new byte[0]; - setDecodeEncryptedPacketResult( - ikeSaRecord, - header, - collectedFrags, - new DecodeResultProtectedError(exception, dummyIkePacketBytes)); - - return new ReceivedIkePacket(header, dummyIkePacketBytes); - } - - private IkeHeader makeDummyIkeHeader( - IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType) { - return new IkeHeader( - ikeSaRecord.getInitiatorSpi(), - ikeSaRecord.getResponderSpi(), - firstPayloadType, - eType, - isResp, - !ikeSaRecord.isLocalInit, - isResp - ? ikeSaRecord.getLocalRequestMessageId() - : ikeSaRecord.getRemoteRequestMessageId()); - } - - private void setDecodeEncryptedPacketResult( - IkeSaRecord ikeSaRecord, - IkeHeader header, - DecodeResultPartial collectedFrags, - DecodeResult result) { - when(mMockIkeMessageHelper.decode( - anyInt(), - any(), - any(), - eq(ikeSaRecord), - eq(header), - any(), - eq(collectedFrags))) - .thenReturn(result); - } - - private IkeMessage makeDummyIkeMessageForTest( - long initSpi, - long respSpi, - @IkeHeader.ExchangeType int eType, - boolean isResp, - boolean fromikeInit, - int messageId, - boolean isEncrypted, - List<IkePayload> payloadList) - throws Exception { - int firstPayloadType = - isEncrypted ? IkePayload.PAYLOAD_TYPE_SK : IkePayload.PAYLOAD_TYPE_NO_NEXT; - - IkeHeader header = - new IkeHeader( - initSpi, respSpi, firstPayloadType, eType, isResp, fromikeInit, messageId); - - return new IkeMessage(header, payloadList); - } - - private static List<IkePayload> hexStrListToIkePayloadList( - List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp) - throws Exception { - List<IkePayload> payloadList = new LinkedList<>(); - for (int i = 0; i < payloadTypeList.size(); i++) { - payloadList.add( - IkeTestUtils.hexStringToIkePayload( - payloadTypeList.get(i), isResp, payloadHexStringList.get(i))); - } - return payloadList; - } - - private void verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket) - throws Exception { - verify(mMockIkeMessageHelper) - .decode( - anyInt(), - any(), - any(), - eq(record), - eq(rcvPacket.ikeHeader), - eq(rcvPacket.ikePacketBytes), - eq(null)); - } - - private static IkeSaRecord makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit) - throws IOException { - Inet4Address initAddress = isLocalInit ? LOCAL_ADDRESS : REMOTE_ADDRESS; - Inet4Address respAddress = isLocalInit ? REMOTE_ADDRESS : LOCAL_ADDRESS; - - return new IkeSaRecord( - IkeSecurityParameterIndex.allocateSecurityParameterIndex(initAddress, initSpi), - IkeSecurityParameterIndex.allocateSecurityParameterIndex(respAddress, respSpi), - isLocalInit, - TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING), - TestUtils.hexStringToByteArray(NONCE_RESP_HEX_STRING), - new byte[KEY_LEN_IKE_SKD], - new byte[KEY_LEN_IKE_INTE], - new byte[KEY_LEN_IKE_INTE], - new byte[KEY_LEN_IKE_ENCR], - new byte[KEY_LEN_IKE_ENCR], - TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING), - TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING), - new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE)); - } - - @Before - public void setUp() throws Exception { - mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG); - IkeManager.setIkeLog(mSpyIkeLog); - - mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec(); - mIpSecManager = mMockIpSecTestUtils.getIpSecManager(); - mContext = mMockIpSecTestUtils.getContext(); - mUdpEncapSocket = mIpSecManager.openUdpEncapsulationSocket(); - mEapSessionConfig = - new EapSessionConfig.Builder() - .setEapSimConfig(EAP_SIM_SUB_ID, TelephonyManager.APPTYPE_USIM) - .build(); - - mMockEapAuthenticatorFactory = mock(IkeEapAuthenticatorFactory.class); - mMockEapAuthenticator = mock(EapAuthenticator.class); - when(mMockEapAuthenticatorFactory.newEapAuthenticator(any(), any(), any(), any())) - .thenReturn(mMockEapAuthenticator); - - mRootCertificate = CertUtils.createCertFromPemFile("self-signed-ca-a.pem"); - mServerEndCertificate = CertUtils.createCertFromPemFile("end-cert-a.pem"); - - mPsk = TestUtils.hexStringToByteArray(PSK_HEX_STRING); - - mChildSessionOptions = buildChildSessionOptions(); - - mIkeEncryptionTransform = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128); - mIkeIntegrityTransform = - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); - mIkePrfTransform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1); - mIkeDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP); - - mSpyUserCbExecutor = - spy( - (command) -> { - command.run(); - }); - - mMockIkeSessionCallback = mock(IkeSessionCallback.class); - mMockChildSessionCallback = mock(ChildSessionCallback.class); - - mLooper = new TestLooper(); - - mMockChildSessionStateMachine = mock(ChildSessionStateMachine.class); - mMockChildSessionFactoryHelper = mock(IChildSessionFactoryHelper.class); - ChildSessionStateMachineFactory.setChildSessionFactoryHelper( - mMockChildSessionFactoryHelper); - setupChildStateMachineFactory(mMockChildSessionStateMachine); - - // Inject longer retransmission timeout - mMockBackoffTimeoutCalculator = mock(IBackoffTimeoutCalculator.class); - when(mMockBackoffTimeoutCalculator.getExponentialBackoffTimeout(anyInt())) - .thenReturn(RETRANSMIT_BACKOFF_TIMEOUT_MS); - Retransmitter.setBackoffTimeoutCalculator(mMockBackoffTimeoutCalculator); - - // Setup state machine - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsPsk(mPsk)); - - mMockIkeMessageHelper = mock(IkeMessage.IIkeMessageHelper.class); - IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper); - resetMockIkeMessageHelper(); - - mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class); - SaRecord.setSaRecordHelper(mMockSaRecordHelper); - - mSpyCurrentIkeSaRecord = spy(makeDummyIkeSaRecord(11, 12, true)); - mSpyLocalInitIkeSaRecord = spy(makeDummyIkeSaRecord(21, 22, true)); - mSpyRemoteInitIkeSaRecord = spy(makeDummyIkeSaRecord(31, 32, false)); - - mExpectedCurrentSaLocalReqMsgId = 0; - mExpectedCurrentSaRemoteReqMsgId = 0; - } - - @After - public void tearDown() throws Exception { - mIkeSessionStateMachine.quit(); - mIkeSessionStateMachine.setDbg(false); - mUdpEncapSocket.close(); - - mSpyCurrentIkeSaRecord.close(); - mSpyLocalInitIkeSaRecord.close(); - mSpyRemoteInitIkeSaRecord.close(); - - IkeManager.resetIkeLog(); - Retransmitter.resetBackoffTimeoutCalculator(); - IkeMessage.setIkeMessageHelper(new IkeMessageHelper()); - SaRecord.setSaRecordHelper(new SaRecordHelper()); - ChildSessionStateMachineFactory.setChildSessionFactoryHelper( - new ChildSessionFactoryHelper()); - } - - private IkeSessionStateMachine makeAndStartIkeSession(IkeSessionOptions ikeOptions) - throws Exception { - IkeSessionStateMachine ikeSession = - new IkeSessionStateMachine( - mLooper.getLooper(), - mContext, - mIpSecManager, - ikeOptions, - mChildSessionOptions, - mSpyUserCbExecutor, - mMockIkeSessionCallback, - mMockChildSessionCallback, - mMockEapAuthenticatorFactory); - ikeSession.setDbg(true); - - mLooper.dispatchAll(); - ikeSession.mLocalAddress = LOCAL_ADDRESS; - - mSpyIkeSocket = spy(IkeSocket.getIkeSocket(mUdpEncapSocket, ikeSession)); - doNothing().when(mSpyIkeSocket).sendIkePacket(any(), any()); - ikeSession.mIkeSocket = mSpyIkeSocket; - - return ikeSession; - } - - public static IkeSaProposal buildSaProposal() throws Exception { - return new IkeSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) - .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) - .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1) - .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP) - .build(); - } - - private IkeSessionOptions.Builder buildIkeSessionOptionsCommon() throws Exception { - return new IkeSessionOptions.Builder() - .setServerAddress(REMOTE_ADDRESS) - .setUdpEncapsulationSocket(mUdpEncapSocket) - .addSaProposal(buildSaProposal()) - .setLocalIdentification(new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS)) - .setRemoteIdentification( - new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS)); - } - - private IkeSessionOptions buildIkeSessionOptionsPsk(byte[] psk) throws Exception { - return buildIkeSessionOptionsCommon().setAuthPsk(psk).build(); - } - - private IkeSessionOptions buildIkeSessionOptionsEap() throws Exception { - return buildIkeSessionOptionsCommon() - .setAuthEap(mRootCertificate, mEapSessionConfig) - .build(); - } - - private ChildSessionOptions buildChildSessionOptions() throws Exception { - ChildSaProposal saProposal = - new ChildSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) - .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) - .build(); - - return new TransportModeChildSessionOptions.Builder().addSaProposal(saProposal).build(); - } - - private ReceivedIkePacket makeIkeInitResponse() throws Exception { - // TODO: Build real IKE INIT response when IKE INIT response validation is implemented. - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); - - payloadHexStringList.add(IKE_SA_PAYLOAD_HEX_STRING); - payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING); - payloadHexStringList.add(FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING); - - // In each test assign different IKE responder SPI in IKE INIT response to avoid remote SPI - // collision during response validation. - // STOPSHIP: b/131617794 allow #mockIkeSetup to be independent in each test after we can - // support IkeSession cleanup. - return makeDummyReceivedIkeInitRespPacket( - 1L /*initiator SPI*/, - 2L /*responder SPI*/, - IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, - true /*isResp*/, - false /*fromIkeInit*/, - payloadTypeList, - payloadHexStringList); - } - - private List<IkePayload> getIkeAuthPayloadListWithChildPayloads( - List<IkePayload> authRelatedPayloads) throws Exception { - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); - - payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); - - List<IkePayload> payloadList = - hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, true /*isResp*/); - payloadList.addAll(authRelatedPayloads); - - return payloadList; - } - - private ReceivedIkePacket makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads) - throws Exception { - List<IkePayload> payloadList = getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); - - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - true /*isResp*/, - payloadList); - } - - private ReceivedIkePacket makeIkeAuthRespWithoutChildPayloads( - List<IkePayload> authRelatedPayloads) throws Exception { - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - true /*isResp*/, - authRelatedPayloads); - } - - private ReceivedIkePacket makeCreateChildCreateMessage(boolean isResp) throws Exception { - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - isResp, - makeCreateChildPayloadList(isResp)); - } - - private ReceivedIkePacket makeRekeyChildCreateMessage(boolean isResp, int spi) - throws Exception { - IkeNotifyPayload rekeyPayload = - new IkeNotifyPayload( - IkePayload.PROTOCOL_ID_ESP, - spi, - IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA, - new byte[0]); - - List<IkePayload> payloadList = makeCreateChildPayloadList(isResp); - payloadList.add(rekeyPayload); - - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - isResp, - payloadList); - } - - private List<IkePayload> makeCreateChildPayloadList(boolean isResp) throws Exception { - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); - - payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); - - return hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); - } - - private ReceivedIkePacket makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp) - throws Exception { - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, - isResp, - Arrays.asList(payloads)); - } - - private ReceivedIkePacket makeRekeyIkeResponse() throws Exception { - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); - - payloadHexStringList.add(IKE_REKEY_SA_PAYLOAD_HEX_STRING); - payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); - - return makeDummyEncryptedReceivedIkePacket( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - true /*isResp*/, - payloadTypeList, - payloadHexStringList); - } - - private ReceivedIkePacket makeDeleteIkeResponse(IkeSaRecord ikeSaRecord) throws Exception { - return makeDummyEncryptedReceivedIkePacket( - ikeSaRecord, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, - true /*isResp*/, - new LinkedList<>(), - new LinkedList<>()); - } - - private ReceivedIkePacket makeDpdIkeRequest(IkeSaRecord saRecord) throws Exception { - return makeDummyEncryptedReceivedIkePacket( - saRecord, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, - false /*isResp*/, - new LinkedList<>(), - new LinkedList<>()); - } - - private ReceivedIkePacket makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes) - throws Exception { - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - EXCHANGE_TYPE_INFORMATIONAL, - false /*isResp*/, - msgId, - new LinkedList<>(), - dummyIkePacketBytes); - } - - private ReceivedIkePacket makeRekeyIkeRequest() throws Exception { - IkeSaPayload saPayload = - (IkeSaPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_SA, - false /*isResp*/, - IKE_REKEY_SA_PAYLOAD_HEX_STRING); - return makeRekeyIkeRequest(saPayload); - } - - private ReceivedIkePacket makeRekeyIkeRequestWithUnacceptableProposal() throws Exception { - IkeSaPayload saPayload = - (IkeSaPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_SA, - false /*isResp*/, - IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING); - return makeRekeyIkeRequest(saPayload); - } - - private ReceivedIkePacket makeRekeyIkeRequest(IkeSaPayload saPayload) throws Exception { - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); - - payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); - payloadHexStringList.add(NONCE_INIT_PAYLOAD_HEX_STRING); - - List<IkePayload> payloadList = - hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/); - payloadList.add(saPayload); - - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - false /*isResp*/, - payloadList); - } - - private ReceivedIkePacket makeDeleteIkeRequest(IkeSaRecord saRecord) throws Exception { - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_DELETE); - - payloadHexStringList.add(DELETE_IKE_PAYLOAD_HEX_STRING); - - return makeDummyEncryptedReceivedIkePacket( - saRecord, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, - false /*isResp*/, - payloadTypeList, - payloadHexStringList); - } - - private ReceivedIkePacket makeResponseWithErrorNotify(IkeNotifyPayload notify) - throws Exception { - List<IkePayload> payloads = new LinkedList<>(); - payloads.add(notify); - return makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, EXCHANGE_TYPE_INFORMATIONAL, true /*isResp*/, payloads); - } - - private static boolean isIkePayloadExist( - List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType) { - for (IkePayload payload : payloadList) { - if (payload.payloadType == payloadType) return true; - } - return false; - } - - private static boolean isNotifyExist( - List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType) { - for (IkeNotifyPayload notify : - IkePayload.getPayloadListForTypeInProvidedList( - PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, payloadList)) { - if (notify.notifyType == notifyType) return true; - } - return false; - } - - private void verifyIncrementLocaReqMsgId() { - assertEquals( - ++mExpectedCurrentSaLocalReqMsgId, - mSpyCurrentIkeSaRecord.getLocalRequestMessageId()); - } - - private void verifyIncrementRemoteReqMsgId() { - assertEquals( - ++mExpectedCurrentSaRemoteReqMsgId, - mSpyCurrentIkeSaRecord.getRemoteRequestMessageId()); - } - - private void verifyRetransmissionStarted() { - assertTrue( - mIkeSessionStateMachine - .getHandler() - .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); - } - - private void verifyRetransmissionStopped() { - assertFalse( - mIkeSessionStateMachine - .getHandler() - .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); - } - - private IkeMessage verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord) { - verify(mMockIkeMessageHelper) - .encryptAndEncode( - anyObject(), - anyObject(), - eq(ikeSaRecord), - mIkeMessageCaptor.capture(), - anyBoolean(), - anyInt()); - return mIkeMessageCaptor.getValue(); - } - - private void verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord) { - verify(mMockIkeMessageHelper, never()) - .encryptAndEncode( - anyObject(), - anyObject(), - eq(ikeSaRecord), - any(IkeMessage.class), - anyBoolean(), - anyInt()); - } - - private void verifyEncryptAndEncodeNeverCalled() { - verify(mMockIkeMessageHelper, never()) - .encryptAndEncode( - anyObject(), - anyObject(), - any(IkeSaRecord.class), - any(IkeMessage.class), - anyBoolean(), - anyInt()); - } - - private void resetMockIkeMessageHelper() { - reset(mMockIkeMessageHelper); - when(mMockIkeMessageHelper.encode(any())).thenReturn(new byte[0]); - when(mMockIkeMessageHelper.encryptAndEncode( - any(), any(), any(), any(), anyBoolean(), anyInt())) - .thenReturn(new byte[1][0]); - } - - @Test - public void testQuit() { - mIkeSessionStateMachine.quit(); - mLooper.dispatchAll(); - - verify(mSpyIkeSocket).releaseReference(eq(mIkeSessionStateMachine)); - verify(mSpyIkeSocket).close(); - } - - @Test - public void testAllocateIkeSpi() throws Exception { - // Test randomness. - IkeSecurityParameterIndex ikeSpiOne = - IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS); - IkeSecurityParameterIndex ikeSpiTwo = - IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS); - - assertNotEquals(ikeSpiOne.getSpi(), ikeSpiTwo.getSpi()); - ikeSpiTwo.close(); - - // Test duplicate SPIs. - long spiValue = ikeSpiOne.getSpi(); - try { - IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS, spiValue); - fail("Expected to fail because duplicate SPI was assigned to the same address."); - } catch (IOException expected) { - - } - - ikeSpiOne.close(); - IkeSecurityParameterIndex ikeSpiThree = - IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS, spiValue); - ikeSpiThree.close(); - } - - private void setupFirstIkeSa() throws Exception { - // Inject IkeSaRecord and release IKE SPI resource since we will lose their references - // later. - when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any(), any())) - .thenAnswer( - (invocation) -> { - captureAndReleaseIkeSpiResource(invocation, 2); - return mSpyCurrentIkeSaRecord; - }); - } - - private void setupRekeyedIkeSa(IkeSaRecord rekeySaRecord) throws Exception { - // Inject IkeSaRecord and release IKE SPI resource since we will lose their references - // later. - when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( - eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) - .thenAnswer( - (invocation) -> { - captureAndReleaseIkeSpiResource(invocation, 4); - return rekeySaRecord; - }); - } - - private void throwExceptionWhenMakeRekeyIkeSa(Exception exception) throws Exception { - // Inject IkeSaRecord and release IKE SPI resource since we will lose their references - // later. - when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( - eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) - .thenAnswer( - (invocation) -> { - captureAndReleaseIkeSpiResource(invocation, 4); - throw exception; - }); - } - - private void captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex) { - IkeSaRecordConfig config = (IkeSaRecordConfig) invocation.getArguments()[ikeConfigIndex]; - config.initSpi.close(); - config.respSpi.close(); - } - - @Test - public void testCreateIkeLocalIkeInit() throws Exception { - setupFirstIkeSa(); - - // Send IKE INIT request - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Receive IKE INIT response - ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - - // Validate outbound IKE INIT request - verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture()); - IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue(); - - IkeHeader ikeHeader = ikeInitReqMessage.ikeHeader; - assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, ikeHeader.exchangeType); - assertFalse(ikeHeader.isResponseMsg); - assertTrue(ikeHeader.fromIkeInitiator); - - List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList; - assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_SA)); - assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_KE)); - assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_NONCE)); - assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP)); - assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP)); - assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED)); - - verify(mSpyIkeSocket) - .registerIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); - - verify(mMockIkeMessageHelper) - .decode(0, dummyReceivedIkePacket.ikeHeader, dummyReceivedIkePacket.ikePacketBytes); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Validate negotiated SA proposal. - IkeSaProposal negotiatedProposal = mIkeSessionStateMachine.mSaProposal; - assertNotNull(negotiatedProposal); - - assertEquals( - new EncryptionTransform[] {mIkeEncryptionTransform}, - negotiatedProposal.getEncryptionTransforms()); - assertEquals( - new IntegrityTransform[] {mIkeIntegrityTransform}, - negotiatedProposal.getIntegrityTransforms()); - assertEquals(new PrfTransform[] {mIkePrfTransform}, negotiatedProposal.getPrfTransforms()); - - // Validate current IkeSaRecord. - verify(mMockSaRecordHelper) - .makeFirstIkeSaRecord( - any(IkeMessage.class), - any(IkeMessage.class), - mIkeSaRecordConfigCaptor.capture()); - - IkeSaRecordConfig ikeSaRecordConfig = mIkeSaRecordConfigCaptor.getValue(); - assertEquals(KEY_LEN_IKE_PRF, ikeSaRecordConfig.prf.getKeyLength()); - assertEquals(KEY_LEN_IKE_INTE, ikeSaRecordConfig.integrityKeyLength); - assertEquals(KEY_LEN_IKE_ENCR, ikeSaRecordConfig.encryptionKeyLength); - assertEquals(CMD_LOCAL_REQUEST_REKEY_IKE, ikeSaRecordConfig.futureRekeyEvent.procedureType); - - // Validate NAT detection - assertTrue(mIkeSessionStateMachine.mIsLocalBehindNat); - assertFalse(mIkeSessionStateMachine.mIsRemoteBehindNat); - - // Validate fragmentation support negotiation - assertTrue(mIkeSessionStateMachine.mSupportFragment); - } - - private void setIkeInitResults() throws Exception { - mIkeSessionStateMachine.mIkeCipher = mock(IkeCipher.class); - mIkeSessionStateMachine.mIkeIntegrity = mock(IkeMacIntegrity.class); - mIkeSessionStateMachine.mIkePrf = mock(IkeMacPrf.class); - mIkeSessionStateMachine.mSaProposal = buildSaProposal(); - mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyCurrentIkeSaRecord; - mIkeSessionStateMachine.mLocalAddress = LOCAL_ADDRESS; - mIkeSessionStateMachine.mIsLocalBehindNat = true; - mIkeSessionStateMachine.mIsRemoteBehindNat = false; - mIkeSessionStateMachine.mSupportFragment = true; - mIkeSessionStateMachine.addIkeSaRecord(mSpyCurrentIkeSaRecord); - } - - /** Initializes the mIkeSessionStateMachine in the IDLE state. */ - private void setupIdleStateMachine() throws Exception { - setIkeInitResults(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - - mDummyChildSmCallback = - createChildAndGetChildSessionSmCallback( - mMockChildSessionStateMachine, CHILD_SPI_REMOTE, mMockChildSessionCallback); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - private void mockIkeInitAndTransitionToIkeAuth(State authState) throws Exception { - setIkeInitResults(); - - // Need to create a real IkeMacPrf instance for authentication because we cannot inject a - // method stub for IkeMacPrf#signBytes. IkeMacPrf#signBytes is inheritted from a package - // protected class IkePrf. We don't have the visibility to mock it. - mIkeSessionStateMachine.mIkePrf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - - mIkeSessionStateMachine.mIkeInitRequestBytes = new byte[0]; - mIkeSessionStateMachine.mIkeInitResponseBytes = new byte[0]; - mIkeSessionStateMachine.mIkeInitNoncePayload = new IkeNoncePayload(); - mIkeSessionStateMachine.mIkeRespNoncePayload = new IkeNoncePayload(); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_FORCE_TRANSITION, authState); - mLooper.dispatchAll(); - } - - private void setupChildStateMachineFactory(ChildSessionStateMachine child) { - // After state machine start, add to the callback->statemachine map - when(mMockChildSessionFactoryHelper.makeChildSessionStateMachine( - eq(mLooper.getLooper()), - eq(mContext), - eq(mChildSessionOptions), - eq(mSpyUserCbExecutor), - any(ChildSessionCallback.class), - any(IChildSessionSmCallback.class))) - .thenReturn(child); - } - - /** - * Utility to register a new callback -> state machine mapping. - * - * <p>Must be used if IkeSessionStateMachine.openChildSession() is not called, but commands - * injected instead. - * - * @param callback The callback to be used for the mapping - * @param sm The ChildSessionStateMachine instance to be used. - */ - private void registerChildStateMachine( - ChildSessionCallback callback, ChildSessionStateMachine sm) { - setupChildStateMachineFactory(sm); - mIkeSessionStateMachine.registerChildSessionCallback( - mChildSessionOptions, callback, false /*isFirstChild*/); - } - - @Test - public void testCreateAdditionalChild() throws Exception { - setupIdleStateMachine(); - - ChildSessionCallback childCallback = mock(ChildSessionCallback.class); - ChildSessionStateMachine childStateMachine = mock(ChildSessionStateMachine.class); - registerChildStateMachine(childCallback, childStateMachine); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_CHILD, - childCallback, - mChildSessionOptions)); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(childStateMachine) - .createChildSession( - eq(LOCAL_ADDRESS), - eq(REMOTE_ADDRESS), - any(), // udpEncapSocket - eq(mIkeSessionStateMachine.mIkePrf), - any()); // sk_d - - // Once for initial child, a second time for the additional child. - verify(mMockChildSessionFactoryHelper) - .makeChildSessionStateMachine( - eq(mLooper.getLooper()), - eq(mContext), - eq(mChildSessionOptions), - eq(mSpyUserCbExecutor), - eq(childCallback), - mChildSessionSmCbCaptor.capture()); - IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue(); - - // Mocking sending request - cb.onOutboundPayloadsReady( - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - false /*isResp*/, - new LinkedList<>(), - childStateMachine); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - IkeMessage createChildRequest = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = createChildRequest.ikeHeader; - assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); - assertFalse(ikeHeader.isResponseMsg); - assertTrue(ikeHeader.fromIkeInitiator); - assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); - assertTrue(createChildRequest.ikePayloadList.isEmpty()); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - - // Mocking receiving response - ReceivedIkePacket dummyCreateChildResp = makeCreateChildCreateMessage(true /*isResp*/); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyCreateChildResp); - mLooper.dispatchAll(); - - verifyIncrementLocaReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyCreateChildResp); - - verify(childStateMachine) - .receiveResponse( - eq(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA), mPayloadListCaptor.capture()); - - List<IkePayload> childRespList = mPayloadListCaptor.getValue(); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); - - // Mock finishing procedure - cb.onProcedureFinished(childStateMachine); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - verifyRetransmissionStopped(); - } - - @Test - public void testTriggerDeleteChildLocal() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, - mMockChildSessionCallback, - null /*childOptions*/)); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(mMockChildSessionStateMachine).deleteChildSession(); - } - - @Test - public void testHandleDeleteChildBeforeCreation() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, - mock(ChildSessionCallback.class), - null /*childOptions*/)); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testTriggerRekeyChildLocal() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, - mMockChildSessionCallback, - null /*childOptions*/)); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(mMockChildSessionStateMachine).rekeyChildSession(); - } - - @Test - public void testScheduleAndTriggerRekeyChildLocal() throws Exception { - setupIdleStateMachine(); - long dummyRekeyTimeout = 10000L; - - ChildLocalRequest rekeyRequest = - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, - mMockChildSessionCallback, - null /*childOptions*/); - mDummyChildSmCallback.scheduleLocalRequest(rekeyRequest, dummyRekeyTimeout); - - mLooper.moveTimeForward(dummyRekeyTimeout); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(mMockChildSessionStateMachine).rekeyChildSession(); - } - - private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( - ChildSessionStateMachine child, int remoteSpi) throws Exception { - return createChildAndGetChildSessionSmCallback( - child, remoteSpi, mock(ChildSessionCallback.class)); - } - - private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( - ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback) - throws Exception { - registerChildStateMachine(childCallback, child); - - IChildSessionSmCallback cb = mIkeSessionStateMachine.new ChildSessionSmCallback(); - cb.onChildSaCreated(remoteSpi, child); - mLooper.dispatchAll(); - - return cb; - } - - private void transitionToChildProcedureOngoing() { - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mChildProcedureOngoing); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - } - - private void verifyChildReceiveDeleteRequest( - ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads) { - verify(child) - .receiveRequest( - eq(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD), - eq(EXCHANGE_TYPE_INFORMATIONAL), - mPayloadListCaptor.capture()); - List<IkePayload> reqPayloads = mPayloadListCaptor.getValue(); - - int numExpectedDelPayloads = expectedDelPayloads.length; - assertEquals(numExpectedDelPayloads, reqPayloads.size()); - - for (int i = 0; i < numExpectedDelPayloads; i++) { - assertEquals(expectedDelPayloads[i], (IkeDeletePayload) reqPayloads.get(i)); - } - } - - private void outboundDeleteChildPayloadsReady( - IChildSessionSmCallback childSmCb, - IkeDeletePayload delPayload, - boolean isResp, - ChildSessionStateMachine child) { - List<IkePayload> outPayloadList = new LinkedList<>(); - outPayloadList.add(delPayload); - childSmCb.onOutboundPayloadsReady( - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, isResp, outPayloadList, child); - mLooper.dispatchAll(); - } - - private List<IkePayload> verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp) { - IkeMessage deleteChildMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = deleteChildMessage.ikeHeader; - assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); - assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - assertEquals(isResp, ikeHeader.isResponseMsg); - - return deleteChildMessage.ikePayloadList; - } - - @Test - public void testDeferChildRequestToChildProcedureOngoing() throws Exception { - setupIdleStateMachine(); - - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); - } - - @Test - public void testRemoteDeleteOneChild() throws Exception { - setupIdleStateMachine(); - transitionToChildProcedureOngoing(); - - // Receive Delete Child Request - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - // Verify received payloads - verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); - - // Outbound payload list ready - IkeDeletePayload outDelPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); - outboundDeleteChildPayloadsReady( - mDummyChildSmCallback, - outDelPayload, - true /*isResp*/, - mMockChildSessionStateMachine); - - // Verify outbound response - List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloadList.size()); - assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); - } - - @Test - public void testRemoteDeleteMultipleChildSession() throws Exception { - ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); - int childOneRemoteSpi = 11; - int childOneLocalSpi = 12; - - ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); - int childTwoRemoteSpi = 21; - int childTwoLocalSpi = 22; - - setupIdleStateMachine(); - IChildSessionSmCallback childSmCbOne = - createChildAndGetChildSessionSmCallback(childOne, childOneRemoteSpi); - IChildSessionSmCallback childSmCbTwo = - createChildAndGetChildSessionSmCallback(childTwo, childTwoRemoteSpi); - - transitionToChildProcedureOngoing(); - - // Receive Delete Child Request - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] { - new IkeDeletePayload(new int[] {childOneRemoteSpi, childTwoRemoteSpi}) - }; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - // Verify received payloads - verifyChildReceiveDeleteRequest(childOne, inboundDelPayloads); - verifyChildReceiveDeleteRequest(childTwo, inboundDelPayloads); - - // childOne outbound payload list ready - IkeDeletePayload outDelPayloadOne = new IkeDeletePayload(new int[] {childOneLocalSpi}); - outboundDeleteChildPayloadsReady(childSmCbOne, outDelPayloadOne, true /*isResp*/, childOne); - mLooper.dispatchAll(); - - // Verify that no response is sent - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // childTwo outbound payload list ready - IkeDeletePayload outDelPayloadTwo = new IkeDeletePayload(new int[] {childTwoLocalSpi}); - outboundDeleteChildPayloadsReady(childSmCbTwo, outDelPayloadTwo, true /*isResp*/, childTwo); - mLooper.dispatchAll(); - - // Verify outbound response - List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(2, payloadList.size()); - assertEquals(outDelPayloadOne, ((IkeDeletePayload) payloadList.get(0))); - assertEquals(outDelPayloadTwo, ((IkeDeletePayload) payloadList.get(1))); - } - - @Test - public void testRemoteDeleteMultipleChildSaInSameSession() throws Exception { - int newChildRemoteSpi = 21; - int newChildLocalSpi = 22; - - setupIdleStateMachine(); - mDummyChildSmCallback.onChildSaCreated(newChildRemoteSpi, mMockChildSessionStateMachine); - - transitionToChildProcedureOngoing(); - - // Receive Delete Child Request - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] { - new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE}), - new IkeDeletePayload(new int[] {newChildRemoteSpi}) - }; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - // Verify received payloads - verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); - - // child outbound payload list ready - IkeDeletePayload outDelPayload = - new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL, newChildLocalSpi}); - outboundDeleteChildPayloadsReady( - mDummyChildSmCallback, - outDelPayload, - true /*isResp*/, - mMockChildSessionStateMachine); - mLooper.dispatchAll(); - - // Verify outbound response - List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloadList.size()); - assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); - } - - @Test - public void testIgnoreUnrecognizedChildSpi() throws Exception { - int unrecognizedSpi = 2; - - setupIdleStateMachine(); - transitionToChildProcedureOngoing(); - - // Receive Delete Child Request - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] { - new IkeDeletePayload(new int[] {unrecognizedSpi, CHILD_SPI_REMOTE}) - }; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - // Verify received payloads - verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); - - // child outbound payload list ready - IkeDeletePayload outPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); - outboundDeleteChildPayloadsReady( - mDummyChildSmCallback, outPayload, true /*isResp*/, mMockChildSessionStateMachine); - mLooper.dispatchAll(); - - // Verify outbound response - List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloadList.size()); - assertEquals(outPayload, ((IkeDeletePayload) payloadList.get(0))); - } - - @Test - public void testRemoteDeleteChildHandlesReqWithNoRecognizedSpi() throws Exception { - int unrecognizedSpi = 2; - - setupIdleStateMachine(); - - // Receive Delete Child Request without any recognized SPI - IkeDeletePayload[] inboundDelPayloads = - new IkeDeletePayload[] {new IkeDeletePayload(new int[] {unrecognizedSpi})}; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); - mLooper.dispatchAll(); - - // Verify outbound empty response was sent - List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertTrue(payloadList.isEmpty()); - - // Verify IKE Session was back to Idle - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testRemoteCreateChild() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - CMD_RECEIVE_IKE_PACKET, makeCreateChildCreateMessage(false /*isResp*/)); - - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, ikePayloadList.size()); - assertEquals( - ERROR_TYPE_NO_ADDITIONAL_SAS, - ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); - } - - @Test - public void testTriggerRemoteRekeyChild() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - CMD_RECEIVE_IKE_PACKET, - makeRekeyChildCreateMessage(false /*isResp*/, CHILD_SPI_REMOTE)); - mLooper.dispatchAll(); - - verify(mMockChildSessionStateMachine) - .receiveRequest( - eq(IKE_EXCHANGE_SUBTYPE_REKEY_CHILD), - eq(EXCHANGE_TYPE_CREATE_CHILD_SA), - any(List.class)); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - } - - @Test - public void testHandleRekeyChildReqWithUnrecognizedSpi() throws Exception { - int unrecognizedSpi = 2; - - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - CMD_RECEIVE_IKE_PACKET, - makeRekeyChildCreateMessage(false /*isResp*/, unrecognizedSpi)); - mLooper.dispatchAll(); - - verify(mMockChildSessionStateMachine, never()).receiveRequest(anyInt(), anyInt(), any()); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, ikePayloadList.size()); - IkeNotifyPayload notifyPayload = (IkeNotifyPayload) ikePayloadList.get(0); - assertEquals(ERROR_TYPE_CHILD_SA_NOT_FOUND, notifyPayload.notifyType); - assertEquals(unrecognizedSpi, notifyPayload.spi); - } - - private void verifyNotifyUserCloseSession() { - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockIkeSessionCallback).onClosed(); - } - - @Test - public void testRcvRemoteDeleteIkeWhenChildProcedureOngoing() throws Exception { - setupIdleStateMachine(); - transitionToChildProcedureOngoing(); - - mIkeSessionStateMachine.sendMessage( - CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); - - mLooper.dispatchAll(); - - verifyNotifyUserCloseSession(); - - // Verify state machine quit properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - - List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertTrue(ikePayloadList.isEmpty()); - } - - @Test - public void testRcvRemoteRekeyIkeWhenChildProcedureOngoing() throws Exception { - setupIdleStateMachine(); - transitionToChildProcedureOngoing(); - - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest()); - - mLooper.dispatchAll(); - - // Since we have forced state machine to transition to ChildProcedureOngoing state without - // really starting any Child procedure, it should transition to Idle at this time. - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, ikePayloadList.size()); - assertEquals( - ERROR_TYPE_TEMPORARY_FAILURE, - ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); - } - - @Test - public void testKillChildSessions() throws Exception { - setupIdleStateMachine(); - - ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); - ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); - registerChildStateMachine(mock(ChildSessionCallback.class), childOne); - registerChildStateMachine(mock(ChildSessionCallback.class), childTwo); - - mIkeSessionStateMachine.mCurrentIkeSaRecord = null; - - mIkeSessionStateMachine.quitNow(); - - mLooper.dispatchAll(); - - verify(childOne).killSession(); - verify(childTwo).killSession(); - } - - private IkeMessage verifyAuthReqAndGetMsg() { - IkeMessage ikeAuthReqMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = ikeAuthReqMessage.ikeHeader; - assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); - assertFalse(ikeHeader.isResponseMsg); - assertTrue(ikeHeader.fromIkeInitiator); - - return ikeAuthReqMessage; - } - - private IkeMessage verifyAuthReqWithChildPayloadsAndGetMsg() { - IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg(); - - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_ID_INITIATOR, IkeIdPayload.class)); - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_ID_RESPONDER, IkeIdPayload.class)); - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class)); - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class)); - - return ikeAuthReqMessage; - } - - private void verifySharedKeyAuthentication( - IkeAuthPskPayload spyAuthPayload, - IkeIdPayload respIdPayload, - List<IkePayload> authRelatedPayloads, - boolean hasChildPayloads) - throws Exception { - // Send IKE AUTH response to IKE state machine - ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp); - mLooper.dispatchAll(); - - // Validate outbound IKE AUTH request - IkeMessage ikeAuthReqMessage; - if (hasChildPayloads) { - ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); - } else { - ikeAuthReqMessage = verifyAuthReqAndGetMsg(); - } - assertNotNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPskPayload.class)); - - // Validate inbound IKE AUTH response - verifyIncrementLocaReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, authResp); - - // Validate authentication is done. Cannot use matchers because IkeAuthPskPayload is final. - verify(spyAuthPayload) - .verifyInboundSignature( - mPsk, - mIkeSessionStateMachine.mIkeInitRequestBytes, - mSpyCurrentIkeSaRecord.nonceInitiator, - respIdPayload.getEncodedPayloadBody(), - mIkeSessionStateMachine.mIkePrf, - mSpyCurrentIkeSaRecord.getSkPr()); - - // Validate that user has been notified - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockIkeSessionCallback).onOpened(any()); - // TODO: Verify sessionConfiguration - - // Verify payload list pair for first Child negotiation - ArgumentCaptor<List<IkePayload>> mReqPayloadListCaptor = - ArgumentCaptor.forClass(List.class); - ArgumentCaptor<List<IkePayload>> mRespPayloadListCaptor = - ArgumentCaptor.forClass(List.class); - verify(mMockChildSessionStateMachine) - .handleFirstChildExchange( - mReqPayloadListCaptor.capture(), - mRespPayloadListCaptor.capture(), - eq(LOCAL_ADDRESS), - eq(REMOTE_ADDRESS), - any(), // udpEncapSocket - eq(mIkeSessionStateMachine.mIkePrf), - any()); // sk_d - List<IkePayload> childReqList = mReqPayloadListCaptor.getValue(); - List<IkePayload> childRespList = mRespPayloadListCaptor.getValue(); - - assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_SA)); - assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); - assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); - assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_NONCE)); - IkeSaPayload reqSaPayload = - IkePayload.getPayloadForTypeInProvidedList( - IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childReqList); - assertFalse(reqSaPayload.isSaResponse); - - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); - assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); - IkeSaPayload respSaPayload = - IkePayload.getPayloadForTypeInProvidedList( - IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childRespList); - assertTrue(respSaPayload.isSaResponse); - - // Mock finishing first Child SA negotiation. - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - - verify(mMockChildSessionFactoryHelper) - .makeChildSessionStateMachine( - eq(mLooper.getLooper()), - eq(mContext), - eq(mChildSessionOptions), - eq(mSpyUserCbExecutor), - eq(mMockChildSessionCallback), - mChildSessionSmCbCaptor.capture()); - IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue(); - - cb.onProcedureFinished(mMockChildSessionStateMachine); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - private IkeAuthPskPayload makeSpyRespPskPayload() throws Exception { - IkeAuthPskPayload spyAuthPayload = - spy( - (IkeAuthPskPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_AUTH, - true /*isResp*/, - PSK_AUTH_RESP_PAYLOAD_HEX_STRING)); - - doNothing() - .when(spyAuthPayload) - .verifyInboundSignature(any(), any(), any(), any(), any(), any()); - return spyAuthPayload; - } - - private IkeAuthDigitalSignPayload makeSpyDigitalSignAuthPayload() throws Exception { - IkeAuthDigitalSignPayload spyAuthPayload = - spy( - (IkeAuthDigitalSignPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_AUTH, - true /*isResp*/, - GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING)); - doNothing() - .when(spyAuthPayload) - .verifyInboundSignature(any(), any(), any(), any(), any(), any()); - return spyAuthPayload; - } - - private IkeIdPayload makeRespIdPayload() throws Exception { - return (IkeIdPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_ID_RESPONDER, - true /*isResp*/, - ID_PAYLOAD_RESPONDER_HEX_STRING); - } - - @Test - public void testCreateIkeLocalIkeAuthPsk() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. - List<IkePayload> authRelatedPayloads = new LinkedList<>(); - IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); - authRelatedPayloads.add(spyAuthPayload); - - IkeIdPayload respIdPayload = makeRespIdPayload(); - authRelatedPayloads.add(respIdPayload); - - verifySharedKeyAuthentication(spyAuthPayload, respIdPayload, authRelatedPayloads, true); - verifyRetransmissionStopped(); - } - - @Test - public void testCreateIkeLocalIkeAuthPskVerifyFail() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Build IKE AUTH response with invalid Auth-PSK Payload and ID-Responder Payload. - List<IkePayload> authRelatedPayloads = new LinkedList<>(); - IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); - doThrow(new AuthenticationFailedException("DummyAuthFailException")) - .when(spyAuthPayload) - .verifyInboundSignature(any(), any(), any(), any(), any(), any()); - authRelatedPayloads.add(spyAuthPayload); - - IkeIdPayload respIdPayload = makeRespIdPayload(); - authRelatedPayloads.add(respIdPayload); - - // Send response to IKE state machine - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); - mLooper.dispatchAll(); - - // Verify Delete request was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); - assertEquals(1, payloads.size()); - assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); - - // Verify IKE Session was closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback) - .onClosedExceptionally(any(AuthenticationFailedException.class)); - } - - @Test - public void testAuthPskHandleRespWithParsingError() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Mock receiving packet with syntax error - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, true /*isResp*/, IkeHeader.EXCHANGE_TYPE_IKE_AUTH); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify Delete request was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); - assertEquals(1, payloads.size()); - assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - } - - @Test - public void testCreateIkeLocalIkeAuthPreEap() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Mock IKE INIT - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Build IKE AUTH response with EAP. Auth, ID-Resp and Cert payloads. - List<IkePayload> authRelatedPayloads = new LinkedList<>(); - - authRelatedPayloads.add(new IkeEapPayload(EAP_DUMMY_MSG)); - authRelatedPayloads.add(makeSpyDigitalSignAuthPayload()); - authRelatedPayloads.add(makeRespIdPayload()); - - IkeCertX509CertPayload certPayload = new IkeCertX509CertPayload(mServerEndCertificate); - authRelatedPayloads.add(certPayload); - - // Send IKE AUTH response to IKE state machine - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeIkeAuthRespWithoutChildPayloads(authRelatedPayloads)); - mLooper.dispatchAll(); - - // Validate outbound IKE AUTH request - IkeMessage ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); - assertNull( - ikeAuthReqMessage.getPayloadForType( - IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPayload.class)); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap); - verifyRetransmissionStopped(); - assertNotNull(mIkeSessionStateMachine.mInitIdPayload); - assertNotNull(mIkeSessionStateMachine.mRespIdPayload); - } - - private IEapCallback verifyEapAuthenticatorCreatedAndGetCallback() { - ArgumentCaptor<IEapCallback> captor = ArgumentCaptor.forClass(IEapCallback.class); - - verify(mMockEapAuthenticatorFactory) - .newEapAuthenticator( - eq(mIkeSessionStateMachine.getHandler().getLooper()), - captor.capture(), - eq(mContext), - eq(mEapSessionConfig)); - - return captor.getValue(); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage() - throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EAP_START_EAP_AUTH, new IkeEapPayload(EAP_DUMMY_MSG)); - mLooper.dispatchAll(); - - verifyEapAuthenticatorCreatedAndGetCallback(); - - verify(mMockEapAuthenticator).processEapMessage(eq(EAP_DUMMY_MSG)); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); - callback.onResponse(EAP_DUMMY_MSG); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Verify EAP response - IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - IkeHeader ikeHeader = resp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); - assertFalse(ikeHeader.isResponseMsg); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - - assertEquals(1, resp.ikePayloadList.size()); - assertArrayEquals(EAP_DUMMY_MSG, ((IkeEapPayload) resp.ikePayloadList.get(0)).eapMessage); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - // Mock sending IKE_AUTH{EAP} request - IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); - callback.onResponse(EAP_DUMMY_MSG); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Send IKE AUTH response with no EAP Payload to IKE state machine - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeIkeAuthRespWithoutChildPayloads(new LinkedList<>())); - mLooper.dispatchAll(); - - // Verify state machine quit properly - verify(mMockIkeSessionCallback) - .onClosedExceptionally(any(AuthenticationFailedException.class)); - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapHandlesSuccess() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); - - // Setup dummy initIdPayload for next state. - mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class); - when(mIkeSessionStateMachine.mInitIdPayload.getEncodedPayloadBody()) - .thenReturn(new byte[0]); - - callback.onSuccess(mPsk, new byte[0]); // use mPsk as MSK, eMSK does not matter - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthPostEap); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapHandlesError() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); - - Throwable error = new IllegalArgumentException(); - callback.onError(error); - mLooper.dispatchAll(); - - // Fires user error callbacks - verify(mMockIkeSessionCallback) - .onClosedExceptionally(argThat(err -> err.getCause() == error)); - - // Verify state machine quit properly - verify(mSpyCurrentIkeSaRecord).close(); - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testCreateIkeLocalIkeAuthInEapHandlesFailure() throws Exception { - mIkeSessionStateMachine.quitNow(); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); - mLooper.dispatchAll(); - - IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); - callback.onFail(); - mLooper.dispatchAll(); - - // Fires user error callbacks - verify(mMockIkeSessionCallback) - .onClosedExceptionally(any(AuthenticationFailedException.class)); - - // Verify state machine quit properly - verify(mSpyCurrentIkeSaRecord).close(); - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testCreateIkeLocalIkeAuthPostEap() throws Exception { - mIkeSessionStateMachine.quitNow(); - reset(mMockChildSessionFactoryHelper); - setupChildStateMachineFactory(mMockChildSessionStateMachine); - mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap()); - - // Setup dummy state from IkeAuthPreEap for next state. - mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class); - when(mIkeSessionStateMachine.mInitIdPayload.getEncodedPayloadBody()) - .thenReturn(new byte[0]); - mIkeSessionStateMachine.mRespIdPayload = - (IkeIdPayload) - IkeTestUtils.hexStringToIkePayload( - IkePayload.PAYLOAD_TYPE_ID_RESPONDER, - true /*isResp*/, - ID_PAYLOAD_RESPONDER_HEX_STRING); - - List<Integer> payloadTypeList = new LinkedList<>(); - List<String> payloadHexStringList = new LinkedList<>(); - - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); - payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); - - payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); - payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); - - mIkeSessionStateMachine.mFirstChildReqList = - hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/); - - // Setup state and go to IN_EAP state - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_EAP_FINISH_EAP_AUTH, mPsk); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. - List<IkePayload> authRelatedPayloads = new LinkedList<>(); - IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); - authRelatedPayloads.add(spyAuthPayload); - - IkeIdPayload respIdPayload = makeRespIdPayload(); - - verifySharedKeyAuthentication(spyAuthPayload, respIdPayload, authRelatedPayloads, false); - verifyRetransmissionStopped(); - } - - @Test - public void testCreateIkeLocalIkeAuthHandlesFirstFrag() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Received IKE fragment - byte[] unencryptedData = "testCreateIkeLocalIkeAuthHandlesFrag".getBytes(); - int fragNum = 1; - int totalFragments = 2; - IkeSkfPayload skfPayload = - IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); - - ReceivedIkePacket packet = - makeDummyReceivedIkeFragmentPacket( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - skfPayload, - PAYLOAD_TYPE_AUTH, - null /* collectedFrags*/); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); - mLooper.dispatchAll(); - - // Verify state doesn't change - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); - - // Verify the IkeSaRecord has stored the fragment. - DecodeResultPartial resultPartial = - mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/); - assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType); - assertEquals(totalFragments, resultPartial.collectedFragsList.length); - assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - - assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(false /*isResp*/)); - } - - @Test - public void testCreateIkeLocalIkeAuthHandlesLastFragOk() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Set previously collected IKE fragments - DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); - mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); - - // Build reassembled IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. - List<IkePayload> authRelatedPayloads = new LinkedList<>(); - IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); - authRelatedPayloads.add(spyAuthPayload); - - IkeIdPayload respIdPayload = makeRespIdPayload(); - authRelatedPayloads.add(respIdPayload); - - List<IkePayload> authPayloadList = - getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); - - // Receive last auth response and do IKE_AUTH - ReceivedIkePacket packet = - makeDummyReceivedLastIkeFragmentPacketOk( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - mockCollectedFrags, - authPayloadList, - "FirstFrag".getBytes()); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); - mLooper.dispatchAll(); - - // Verify IKE AUTH is done - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - - // Verify collected response fragments are cleared. - assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); - verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); - } - - @Test - public void testCreateIkeLocalIkeAuthHandlesLastFragError() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Set previously collected IKE fragments - DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); - mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); - - // Receive last auth response with syntax error - ReceivedIkePacket packet = - makeDummyReceivedLastIkeFragmentPacketError( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - mockCollectedFrags, - new InvalidSyntaxException("IkeStateMachineTest")); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); - mLooper.dispatchAll(); - - // Verify Delete request is sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); - assertEquals(1, payloads.size()); - assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - - // Collected response fragments are cleared - assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); - verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); - } - - @Test - public void testRekeyIkeLocalCreateSendsRequest() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - verifyRetransmissionStarted(); - - // Verify outbound message - IkeMessage rekeyMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = rekeyMsg.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); - assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); - assertFalse(ikeHeader.isResponseMsg); - assertTrue(ikeHeader.fromIkeInitiator); - - // Verify SA payload & proposals - IkeSaPayload saPayload = - rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class); - assertFalse(saPayload.isSaResponse); - assertEquals(1, saPayload.proposalList.size()); - - IkeSaPayload.IkeProposal proposal = - (IkeSaPayload.IkeProposal) saPayload.proposalList.get(0); - assertEquals(1, proposal.number); // Must be 1-indexed - assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); - assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize); - assertEquals(mIkeSessionStateMachine.mSaProposal, proposal.saProposal); - - // Verify Nonce and KE payloads exist. - assertNotNull( - rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); - - IkeKePayload kePayload = - rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class); - assertNotNull(kePayload); - assertTrue(kePayload.isOutbound); - } - - @Test - public void testRekeyIkeLocalCreateHandlesResponse() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Prepare "rekeyed" SA - setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); - - // Receive Rekey response - ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); - - // Verify in delete state, and new SA record was saved: - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); - verifyRetransmissionStarted(); - assertEquals(mSpyLocalInitIkeSaRecord, mIkeSessionStateMachine.mLocalInitNewIkeSaRecord); - verify(mSpyIkeSocket) - .registerIke( - eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); - } - - @Test - public void testRekeyIkeLocalCreateHandleRespWithParsingError() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Mock receiving packet with syntax error - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify Delete request was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); - assertEquals(1, payloads.size()); - assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - } - - @Test - public void testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - - // Mock receiving packet with NO_PROPOSAL_CHOSEN - ReceivedIkePacket resp = - makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN)); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); - mLooper.dispatchAll(); - - // Verify IKE Session goes back to Idle - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - // Move time forward to trigger retry - mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - } - - @Test - public void testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - resetMockIkeMessageHelper(); - - // Mock receiving packet with NO_PROPOSAL_CHOSEN - ReceivedIkePacket resp = - makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX)); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); - mLooper.dispatchAll(); - - // Verify no message was sent because a fatal error notification was received - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - } - - @Test - public void testRekeyIkeLocalCreateSaCreationFail() throws Exception { - // Throw error when building new IKE SA - throwExceptionWhenMakeRekeyIkeSa( - new GeneralSecurityException("testRekeyIkeLocalCreateSaCreationFail")); - - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - resetMockIkeMessageHelper(); - - // Receive Rekey response - ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); - mLooper.dispatchAll(); - - // Verify Delete request was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); - assertEquals(1, payloads.size()); - assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); - } - - @Test - public void testRekeyIkeLocalCreateHandleReqWithNonFatalError() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Build protocol exception - List<Integer> unsupportedPayloads = new LinkedList<>(); - unsupportedPayloads.add(PAYLOAD_TYPE_UNSUPPORTED); - UnsupportedCriticalPayloadException exception = - new UnsupportedCriticalPayloadException(unsupportedPayloads); - - // Mock receiving packet with unsupported critical payload - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithDecodingError( - mSpyCurrentIkeSaRecord, - false /*isResp*/, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - exception); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify error notification was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloads.size()); - - IkePayload payload = payloads.get(0); - assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); - assertEquals( - ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, ((IkeNotifyPayload) payload).notifyType); - - // Verify IKE Session stays in the same state - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - } - - private void mockCreateAndTransitionToRekeyDeleteLocal() { - // Seed fake rekey data and force transition to RekeyIkeLocalDelete - mIkeSessionStateMachine.mLocalInitNewIkeSaRecord = mSpyLocalInitIkeSaRecord; - mIkeSessionStateMachine.addIkeSaRecord(mSpyLocalInitIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeLocalDelete); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - } - - @Test - public void testRekeyIkeLocalDeleteSendsRequest() throws Exception { - setupIdleStateMachine(); - mockCreateAndTransitionToRekeyDeleteLocal(); - - // Verify Rekey-Delete request - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); - verifyRetransmissionStarted(); - - // Verify outbound message - IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = delMsg.ikeHeader; - assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); - assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - assertFalse(ikeHeader.isResponseMsg); - - List<IkeDeletePayload> deletePayloadList = - delMsg.getPayloadListForType( - IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); - assertEquals(1, deletePayloadList.size()); - - IkeDeletePayload deletePayload = deletePayloadList.get(0); - assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); - assertEquals(0, deletePayload.numSpi); - assertEquals(0, deletePayload.spiSize); - assertArrayEquals(new int[0], deletePayload.spisToDelete); - } - - private void verifyRekeyReplaceSa(IkeSaRecord newSaRecord) { - verify(mSpyCurrentIkeSaRecord).close(); - verify(mSpyIkeSocket).unregisterIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi())); - verify(mSpyIkeSocket, never()).unregisterIke(eq(newSaRecord.getLocalSpi())); - - assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, newSaRecord); - - verify(mMockChildSessionStateMachine).setSkD(newSaRecord.getSkD()); - } - - @Test - public void testRekeyIkeLocalDeleteHandlesResponse() throws Exception { - setupIdleStateMachine(); - mockCreateAndTransitionToRekeyDeleteLocal(); - - // Receive Delete response - ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = - makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); - verify(mMockIkeSessionCallback, never()).onClosed(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - verifyRetransmissionStopped(); - } - - @Test - public void testRekeyIkeLocalDeleteHandlesRespWithParsingError() throws Exception { - setupIdleStateMachine(); - mockCreateAndTransitionToRekeyDeleteLocal(); - resetMockIkeMessageHelper(); - - // Mock receiving packet with syntax error - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify no more request out - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - verifyRetransmissionStopped(); - } - - @Test - public void testRekeyIkeLocalDeleteWithRequestOnNewSa() throws Exception { - setupIdleStateMachine(); - mockCreateAndTransitionToRekeyDeleteLocal(); - - // Receive an empty (DPD) request on the new IKE SA - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDpdIkeRequest(mSpyLocalInitIkeSaRecord)); - mLooper.dispatchAll(); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - verifyRetransmissionStopped(); - } - - @Test - public void testRekeyIkeLocalDeleteWithRequestFragOnNewSa() throws Exception { - setupIdleStateMachine(); - mockCreateAndTransitionToRekeyDeleteLocal(); - - // Received IKE fragment - byte[] unencryptedData = "testRekeyIkeLocalDeleteWithRequestFragOnNewSa".getBytes(); - int fragNum = 1; - int totalFragments = 2; - IkeSkfPayload skfPayload = - IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); - - ReceivedIkePacket packet = - makeDummyReceivedIkeFragmentPacket( - mSpyLocalInitIkeSaRecord, - false /*isResp*/, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - skfPayload, - PAYLOAD_TYPE_SA, - null /* collectedFrags*/); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); - mLooper.dispatchAll(); - - // Verify rekey is done. - verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); - verifyRetransmissionStopped(); - - // Verify the IkeSaRecord has stored the new fragment. - DecodeResultPartial resultPartial = - mSpyLocalInitIkeSaRecord.getCollectedFragments(false /*isResp*/); - assertEquals(PAYLOAD_TYPE_SA, resultPartial.firstPayloadType); - assertEquals(totalFragments, resultPartial.collectedFragsList.length); - assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - } - - @Test - public void testRekeyIkeRemoteDeleteWithRequestOnNewSa() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyIkeRemoteDelete - mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; - mIkeSessionStateMachine.addIkeSaRecord(mSpyRemoteInitIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - // Receive an empty (DPD) request on the new IKE SA - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDpdIkeRequest(mSpyRemoteInitIkeSaRecord)); - mLooper.dispatchAll(); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testRekeyIkeRemoteCreate() throws Exception { - setupIdleStateMachine(); - - setupRekeyedIkeSa(mSpyRemoteInitIkeSaRecord); - - // Receive Rekey request - ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementRemoteReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); - - // Verify SA created with correct parameters - ArgumentCaptor<SaRecord.IkeSaRecordConfig> recordConfigCaptor = - ArgumentCaptor.forClass(SaRecord.IkeSaRecordConfig.class); - verify(mMockSaRecordHelper) - .makeRekeyedIkeSaRecord(any(), any(), any(), any(), recordConfigCaptor.capture()); - assertEquals(IKE_REKEY_SA_INITIATOR_SPI, recordConfigCaptor.getValue().initSpi.getSpi()); - - // Verify outbound CREATE_CHILD_SA message - IkeMessage rekeyCreateResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - IkeHeader rekeyCreateRespHeader = rekeyCreateResp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyCreateRespHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyCreateRespHeader.exchangeType); - assertTrue(rekeyCreateRespHeader.isResponseMsg); - assertTrue(rekeyCreateRespHeader.fromIkeInitiator); - assertNotNull( - rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); - assertNotNull( - rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class)); - assertNotNull( - rekeyCreateResp.getPayloadForType( - IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); - - // Verify SA, StateMachine state - assertEquals(mSpyCurrentIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordAwaitingRemoteDel); - assertEquals(mSpyRemoteInitIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordSurviving); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); - verify(mSpyIkeSocket) - .registerIke( - eq(mSpyRemoteInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); - } - - @Test - public void testRekeyIkeRemoteCreateHandlesInvalidReq() throws Exception { - setupIdleStateMachine(); - - // Receive Rekey request - ReceivedIkePacket request = makeRekeyIkeRequestWithUnacceptableProposal(); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); - mLooper.dispatchAll(); - - verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); - } - - @Test - public void testRekeyIkeRemoteCreateSaCreationFailure() throws Exception { - // Throw error when building new IKE SA - throwExceptionWhenMakeRekeyIkeSa( - new GeneralSecurityException("testRekeyIkeRemoteCreateSaCreationFailure")); - setupIdleStateMachine(); - - // Receive Rekey request - ReceivedIkePacket request = makeRekeyIkeRequest(); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); - mLooper.dispatchAll(); - - verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); - } - - private void verifyProcessRekeyReqFailure(int expectedErrorCode) { - // Verify IKE Session is back to Idle - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - // Verify error notification was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloads.size()); - IkeNotifyPayload notify = (IkeNotifyPayload) payloads.get(0); - assertEquals(expectedErrorCode, notify.notifyType); - } - - @Test - public void testRekeyIkeRemoteDelete() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyIkeLocalDelete - mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - // Rekey Delete request - ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket = - makeDeleteIkeRequest(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementRemoteReqMsgId(); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); - - // Verify outbound DELETE_IKE_SA message - IkeMessage rekeyDeleteResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - IkeHeader rekeyDeleteRespHeader = rekeyDeleteResp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyDeleteRespHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, rekeyDeleteRespHeader.exchangeType); - assertTrue(rekeyDeleteRespHeader.isResponseMsg); - assertTrue(rekeyDeleteRespHeader.fromIkeInitiator); - assertTrue(rekeyDeleteResp.ikePayloadList.isEmpty()); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); - - verify(mMockIkeSessionCallback, never()).onClosed(); - - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testRekeyIkeRemoteDeleteExitAndRenter() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyIkeLocalDelete - mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - // Trigger a timeout, and immediately re-enter remote-delete - mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - // Shift time forward, and assert the previous timeout was NOT fired. - mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); - mLooper.dispatchAll(); - - // Verify no request received, or response sent. - verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject()); - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // Verify final state has not changed - signal was not sent. - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); - } - - @Test - public void testRekeyIkeRemoteDeleteTimedOut() throws Exception { - setupIdleStateMachine(); - - // Seed fake rekey data and force transition to RekeyIkeLocalDelete - mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS); - mLooper.dispatchAll(); - - // Verify no request received, or response sent. - verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject()); - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // Verify final state - Idle, with new SA, and old SA closed. - verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testSimulRekey() throws Exception { - setupIdleStateMachine(); - - // Prepare "rekeyed" SA - setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); - when(mSpyLocalInitIkeSaRecord.compareTo(mSpyRemoteInitIkeSaRecord)).thenReturn(1); - - // Send Rekey request on mSpyCurrentIkeSaRecord - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - - // Receive Rekey request on mSpyCurrentIkeSaRecord - ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementRemoteReqMsgId(); - - // Receive Rekey response on mSpyCurrentIkeSaRecord - ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - verify(mSpyIkeSocket) - .registerIke( - eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); - - // Receive Delete response on mSpyCurrentIkeSaRecord - ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = - makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - - // Verify - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); - verify(mMockIkeSessionCallback, never()).onClosed(); - } - - @Test - public void testOpenIkeSession() throws Exception { - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.Initial); - - mIkeSessionStateMachine.openSession(); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit); - } - - @Test - public void testIkeInitSchedulesRekey() throws Exception { - setupFirstIkeSa(); - - // Send IKE INIT request - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); - - // Receive IKE INIT response - ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); - - // Mock IKE AUTH and transition to Idle - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - mIkeSessionStateMachine.mSaProposal = buildSaProposal(); - - // Move time forward to trigger rekey - mLooper.moveTimeForward(SA_SOFT_LIFETIME_MS); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - } - - @Test - public void testRekeyCreateIkeSchedulesRekey() throws Exception { - setupIdleStateMachine(); - - // Send Rekey-Create request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - - // Prepare "rekeyed" SA - setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); - - // Receive Rekey response - ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); - mLooper.dispatchAll(); - - // Mock rekey delete and transition to Idle - mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyLocalInitIkeSaRecord; - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - - // Move time forward to trigger rekey - mLooper.moveTimeForward(SA_SOFT_LIFETIME_MS); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - } - - @Test - public void testBuildEncryptedInformationalMessage() throws Exception { - IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX, new byte[0]); - - boolean isResp = false; - IkeMessage generated = - mIkeSessionStateMachine.buildEncryptedInformationalMessage( - mSpyCurrentIkeSaRecord, new IkeInformationalPayload[] {payload}, isResp, 0); - - assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), generated.ikeHeader.ikeInitiatorSpi); - assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), generated.ikeHeader.ikeResponderSpi); - assertEquals( - mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), generated.ikeHeader.messageId); - assertEquals(isResp, generated.ikeHeader.isResponseMsg); - assertEquals(IkePayload.PAYLOAD_TYPE_SK, generated.ikeHeader.nextPayloadType); - - List<IkeNotifyPayload> generatedPayloads = - generated.getPayloadListForType( - IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); - assertEquals(1, generatedPayloads.size()); - - IkeNotifyPayload generatedPayload = generatedPayloads.get(0); - assertArrayEquals(new byte[0], generatedPayload.notifyData); - assertEquals(ERROR_TYPE_INVALID_SYNTAX, generatedPayload.notifyType); - } - - private void verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord) { - if (expectedPackets == null) { - assertNull(saRecord.getLastSentRespAllPackets()); - return; - } - - assertEquals(expectedPackets.length, saRecord.getLastSentRespAllPackets().size()); - for (int i = 0; i < expectedPackets.length; i++) { - assertArrayEquals(expectedPackets[i], saRecord.getLastSentRespAllPackets().get(i)); - } - } - - @Test - public void testEncryptedRetransmitterImmediatelySendsRequest() throws Exception { - setupIdleStateMachine(); - byte[][] dummyLastRespBytes = - new byte[][] {"testRetransmitterSendsRequestLastResp".getBytes()}; - mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyLastRespBytes)); - - IkeMessage spyIkeReqMessage = - spy( - new IkeMessage( - new IkeHeader( - mSpyCurrentIkeSaRecord.getInitiatorSpi(), - mSpyCurrentIkeSaRecord.getResponderSpi(), - IkePayload.PAYLOAD_TYPE_SK, - EXCHANGE_TYPE_INFORMATIONAL, - false /*isResp*/, - mSpyCurrentIkeSaRecord.isLocalInit, - mSpyCurrentIkeSaRecord.getLocalRequestMessageId()), - new LinkedList<>())); - - // Use something unique as a sentinel value - byte[][] dummyReqBytesList = - new byte[][] { - "testRetransmitterSendsReqFrag1".getBytes(), - "testRetransmitterSendsReqFrag2".getBytes() - }; - - doReturn(dummyReqBytesList) - .when(spyIkeReqMessage) - .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); - - IkeSessionStateMachine.EncryptedRetransmitter retransmitter = - mIkeSessionStateMachine.new EncryptedRetransmitter(spyIkeReqMessage); - - // Verify message is sent out, and that request does not change cached retransmit-response - // mLastSentIkeResp. - verify(mSpyIkeSocket).sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS)); - verify(mSpyIkeSocket).sendIkePacket(eq(dummyReqBytesList[1]), eq(REMOTE_ADDRESS)); - verifyLastSentRespAllPackets(dummyLastRespBytes, mSpyCurrentIkeSaRecord); - } - - // TODO: b/141275871 Test retransmisstions are fired for correct times within certain time. - - @Test - public void testCacheLastRequestAndResponse() throws Exception { - setupIdleStateMachine(); - mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(null /*reqPacket*/); - mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(null /*respPacketList*/); - - byte[] dummyIkeReqFirstPacket = "testLastSentRequest".getBytes(); - byte[][] dummyIkeResp = - new byte[][] { - "testLastSentRespFrag1".getBytes(), "testLastSentRespFrag2".getBytes() - }; - - when(mMockIkeMessageHelper.encryptAndEncode( - any(), - any(), - eq(mSpyCurrentIkeSaRecord), - any(IkeMessage.class), - anyBoolean(), - anyInt())) - .thenReturn(dummyIkeResp); - - // Receive a DPD request, expect to send dummyIkeResp - ReceivedIkePacket dummyDpdRequest = - makeDpdIkeRequest( - mSpyCurrentIkeSaRecord.getRemoteRequestMessageId(), dummyIkeReqFirstPacket); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); - mLooper.dispatchAll(); - - verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); - verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[1]), eq(REMOTE_ADDRESS)); - - verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); - assertTrue(mSpyCurrentIkeSaRecord.isRetransmittedRequest(dummyIkeReqFirstPacket)); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testReplyRetransmittedRequest() throws Exception { - setupIdleStateMachine(); - - // Mock last sent request and response - byte[] dummyIkeReqFirstPacket = "testRcvRetransmittedRequestReq".getBytes(); - byte[][] dummyIkeResp = new byte[][] {"testRcvRetransmittedRequestResp".getBytes()}; - - mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); - mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp)); - mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId(); - - // Build request with last validated message ID - ReceivedIkePacket request = - makeDpdIkeRequest( - mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, - dummyIkeReqFirstPacket); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); - - mLooper.dispatchAll(); - - verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); - verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testDiscardFakeRetransmittedRequest() throws Exception { - setupIdleStateMachine(); - - // Mock last sent request and response - byte[] dummyIkeReqFirstPacket = "testDiscardFakeRetransmittedRequestReq".getBytes(); - byte[][] dummyIkeResp = new byte[][] {"testDiscardFakeRetransmittedRequestResp".getBytes()}; - mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); - mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp)); - mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId(); - - // Build request with last validated message ID but different bytes - ReceivedIkePacket request = - makeDpdIkeRequest( - mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, new byte[0]); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); - - mLooper.dispatchAll(); - - verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); - verify(mSpyIkeSocket, never()).sendIkePacket(any(), any()); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } - - @Test - public void testDiscardRetransmittedResponse() throws Exception { - mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); - verifyRetransmissionStarted(); - - // Build and send fake response with last validated message ID to IKE state machine - ReceivedIkePacket resp = - makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, - true /*isResp*/, - mSpyCurrentIkeSaRecord.getLocalRequestMessageId() - 1, - new LinkedList<>(), - new byte[0]); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); - mLooper.dispatchAll(); - - // Verify current state does not change - verifyRetransmissionStarted(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); - } - - @Test - public void testDeleteIkeLocalDeleteRequest() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Verify outbound message - IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = delMsg.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertFalse(ikeHeader.isResponseMsg); - assertTrue(ikeHeader.fromIkeInitiator); - - List<IkeDeletePayload> deletePayloadList = - delMsg.getPayloadListForType( - IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); - assertEquals(1, deletePayloadList.size()); - - IkeDeletePayload deletePayload = deletePayloadList.get(0); - assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); - assertEquals(0, deletePayload.numSpi); - assertEquals(0, deletePayload.spiSize); - assertArrayEquals(new int[0], deletePayload.spisToDelete); - } - - @Test - public void testDeleteIkeLocalDeleteResponse() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - ReceivedIkePacket received = makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); - mLooper.dispatchAll(); - verifyIncrementLocaReqMsgId(); - - verifyNotifyUserCloseSession(); - - // Verify state machine quit properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testDeleteIkeLocalDeleteResponseWithParsingError() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - resetMockIkeMessageHelper(); - - // Mock receiving response with syntax error - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify no more request out - verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); - - // Verify state machine quit properly - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testDeleteIkeLocalDeleteHandlesInvalidResp() throws Exception { - setupIdleStateMachine(); - - // Send delete request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); - mLooper.dispatchAll(); - - // Receive response with wrong exchange type - ReceivedIkePacket resp = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, - true /*isResp*/, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); - mLooper.dispatchAll(); - - // Verify state machine quit properly - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testDeleteIkeLocalDeleteReceivedNonDeleteRequest() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Verify delete sent out. - verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - resetMockIkeMessageHelper(); // Discard value. - - ReceivedIkePacket received = makeRekeyIkeRequest(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); - - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - verifyIncrementRemoteReqMsgId(); - - // Verify outbound response - IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = resp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertTrue(ikeHeader.isResponseMsg); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - - List<IkeNotifyPayload> notificationPayloadList = - resp.getPayloadListForType(IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); - assertEquals(1, notificationPayloadList.size()); - - IkeNotifyPayload notifyPayload = notificationPayloadList.get(0); - assertEquals(IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType); - } - - @Test - public void testDeleteIkeRemoteDelete() throws Exception { - setupIdleStateMachine(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, - makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); - - mLooper.dispatchAll(); - verifyIncrementRemoteReqMsgId(); - - // Verify outbound message - IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - - IkeHeader ikeHeader = delMsg.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertTrue(ikeHeader.isResponseMsg); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - - assertTrue(delMsg.ikePayloadList.isEmpty()); - - verifyNotifyUserCloseSession(); - - // Verify state machine quit properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - @Test - public void testReceiveDpd() throws Exception { - setupIdleStateMachine(); - - // Receive a DPD request, expect to stay in IDLE state - ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); - - // Verify outbound response - IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - IkeHeader ikeHeader = resp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertTrue(ikeHeader.isResponseMsg); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - assertTrue(resp.ikePayloadList.isEmpty()); - } - - @Test - public void testReceiveDpdNonIdle() throws Exception { - setupIdleStateMachine(); - - // Move to a non-idle state. Use RekeyIkeRemoteDelete, as it doesn't send out any requests. - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mRekeyIkeRemoteDelete); - mLooper.dispatchAll(); - - // In a rekey state, receiving (and handling) a DPD should not result in a change of states - ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); - - verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); - - // Verify outbound response - IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - IkeHeader ikeHeader = resp.ikeHeader; - assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); - assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); - assertTrue(ikeHeader.isResponseMsg); - assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); - assertTrue(resp.ikePayloadList.isEmpty()); - } - - @Test - public void testIdleTriggersNewRequests() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - - // Verify that the command is executed, and the state machine transitions to the right state - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - verifyRetransmissionStarted(); - } - - @Test - public void testNonIdleStateDoesNotTriggerNewRequests() throws Exception { - setupIdleStateMachine(); - - // Force ourselves into a non-idle state - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving); - mLooper.dispatchAll(); - verifyEncryptAndEncodeNeverCalled(); - - // Queue a local request, and expect that it is not run (yet) - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, - new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); - mLooper.dispatchAll(); - - // Verify that the state machine is still in the Receiving state - verifyEncryptAndEncodeNeverCalled(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.Receiving); - - // Go back to Idle, and expect to immediately transition to RekeyIkeLocalCreate from the - // queued request - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); - } - - @Test - public void testOpenChildSessionValidatesArgs() throws Exception { - setupIdleStateMachine(); - - // Expect failure - no callbacks provided - try { - mIkeSessionStateMachine.openChildSession(mChildSessionOptions, null); - } catch (IllegalArgumentException expected) { - } - - // Expect failure - callbacks already registered - try { - mIkeSessionStateMachine.openChildSession( - mChildSessionOptions, mMockChildSessionCallback); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testOpenChildSession() throws Exception { - setupIdleStateMachine(); - - ChildSessionCallback cb = mock(ChildSessionCallback.class); - mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb); - - // Test that inserting the same cb returns an error, even before the state - // machine has a chance to process it. - try { - mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb); - } catch (IllegalArgumentException expected) { - } - - verify(mMockChildSessionFactoryHelper) - .makeChildSessionStateMachine( - eq(mLooper.getLooper()), - eq(mContext), - eq(mChildSessionOptions), - eq(mSpyUserCbExecutor), - eq(cb), - any()); - - // Verify state in IkeSessionStateMachine - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - - synchronized (mIkeSessionStateMachine.mChildCbToSessions) { - assertTrue(mIkeSessionStateMachine.mChildCbToSessions.containsKey(cb)); - } - } - - @Test - public void testCloseChildSessionValidatesArgs() throws Exception { - setupIdleStateMachine(); - - // Expect failure - callbacks not registered - try { - mIkeSessionStateMachine.closeChildSession(mock(ChildSessionCallback.class)); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testCloseChildSession() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - } - - @Test - public void testCloseImmediatelyAfterOpenChildSession() throws Exception { - setupIdleStateMachine(); - - ChildSessionCallback cb = mock(ChildSessionCallback.class); - mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb); - - // Verify that closing the session immediately still picks up the child callback - // even before the looper has a chance to run. - mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); - } - - @Test - public void testOnChildSessionClosed() throws Exception { - setupIdleStateMachine(); - - mDummyChildSmCallback.onChildSessionClosed(mMockChildSessionCallback); - - synchronized (mIkeSessionStateMachine.mChildCbToSessions) { - assertFalse( - mIkeSessionStateMachine.mChildCbToSessions.containsKey( - mMockChildSessionCallback)); - } - } - - @Test - public void testHandleUnexpectedExceptionInEnterState() throws Exception { - Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); - IkeManager.setIkeLog(spyIkeLog); - - IkeSessionOptions mockSessionOptions = mock(IkeSessionOptions.class); - when(mockSessionOptions.getSaProposals()).thenThrow(mock(RuntimeException.class)); - - IkeSessionStateMachine ikeSession = - new IkeSessionStateMachine( - mLooper.getLooper(), - mContext, - mIpSecManager, - mockSessionOptions, - mChildSessionOptions, - mSpyUserCbExecutor, - mMockIkeSessionCallback, - mMockChildSessionCallback, - mMockEapAuthenticatorFactory); - // Send IKE INIT request - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); - mLooper.dispatchAll(); - - assertNull(ikeSession.getCurrentState()); - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); - verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); - } - - @Test - public void testHandleUnexpectedExceptionInProcessStateMsg() throws Exception { - Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); - IkeManager.setIkeLog(spyIkeLog); - - setupIdleStateMachine(); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, null /*receivedIkePacket*/); - mLooper.dispatchAll(); - - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mSpyUserCbExecutor).execute(any(Runnable.class)); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); - verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); - } - - @Test - public void testCreateIkeLocalIkeInitRcvErrorNotify() throws Exception { - // Send IKE INIT request - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); - mLooper.dispatchAll(); - verifyRetransmissionStarted(); - - // Receive IKE INIT response with erro notification. - List<IkePayload> payloads = new LinkedList<>(); - payloads.add(new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN)); - ReceivedIkePacket resp = - makeDummyUnencryptedReceivedIkePacket( - 1L /*initiator SPI*/, - 2L /*respodner SPI*/, - IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, - true /*isResp*/, - false /*fromIkeInit*/, - payloads); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); - mLooper.dispatchAll(); - - // Fires user error callbacks - verify(mMockIkeSessionCallback) - .onClosedExceptionally( - argThat(err -> err instanceof NoValidProposalChosenException)); - // Verify state machine quit properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - } - - private void mockSendRekeyChildReq() throws Exception { - setupIdleStateMachine(); - - ChildLocalRequest childLocalRequest = - new ChildLocalRequest( - IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, - mMockChildSessionCallback, - null /*childOptions*/); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, childLocalRequest); - mLooper.dispatchAll(); - - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(mMockChildSessionStateMachine).rekeyChildSession(); - - // Mocking sending request - mDummyChildSmCallback.onOutboundPayloadsReady( - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, - false /*isResp*/, - new LinkedList<>(), - mMockChildSessionStateMachine); - mLooper.dispatchAll(); - } - - private void mockRcvTempFail() throws Exception { - ReceivedIkePacket resp = - makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_TEMPORARY_FAILURE)); - - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - } - - @Test - public void testTempFailureHandlerScheduleRetry() throws Exception { - mockSendRekeyChildReq(); - - // Mock sending TEMPORARY_FAILURE response - mockRcvTempFail(); - - // Move time forward to trigger retry - mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); - mLooper.dispatchAll(); - - // Verify that rekey is triggered again - assertTrue( - mIkeSessionStateMachine.getCurrentState() - instanceof IkeSessionStateMachine.ChildProcedureOngoing); - verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession(); - } - - @Test - public void testTempFailureHandlerTimeout() throws Exception { - long currentTime = 0; - int retryCnt = 0; - - mockSendRekeyChildReq(); - - while (currentTime + RETRY_INTERVAL_MS < TEMP_FAILURE_RETRY_TIMEOUT_MS) { - mockRcvTempFail(); - - mLooper.moveTimeForward(RETRY_INTERVAL_MS); - currentTime += RETRY_INTERVAL_MS; - mLooper.dispatchAll(); - - retryCnt++; - verify(mMockChildSessionStateMachine, times(1 + retryCnt)).rekeyChildSession(); - } - - mLooper.moveTimeForward(RETRY_INTERVAL_MS); - mLooper.dispatchAll(); - - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); - } - - @Test - public void testTempFailureHandlerCancelTimer() throws Exception { - mockSendRekeyChildReq(); - - // Mock sending TEMPORARY_FAILURE response - mockRcvTempFail(); - - // Move time forward to trigger retry - mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); - mLooper.dispatchAll(); - verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession(); - - // Mock sending a valid response - ReceivedIkePacket resp = - makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - EXCHANGE_TYPE_CREATE_CHILD_SA, - true /*isResp*/, - new LinkedList<>()); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); - mLooper.dispatchAll(); - - // Move time forward - mLooper.moveTimeForward(IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS); - mLooper.dispatchAll(); - - // Validate IKE Session is not closed - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - // Validate no more retry - verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession(); - } - - @Test - public void testIdleReceiveRequestWithFatalError() throws Exception { - setupIdleStateMachine(); - - // Mock receiving packet with syntax error - ReceivedIkePacket mockInvalidPacket = - makeDummyReceivedIkePacketWithInvalidSyntax( - mSpyCurrentIkeSaRecord, - false /*isResp*/, - IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); - mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); - mLooper.dispatchAll(); - - // Verify Delete request was sent - List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, payloads.size()); - - IkePayload payload = payloads.get(0); - assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); - assertEquals(ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) payload).notifyType); - - // Verify IKE Session is closed properly - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - } - - @Test - public void testHandlesInvalidRequest() throws Exception { - setupIdleStateMachine(); - - mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, - mIkeSessionStateMachine.mChildProcedureOngoing); - - // Receive an IKE AUTH request - ReceivedIkePacket request = - makeDummyEncryptedReceivedIkePacketWithPayloadList( - mSpyCurrentIkeSaRecord, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - false /*isResp*/, - new LinkedList<IkePayload>()); - mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); - mLooper.dispatchAll(); - - // Verify error notification was sent - List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); - assertEquals(1, ikePayloadList.size()); - assertEquals( - ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); - - // Verify IKE Session has quit - assertNull(mIkeSessionStateMachine.getCurrentState()); - verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); - } - - @Test - public void testIdleHandlesUnprotectedPacket() throws Exception { - setupIdleStateMachine(); - - ReceivedIkePacket req = - makeDummyReceivedIkePacketWithUnprotectedError( - mSpyCurrentIkeSaRecord, - false /*isResp*/, - EXCHANGE_TYPE_INFORMATIONAL, - mock(IkeException.class)); - - mLooper.dispatchAll(); - assertTrue( - mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java deleted file mode 100644 index 1b8761f7..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * 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.internal.net.ipsec.ike; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.any; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; - -import android.content.Context; -import android.net.IpSecManager; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.os.HandlerThread; -import android.os.Looper; -import android.system.ErrnoException; -import android.system.Os; -import android.system.OsConstants; -import android.util.Log; -import android.util.LongSparseArray; - -import androidx.test.InstrumentationRegistry; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.IkeSocket.PacketReceiver; -import com.android.internal.net.ipsec.ike.message.IkeHeader; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.mockito.ArgumentCaptor; - -import java.io.FileDescriptor; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -public final class IkeSocketTest { - private static final int REMOTE_RECV_BUFF_SIZE = 2048; - private static final int TIMEOUT = 1000; - - private static final String NON_ESP_MARKER_HEX_STRING = "00000000"; - private static final String IKE_REQ_MESSAGE_HEX_STRING = - "5f54bf6d8b48e6e100000000000000002120220800000000" - + "00000150220000300000002c010100040300000c0100000c" - + "800e00800300000803000002030000080400000200000008" - + "020000022800008800020000b4a2faf4bb54878ae21d6385" - + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656" - + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37" - + "534036040610ebdd92f46bef84f0be7db860351843858f8a" - + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb" - + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024" - + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7" - + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb" - + "881eab2051d8663f421d10b02b00001c00004005d915368c" - + "a036004cb578ae3e3fb268509aeab1900000002069936922" - + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500"; - - private static final String LOCAL_SPI = "0000000000000000"; - private static final String REMOTE_SPI = "5f54bf6d8b48e6e1"; - - private static final String DATA_ONE = "one 1"; - private static final String DATA_TWO = "two 2"; - - private static final String IPV4_LOOPBACK = "127.0.0.1"; - - private byte[] mDataOne; - private byte[] mDataTwo; - - private long mLocalSpi; - private long mRemoteSpi; - - private LongSparseArray mSpiToIkeStateMachineMap; - private PacketReceiver mPacketReceiver; - - private UdpEncapsulationSocket mClientUdpEncapSocket; - private InetAddress mLocalAddress; - private FileDescriptor mDummyRemoteServerFd; - - private IkeSessionStateMachine mMockIkeSessionStateMachine; - - @Before - public void setUp() throws Exception { - Context context = InstrumentationRegistry.getContext(); - IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE); - mClientUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket(); - - mLocalAddress = InetAddress.getByName(IPV4_LOOPBACK); - mDummyRemoteServerFd = getBoundUdpSocket(mLocalAddress); - - mDataOne = DATA_ONE.getBytes("UTF-8"); - mDataTwo = DATA_TWO.getBytes("UTF-8"); - - ByteBuffer localSpiBuffer = ByteBuffer.wrap(TestUtils.hexStringToByteArray(LOCAL_SPI)); - mLocalSpi = localSpiBuffer.getLong(); - ByteBuffer remoteSpiBuffer = ByteBuffer.wrap(TestUtils.hexStringToByteArray(REMOTE_SPI)); - mRemoteSpi = remoteSpiBuffer.getLong(); - - mMockIkeSessionStateMachine = mock(IkeSessionStateMachine.class); - - mSpiToIkeStateMachineMap = new LongSparseArray<IkeSessionStateMachine>(); - mSpiToIkeStateMachineMap.put(mLocalSpi, mMockIkeSessionStateMachine); - - mPacketReceiver = new IkeSocket.PacketReceiver(); - } - - @After - public void tearDown() throws Exception { - mClientUdpEncapSocket.close(); - IkeSocket.setPacketReceiver(mPacketReceiver); - Os.close(mDummyRemoteServerFd); - } - - private static FileDescriptor getBoundUdpSocket(InetAddress address) throws Exception { - FileDescriptor sock = - Os.socket(OsConstants.AF_INET, OsConstants.SOCK_DGRAM, OsConstants.IPPROTO_UDP); - Os.bind(sock, address, IkeSocket.IKE_SERVER_PORT); - return sock; - } - - @Test - public void testGetAndCloseIkeSocket() throws Exception { - // Must be prepared here; AndroidJUnitRunner runs tests on different threads from the - // setUp() call. Since the new Handler() call is run in getIkeSocket, the Looper must be - // prepared here. - if (Looper.myLooper() == null) Looper.prepare(); - - IkeSessionStateMachine mMockIkeSessionOne = mock(IkeSessionStateMachine.class); - IkeSessionStateMachine mMockIkeSessionTwo = mock(IkeSessionStateMachine.class); - - IkeSocket ikeSocketOne = IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionOne); - assertEquals(1, ikeSocketOne.mAliveIkeSessions.size()); - - IkeSocket ikeSocketTwo = IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionTwo); - assertEquals(ikeSocketOne, ikeSocketTwo); - assertEquals(2, ikeSocketTwo.mAliveIkeSessions.size()); - - ikeSocketOne.releaseReference(mMockIkeSessionOne); - assertEquals(1, ikeSocketOne.mAliveIkeSessions.size()); - - ikeSocketTwo.releaseReference(mMockIkeSessionTwo); - assertEquals(0, ikeSocketTwo.mAliveIkeSessions.size()); - } - - @Test - public void testSendIkePacket() throws Exception { - if (Looper.myLooper() == null) Looper.prepare(); - - // Send IKE packet - IkeSocket ikeSocket = - IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionStateMachine); - ikeSocket.sendIkePacket(mDataOne, mLocalAddress); - - byte[] receivedData = receive(mDummyRemoteServerFd); - - // Verify received data - ByteBuffer expectedBuffer = - ByteBuffer.allocate(IkeSocket.NON_ESP_MARKER_LEN + mDataOne.length); - expectedBuffer.put(IkeSocket.NON_ESP_MARKER).put(mDataOne); - - assertArrayEquals(expectedBuffer.array(), receivedData); - - ikeSocket.releaseReference(mMockIkeSessionStateMachine); - } - - @Test - public void testReceiveIkePacket() throws Exception { - // Create working thread. - HandlerThread mIkeThread = new HandlerThread("IkeSocketTest"); - mIkeThread.start(); - - // Create IkeSocket on working thread. - IkeSocketReceiver socketReceiver = new IkeSocketReceiver(); - TestCountDownLatch createLatch = new TestCountDownLatch(); - mIkeThread - .getThreadHandler() - .post( - () -> { - try { - socketReceiver.setIkeSocket( - IkeSocket.getIkeSocket( - mClientUdpEncapSocket, - mMockIkeSessionStateMachine)); - createLatch.countDown(); - Log.d("IkeSocketTest", "IkeSocket created."); - } catch (ErrnoException e) { - Log.e("IkeSocketTest", "error encountered creating IkeSocket ", e); - } - }); - createLatch.await(); - - IkeSocket ikeSocket = socketReceiver.getIkeSocket(); - assertNotNull(ikeSocket); - - // Configure IkeSocket - TestCountDownLatch receiveLatch = new TestCountDownLatch(); - DummyPacketReceiver packetReceiver = new DummyPacketReceiver(receiveLatch); - IkeSocket.setPacketReceiver(packetReceiver); - - // Send first packet. - sendToIkeSocket(mDummyRemoteServerFd, mDataOne, mLocalAddress); - receiveLatch.await(); - - assertEquals(1, ikeSocket.numPacketsReceived()); - assertArrayEquals(mDataOne, packetReceiver.mReceivedData); - - // Send second packet. - sendToIkeSocket(mDummyRemoteServerFd, mDataTwo, mLocalAddress); - receiveLatch.await(); - - assertEquals(2, ikeSocket.numPacketsReceived()); - assertArrayEquals(mDataTwo, packetReceiver.mReceivedData); - - // Close IkeSocket. - TestCountDownLatch closeLatch = new TestCountDownLatch(); - ikeSocket - .getHandler() - .post( - () -> { - ikeSocket.releaseReference(mMockIkeSessionStateMachine); - closeLatch.countDown(); - }); - closeLatch.await(); - - mIkeThread.quitSafely(); - } - - @Test - public void testHandlePacket() throws Exception { - byte[] recvBuf = - TestUtils.hexStringToByteArray( - NON_ESP_MARKER_HEX_STRING + IKE_REQ_MESSAGE_HEX_STRING); - - mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap); - - byte[] expectedIkePacketBytes = TestUtils.hexStringToByteArray(IKE_REQ_MESSAGE_HEX_STRING); - ArgumentCaptor<IkeHeader> ikeHeaderCaptor = ArgumentCaptor.forClass(IkeHeader.class); - verify(mMockIkeSessionStateMachine) - .receiveIkePacket(ikeHeaderCaptor.capture(), eq(expectedIkePacketBytes)); - - IkeHeader capturedIkeHeader = ikeHeaderCaptor.getValue(); - assertEquals(mRemoteSpi, capturedIkeHeader.ikeInitiatorSpi); - assertEquals(mLocalSpi, capturedIkeHeader.ikeResponderSpi); - } - - @Test - public void testHandleEspPacket() throws Exception { - byte[] recvBuf = - TestUtils.hexStringToByteArray( - NON_ESP_MARKER_HEX_STRING + IKE_REQ_MESSAGE_HEX_STRING); - // Modify Non-ESP Marker - recvBuf[0] = 1; - - mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap); - - verify(mMockIkeSessionStateMachine, never()).receiveIkePacket(any(), any()); - } - - @Test - public void testHandlePacketWithMalformedHeader() throws Exception { - String malformedIkePacketHexString = "5f54bf6d8b48e6e100000000000000002120220800000000"; - byte[] recvBuf = - TestUtils.hexStringToByteArray( - NON_ESP_MARKER_HEX_STRING + malformedIkePacketHexString); - - mPacketReceiver.handlePacket(recvBuf, mSpiToIkeStateMachineMap); - - verify(mMockIkeSessionStateMachine, never()).receiveIkePacket(any(), any()); - } - - private byte[] receive(FileDescriptor mfd) throws Exception { - byte[] receiveBuffer = new byte[REMOTE_RECV_BUFF_SIZE]; - AtomicInteger bytesRead = new AtomicInteger(-1); - Thread receiveThread = - new Thread( - () -> { - while (bytesRead.get() < 0) { - try { - bytesRead.set( - Os.recvfrom( - mDummyRemoteServerFd, - receiveBuffer, - 0, - REMOTE_RECV_BUFF_SIZE, - 0, - null)); - } catch (Exception e) { - Log.e( - "IkeSocketTest", - "Error encountered reading from socket", - e); - } - } - Log.d( - "IkeSocketTest", - "Packet received with size of " + bytesRead.get()); - }); - - receiveThread.start(); - receiveThread.join(TIMEOUT); - - return Arrays.copyOfRange(receiveBuffer, 0, bytesRead.get()); - } - - private void sendToIkeSocket(FileDescriptor fd, byte[] data, InetAddress destAddress) - throws Exception { - Os.sendto(fd, data, 0, data.length, 0, destAddress, mClientUdpEncapSocket.getPort()); - } - - private static class IkeSocketReceiver { - private IkeSocket mIkeSocket; - - void setIkeSocket(IkeSocket ikeSocket) { - mIkeSocket = ikeSocket; - } - - IkeSocket getIkeSocket() { - return mIkeSocket; - } - } - - private static class DummyPacketReceiver implements IkeSocket.IPacketReceiver { - byte[] mReceivedData = null; - final TestCountDownLatch mLatch; - - DummyPacketReceiver(TestCountDownLatch latch) { - mLatch = latch; - } - - public void handlePacket( - byte[] revbuf, LongSparseArray<IkeSessionStateMachine> spiToIkeSession) { - mReceivedData = Arrays.copyOfRange(revbuf, 0, revbuf.length); - mLatch.countDown(); - Log.d("IkeSocketTest", "Packet received"); - } - } - - private static class TestCountDownLatch { - private CountDownLatch mLatch; - - TestCountDownLatch() { - reset(); - } - - private void reset() { - mLatch = new CountDownLatch(1); - } - - void countDown() { - mLatch.countDown(); - } - - void await() { - try { - if (!mLatch.await(TIMEOUT, TimeUnit.MILLISECONDS)) { - fail("Time out"); - } - } catch (InterruptedException e) { - fail(e.toString()); - } - reset(); - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java deleted file mode 100644 index 646b9d9a..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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.internal.net.ipsec.ike; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.AdditionalMatchers.aryEq; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.IpSecManager; -import android.net.IpSecManager.SecurityParameterIndex; -import android.net.IpSecManager.UdpEncapsulationSocket; -import android.net.IpSecTransform; -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest; -import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest; -import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex; -import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecord; -import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecordConfig; -import com.android.internal.net.ipsec.ike.SaRecord.IIpSecTransformHelper; -import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord; -import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecordConfig; -import com.android.internal.net.ipsec.ike.SaRecord.IpSecTransformHelper; -import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -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.testutils.MockIpSecTestUtils; -import com.android.server.IpSecService; - -import libcore.net.InetAddressUtils; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.net.Inet4Address; - -@RunWith(JUnit4.class) -public final class SaRecordTest { - private static final Inet4Address LOCAL_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200")); - private static final Inet4Address REMOTE_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100")); - - private static final String PRF_KEY_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String DATA_TO_SIGN_HEX_STRING = "010000000a50500d"; - private static final String CALCULATED_MAC_HEX_STRING = - "D83B20CC6A0932B2A7CEF26E4020ABAAB64F0C6A"; - - private static final long IKE_INIT_SPI = 0x5F54BF6D8B48E6E1L; - private static final long IKE_RESP_SPI = 0x909232B3D1EDCB5CL; - - private static final String IKE_NONCE_INIT_HEX_STRING = - "C39B7F368F4681B89FA9B7BE6465ABD7C5F68B6ED5D3B4C72CB4240EB5C46412"; - private static final String IKE_NONCE_RESP_HEX_STRING = - "9756112CA539F5C25ABACC7EE92B73091942A9C06950F98848F1AF1694C4DDFF"; - - private static final String IKE_SHARED_DH_KEY_HEX_STRING = - "C14155DEA40056BD9C76FB4819687B7A397582F4CD5AFF4B" - + "8F441C56E0C08C84234147A0BA249A555835A048E3CA2980" - + "7D057A61DD26EEFAD9AF9C01497005E52858E29FB42EB849" - + "6731DF96A11CCE1F51137A9A1B900FA81AEE7898E373D4E4" - + "8B899BBECA091314ECD4B6E412EF4B0FEF798F54735F3180" - + "7424A318287F20E8"; - - private static final String IKE_SKEYSEED_HEX_STRING = - "8C42F3B1F5F81C7BAAC5F33E9A4F01987B2F9657"; - private static final String IKE_SK_D_HEX_STRING = "C86B56EFCF684DCC2877578AEF3137167FE0EBF6"; - private static final String IKE_SK_AUTH_INIT_HEX_STRING = - "554FBF5A05B7F511E05A30CE23D874DB9EF55E51"; - private static final String IKE_SK_AUTH_RESP_HEX_STRING = - "36D83420788337CA32ECAA46892C48808DCD58B1"; - private static final String IKE_SK_ENCR_INIT_HEX_STRING = "5CBFD33F75796C0188C4A3A546AEC4A1"; - private static final String IKE_SK_ENCR_RESP_HEX_STRING = "C33B35FCF29514CD9D8B4A695E1A816E"; - private static final String IKE_SK_PRF_INIT_HEX_STRING = - "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String IKE_SK_PRF_RESP_HEX_STRING = - "A30E6B08BE56C0E6BFF4744143C75219299E1BEB"; - private static final String IKE_KEY_MAT = - IKE_SK_D_HEX_STRING - + IKE_SK_AUTH_INIT_HEX_STRING - + IKE_SK_AUTH_RESP_HEX_STRING - + IKE_SK_ENCR_INIT_HEX_STRING - + IKE_SK_ENCR_RESP_HEX_STRING - + IKE_SK_PRF_INIT_HEX_STRING - + IKE_SK_PRF_RESP_HEX_STRING; - - private static final int IKE_AUTH_ALGO_KEY_LEN = 20; - private static final int IKE_ENCR_ALGO_KEY_LEN = 16; - private static final int IKE_PRF_KEY_LEN = 20; - private static final int IKE_SK_D_KEY_LEN = IKE_PRF_KEY_LEN; - - private static final int FIRST_CHILD_INIT_SPI = 0x2ad4c0a2; - private static final int FIRST_CHILD_RESP_SPI = 0xcae7019f; - - private static final String FIRST_CHILD_ENCR_INIT_HEX_STRING = - "1B865CEA6E2C23973E8C5452ADC5CD7D"; - private static final String FIRST_CHILD_ENCR_RESP_HEX_STRING = - "5E82FEDACC6DCB0756DDD7553907EBD1"; - private static final String FIRST_CHILD_AUTH_INIT_HEX_STRING = - "A7A5A44F7EF4409657206C7DC52B7E692593B51E"; - private static final String FIRST_CHILD_AUTH_RESP_HEX_STRING = - "CDE612189FD46DE870FAEC04F92B40B0BFDBD9E1"; - private static final String FIRST_CHILD_KEY_MAT = - FIRST_CHILD_ENCR_INIT_HEX_STRING - + FIRST_CHILD_AUTH_INIT_HEX_STRING - + FIRST_CHILD_ENCR_RESP_HEX_STRING - + FIRST_CHILD_AUTH_RESP_HEX_STRING; - - private static final int FIRST_CHILD_AUTH_ALGO_KEY_LEN = 20; - private static final int FIRST_CHILD_ENCR_ALGO_KEY_LEN = 16; - - private IkeMacPrf mIkeHmacSha1Prf; - private IkeMacIntegrity mHmacSha1IntegrityMac; - private IkeCipher mAesCbcCipher; - - private LocalRequest mMockFutureRekeyIkeEvent; - private ChildLocalRequest mMockFutureRekeyChildEvent; - - private SaRecordHelper mSaRecordHelper = new SaRecordHelper(); - - @Before - public void setUp() throws Exception { - mIkeHmacSha1Prf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - mHmacSha1IntegrityMac = - IkeMacIntegrity.create( - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96), - IkeMessage.getSecurityProvider()); - mAesCbcCipher = - IkeCipher.create( - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, - SaProposal.KEY_LEN_AES_128), - IkeMessage.getSecurityProvider()); - - mMockFutureRekeyIkeEvent = mock(LocalRequest.class); - mMockFutureRekeyChildEvent = mock(ChildLocalRequest.class); - } - - // Test generating keying material for making IKE SA. - @Test - public void testMakeIkeSaRecord() throws Exception { - byte[] sKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING); - byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING); - byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING); - - IkeSecurityParameterIndex ikeInitSpi = - IkeSecurityParameterIndex.allocateSecurityParameterIndex( - LOCAL_ADDRESS, IKE_INIT_SPI); - IkeSecurityParameterIndex ikeRespSpi = - IkeSecurityParameterIndex.allocateSecurityParameterIndex( - REMOTE_ADDRESS, IKE_RESP_SPI); - IkeSaRecordConfig ikeSaRecordConfig = - new IkeSaRecordConfig( - ikeInitSpi, - ikeRespSpi, - mIkeHmacSha1Prf, - IKE_AUTH_ALGO_KEY_LEN, - IKE_ENCR_ALGO_KEY_LEN, - true /*isLocalInit*/, - mMockFutureRekeyIkeEvent); - - int keyMaterialLen = - IKE_SK_D_KEY_LEN - + IKE_AUTH_ALGO_KEY_LEN * 2 - + IKE_ENCR_ALGO_KEY_LEN * 2 - + IKE_PRF_KEY_LEN * 2; - - IkeSaRecord ikeSaRecord = - mSaRecordHelper.makeIkeSaRecord(sKeySeed, nonceInit, nonceResp, ikeSaRecordConfig); - - assertTrue(ikeSaRecord.isLocalInit); - assertEquals(IKE_INIT_SPI, ikeSaRecord.getInitiatorSpi()); - assertEquals(IKE_RESP_SPI, ikeSaRecord.getResponderSpi()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING), ikeSaRecord.getSkD()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_AUTH_INIT_HEX_STRING), - ikeSaRecord.getOutboundIntegrityKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_AUTH_RESP_HEX_STRING), - ikeSaRecord.getInboundIntegrityKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_ENCR_INIT_HEX_STRING), - ikeSaRecord.getOutboundEncryptionKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_ENCR_RESP_HEX_STRING), - ikeSaRecord.getInboundDecryptionKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_PRF_INIT_HEX_STRING), ikeSaRecord.getSkPi()); - assertArrayEquals( - TestUtils.hexStringToByteArray(IKE_SK_PRF_RESP_HEX_STRING), ikeSaRecord.getSkPr()); - - ikeSaRecord.close(); - - verify(mMockFutureRekeyIkeEvent).cancel(); - } - - // Test generating keying material and building IpSecTransform for making Child SA. - @Test - public void testMakeChildSaRecord() throws Exception { - byte[] sharedKey = new byte[0]; - byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING); - byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING); - - MockIpSecTestUtils mockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec(); - IpSecManager ipSecManager = mockIpSecTestUtils.getIpSecManager(); - IpSecService mockIpSecService = mockIpSecTestUtils.getIpSecService(); - Context context = mockIpSecTestUtils.getContext(); - - when(mockIpSecService.allocateSecurityParameterIndex( - eq(LOCAL_ADDRESS.getHostAddress()), anyInt(), anyObject())) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(FIRST_CHILD_INIT_SPI)); - when(mockIpSecService.allocateSecurityParameterIndex( - eq(REMOTE_ADDRESS.getHostAddress()), anyInt(), anyObject())) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(FIRST_CHILD_RESP_SPI)); - - SecurityParameterIndex childInitSpi = - ipSecManager.allocateSecurityParameterIndex(LOCAL_ADDRESS); - SecurityParameterIndex childRespSpi = - ipSecManager.allocateSecurityParameterIndex(REMOTE_ADDRESS); - - byte[] initAuthKey = TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_INIT_HEX_STRING); - byte[] respAuthKey = TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_RESP_HEX_STRING); - byte[] initEncryptionKey = TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_INIT_HEX_STRING); - byte[] respEncryptionKey = TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_RESP_HEX_STRING); - - IIpSecTransformHelper mockIpSecHelper; - mockIpSecHelper = mock(IIpSecTransformHelper.class); - SaRecord.setIpSecTransformHelper(mockIpSecHelper); - - IpSecTransform mockInTransform = mock(IpSecTransform.class); - IpSecTransform mockOutTransform = mock(IpSecTransform.class); - UdpEncapsulationSocket mockUdpEncapSocket = mock(UdpEncapsulationSocket.class); - - when(mockIpSecHelper.makeIpSecTransform( - eq(context), - eq(LOCAL_ADDRESS), - eq(mockUdpEncapSocket), - eq(childRespSpi), - eq(mHmacSha1IntegrityMac), - eq(mAesCbcCipher), - aryEq(initAuthKey), - aryEq(initEncryptionKey), - eq(false))) - .thenReturn(mockOutTransform); - - when(mockIpSecHelper.makeIpSecTransform( - eq(context), - eq(REMOTE_ADDRESS), - eq(mockUdpEncapSocket), - eq(childInitSpi), - eq(mHmacSha1IntegrityMac), - eq(mAesCbcCipher), - aryEq(respAuthKey), - aryEq(respEncryptionKey), - eq(false))) - .thenReturn(mockInTransform); - - ChildSaRecordConfig childSaRecordConfig = - new ChildSaRecordConfig( - mockIpSecTestUtils.getContext(), - childInitSpi, - childRespSpi, - LOCAL_ADDRESS, - REMOTE_ADDRESS, - mockUdpEncapSocket, - mIkeHmacSha1Prf, - mHmacSha1IntegrityMac, - mAesCbcCipher, - TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING), - false /*isTransport*/, - true /*isLocalInit*/, - mMockFutureRekeyChildEvent); - - ChildSaRecord childSaRecord = - mSaRecordHelper.makeChildSaRecord( - sharedKey, nonceInit, nonceResp, childSaRecordConfig); - - assertTrue(childSaRecord.isLocalInit); - assertEquals(FIRST_CHILD_INIT_SPI, childSaRecord.getLocalSpi()); - assertEquals(FIRST_CHILD_RESP_SPI, childSaRecord.getRemoteSpi()); - assertEquals(mockInTransform, childSaRecord.getInboundIpSecTransform()); - assertEquals(mockOutTransform, childSaRecord.getOutboundIpSecTransform()); - - assertArrayEquals( - TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_INIT_HEX_STRING), - childSaRecord.getOutboundIntegrityKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_RESP_HEX_STRING), - childSaRecord.getInboundIntegrityKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_INIT_HEX_STRING), - childSaRecord.getOutboundEncryptionKey()); - assertArrayEquals( - TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_RESP_HEX_STRING), - childSaRecord.getInboundDecryptionKey()); - - childSaRecord.close(); - verify(mMockFutureRekeyChildEvent).cancel(); - - SaRecord.setIpSecTransformHelper(new IpSecTransformHelper()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java deleted file mode 100644 index a3b2253e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.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 android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.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/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java deleted file mode 100644 index ed625660..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.crypto; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.IpSecAlgorithm; -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Arrays; - -@RunWith(JUnit4.class) -public final class IkeMacIntegrityTest { - private static final String DATA_TO_AUTH_HEX_STRING = - "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec" - + "230000d0b9132b7bb9f658dfdc648e5017a6322a030c316c" - + "e55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58" - + "46de333ecd3ea2b705d18293b130395300ba92a351041345" - + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f" - + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60" - + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b" - + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423" - + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3" - + "59eb4e81"; - private static final String INTEGRITY_KEY_HEX_STRING = - "554fbf5a05b7f511e05a30ce23d874db9ef55e51"; - private static final String CHECKSUM_HEX_STRING = "ae6e0f22abdad69ba8007d50"; - - private IkeMacIntegrity mHmacSha1IntegrityMac; - private byte[] mHmacSha1IntegrityKey; - - private byte[] mDataToAuthenticate; - - @Before - public void setUp() throws Exception { - mHmacSha1IntegrityMac = - IkeMacIntegrity.create( - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96), - IkeMessage.getSecurityProvider()); - mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING); - - mDataToAuthenticate = TestUtils.hexStringToByteArray(DATA_TO_AUTH_HEX_STRING); - } - - @Test - public void testGenerateChecksum() throws Exception { - byte[] calculatedChecksum = - mHmacSha1IntegrityMac.generateChecksum(mHmacSha1IntegrityKey, mDataToAuthenticate); - - byte[] expectedChecksum = TestUtils.hexStringToByteArray(CHECKSUM_HEX_STRING); - assertArrayEquals(expectedChecksum, calculatedChecksum); - } - - @Test - public void testGenerateChecksumWithDifferentKey() throws Exception { - byte[] integrityKey = mHmacSha1IntegrityKey.clone(); - integrityKey[0]++; - - byte[] calculatedChecksum = - mHmacSha1IntegrityMac.generateChecksum(integrityKey, mDataToAuthenticate); - - byte[] expectedChecksum = TestUtils.hexStringToByteArray(CHECKSUM_HEX_STRING); - assertFalse(Arrays.equals(expectedChecksum, calculatedChecksum)); - } - - @Test - public void testGenerateChecksumWithInvalidKey() throws Exception { - byte[] integrityKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING + "0000"); - - try { - byte[] calculatedChecksum = - mHmacSha1IntegrityMac.generateChecksum(integrityKey, mDataToAuthenticate); - fail("Expected to fail due to invalid authentication key."); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testBuildIpSecAlgorithm() throws Exception { - IpSecAlgorithm ipsecAlgorithm = - mHmacSha1IntegrityMac.buildIpSecAlgorithmWithKey(mHmacSha1IntegrityKey); - - IpSecAlgorithm expectedIpSecAlgorithm = - new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, mHmacSha1IntegrityKey, 96); - - assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm)); - } - - @Test - public void buildIpSecAlgorithmWithInvalidKey() throws Exception { - byte[] encryptionKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING + "00"); - - try { - mHmacSha1IntegrityMac.buildIpSecAlgorithmWithKey(encryptionKey); - - fail("Expected to fail due to integrity key with wrong length."); - } catch (IllegalArgumentException expected) { - - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java deleted file mode 100644 index 717886f7..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.crypto; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertFalse; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.util.Arrays; - -@RunWith(JUnit4.class) -public final class IkeMacPrfTest { - - private static final String PRF_KEY_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String DATA_TO_SIGN_HEX_STRING = "010000000a50500d"; - private static final String CALCULATED_MAC_HEX_STRING = - "D83B20CC6A0932B2A7CEF26E4020ABAAB64F0C6A"; - - private static final String IKE_INIT_SPI = "5F54BF6D8B48E6E1"; - private static final String IKE_RESP_SPI = "909232B3D1EDCB5C"; - - private static final String IKE_NONCE_INIT_HEX_STRING = - "C39B7F368F4681B89FA9B7BE6465ABD7C5F68B6ED5D3B4C72CB4240EB5C46412"; - private static final String IKE_NONCE_RESP_HEX_STRING = - "9756112CA539F5C25ABACC7EE92B73091942A9C06950F98848F1AF1694C4DDFF"; - - private static final String IKE_SHARED_DH_KEY_HEX_STRING = - "C14155DEA40056BD9C76FB4819687B7A397582F4CD5AFF4B" - + "8F441C56E0C08C84234147A0BA249A555835A048E3CA2980" - + "7D057A61DD26EEFAD9AF9C01497005E52858E29FB42EB849" - + "6731DF96A11CCE1F51137A9A1B900FA81AEE7898E373D4E4" - + "8B899BBECA091314ECD4B6E412EF4B0FEF798F54735F3180" - + "7424A318287F20E8"; - - private static final String IKE_SKEYSEED_HEX_STRING = - "8C42F3B1F5F81C7BAAC5F33E9A4F01987B2F9657"; - private static final String IKE_SK_D_HEX_STRING = "C86B56EFCF684DCC2877578AEF3137167FE0EBF6"; - private static final String IKE_SK_AUTH_INIT_HEX_STRING = - "554FBF5A05B7F511E05A30CE23D874DB9EF55E51"; - private static final String IKE_SK_AUTH_RESP_HEX_STRING = - "36D83420788337CA32ECAA46892C48808DCD58B1"; - private static final String IKE_SK_ENCR_INIT_HEX_STRING = "5CBFD33F75796C0188C4A3A546AEC4A1"; - private static final String IKE_SK_ENCR_RESP_HEX_STRING = "C33B35FCF29514CD9D8B4A695E1A816E"; - private static final String IKE_SK_PRF_INIT_HEX_STRING = - "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String IKE_SK_PRF_RESP_HEX_STRING = - "A30E6B08BE56C0E6BFF4744143C75219299E1BEB"; - private static final String IKE_KEY_MAT = - IKE_SK_D_HEX_STRING - + IKE_SK_AUTH_INIT_HEX_STRING - + IKE_SK_AUTH_RESP_HEX_STRING - + IKE_SK_ENCR_INIT_HEX_STRING - + IKE_SK_ENCR_RESP_HEX_STRING - + IKE_SK_PRF_INIT_HEX_STRING - + IKE_SK_PRF_RESP_HEX_STRING; - - private static final int IKE_AUTH_ALGO_KEY_LEN = 20; - private static final int IKE_ENCR_ALGO_KEY_LEN = 16; - private static final int IKE_PRF_KEY_LEN = 20; - private static final int IKE_SK_D_KEY_LEN = IKE_PRF_KEY_LEN; - - private static final String FIRST_CHILD_ENCR_INIT_HEX_STRING = - "1B865CEA6E2C23973E8C5452ADC5CD7D"; - private static final String FIRST_CHILD_ENCR_RESP_HEX_STRING = - "5E82FEDACC6DCB0756DDD7553907EBD1"; - private static final String FIRST_CHILD_AUTH_INIT_HEX_STRING = - "A7A5A44F7EF4409657206C7DC52B7E692593B51E"; - private static final String FIRST_CHILD_AUTH_RESP_HEX_STRING = - "CDE612189FD46DE870FAEC04F92B40B0BFDBD9E1"; - private static final String FIRST_CHILD_KEY_MAT = - FIRST_CHILD_ENCR_INIT_HEX_STRING - + FIRST_CHILD_AUTH_INIT_HEX_STRING - + FIRST_CHILD_ENCR_RESP_HEX_STRING - + FIRST_CHILD_AUTH_RESP_HEX_STRING; - - private static final int FIRST_CHILD_AUTH_ALGO_KEY_LEN = 20; - private static final int FIRST_CHILD_ENCR_ALGO_KEY_LEN = 16; - - private IkeMacPrf mIkeHmacSha1Prf; - - @Before - public void setUp() throws Exception { - mIkeHmacSha1Prf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - } - - @Test - public void testsignBytes() throws Exception { - byte[] skpBytes = TestUtils.hexStringToByteArray(PRF_KEY_HEX_STRING); - byte[] dataBytes = TestUtils.hexStringToByteArray(DATA_TO_SIGN_HEX_STRING); - - byte[] calculatedBytes = mIkeHmacSha1Prf.signBytes(skpBytes, dataBytes); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(CALCULATED_MAC_HEX_STRING); - assertArrayEquals(expectedBytes, calculatedBytes); - } - - @Test - public void testGenerateSKeySeed() throws Exception { - byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING); - byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING); - byte[] sharedDhKey = TestUtils.hexStringToByteArray(IKE_SHARED_DH_KEY_HEX_STRING); - - byte[] calculatedSKeySeed = - mIkeHmacSha1Prf.generateSKeySeed(nonceInit, nonceResp, sharedDhKey); - - byte[] expectedSKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING); - assertArrayEquals(expectedSKeySeed, calculatedSKeySeed); - } - - @Test - public void testGenerateRekeyedSKeySeed() throws Exception { - byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING); - byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING); - byte[] sharedDhKey = TestUtils.hexStringToByteArray(IKE_SHARED_DH_KEY_HEX_STRING); - byte[] old_skd = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING); - - byte[] calculatedSKeySeed = - mIkeHmacSha1Prf.generateRekeyedSKeySeed(old_skd, nonceInit, nonceResp, sharedDhKey); - - // Verify that the new sKeySeed is different. - // TODO: Find actual test vectors to test positive case. - byte[] oldSKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING); - assertFalse(Arrays.equals(oldSKeySeed, calculatedSKeySeed)); - } - - @Test - public void testGenerateKeyMatForIke() throws Exception { - byte[] prfKey = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING); - byte[] prfData = - TestUtils.hexStringToByteArray( - IKE_NONCE_INIT_HEX_STRING - + IKE_NONCE_RESP_HEX_STRING - + IKE_INIT_SPI - + IKE_RESP_SPI); - int keyMaterialLen = - IKE_SK_D_KEY_LEN - + IKE_AUTH_ALGO_KEY_LEN * 2 - + IKE_ENCR_ALGO_KEY_LEN * 2 - + IKE_PRF_KEY_LEN * 2; - - byte[] calculatedKeyMat = mIkeHmacSha1Prf.generateKeyMat(prfKey, prfData, keyMaterialLen); - - byte[] expectedKeyMat = TestUtils.hexStringToByteArray(IKE_KEY_MAT); - assertArrayEquals(expectedKeyMat, calculatedKeyMat); - } - - @Test - public void testGenerateKeyMatForFirstChild() throws Exception { - byte[] prfKey = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING); - byte[] prfData = - TestUtils.hexStringToByteArray( - IKE_NONCE_INIT_HEX_STRING + IKE_NONCE_RESP_HEX_STRING); - int keyMaterialLen = FIRST_CHILD_AUTH_ALGO_KEY_LEN * 2 + FIRST_CHILD_ENCR_ALGO_KEY_LEN * 2; - - byte[] calculatedKeyMat = mIkeHmacSha1Prf.generateKeyMat(prfKey, prfData, keyMaterialLen); - - byte[] expectedKeyMat = TestUtils.hexStringToByteArray(FIRST_CHILD_KEY_MAT); - assertArrayEquals(expectedKeyMat, calculatedKeyMat); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java deleted file mode 100644 index 3f3a0e10..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.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 android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.message.IkeMessage; -import com.android.internal.net.ipsec.ike.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 javax.crypto.IllegalBlockSizeException; - -@RunWith(JUnit4.class) -public final class IkeNormalModeCipherTest { - private static final String IKE_AUTH_INIT_REQUEST_IV = "b9132b7bb9f658dfdc648e5017a6322a"; - private static final String IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA = - "030c316ce55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58" - + "46de333ecd3ea2b705d18293b130395300ba92a351041345" - + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f" - + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60" - + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b" - + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423" - + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3" - + "59eb4e81"; - private static final String IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA = - "2400000c010000000a50500d2700000c010000000a505050" - + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327" - + "44dfb2c12c00002c00000028010304032ad4c0a20300000c" - + "0100000c800e008003000008030000020000000805000000" - + "2d00001801000000070000100000ffff00000000ffffffff" - + "2900001801000000070000100000ffff00000000ffffffff" - + "29000008000040000000000c000040010000000100000000" - + "000000000000000b"; - - private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1"; - - private static final int AES_BLOCK_SIZE = 16; - - private IkeNormalModeCipher mAesCbcCipher; - private byte[] mAesCbcKey; - - private byte[] mIv; - private byte[] mEncryptedPaddedData; - private byte[] mUnencryptedPaddedData; - - @Before - public void setUp() throws Exception { - mAesCbcCipher = - (IkeNormalModeCipher) - IkeCipher.create( - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, - SaProposal.KEY_LEN_AES_128), - IkeMessage.getSecurityProvider()); - mAesCbcKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP); - - mIv = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_IV); - mEncryptedPaddedData = - TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA); - mUnencryptedPaddedData = - TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA); - } - - @Test - public void testBuild() throws Exception { - assertFalse(mAesCbcCipher.isAead()); - assertEquals(AES_BLOCK_SIZE, mAesCbcCipher.getBlockSize()); - assertEquals(AES_BLOCK_SIZE, mAesCbcCipher.generateIv().length); - } - - @Test - public void testGenerateRandomIv() throws Exception { - assertFalse(Arrays.equals(mAesCbcCipher.generateIv(), mAesCbcCipher.generateIv())); - } - - @Test - public void testEncryptWithNormalCipher() throws Exception { - byte[] calculatedData = mAesCbcCipher.encrypt(mUnencryptedPaddedData, mAesCbcKey, mIv); - - assertArrayEquals(mEncryptedPaddedData, calculatedData); - } - - @Test - public void testDecryptWithNormalCipher() throws Exception { - byte[] calculatedData = mAesCbcCipher.decrypt(mEncryptedPaddedData, mAesCbcKey, mIv); - assertArrayEquals(mUnencryptedPaddedData, calculatedData); - } - - @Test - public void testEncryptWithWrongKey() throws Exception { - byte[] encryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP + "00"); - - try { - mAesCbcCipher.encrypt(mEncryptedPaddedData, encryptionKey, mIv); - fail("Expected to fail due to encryption key with wrong length."); - } catch (IllegalArgumentException expected) { - - } - } - - @Test - public void testDecryptWithNormalCipherWithBadPad() throws Exception { - byte[] dataToDecrypt = - TestUtils.hexStringToByteArray( - IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA + "00"); - try { - mAesCbcCipher.decrypt(dataToDecrypt, mAesCbcKey, mIv); - fail("Expected to fail when try to decrypt data with bad padding"); - } catch (IllegalBlockSizeException expected) { - - } - } - - @Test - public void testBuildIpSecAlgorithm() throws Exception { - IpSecAlgorithm ipsecAlgorithm = mAesCbcCipher.buildIpSecAlgorithmWithKey(mAesCbcKey); - - IpSecAlgorithm expectedIpSecAlgorithm = - new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, mAesCbcKey); - - assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm)); - } - - @Test - public void buildIpSecAlgorithmWithInvalidKey() throws Exception { - byte[] encryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP + "00"); - - try { - mAesCbcCipher.buildIpSecAlgorithmWithKey(encryptionKey); - - fail("Expected to fail due to encryption key with wrong length."); - } catch (IllegalArgumentException expected) { - - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java deleted file mode 100644 index 96921c30..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static com.android.internal.net.ipsec.ike.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; -import static org.junit.Assert.fail; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; -import com.android.internal.net.ipsec.ike.testutils.CertUtils; - -import org.junit.Before; -import org.junit.Test; - -import java.security.PrivateKey; -import java.security.cert.X509Certificate; - -public final class IkeAuthDigitalSignPayloadTest { - // TODO: Build a RSA_SHA1 signature and add tests for it. - - // RSA_SHA2_256 - private static final String AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING = - "0e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d4136b9f" - + "69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8" - + "e12c5d982aa4efdaeac36a02b222aa96242cc424"; - private static final String SIGNATURE = - "6f76af4150d653c5d4136b9f69d905849bf075c563e6d14ccda42361ec3e7d12" - + "c72e2dece5711ea1d952f7b8e12c5d982aa4efdaeac36a02b222aa96242cc424"; - - private static final String IKE_INIT_RESP_HEX_STRING = - "02458497587b09d488d5b76480bce53d2120222000000000000001cc2200002c" - + "00000028010100040300000801000003030000080300000203000008020000020" - + "00000080400000e28000108000e000013d60e51c40922cb121e395bacbd627cdd" - + "d3240baa4fcefd29f65f8dd37329d68d4fb4854f8b8f07cfb60900e276d99a396" - + "1112ee866b5456cf588dc1092fd3bc19668fb8fa42872f51c0ee748bdb665dcbe" - + "15ac454f6ed966149954dac5187638d1ab61869d97a4873c4733c48cbe3acc8a6" - + "5cfea3ce83fd09fba174bf0ec56d73a0585859399e61c2c38e695841f8df8a511" - + "aadd438f56634165ad9b88e858c1585f1bee646943b8a96f5397721079a127b87" - + "fd286e8f869ae021ce82adf91fa360217ac32268b39b698bf06a4e89b8d0267af" - + "1c5b979b6493adb10a0e14aa707309e914b8d377903e75cb13cffbfde9c26842f" - + "b49a07a4497c9907d39515b290000244b8aed6297c09a5a0dda06c873f5573b34" - + "886dd779e90c19beca3fc54ab3cae02900001c00004004d8e7cb9d1e689ae8c84" - + "c5078355436f3347376ff2900001c0000400545bc3f2113770de91c769094f1bd" - + "614534e765ea290000080000402e290000100000402f000100020003000400000" - + "00800004014"; - private static final String NONCE_INIT_HEX_STRING = - "a5dded450b5ffd2670f37954367fce28279a085c830a03358b10b0872c0578f9"; - private static final String ID_RESP_PAYLOAD_BODY_HEX_STRING = "01000000c0a82b8a"; - private static final String SKP_RESP_HEX_STRING = "8FE8EC3153EDE924C23D6630D3C992A494E2F256"; - - private static final byte[] IKE_INIT_RESP_REQUEST = - TestUtils.hexStringToByteArray(IKE_INIT_RESP_HEX_STRING); - private static final byte[] NONCE_INIT_RESP = - TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING); - private static final byte[] ID_RESP_PAYLOAD_BODY = - TestUtils.hexStringToByteArray(ID_RESP_PAYLOAD_BODY_HEX_STRING); - private static final byte[] PRF_RESP_KEY = TestUtils.hexStringToByteArray(SKP_RESP_HEX_STRING); - - private IkeMacPrf mIkeHmacSha1Prf; - - @Before - public void setUp() throws Exception { - mIkeHmacSha1Prf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - } - - @Test - public void testDecodeGenericDigitalSignPayload() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING); - IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket); - - assertTrue(payload instanceof IkeAuthDigitalSignPayload); - IkeAuthDigitalSignPayload dsPayload = (IkeAuthDigitalSignPayload) payload; - assertEquals(SIGNATURE_ALGO_RSA_SHA2_256, dsPayload.signatureAlgoAndHash); - assertArrayEquals(dsPayload.signature, TestUtils.hexStringToByteArray(SIGNATURE)); - } - - @Test - public void testVerifyInboundSignature() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING); - IkeAuthDigitalSignPayload payload = - (IkeAuthDigitalSignPayload) IkeAuthPayload.getIkeAuthPayload(false, inputPacket); - - X509Certificate cert = CertUtils.createCertFromPemFile("end-cert-small.pem"); - - payload.verifyInboundSignature( - cert, - IKE_INIT_RESP_REQUEST, - NONCE_INIT_RESP, - ID_RESP_PAYLOAD_BODY, - mIkeHmacSha1Prf, - PRF_RESP_KEY); - } - - @Test - public void testVerifyInboundSignatureFail() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING); - IkeAuthDigitalSignPayload payload = - (IkeAuthDigitalSignPayload) IkeAuthPayload.getIkeAuthPayload(false, inputPacket); - - assertArrayEquals(payload.signature, TestUtils.hexStringToByteArray(SIGNATURE)); - X509Certificate cert = CertUtils.createCertFromPemFile("end-cert-a.pem"); - - try { - payload.verifyInboundSignature( - cert, - IKE_INIT_RESP_REQUEST, - NONCE_INIT_RESP, - ID_RESP_PAYLOAD_BODY, - mIkeHmacSha1Prf, - 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/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java deleted file mode 100644 index 989b4689..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -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.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; - -import org.junit.Before; -import org.junit.Test; - -public final class IkeAuthPayloadTest { - private static final String PSK_AUTH_PAYLOAD_HEX_STRING = - "02000000df7c038aefaaa32d3f44b228b52a332744dfb2c1"; - private static final String PSK_AUTH_PAYLOAD_SIGNATURE_HEX_STRING = - "df7c038aefaaa32d3f44b228b52a332744dfb2c1"; - private static final String PSK_ID_PAYLOAD_HEX_STRING = "010000000a50500d"; - private static final String PSK_SKP_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485"; - private static final String PSK_SIGNED_OCTETS_APPENDIX_HEX_STRING = - "D83B20CC6A0932B2A7CEF26E4020ABAAB64F0C6A"; - private static final String PSK_IKE_INIT_REQUEST_HEX_STRING = - "5f54bf6d8b48e6e1000000000000000021202208" - + "0000000000000150220000300000002c01010004" - + "0300000c0100000c800e00800300000803000002" - + "0300000804000002000000080200000228000088" - + "00020000b4a2faf4bb54878ae21d638512ece55d" - + "9236fc5046ab6cef82220f421f3ce6361faf3656" - + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9" - + "ece8ac37534036040610ebdd92f46bef84f0be7d" - + "b860351843858f8acf87056e272377f70c9f2d81" - + "e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" - + "6bbeb08214c707137607958729000024c39b7f36" - + "8f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7" - + "2cb4240eb5c464122900001c00004004e54f73b7" - + "d83f6beb881eab2051d8663f421d10b02b00001c" - + "00004005d915368ca036004cb578ae3e3fb26850" - + "9aeab19000000020699369228741c6d4ca094c93" - + "e242c9de19e7b7c60000000500000500"; - private static final String PSK_NONCE_RESP_HEX_STRING = - "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; - private static final String PSK_INIT_SIGNED_OCTETS = - "5F54BF6D8B48E6E1000000000000000021202208" - + "0000000000000150220000300000002C01010004" - + "0300000C0100000C800E00800300000803000002" - + "0300000804000002000000080200000228000088" - + "00020000B4A2FAF4BB54878AE21D638512ECE55D" - + "9236FC5046AB6CEF82220F421F3CE6361FAF3656" - + "4ECB6D28798A94AAD7B2B4B603DDEAAA5630ADB9" - + "ECE8AC37534036040610EBDD92F46BEF84F0BE7D" - + "B860351843858F8ACF87056E272377F70C9F2D81" - + "E29C7B0CE4F291A3A72476BB0B278FD4B7B0A4C2" - + "6BBEB08214C707137607958729000024C39B7F36" - + "8F4681B89FA9B7BE6465ABD7C5F68B6ED5D3B4C7" - + "2CB4240EB5C464122900001C00004004E54F73B7" - + "D83F6BEB881EAB2051D8663F421D10B02B00001C" - + "00004005D915368CA036004CB578AE3E3FB26850" - + "9AEAB19000000020699369228741C6D4CA094C93" - + "E242C9DE19E7B7C600000005000005009756112C" - + "A539F5C25ABACC7EE92B73091942A9C06950F988" - + "48F1AF1694C4DDFFD83B20CC6A0932B2A7CEF26E" - + "4020ABAAB64F0C6A"; - - private static final int AUTH_METHOD_POSITION = 0; - - private IkeMacPrf mIkeHmacSha1Prf; - - @Before - public void setUp() throws Exception { - mIkeHmacSha1Prf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - } - - @Test - public void testDecodeIkeAuthPayload() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_HEX_STRING); - IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket); - - assertEquals(IkeAuthPayload.AUTH_METHOD_PRE_SHARED_KEY, payload.authMethod); - assertTrue(payload instanceof IkeAuthPskPayload); - - byte[] expectedSignature = - TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_SIGNATURE_HEX_STRING); - assertArrayEquals(expectedSignature, ((IkeAuthPskPayload) payload).signature); - } - - @Test - public void testDecodeIkeAuthPayloadWithUnsupportedMethod() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_HEX_STRING); - inputPacket[AUTH_METHOD_POSITION] = 0; - try { - IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket); - fail("Expected Exception: authentication method is not supported"); - } catch (AuthenticationFailedException e) { - } - } - - @Test - public void testGetSignedOctets() throws Exception { - byte[] skpBytes = TestUtils.hexStringToByteArray(PSK_SKP_HEX_STRING); - byte[] idBytes = TestUtils.hexStringToByteArray(PSK_ID_PAYLOAD_HEX_STRING); - byte[] ikeInitRequest = TestUtils.hexStringToByteArray(PSK_IKE_INIT_REQUEST_HEX_STRING); - byte[] nonceResp = TestUtils.hexStringToByteArray(PSK_NONCE_RESP_HEX_STRING); - - byte[] calculatedBytes = - IkeAuthPayload.getSignedOctets( - ikeInitRequest, nonceResp, idBytes, mIkeHmacSha1Prf, skpBytes); - byte[] expectedBytes = TestUtils.hexStringToByteArray(PSK_INIT_SIGNED_OCTETS); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java deleted file mode 100644 index cad60522..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.Arrays; - -public final class IkeAuthPskPayloadTest { - private static final String PSK_AUTH_PAYLOAD_HEX_STRING = - "2100001c02000000df7c038aefaaa32d3f44b228b52a332744dfb2c1"; - private static final String PSK_AUTH_PAYLOAD_BODY_HEX_STRING = - "02000000df7c038aefaaa32d3f44b228b52a332744dfb2c1"; - private static final String PSK_AUTH_PAYLOAD_SIGNATURE_HEX_STRING = - "df7c038aefaaa32d3f44b228b52a332744dfb2c1"; - - private static final String PSK_IKE_INIT_REQUEST_HEX_STRING = - "5f54bf6d8b48e6e1000000000000000021202208" - + "0000000000000150220000300000002c01010004" - + "0300000c0100000c800e00800300000803000002" - + "0300000804000002000000080200000228000088" - + "00020000b4a2faf4bb54878ae21d638512ece55d" - + "9236fc5046ab6cef82220f421f3ce6361faf3656" - + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9" - + "ece8ac37534036040610ebdd92f46bef84f0be7d" - + "b860351843858f8acf87056e272377f70c9f2d81" - + "e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" - + "6bbeb08214c707137607958729000024c39b7f36" - + "8f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7" - + "2cb4240eb5c464122900001c00004004e54f73b7" - + "d83f6beb881eab2051d8663f421d10b02b00001c" - + "00004005d915368ca036004cb578ae3e3fb26850" - + "9aeab19000000020699369228741c6d4ca094c93" - + "e242c9de19e7b7c60000000500000500"; - private static final String PSK_NONCE_RESP_HEX_STRING = - "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; - private static final String PSK_ID_INITIATOR_PAYLOAD_HEX_STRING = "010000000a50500d"; - - private static final String PSK_HEX_STRING = "6A756E69706572313233"; - private static final String PSK_SKP_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485"; - - private static final byte[] PSK = TestUtils.hexStringToByteArray(PSK_HEX_STRING); - private static final byte[] IKE_INIT_REQUEST = - TestUtils.hexStringToByteArray(PSK_IKE_INIT_REQUEST_HEX_STRING); - private static final byte[] NONCE = TestUtils.hexStringToByteArray(PSK_NONCE_RESP_HEX_STRING); - private static final byte[] ID_PAYLOAD_BODY = - TestUtils.hexStringToByteArray(PSK_ID_INITIATOR_PAYLOAD_HEX_STRING); - private static final byte[] PRF_KEY = TestUtils.hexStringToByteArray(PSK_SKP_HEX_STRING); - private static final byte[] SIGNATURE = - TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_SIGNATURE_HEX_STRING); - - private IkeMacPrf mIkeHmacSha1Prf; - - @Before - public void setUp() throws Exception { - mIkeHmacSha1Prf = - IkeMacPrf.create( - new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1), - IkeMessage.getSecurityProvider()); - } - - @Test - public void testBuildOutboundIkeAuthPskPayload() throws Exception { - IkeAuthPskPayload payload = - new IkeAuthPskPayload( - PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY); - - assertEquals(IkeAuthPayload.AUTH_METHOD_PRE_SHARED_KEY, payload.authMethod); - assertArrayEquals(SIGNATURE, payload.signature); - - // Verify payload length - int payloadLength = payload.getPayloadLength(); - byte[] expectedPayload = TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_HEX_STRING); - assertEquals(expectedPayload.length, payloadLength); - - // Verify encoding - ByteBuffer byteBuffer = ByteBuffer.allocate(payloadLength); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_SA, byteBuffer); - assertArrayEquals(expectedPayload, byteBuffer.array()); - } - - private IkeAuthPskPayload buildPskPayload() throws Exception { - byte[] payloadBody = TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_BODY_HEX_STRING); - IkeAuthPskPayload pskPayload = - (IkeAuthPskPayload) IkeAuthPayload.getIkeAuthPayload(false, payloadBody); - return pskPayload; - } - - @Test - public void testDecodeIkeAuthPskPayload() throws Exception { - IkeAuthPskPayload pskPayload = buildPskPayload(); - - assertArrayEquals(SIGNATURE, pskPayload.signature); - } - - @Test - public void testVerifyReceivedSignature() throws Exception { - IkeAuthPskPayload pskPayload = buildPskPayload(); - - pskPayload.verifyInboundSignature( - PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY); - } - - @Test - public void testVerifyReceivedSignatureFailure() throws Exception { - IkeAuthPskPayload pskPayload = buildPskPayload(); - byte[] nonce = Arrays.copyOf(NONCE, NONCE.length); - nonce[0]++; - - try { - pskPayload.verifyInboundSignature( - PSK, IKE_INIT_REQUEST, nonce, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY); - fail("Expected signature verification to have failed due to mismatched signatures."); - } catch (AuthenticationFailedException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java deleted file mode 100644 index 2bb72e33..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.fail; - -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.testutils.CertUtils; - -import org.junit.Before; -import org.junit.Test; - -import java.security.cert.TrustAnchor; -import java.security.cert.X509Certificate; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -public final class IkeCertPayloadTest { - private X509Certificate mEndCertA; - private X509Certificate mEndCertB; - private X509Certificate mEndCertSmall; - - private X509Certificate mIntermediateCertBOne; - private X509Certificate mIntermediateCertBTwo; - - private TrustAnchor mTrustAnchorA; - private TrustAnchor mTrustAnchorB; - private TrustAnchor mTrustAnchorSmall; - - @Before - public void setUp() throws Exception { - mEndCertA = CertUtils.createCertFromPemFile("end-cert-a.pem"); - mTrustAnchorA = - new TrustAnchor( - CertUtils.createCertFromPemFile("self-signed-ca-a.pem"), - null /*nameConstraints*/); - - mEndCertB = CertUtils.createCertFromPemFile("end-cert-b.pem"); - mIntermediateCertBOne = CertUtils.createCertFromPemFile("intermediate-ca-b-one.pem"); - mIntermediateCertBTwo = CertUtils.createCertFromPemFile("intermediate-ca-b-two.pem"); - mTrustAnchorB = - new TrustAnchor( - CertUtils.createCertFromPemFile("self-signed-ca-b.pem"), - null /*nameConstraints*/); - - mEndCertSmall = CertUtils.createCertFromPemFile("end-cert-small.pem"); - mTrustAnchorSmall = - new TrustAnchor( - CertUtils.createCertFromPemFile("self-signed-ca-small.pem"), - null /*nameConstraints*/); - } - - @Test - public void testValidateCertsNoIntermediateCerts() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - certList.add(mEndCertA); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorA); - - IkeCertPayload.validateCertificates(mEndCertA, certList, null /*crlList*/, trustAnchors); - } - - @Test - public void testValidateCertsWithIntermediateCerts() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - - certList.add(mEndCertB); - certList.add(mIntermediateCertBTwo); - certList.add(mIntermediateCertBOne); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorB); - - IkeCertPayload.validateCertificates(mEndCertB, certList, null /*crlList*/, trustAnchors); - } - - @Test - public void testValidateCertsWithMultiTrustAnchors() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - certList.add(mEndCertA); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorA); - trustAnchors.add(mTrustAnchorB); - - IkeCertPayload.validateCertificates(mEndCertA, certList, null /*crlList*/, trustAnchors); - } - - @Test - public void testValidateCertsWithWrongTrustAnchor() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - certList.add(mEndCertA); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorB); - - try { - IkeCertPayload.validateCertificates( - mEndCertA, certList, null /*crlList*/, trustAnchors); - fail("Expected to fail due to absence of valid trust anchor."); - } catch (AuthenticationFailedException expected) { - } - } - - @Test - public void testValidateCertsWithMissingIntermediateCerts() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - certList.add(mEndCertB); - certList.add(mIntermediateCertBOne); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorB); - - try { - IkeCertPayload.validateCertificates( - mEndCertA, certList, null /*crlList*/, trustAnchors); - fail("Expected to fail due to absence of intermediate certificate."); - } catch (AuthenticationFailedException expected) { - } - } - - @Test - public void testValidateCertsWithSmallSizeKey() throws Exception { - List<X509Certificate> certList = new LinkedList<>(); - certList.add(mEndCertSmall); - - Set<TrustAnchor> trustAnchors = new HashSet<>(); - trustAnchors.add(mTrustAnchorSmall); - - try { - IkeCertPayload.validateCertificates( - mEndCertSmall, certList, null /*crlList*/, trustAnchors); - fail("Expected to fail because certificates use small size key"); - } catch (AuthenticationFailedException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java deleted file mode 100644 index ef6ec289..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertEquals; -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.AuthenticationFailedException; - -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.util.Arrays; -import java.util.Base64; - -public final class IkeCertX509CertPayloadTest { - private static final String CERT_PAYLOAD_BODY_HEX_STRING = - "043082042130820209a003020102020827a2b30cdd5043ab300d06092a864886" - + "f70d01010c05003035310b3009060355040613024e5a310e300c060355040a13" - + "054576697461311630140603550403130d457669746120526f6f74204341301e" - + "170d3138313033303139303034305a170d3230313032393139303034305a3036" - + "310b3009060355040613024e5a310e300c060355040a13054576697461311730" - + "150603550403130e3139322e3136382e34332e31303330820122300d06092a86" - + "4886f70d01010105000382010f003082010a0282010100b15dd29d25ef546532" - + "2b85b2db5aefbff85b2f8e90a67c5ce48a7baee696d645602b1122501e10aec4" - + "7733a875a6f02432a4d684e67bdab36549996f3a2fc919cf769dc3a3b270791a" - + "3682c868225e5478df1d2467b1afafd608db2696c484a0134f8069f9ed0b55fc" - + "656b15fef6b9b151debfd1d96f6bba0f032432ec6497573d47f3539b4754f33a" - + "89ea4d3986ad33137a750b36073fe50188c169a851c092506ea383ceb58b55ad" - + "f55956e037118f2f747be6dc3f0f741ec1d658defcd9197b8750a75ae9c1b1c7" - + "2f2ff91f561d1b3d77d54037e8cfe3738668a3de42cf7eab21353ae322e40eb4" - + "8dcf38eb34572118315047133f7727cab46f10f9f70de30203010001a3343032" - + "301f0603551d23041830168014fbcb6762ffde82b4d63d069beeac583228ab32" - + "25300f0603551d11040830068704c0a82b67300d06092a864886f70d01010c05" - + "0003820201006f26b5973346030b7297d50e3ce4cd8ca5b1527fd9045b4bb540" - + "a7cd0193e16732346d6fb99c2058a17f0129460ba6e4832b6b4a6c51731ceea4" - + "5464e0f179b860b3f0bf10956b1f4bae8cecdfc08261a3c00e8aa0ddbbe9ca08" - + "6a954ec9e3bcb0ea907e617e98a97ec1c2b7c2190b10a8117b12e56640830c1f" - + "c6492a8f7062e92b7e2d03f22173fb333b9a45d96c9842fc16c0c6658428fbdf" - + "6351be6fe65f7e1f329d7a07dad617837208e72539774ef46a72bc8e279fca74" - + "d68fbfba91de8d62331c2df135ce234b007afc330f96d3ee80888ba102334c32" - + "2d25a78d26a2c9434fafdfa9ea35acadf4938a69623de5ee966d1d550d851df3" - + "d99b477f804a6eb2d8c16f80161a9511674bfa514f5d127c856ca6c0dff07eba" - + "87672e2154c4fd0f3b906ff888978315a041b3fdbc7cf8e2306e0b20b3a79d2b" - + "5a59f7f6b8e784af57d43be4be37f9381a6ff6c3fa477fed151d586c42634e0a" - + "88e699a9f3b38459589ea014d549b7ed7fd551bd544d464d955476ed1c051fa1" - + "a7351d5d4f13efe232bc847a245c85a4a04abf66abd7d983b254a67d0189206c" - + "8fc8989f38e63bd827552e209a2aa119d0622f0defe08cef0bf48a3459c09ad9" - + "8f729b51bb57f2518385abd790ff3d80d1cdce1218f61ea45c0c6fc9814c300d" - + "abc24a747560744e9861c9395dd2f849b4d1196fe302ac8a063afeea9bc9d637" - + "2fedb79130bb"; - - private static final String CLIENT_END_CERTIFICATE = - "MIIEITCCAgmgAwIBAgIIJ6KzDN1QQ6swDQYJKoZIhvcNAQEMBQAwNTELMAkGA1UE" - + "BhMCTloxDjAMBgNVBAoTBUV2aXRhMRYwFAYDVQQDEw1Fdml0YSBSb290IENBMB4X" - + "DTE4MTAzMDE5MDA0MFoXDTIwMTAyOTE5MDA0MFowNjELMAkGA1UEBhMCTloxDjAM" - + "BgNVBAoTBUV2aXRhMRcwFQYDVQQDEw4xOTIuMTY4LjQzLjEwMzCCASIwDQYJKoZI" - + "hvcNAQEBBQADggEPADCCAQoCggEBALFd0p0l71RlMiuFstta77/4Wy+OkKZ8XOSK" - + "e67mltZFYCsRIlAeEK7EdzOodabwJDKk1oTme9qzZUmZbzovyRnPdp3Do7JweRo2" - + "gshoIl5UeN8dJGexr6/WCNsmlsSEoBNPgGn57QtV/GVrFf72ubFR3r/R2W9rug8D" - + "JDLsZJdXPUfzU5tHVPM6iepNOYatMxN6dQs2Bz/lAYjBaahRwJJQbqODzrWLVa31" - + "WVbgNxGPL3R75tw/D3QewdZY3vzZGXuHUKda6cGxxy8v+R9WHRs9d9VAN+jP43OG" - + "aKPeQs9+qyE1OuMi5A60jc846zRXIRgxUEcTP3cnyrRvEPn3DeMCAwEAAaM0MDIw" - + "HwYDVR0jBBgwFoAU+8tnYv/egrTWPQab7qxYMiirMiUwDwYDVR0RBAgwBocEwKgr" - + "ZzANBgkqhkiG9w0BAQwFAAOCAgEAbya1lzNGAwtyl9UOPOTNjKWxUn/ZBFtLtUCn" - + "zQGT4WcyNG1vuZwgWKF/ASlGC6bkgytrSmxRcxzupFRk4PF5uGCz8L8QlWsfS66M" - + "7N/AgmGjwA6KoN276coIapVOyeO8sOqQfmF+mKl+wcK3whkLEKgRexLlZkCDDB/G" - + "SSqPcGLpK34tA/Ihc/szO5pF2WyYQvwWwMZlhCj732NRvm/mX34fMp16B9rWF4Ny" - + "COclOXdO9GpyvI4nn8p01o+/upHejWIzHC3xNc4jSwB6/DMPltPugIiLoQIzTDIt" - + "JaeNJqLJQ0+v36nqNayt9JOKaWI95e6WbR1VDYUd89mbR3+ASm6y2MFvgBYalRFn" - + "S/pRT10SfIVspsDf8H66h2cuIVTE/Q87kG/4iJeDFaBBs/28fPjiMG4LILOnnSta" - + "Wff2uOeEr1fUO+S+N/k4Gm/2w/pHf+0VHVhsQmNOCojmmanzs4RZWJ6gFNVJt+1/" - + "1VG9VE1GTZVUdu0cBR+hpzUdXU8T7+IyvIR6JFyFpKBKv2ar19mDslSmfQGJIGyP" - + "yJifOOY72CdVLiCaKqEZ0GIvDe/gjO8L9Io0WcCa2Y9ym1G7V/JRg4Wr15D/PYDR" - + "zc4SGPYepFwMb8mBTDANq8JKdHVgdE6YYck5XdL4SbTRGW/jAqyKBjr+6pvJ1jcv" - + "7beRMLs="; - private static final int CERTIFICATE_OFFSET = 1; - - @Test - public void testDecodeX509Certificate() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(CERT_PAYLOAD_BODY_HEX_STRING); - IkeCertPayload certPayload = IkeCertPayload.getIkeCertPayload(false, inputPacket); - - assertTrue(certPayload instanceof IkeCertX509CertPayload); - X509Certificate expectedCert = pemStringToCertificate(CLIENT_END_CERTIFICATE); - assertEquals(expectedCert, ((IkeCertX509CertPayload) certPayload).certificate); - } - - @Test - public void testDecodeX509CertificateWithUnexpectedTrailing() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(CERT_PAYLOAD_BODY_HEX_STRING + "ffff"); - try { - IkeCertPayload.getIkeCertPayload(false, inputPacket); - fail("Expected AuthenticationFailedException: " + "Unexpected trailing bytes."); - } catch (AuthenticationFailedException expected) { - } - } - - @Test - public void testDecodeGetNoX509Certificate() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(CERT_PAYLOAD_BODY_HEX_STRING); - inputPacket[CERTIFICATE_OFFSET] = 0; - try { - IkeCertPayload.getIkeCertPayload(false, inputPacket); - fail("Expected AuthenticationFailedException: " + "No certificate got."); - } catch (AuthenticationFailedException expected) { - } - } - - @Test - public void testDecodeInvalidX509Certificate() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(CERT_PAYLOAD_BODY_HEX_STRING); - try { - IkeCertPayload.getIkeCertPayload( - false, Arrays.copyOfRange(inputPacket, 0, inputPacket.length - 1)); - fail("Expected AuthenticationFailedException: " + "Certificate parsing exception."); - } catch (AuthenticationFailedException expected) { - } - } - - private X509Certificate pemStringToCertificate(String certPemStr) throws Exception { - CertificateFactory factory = - CertificateFactory.getInstance("X.509", IkeMessage.getSecurityProvider()); - Base64.Decoder bs64Decoder = Base64.getDecoder(); - byte[] decodedBytes = bs64Decoder.decode(certPemStr); - return (X509Certificate) - factory.generateCertificate(new ByteArrayInputStream(decodedBytes)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java deleted file mode 100644 index 9fc32229..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java +++ /dev/null @@ -1,631 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -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 com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REPLY; -import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REQUEST; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.net.LinkAddress; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttrIpv4AddressBase; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttrIpv6AddrRangeBase; -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.ConfigAttributeIpv4Dhcp; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns; -import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet; - -import libcore.net.InetAddressUtils; - -import org.junit.Before; -import org.junit.Test; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.LinkedList; -import java.util.List; - -public final class IkeConfigPayloadTest { - private static final String CONFIG_REQ_PAYLOAD_HEX = - "2900001801000000000100000008000000030000000a0000"; - private static final String CONFIG_RESP_PAYLOAD_HEX = - "210000200200000000010004c000026400030004080808080003000408080404"; - private static final String CONFIG_RESP_PAYLOAD_INVALID_ONE_HEX = - "210000200200000000010004c000026400020004fffffffe00020004fffffffe"; - private static final String CONFIG_RESP_PAYLOAD_INVALID_TWO_HEX = - "210000100200000000020004fffffffe"; - - private static final byte[] CONFIG_REQ_PAYLOAD = - TestUtils.hexStringToByteArray(CONFIG_REQ_PAYLOAD_HEX); - private static final byte[] CONFIG_RESP_PAYLOAD = - TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_HEX); - - 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 int IP4_PREFIX_LEN = 28; - private static final LinkAddress IPV4_LINK_ADDRESS = - new LinkAddress(IPV4_ADDRESS, IP4_PREFIX_LEN); - - private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE = - TestUtils.hexStringToByteArray("00010004c0000264"); - private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("00010000"); - - private static final byte[] IPV4_NETMASK_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("00020000"); - - private static final Inet4Address IPV4_DNS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8")); - private static final byte[] IPV4_DNS_ATTRIBUTE_VALUE = - TestUtils.hexStringToByteArray("08080808"); - 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 = - TestUtils.hexStringToByteArray("000d0008c0000264fffffff0"); - private static final byte[] IPV4_SUBNET_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("000d0000"); - - private static final Inet6Address IPV6_ADDRESS = - (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1")); - private static final int IP6_PREFIX_LEN = 64; - private static final LinkAddress IPV6_LINK_ADDRESS = - new LinkAddress(IPV6_ADDRESS, IP6_PREFIX_LEN); - - private static final byte[] IPV6_ADDRESS_ATTRIBUTE_VALUE = - TestUtils.hexStringToByteArray("20010db800000000000000000000000140"); - private static final byte[] IPV6_ADDRESS_ATTRIBUTE_WITH_VALUE = - TestUtils.hexStringToByteArray("0008001120010db800000000000000000000000140"); - private static final byte[] IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("00080000"); - - private static final byte[] IPV6_SUBNET_ATTRIBUTE_VALUE = IPV6_ADDRESS_ATTRIBUTE_VALUE; - private static final byte[] IPV6_SUBNET_ATTRIBUTE_WITH_VALUE = - TestUtils.hexStringToByteArray("000f001120010db800000000000000000000000140"); - private static final byte[] IPV6_SUBNET_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("000f0000"); - - private static final Inet6Address IPV6_DNS = - (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8:100::1")); - private static final byte[] IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE = - TestUtils.hexStringToByteArray("000a0000"); - - private Inet4Address[] mNetMasks; - private int[] mIpv4PrefixLens; - - @Before - public void setUp() throws Exception { - mNetMasks = - new Inet4Address[] { - (Inet4Address) (InetAddressUtils.parseNumericAddress("0.0.0.0")), - (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.255")), - (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.240")) - }; - mIpv4PrefixLens = new int[] {0, 32, 28}; - } - - private IkeConfigPayload verifyDecodeHeaderAndGetPayload( - IkePayload payload, int expectedConfigType) { - assertEquals(PAYLOAD_TYPE_CP, payload.payloadType); - assertFalse(payload.isCritical); - assertTrue(payload instanceof IkeConfigPayload); - - IkeConfigPayload configPayload = (IkeConfigPayload) payload; - assertEquals(expectedConfigType, configPayload.configType); - - return configPayload; - } - - @Test - public void testDecodeConfigRequest() throws Exception { - IkePayload payload = - IkePayloadFactory.getIkePayload( - PAYLOAD_TYPE_CP, - false /*isResp*/, - ByteBuffer.wrap(CONFIG_REQ_PAYLOAD)) - .first; - - IkeConfigPayload configPayload = - verifyDecodeHeaderAndGetPayload(payload, CONFIG_TYPE_REQUEST); - - List<ConfigAttribute> recognizedAttributeList = configPayload.recognizedAttributeList; - assertEquals(4, recognizedAttributeList.size()); - - ConfigAttribute att = recognizedAttributeList.get(0); - assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, att.attributeType); - assertNull(((ConfigAttributeIpv4Address) att).address); - - att = recognizedAttributeList.get(1); - assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, att.attributeType); - assertNull(((ConfigAttributeIpv6Address) att).linkAddress); - - att = recognizedAttributeList.get(2); - assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType); - assertNull(((ConfigAttributeIpv4Dns) att).address); - - att = recognizedAttributeList.get(3); - assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, att.attributeType); - assertNull(((ConfigAttributeIpv6Dns) att).address); - } - - @Test - public void testDecodeConfigResponse() throws Exception { - IkePayload payload = - IkePayloadFactory.getIkePayload( - PAYLOAD_TYPE_CP, - true /*isResp*/, - ByteBuffer.wrap(CONFIG_RESP_PAYLOAD)) - .first; - - IkeConfigPayload configPayload = - verifyDecodeHeaderAndGetPayload(payload, CONFIG_TYPE_REPLY); - - List<ConfigAttribute> recognizedAttributeList = configPayload.recognizedAttributeList; - assertEquals(3, recognizedAttributeList.size()); - - ConfigAttribute att = recognizedAttributeList.get(0); - assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, att.attributeType); - assertEquals(IPV4_ADDRESS, ((ConfigAttributeIpv4Address) att).address); - - att = recognizedAttributeList.get(1); - assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType); - assertEquals(IPV4_DNS, ((ConfigAttributeIpv4Dns) att).address); - - att = recognizedAttributeList.get(2); - InetAddress expectedDns = InetAddress.getByName("8.8.4.4"); - assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType); - assertEquals(expectedDns, ((ConfigAttributeIpv4Dns) att).address); - } - - @Test - public void testDecodeConfigRespWithTwoNetmask() throws Exception { - byte[] configPayloadBytes = - TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_INVALID_ONE_HEX); - try { - IkePayloadFactory.getIkePayload( - PAYLOAD_TYPE_CP, true /*isResp*/, ByteBuffer.wrap(configPayloadBytes)); - fail("Expected to fail because more than on netmask found"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testDecodeConfigRespNetmaskFoundWithoutIpv4Addr() throws Exception { - byte[] configPayloadBytes = - TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_INVALID_TWO_HEX); - try { - IkePayloadFactory.getIkePayload( - PAYLOAD_TYPE_CP, true /*isResp*/, ByteBuffer.wrap(configPayloadBytes)); - fail("Expected to fail because netmask is found without a IPv4 address"); - } catch (InvalidSyntaxException expected) { - } - } - - private ConfigAttribute makeMockAttribute(byte[] encodedAttribute) { - ConfigAttribute mockAttribute = mock(ConfigAttribute.class); - - when(mockAttribute.getAttributeLen()).thenReturn(encodedAttribute.length); - - doAnswer( - (invocation) -> { - ByteBuffer buffer = (ByteBuffer) invocation.getArguments()[0]; - buffer.put(encodedAttribute); - return null; - }) - .when(mockAttribute) - .encodeAttributeToByteBuffer(any(ByteBuffer.class)); - - return mockAttribute; - } - - @Test - public void testBuildAndEncodeOutboundConfig() throws Exception { - List<ConfigAttribute> mockAttributeList = new LinkedList<>(); - mockAttributeList.add(makeMockAttribute(IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE)); - mockAttributeList.add(makeMockAttribute(IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE)); - mockAttributeList.add(makeMockAttribute(IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE)); - mockAttributeList.add(makeMockAttribute(IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE)); - IkeConfigPayload configPayload = new IkeConfigPayload(false /*isReply*/, mockAttributeList); - - assertEquals(PAYLOAD_TYPE_CP, configPayload.payloadType); - assertFalse(configPayload.isCritical); - assertEquals(CONFIG_TYPE_REQUEST, configPayload.configType); - assertEquals(mockAttributeList, configPayload.recognizedAttributeList); - - ByteBuffer buffer = ByteBuffer.allocate(configPayload.getPayloadLength()); - configPayload.encodeToByteBuffer(PAYLOAD_TYPE_NOTIFY, buffer); - assertArrayEquals(CONFIG_REQ_PAYLOAD, buffer.array()); - } - - private void verifyBuildAndEncodeAttributeCommon( - ConfigAttribute attribute, int expectedAttributeType, byte[] expectedEncodedAttribute) { - assertEquals(expectedAttributeType, attribute.attributeType); - - ByteBuffer buffer = ByteBuffer.allocate(attribute.getAttributeLen()); - attribute.encodeAttributeToByteBuffer(buffer); - assertArrayEquals(expectedEncodedAttribute, buffer.array()); - } - - private void verifyEncodeIpv4AddresBaseAttribute( - ConfigAttrIpv4AddressBase attribute, - int expectedAttributeType, - byte[] expectedEncodedAttribute, - Inet4Address expectedAddress) { - verifyBuildAndEncodeAttributeCommon( - attribute, expectedAttributeType, expectedEncodedAttribute); - assertEquals(expectedAddress, attribute.address); - } - - private void verifyEncodeIpv6RangeBaseAttribute( - ConfigAttrIpv6AddrRangeBase attribute, - int expectedAttributeType, - byte[] expectedEncodedAttribute, - LinkAddress expectedLinkAddress) { - verifyBuildAndEncodeAttributeCommon( - attribute, expectedAttributeType, expectedEncodedAttribute); - assertEquals(expectedLinkAddress, attribute.linkAddress); - } - - @Test - public void testDecodeIpv4AddressWithValue() throws Exception { - ConfigAttributeIpv4Address attributeIp4Address = - new ConfigAttributeIpv4Address(IPV4_ADDRESS.getAddress()); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType); - assertEquals(IPV4_ADDRESS, attributeIp4Address.address); - } - - @Test - public void testDecodeIpv4AddressWithoutValue() throws Exception { - ConfigAttributeIpv4Address attributeIp4Address = - new ConfigAttributeIpv4Address(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType); - assertNull(attributeIp4Address.address); - } - - @Test - public void testDecodeIpv4AddressWithInvalidValue() throws Exception { - byte[] invalidValue = new byte[] {1}; - - try { - ConfigAttributeIpv4Address attributeIp4Address = - new ConfigAttributeIpv4Address(invalidValue); - fail("Expected to fail due to invalid attribute value"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testEncodeIpv4AddressWithValue() throws Exception { - ConfigAttributeIpv4Address attributeIp4Address = - new ConfigAttributeIpv4Address(IPV4_ADDRESS); - - verifyEncodeIpv4AddresBaseAttribute( - attributeIp4Address, - CONFIG_ATTR_INTERNAL_IP4_ADDRESS, - IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE, - IPV4_ADDRESS); - } - - @Test - public void testEncodeIpv4AddressWithoutValue() throws Exception { - ConfigAttributeIpv4Address attributeIp4Address = new ConfigAttributeIpv4Address(); - - verifyEncodeIpv4AddresBaseAttribute( - attributeIp4Address, - CONFIG_ATTR_INTERNAL_IP4_ADDRESS, - IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE, - null /*expectedAddress*/); - } - - @Test - public void testDecodeIpv4NetmaskWithValue() throws Exception { - ConfigAttributeIpv4Netmask attribute = - new ConfigAttributeIpv4Netmask(IPV4_NETMASK.getAddress()); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_NETMASK, attribute.attributeType); - assertEquals(IPV4_NETMASK, attribute.address); - } - - @Test - public void testDecodeIpv4NetmaskWithoutValue() throws Exception { - ConfigAttributeIpv4Netmask attribute = new ConfigAttributeIpv4Netmask(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_NETMASK, attribute.attributeType); - assertNull(attribute.address); - } - - @Test - public void testEncodeIpv4Netmask() throws Exception { - ConfigAttributeIpv4Netmask attribute = new ConfigAttributeIpv4Netmask(); - - verifyEncodeIpv4AddresBaseAttribute( - attribute, - CONFIG_ATTR_INTERNAL_IP4_NETMASK, - IPV4_NETMASK_ATTRIBUTE_WITHOUT_VALUE, - null /*expectedAddress*/); - } - - @Test - public void testDecodeIpv4DnsWithValue() throws Exception { - ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns(IPV4_DNS.getAddress()); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, attribute.attributeType); - assertEquals(IPV4_DNS, attribute.address); - } - - @Test - public void testDecodeIpv4DnsWithoutValue() throws Exception { - ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, attribute.attributeType); - assertNull(attribute.address); - } - - @Test - public void testEncodeIpv4Dns() throws Exception { - ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns(); - - verifyEncodeIpv4AddresBaseAttribute( - attribute, - CONFIG_ATTR_INTERNAL_IP4_DNS, - IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE, - null /*expectedAddress*/); - } - - @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); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_SUBNET, attributeIp4Subnet.attributeType); - assertEquals(IPV4_LINK_ADDRESS, attributeIp4Subnet.linkAddress); - } - - @Test - public void testDecodeIpv4SubnetWithoutValue() throws Exception { - ConfigAttributeIpv4Subnet attributeIp4Subnet = new ConfigAttributeIpv4Subnet(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP4_SUBNET, attributeIp4Subnet.attributeType); - assertNull(attributeIp4Subnet.linkAddress); - } - - @Test - public void testDecodeIpv4SubnetWithInvalidValue() throws Exception { - byte[] ipAddress = IPV4_ADDRESS.getAddress(); - ByteBuffer buffer = ByteBuffer.allocate(ipAddress.length * 2); - buffer.put(ipAddress).put(ipAddress); - - try { - new ConfigAttributeIpv4Subnet(buffer.array()); - fail("Expected to fail due to invalid netmask."); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testEncodeIpv4SubnetWithoutValue() throws Exception { - ConfigAttributeIpv4Subnet attributeIp4Subnet = new ConfigAttributeIpv4Subnet(); - - verifyBuildAndEncodeAttributeCommon( - attributeIp4Subnet, - CONFIG_ATTR_INTERNAL_IP4_SUBNET, - IPV4_SUBNET_ATTRIBUTE_WITHOUT_VALUE); - assertNull(attributeIp4Subnet.linkAddress); - } - - @Test - public void testNetmaskToPrefixLen() throws Exception { - for (int i = 0; i < mNetMasks.length; i++) { - assertEquals(mIpv4PrefixLens[i], ConfigAttribute.netmaskToPrefixLen(mNetMasks[i])); - } - } - - @Test - public void testPrefixToNetmaskBytes() throws Exception { - for (int i = 0; i < mIpv4PrefixLens.length; i++) { - assertArrayEquals( - mNetMasks[i].getAddress(), - ConfigAttribute.prefixToNetmaskBytes(mIpv4PrefixLens[i])); - } - } - - @Test - public void testDecodeIpv6AddressWithValue() throws Exception { - ConfigAttributeIpv6Address attributeIp6Address = - new ConfigAttributeIpv6Address(IPV6_ADDRESS_ATTRIBUTE_VALUE); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, attributeIp6Address.attributeType); - assertEquals(IPV6_LINK_ADDRESS, attributeIp6Address.linkAddress); - } - - @Test - public void testDecodeIpv6AddressWithoutValue() throws Exception { - ConfigAttributeIpv6Address attributeIp6Address = - new ConfigAttributeIpv6Address(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, attributeIp6Address.attributeType); - assertNull(attributeIp6Address.linkAddress); - } - - @Test - public void testDecodeIpv6AddressWithInvalidValue() throws Exception { - byte[] invalidValue = new byte[] {1}; - - try { - ConfigAttributeIpv6Address attributeIp6Address = - new ConfigAttributeIpv6Address(invalidValue); - fail("Expected to fail due to invalid attribute value"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testEncodeIpv6AddressWithValue() throws Exception { - ConfigAttributeIpv6Address attributeIp6Address = - new ConfigAttributeIpv6Address(IPV6_LINK_ADDRESS); - - verifyEncodeIpv6RangeBaseAttribute( - attributeIp6Address, - CONFIG_ATTR_INTERNAL_IP6_ADDRESS, - IPV6_ADDRESS_ATTRIBUTE_WITH_VALUE, - IPV6_LINK_ADDRESS); - } - - @Test - public void testEncodeIpv6AddressWithoutValue() throws Exception { - ConfigAttributeIpv6Address attributeIp6Address = new ConfigAttributeIpv6Address(); - - verifyEncodeIpv6RangeBaseAttribute( - attributeIp6Address, - CONFIG_ATTR_INTERNAL_IP6_ADDRESS, - IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE, - null /*expectedLinkAddress*/); - } - - @Test - public void testDecodeIpv6SubnetWithValue() throws Exception { - ConfigAttributeIpv6Subnet attributeIp6Subnet = - new ConfigAttributeIpv6Subnet(IPV6_SUBNET_ATTRIBUTE_VALUE); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_SUBNET, attributeIp6Subnet.attributeType); - assertEquals(IPV6_LINK_ADDRESS, attributeIp6Subnet.linkAddress); - } - - @Test - public void testDecodeIpv6SubnetWithoutValue() throws Exception { - ConfigAttributeIpv6Subnet attributeIp6Subnet = new ConfigAttributeIpv6Subnet(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_SUBNET, attributeIp6Subnet.attributeType); - assertNull(attributeIp6Subnet.linkAddress); - } - - @Test - public void testEncodeIpv6SubnetWithoutValue() throws Exception { - ConfigAttributeIpv6Subnet attributeIp6Subnet = new ConfigAttributeIpv6Subnet(); - - verifyEncodeIpv6RangeBaseAttribute( - attributeIp6Subnet, - CONFIG_ATTR_INTERNAL_IP6_SUBNET, - IPV6_SUBNET_ATTRIBUTE_WITHOUT_VALUE, - null /*expectedLinkAddress*/); - } - - @Test - public void testDecodeIpv6DnsWithValue() throws Exception { - ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns(IPV6_DNS.getAddress()); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, attribute.attributeType); - assertEquals(IPV6_DNS, attribute.address); - } - - @Test - public void testDecodeIpv6DnsWithoutValue() throws Exception { - ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns(new byte[0]); - - assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, attribute.attributeType); - assertNull(attribute.address); - } - - @Test - public void testEncodeIpv6Dns() throws Exception { - ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns(); - - verifyBuildAndEncodeAttributeCommon( - attribute, CONFIG_ATTR_INTERNAL_IP6_DNS, IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE); - assertNull(attribute.address); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java deleted file mode 100644 index 6be5336f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_ESP; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_IKE; -import static com.android.internal.net.ipsec.ike.message.IkePayload.SPI_LEN_IPSEC; -import static com.android.internal.net.ipsec.ike.message.IkePayload.SPI_LEN_NOT_INCLUDED; - -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 com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; - -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.Arrays; - -public final class IkeDeletePayloadTest { - private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000"; - private static final String DELETE_CHILD_PAYLOAD_HEX_STRING = "0000000c030400012ad4c0a2"; - private static final String CHILD_SPI = "2ad4c0a2"; - - private static final String DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING = - "0000001003040002abcdef0120fedcba"; - private static final String[] MULTIPLE_CHILD_SPIS = new String[] {"abcdef01", "20fedcba"}; - - private static final int NUM_CHILD_SPI = 1; - - private static final int PROTOCOL_ID_OFFSET = 4; - private static final int SPI_SIZE_OFFSET = 5; - private static final int NUM_OF_SPI_OFFSET = 6; - - @Test - public void testDecodeDeleteIkePayload() throws Exception { - ByteBuffer inputBuffer = - ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING)); - - IkePayload payload = - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer) - .first; - - assertTrue(payload instanceof IkeDeletePayload); - - IkeDeletePayload deletePayload = (IkeDeletePayload) payload; - assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); - assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, deletePayload.spiSize); - assertEquals(0, deletePayload.numSpi); - assertArrayEquals(new int[0], deletePayload.spisToDelete); - } - - @Test - public void testDecodeDeleteChildPayload() throws Exception { - ByteBuffer inputBuffer = - ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING)); - - IkePayload payload = - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer) - .first; - - assertTrue(payload instanceof IkeDeletePayload); - - IkeDeletePayload deletePayload = (IkeDeletePayload) payload; - assertEquals(IkePayload.PROTOCOL_ID_ESP, deletePayload.protocolId); - assertEquals(IkePayload.SPI_LEN_IPSEC, deletePayload.spiSize); - assertEquals(NUM_CHILD_SPI, deletePayload.numSpi); - - int expectedChildSpi = TestUtils.hexStringToInt(CHILD_SPI); - assertArrayEquals(new int[] {expectedChildSpi}, deletePayload.spisToDelete); - } - - @Test - public void testDecodeWithInvalidProtocol() throws Exception { - byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - deletePayloadBytes[PROTOCOL_ID_OFFSET] = -1; - ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes); - - try { - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer); - fail("Expected to fail due to unrecognized protocol ID."); - } catch (InvalidSyntaxException expected) { - - } - } - - @Test - public void testDecodeWithInvalidSpiSize() throws Exception { - byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - deletePayloadBytes[SPI_SIZE_OFFSET] = IkePayload.SPI_LEN_IPSEC; - ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes); - - try { - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer); - fail("Expected to fail due to invalid SPI size in Delete IKE Payload."); - } catch (InvalidSyntaxException expected) { - - } - } - - @Test - public void testDecodeWithInvalidNumSpi() throws Exception { - byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - deletePayloadBytes[NUM_OF_SPI_OFFSET] = 1; - ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes); - - try { - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer); - fail("Expected to fail because number of SPI is not zero in Delete IKE Payload."); - } catch (InvalidSyntaxException expected) { - - } - } - - @Test - public void testDecodeWithInvalidNumSpiAndSpiSize() throws Exception { - byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - deletePayloadBytes[SPI_SIZE_OFFSET] = 1; - deletePayloadBytes[NUM_CHILD_SPI] = 4; - ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes); - - try { - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer); - fail("Expected to fail due to invalid SPI size in Delete IKE Payload."); - } catch (InvalidSyntaxException expected) { - - } - } - - @Test - public void testOutboundConstructorForIke() throws Exception { - IkeDeletePayload deletePayload = new IkeDeletePayload(); - - assertEquals(PROTOCOL_ID_IKE, deletePayload.protocolId); - assertEquals(SPI_LEN_NOT_INCLUDED, deletePayload.spiSize); - assertEquals(0, deletePayload.numSpi); - assertEquals(0, deletePayload.spisToDelete.length); - } - - @Test - public void testOutboundConstructorWithSingleChildSa() throws Exception { - int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)}; - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - - assertEquals(PROTOCOL_ID_ESP, deletePayload.protocolId); - assertEquals(SPI_LEN_IPSEC, deletePayload.spiSize); - assertEquals(NUM_CHILD_SPI, deletePayload.numSpi); - assertArrayEquals(childSpis, deletePayload.spisToDelete); - } - - @Test - public void testOutboundConstructorWithMultipleChildSas() throws Exception { - int[] childSpis = new int[] {0x1, 0x2, 0xfffffffd, 0xffffffff}; - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - - assertEquals(PROTOCOL_ID_ESP, deletePayload.protocolId); - assertEquals(SPI_LEN_IPSEC, deletePayload.spiSize); - assertEquals(childSpis.length, deletePayload.numSpi); - assertArrayEquals(childSpis, deletePayload.spisToDelete); - } - - @Test - public void testOutboundConstructorWithNoChildSas() throws Exception { - try { - IkeDeletePayload deletePayload = new IkeDeletePayload(new int[] {}); - fail("Expected exception for invalid SPI list"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testEncodeForIke() throws Exception { - IkeDeletePayload deletePayload = new IkeDeletePayload(); - ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength()); - - deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb); - - byte[] expectedPayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedPayloadBytes, bb.array()); - } - - @Test - public void testEncodeWithSingleChildSa() throws Exception { - int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)}; - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength()); - - deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb); - - byte[] expectedPayloadBytes = - TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedPayloadBytes, bb.array()); - } - - @Test - public void testEncodeWithMultipleChildSas() throws Exception { - int[] childSpis = - Arrays.stream(MULTIPLE_CHILD_SPIS) - .mapToInt(val -> TestUtils.hexStringToInt(val)) - .toArray(); - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength()); - - deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb); - - byte[] expectedPayloadBytes = - TestUtils.hexStringToByteArray(DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedPayloadBytes, bb.array()); - } - - @Test - public void testPayloadLengthForIke() throws Exception { - IkeDeletePayload deletePayload = new IkeDeletePayload(); - - byte[] expectedPayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING); - assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength()); - } - - @Test - public void testPayloadLengthWithSingleChildSa() throws Exception { - int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)}; - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - - byte[] expectedPayloadBytes = - TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING); - assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength()); - } - - @Test - public void testPayloadLengthWithMultipleChildSas() throws Exception { - int[] childSpis = - Arrays.stream(MULTIPLE_CHILD_SPIS) - .mapToInt(val -> TestUtils.hexStringToInt(val)) - .toArray(); - IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis); - - byte[] expectedPayloadBytes = - TestUtils.hexStringToByteArray(DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING); - assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java deleted file mode 100644 index fff82b60..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static com.android.internal.net.TestUtils.hexStringToByteArray; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -public class IkeEapPayloadTest { - private static final String EAP_SUCCESS_STRING = "03010004"; - private static final byte[] EAP_SUCCESS_PACKET = hexStringToByteArray(EAP_SUCCESS_STRING); - - private static final byte[] IKE_EAP_PAYLOAD = - hexStringToByteArray( - "00000008" + EAP_SUCCESS_STRING); - - @Test - public void testDecodeIkeEapPayload() throws Exception { - ByteBuffer input = ByteBuffer.wrap(IKE_EAP_PAYLOAD); - IkePayload result = IkePayloadFactory - .getIkePayload(IkePayload.PAYLOAD_TYPE_EAP, true, input).first; - - assertTrue(result instanceof IkeEapPayload); - IkeEapPayload ikeEapPayload = (IkeEapPayload) result; - assertArrayEquals(EAP_SUCCESS_PACKET, ikeEapPayload.eapMessage); - } - - @Test - public void testEncodeToByteBuffer() { - IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET); - ByteBuffer result = ByteBuffer.allocate(IKE_EAP_PAYLOAD.length); - - ikeEapPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, result); - assertArrayEquals(IKE_EAP_PAYLOAD, result.array()); - } - - @Test - public void testOutboundConstructorForIke() { - IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET); - assertArrayEquals(EAP_SUCCESS_PACKET, ikeEapPayload.eapMessage); - } - - @Test - public void testGetPayloadLength() { - IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET); - assertEquals(IKE_EAP_PAYLOAD.length, ikeEapPayload.getPayloadLength()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java deleted file mode 100644 index 36c7648a..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java +++ /dev/null @@ -1,489 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeCombinedModeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; - -import org.junit.Before; -import org.junit.Test; - -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"; - private static final String IKE_AUTH_INIT_REQUEST_IV = "b9132b7bb9f658dfdc648e5017a6322a"; - private static final String IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA = - "030c316ce55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58" - + "46de333ecd3ea2b705d18293b130395300ba92a351041345" - + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f" - + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60" - + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b" - + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423" - + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3" - + "59eb4e81"; - private static final String IKE_AUTH_INIT_REQUEST_CHECKSUM = "ae6e0f22abdad69ba8007d50"; - - private static final String IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA = - "2400000c010000000a50500d2700000c010000000a505050" - + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327" - + "44dfb2c12c00002c00000028010304032ad4c0a20300000c" - + "0100000c800e008003000008030000020000000805000000" - + "2d00001801000000070000100000ffff00000000ffffffff" - + "2900001801000000070000100000ffff00000000ffffffff" - + "29000008000040000000000c0000400100000001"; - private static final String IKE_AUTH_INIT_REQUEST_PADDING = "0000000000000000000000"; - private static final int HMAC_SHA1_CHECKSUM_LEN = 12; - - private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1"; - private static final String INTE_KEY_FROM_INIT_TO_RESP = - "554fbf5a05b7f511e05a30ce23d874db9ef55e51"; - - private static final String ENCR_ALGO_AES_CBC = "AES/CBC/NoPadding"; - - // Test vectors for IKE message protected by HmacSha1 and 3DES - private static final String HMAC_SHA1_3DES_MSG_HEX_STRING = - "5837b1bd28ec424f85ddd0c609c8dbfe2e20232000000002" - + "00000064300000488beaf41d88544baabd95eac60269f19a" - + "5986295fe318ce02f65368cd957985f36b183794c4c78d35" - + "437762297a131a773d7f7806aaa0c590f48b9d71001f4d65" - + "70a44533"; - - private static final String HMAC_SHA1_3DES_DECRYPTED_BODY_HEX_STRING = - "00000028013c00241a013c001f10dac4f8b759138776091dd0f00033c5b07374726f6e675377616e"; - - private static final String HMAC_SHA1_3DES_MSG_ENCR_KEY = - "ee0fdd6d35bbdbe9eeef2f24495b6632e5047bdd8e413c87"; - 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; - - private IkeMacIntegrity mHmacSha1IntegrityMac; - private byte[] mHmacSha1IntegrityKey; - - private byte[] mDataToPadAndEncrypt; - private byte[] mDataToAuthenticate; - private byte[] mEncryptedPaddedData; - private byte[] mIkeMessage; - - private byte[] mChecksum; - private byte[] mIv; - private byte[] mPadding; - - 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 = - TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA); - String hexStringToAuthenticate = - IKE_AUTH_INIT_REQUEST_HEADER - + IKE_AUTH_INIT_REQUEST_SK_HEADER - + IKE_AUTH_INIT_REQUEST_IV - + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA; - mDataToAuthenticate = TestUtils.hexStringToByteArray(hexStringToAuthenticate); - mEncryptedPaddedData = - TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA); - mIkeMessage = - TestUtils.hexStringToByteArray( - IKE_AUTH_INIT_REQUEST_HEADER - + IKE_AUTH_INIT_REQUEST_SK_HEADER - + IKE_AUTH_INIT_REQUEST_IV - + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA - + IKE_AUTH_INIT_REQUEST_CHECKSUM); - - mChecksum = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_CHECKSUM); - 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( - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, - SaProposal.KEY_LEN_AES_128), - IkeMessage.getSecurityProvider()); - mAesCbcKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP); - - mHmacSha1IntegrityMac = - IkeMacIntegrity.create( - 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 - public void testValidateChecksum() throws Exception { - IkeEncryptedPayloadBody.validateInboundChecksumOrThrow( - mDataToAuthenticate, mHmacSha1IntegrityMac, mHmacSha1IntegrityKey, mChecksum); - } - - @Test - public void testThrowForInvalidChecksum() throws Exception { - byte[] dataToAuthenticate = Arrays.copyOf(mDataToAuthenticate, mDataToAuthenticate.length); - dataToAuthenticate[0]++; - - try { - IkeEncryptedPayloadBody.validateInboundChecksumOrThrow( - dataToAuthenticate, mHmacSha1IntegrityMac, mHmacSha1IntegrityKey, mChecksum); - fail("Expected GeneralSecurityException due to mismatched checksum."); - } catch (GeneralSecurityException expected) { - } - } - - @Test - public void testCalculatePaddingPlaintextShorterThanBlockSize() throws Exception { - int blockSize = 16; - int plainTextLength = 15; - int expectedPadLength = 0; - - byte[] calculatedPadding = - IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize); - assertEquals(expectedPadLength, calculatedPadding.length); - } - - @Test - public void testCalculatePaddingPlaintextInBlockSize() throws Exception { - int blockSize = 16; - int plainTextLength = 16; - int expectedPadLength = 15; - - byte[] calculatedPadding = - IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize); - assertEquals(expectedPadLength, calculatedPadding.length); - } - - @Test - public void testCalculatePaddingPlaintextLongerThanBlockSize() throws Exception { - int blockSize = 16; - int plainTextLength = 17; - int expectedPadLength = 14; - - byte[] calculatedPadding = - IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize); - assertEquals(expectedPadLength, calculatedPadding.length); - } - - @Test - public void testEncrypt() throws Exception { - byte[] calculatedData = - IkeEncryptedPayloadBody.normalModeEncrypt( - mDataToPadAndEncrypt, mAesCbcCipher, mAesCbcKey, mIv, mPadding); - - assertArrayEquals(mEncryptedPaddedData, calculatedData); - } - - @Test - public void testDecrypt() throws Exception { - byte[] calculatedPlainText = - IkeEncryptedPayloadBody.normalModeDecrypt( - mEncryptedPaddedData, mAesCbcCipher, mAesCbcKey, mIv); - - assertArrayEquals(mDataToPadAndEncrypt, calculatedPlainText); - } - - @Test - public void testBuildAndEncodeOutboundIkeEncryptedPayloadBody() throws Exception { - IkeHeader ikeHeader = new IkeHeader(mIkeMessage); - - IkeEncryptedPayloadBody payloadBody = - new IkeEncryptedPayloadBody( - ikeHeader, - IkePayload.PAYLOAD_TYPE_ID_INITIATOR, - new byte[0] /*skfHeader*/, - mDataToPadAndEncrypt, - mHmacSha1IntegrityMac, - mAesCbcCipher, - mHmacSha1IntegrityKey, - mAesCbcKey, - mIv, - mPadding); - - byte[] expectedEncodedData = - TestUtils.hexStringToByteArray( - IKE_AUTH_INIT_REQUEST_IV - + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA - + IKE_AUTH_INIT_REQUEST_CHECKSUM); - assertArrayEquals(expectedEncodedData, payloadBody.encode()); - } - - @Test - public void testAuthAndDecodeHmacSha1AesCbc() throws Exception { - IkeEncryptedPayloadBody payloadBody = - new IkeEncryptedPayloadBody( - mIkeMessage, - ENCRYPTED_BODY_SK_OFFSET, - mHmacSha1IntegrityMac, - mAesCbcCipher, - mHmacSha1IntegrityKey, - mAesCbcKey); - - assertArrayEquals(mDataToPadAndEncrypt, payloadBody.getUnencryptedData()); - } - - @Test - public void testAuthAndDecodeHmacSha13Des() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_HEX_STRING); - byte[] expectedDecryptedData = - TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_DECRYPTED_BODY_HEX_STRING); - - IkeEncryptedPayloadBody payloadBody = - new IkeEncryptedPayloadBody( - message, - ENCRYPTED_BODY_SK_OFFSET, - mHmacSha1IntegrityMac, - 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/internal/net/ipsec/ike/message/IkeHeaderTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeHeaderTest.java deleted file mode 100644 index 4592815d..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeHeaderTest.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.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 com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.InvalidMajorVersionException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -public final class IkeHeaderTest { - private static final String IKE_HEADER_HEX_STRING = - "8f54bf6d8b48e6e10000000000000000212022080000000000000150"; - private static final String IKE_SA_INIT_RAW_PACKET = - "8f54bf6d8b48e6e100000000000000002120220800000000" - + "00000150220000300000002c010100040300000c0100000c" - + "800e00800300000803000002030000080400000200000008" - + "020000022800008800020000b4a2faf4bb54878ae21d6385" - + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656" - + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37" - + "534036040610ebdd92f46bef84f0be7db860351843858f8a" - + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb" - + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024" - + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7" - + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb" - + "881eab2051d8663f421d10b02b00001c00004005d915368c" - + "a036004cb578ae3e3fb268509aeab1900000002069936922" - + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500"; - - private static final String IKE_INITIATOR_SPI = "8f54bf6d8b48e6e1"; - private static final String IKE_RESPODNER_SPI = "0000000000000000"; - - @IkePayload.PayloadType - private static final byte IKE_FIRST_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_SA; - - private static final byte IKE_MAJOR_VERSION = 2; - private static final byte IKE_MINOR_VERSION = 0; - - @IkeHeader.ExchangeType - private static final int IKE_EXCHANGE_TYPE = IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT; - - private static final int IKE_MSG_ID = 0; - private static final int IKE_MSG_LENGTH = 336; - private static final int IKE_MSG_BODY_LENGTH = IKE_MSG_LENGTH - IkeHeader.IKE_HEADER_LENGTH; - - // Byte offsets of version field in IKE message header. - private static final int VERSION_OFFSET = 17; - // Byte offsets of exchange type in IKE message header. - private static final int EXCHANGE_TYPE_OFFSET = 18; - // Byte offsets of message length in IKE message header. - private static final int MESSAGE_LENGTH_OFFSET = 24; - - @Test - public void testDecodeIkeHeader() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - IkeHeader header = new IkeHeader(inputPacket); - - assertEquals(IKE_MSG_LENGTH, inputPacket.length); - - long initSpi = Long.parseUnsignedLong(IKE_INITIATOR_SPI, 16); - assertEquals(initSpi, header.ikeInitiatorSpi); - long respSpi = Long.parseUnsignedLong(IKE_RESPODNER_SPI, 16); - assertEquals(respSpi, header.ikeResponderSpi); - - assertEquals(IKE_FIRST_PAYLOAD_TYPE, header.nextPayloadType); - assertEquals(IKE_MAJOR_VERSION, header.majorVersion); - assertEquals(IKE_MINOR_VERSION, header.minorVersion); - assertEquals(IKE_EXCHANGE_TYPE, header.exchangeType); - assertFalse(header.isResponseMsg); - assertTrue(header.fromIkeInitiator); - assertEquals(IKE_MSG_ID, header.messageId); - assertEquals(IKE_MSG_LENGTH, header.getInboundMessageLength()); - } - - @Test - public void testDecodeIkeHeaderWithInvalidMajorVersion() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set major version 3. - inputPacket[VERSION_OFFSET] = (byte) 0x30; - // Set Exchange type 0 - inputPacket[EXCHANGE_TYPE_OFFSET] = (byte) 0x00; - - InvalidMajorVersionException exception = - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg( - inputPacket, InvalidMajorVersionException.class); - - assertEquals(3, exception.getMajorVerion()); - } - - @Test - public void testDecodeIkeHeaderWithInvalidExchangeType() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set Exchange type 0 - inputPacket[EXCHANGE_TYPE_OFFSET] = (byte) 0x00; - - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class); - } - - @Test - public void testDecodeIkeHeaderWithInvalidPacketLength() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set Exchange type 0 - inputPacket[MESSAGE_LENGTH_OFFSET] = (byte) 0x01; - - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class); - } - - @Test - public void testEncodeIkeHeader() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - IkeHeader header = new IkeHeader(inputPacket); - - ByteBuffer byteBuffer = ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH); - header.encodeToByteBuffer(byteBuffer, IKE_MSG_BODY_LENGTH); - - byte[] expectedPacket = TestUtils.hexStringToByteArray(IKE_HEADER_HEX_STRING); - assertArrayEquals(expectedPacket, byteBuffer.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java deleted file mode 100644 index 75552b31..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import android.net.ipsec.ike.IkeFqdnIdentification; -import android.net.ipsec.ike.IkeIdentification; -import android.net.ipsec.ike.IkeIpv4AddrIdentification; -import android.net.ipsec.ike.IkeIpv6AddrIdentification; -import android.net.ipsec.ike.IkeKeyIdIdentification; -import android.net.ipsec.ike.IkeRfc822AddrIdentification; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; - -import org.junit.Test; - -import java.net.Inet4Address; -import java.net.Inet6Address; -import java.nio.ByteBuffer; - -public final class IkeIdPayloadTest { - - private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING = - "2700000c01000000c0000264"; - private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING = "01000000c0000264"; - private static final String IPV4_ADDR_STRING = "192.0.2.100"; - - private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING = - "27000018050000000000200100000db80000000000000001"; - private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING = - "050000000000200100000db80000000000000001"; - private static final String IPV6_ADDR_STRING = "0:2001:0:db8::1"; - - private static final String FQDN_ID_PAYLOAD_HEX_STRING = - "2500001702000000696B652E616E64726F69642E6E6574"; - private static final String FQDN_ID_PAYLOAD_BODY_HEX_STRING = - "02000000696B652E616E64726F69642E6E6574"; - private static final String FQDN = "ike.android.net"; - - private static final String RFC822_ADDR_ID_PAYLOAD_HEX_STRING = - "2500001e03000000616e64726f6964696b65406578616d706c652e636f6d"; - private static final String RFC822_ADDR_ID_PAYLOAD_BODY_HEX_STRING = - "03000000616e64726f6964696b65406578616d706c652e636f6d"; - private static final String RFC822_NAME = "androidike@example.com"; - - private static final String KEY_ID_PAYLOAD_HEX_STRING = - "250000170b000000616E64726F6964496B654B65794964"; - private static final String KEY_ID_PAYLOAD_BODY_HEX_STRING = - "0b000000616E64726F6964496B654B65794964"; - private static final byte[] KEY_ID = "androidIkeKeyId".getBytes(); - - private static final int ID_TYPE_OFFSET = 0; - - @Test - public void testDecodeIpv4AddrIdPayload() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING); - IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false); - - assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType); - assertEquals(IkeIdentification.ID_TYPE_IPV4_ADDR, payload.ikeId.idType); - IkeIpv4AddrIdentification ikeId = (IkeIpv4AddrIdentification) payload.ikeId; - Inet4Address expectedAddr = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING); - assertEquals(expectedAddr, ikeId.ipv4Address); - } - - @Test - public void testDecodeIpv6AddrIdPayload() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING); - IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false); - - assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType); - assertEquals(IkeIdentification.ID_TYPE_IPV6_ADDR, payload.ikeId.idType); - IkeIpv6AddrIdentification ikeId = (IkeIpv6AddrIdentification) payload.ikeId; - Inet6Address expectedAddr = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING); - assertEquals(expectedAddr, ikeId.ipv6Address); - } - - @Test - public void testDecodeFqdnIdPayload() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(FQDN_ID_PAYLOAD_BODY_HEX_STRING); - IkeIdPayload payload = - new IkeIdPayload(false /*critical*/, inputPacket, false /*isInitiator*/); - - assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType); - assertArrayEquals(inputPacket, payload.getEncodedPayloadBody()); - assertEquals(IkeIdentification.ID_TYPE_FQDN, payload.ikeId.idType); - IkeFqdnIdentification ikeId = (IkeFqdnIdentification) payload.ikeId; - assertEquals(FQDN, ikeId.fqdn); - } - - @Test - public void testDecodeRfc822AddrIdPayload() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(RFC822_ADDR_ID_PAYLOAD_BODY_HEX_STRING); - IkeIdPayload payload = - new IkeIdPayload(false /*critical*/, inputPacket, true /*isInitiator*/); - - assertEquals(IkePayload.PAYLOAD_TYPE_ID_INITIATOR, payload.payloadType); - assertEquals(IkeIdentification.ID_TYPE_RFC822_ADDR, payload.ikeId.idType); - IkeRfc822AddrIdentification ikeId = (IkeRfc822AddrIdentification) payload.ikeId; - assertEquals(RFC822_NAME, ikeId.rfc822Name); - } - - @Test - public void testDecodeKeyIdPayload() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(KEY_ID_PAYLOAD_BODY_HEX_STRING); - IkeIdPayload payload = - new IkeIdPayload(false /*critical*/, inputPacket, true /*isInitiator*/); - - assertEquals(IkePayload.PAYLOAD_TYPE_ID_INITIATOR, payload.payloadType); - assertEquals(IkeIdentification.ID_TYPE_KEY_ID, payload.ikeId.idType); - IkeKeyIdIdentification ikeId = (IkeKeyIdIdentification) payload.ikeId; - assertArrayEquals(KEY_ID, ikeId.keyId); - } - - @Test - public void testDecodeUnsupportedIdType() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING); - inputPacket[ID_TYPE_OFFSET] = 0; - - try { - new IkeIdPayload(false, inputPacket, true); - fail("Expected AuthenticationFailedException: ID Type is unsupported."); - } catch (AuthenticationFailedException expected) { - } - } - - @Test - public void testConstructAndEncodeIpv4AddrIdPayload() throws Exception { - Inet4Address ipv4Address = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING); - IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv4AddrIdentification(ipv4Address)); - - ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer); - - byte[] expectedBytes = - TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING); - assertArrayEquals(expectedBytes, inputBuffer.array()); - } - - @Test - public void testConstructAndEncodeIpv6AddrIdPayload() throws Exception { - Inet6Address ipv6Address = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING); - IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv6AddrIdentification(ipv6Address)); - - ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer); - - byte[] expectedBytes = - TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING); - assertArrayEquals(expectedBytes, inputBuffer.array()); - } - - @Test - public void testConstructAndEncodeFqdnIdPayload() throws Exception { - IkeIdPayload payload = - new IkeIdPayload(false /*isInitiator*/, new IkeFqdnIdentification(FQDN)); - - ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(FQDN_ID_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedBytes, inputBuffer.array()); - } - - @Test - public void testConstructAndEncodeRfc822AddrIdPayload() throws Exception { - IkeIdPayload payload = - new IkeIdPayload( - true /*isInitiator*/, new IkeRfc822AddrIdentification(RFC822_NAME)); - - ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(RFC822_ADDR_ID_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedBytes, inputBuffer.array()); - } - - @Test - public void testConstructAndEncodeKeyIdPayload() throws Exception { - IkeIdPayload payload = - new IkeIdPayload(true /*isInitiator*/, new IkeKeyIdIdentification(KEY_ID)); - - ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(KEY_ID_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedBytes, inputBuffer.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java deleted file mode 100644 index f5046dca..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.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 android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.IkeDhParams; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.utils.BigIntegerUtils; - -import org.junit.Before; -import org.junit.Test; - -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.security.GeneralSecurityException; -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"; - - private DHPrivateKeySpec mPrivateKeySpec; - - @Before - public void setUp() 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); - mPrivateKeySpec = new DHPrivateKeySpec(privateKeyValue, primeValue, baseGenValue); - } - - @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 { - byte[] remotePublicKey = TestUtils.hexStringToByteArray(PUBLIC_KEY_REMOTE); - byte[] sharedKeyBytes = IkeKePayload.getSharedKey(mPrivateKeySpec, remotePublicKey); - - byte[] expectedSharedKeyBytes = TestUtils.hexStringToByteArray(EXPECTED_SHARED_KEY); - assertTrue(Arrays.equals(expectedSharedKeyBytes, sharedKeyBytes)); - } - - @Test - public void testGetSharedkeyWithInvalidRemoteKey() throws Exception { - byte[] remotePublicKey = TestUtils.hexStringToByteArray(PRIME_1024_BIT_MODP_160_SUBGROUP); - - try { - byte[] sharedKeyBytes = IkeKePayload.getSharedKey(mPrivateKeySpec, remotePublicKey); - fail("Expected to fail because of invalid remote public key."); - } catch (GeneralSecurityException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java deleted file mode 100644 index 38b41527..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java +++ /dev/null @@ -1,935 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_OK; -import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_PROTECTED_ERROR; -import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_UNPROTECTED_ERROR; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_AUTH; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_ID_INITIATOR; -import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NO_NEXT; -import static com.android.internal.net.ipsec.ike.message.IkeTestUtils.makeDummySkfPayload; - -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.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyBoolean; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.net.ipsec.ike.exceptions.IkeException; -import android.net.ipsec.ike.exceptions.IkeInternalException; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher; -import com.android.internal.net.ipsec.ike.exceptions.InvalidMessageIdException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultError; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial; -import com.android.internal.net.ipsec.ike.message.IkePayloadFactory.IIkePayloadDecoder; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.security.GeneralSecurityException; -import java.util.Arrays; -import java.util.LinkedList; - -import javax.crypto.IllegalBlockSizeException; - -public final class IkeMessageTest { - private static final String IKE_SA_INIT_HEADER_RAW_PACKET = - "8f54bf6d8b48e6e10000000000000000212022080000000000000150"; - private static final String IKE_SA_INIT_BODY_RAW_PACKET = - "220000300000002c010100040300000c0100000c" - + "800e00800300000803000002030000080400000200000008" - + "020000022800008800020000b4a2faf4bb54878ae21d6385" - + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656" - + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37" - + "534036040610ebdd92f46bef84f0be7db860351843858f8a" - + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb" - + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024" - + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7" - + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb" - + "881eab2051d8663f421d10b02b00001c00004005d915368c" - + "a036004cb578ae3e3fb268509aeab1900000002069936922" - + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500"; - private static final String IKE_SA_INIT_RAW_PACKET = - IKE_SA_INIT_HEADER_RAW_PACKET + IKE_SA_INIT_BODY_RAW_PACKET; - - // Byte offsets of first payload type in IKE message header. - private static final int FIRST_PAYLOAD_TYPE_OFFSET = 16; - // Byte offsets of first payload's critical bit in IKE message body. - private static final int PAYLOAD_CRITICAL_BIT_OFFSET = 1; - // Byte offsets of first payload length in IKE message body. - private static final int FIRST_PAYLOAD_LENGTH_OFFSET = 2; - // Byte offsets of last payload length in IKE message body. - private static final int LAST_PAYLOAD_LENGTH_OFFSET = 278; - - private static final String IKE_AUTH_HEADER_HEX_STRING = - "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec"; - private static final String IKE_AUTH_BODY_HEX_STRING = - "230000d0b9132b7bb9f658dfdc648e5017a6322a030c316c" - + "e55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58" - + "46de333ecd3ea2b705d18293b130395300ba92a351041345" - + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f" - + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60" - + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b" - + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423" - + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3" - + "59eb4e81ae6e0f22abdad69ba8007d50"; - - private static final String IKE_AUTH_EXPECTED_CHECKSUM_HEX_STRING = "ae6e0f22abdad69ba8007d50"; - private static final String IKE_AUTH_HEX_STRING = - IKE_AUTH_HEADER_HEX_STRING + IKE_AUTH_BODY_HEX_STRING; - - private static final String IKE_AUTH_UNENCRYPTED_PADDED_DATA_HEX_STRING = - "2400000c010000000a50500d2700000c010000000a505050" - + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327" - + "44dfb2c12c00002c00000028010304032ad4c0a20300000c" - + "0100000c800e008003000008030000020000000805000000" - + "2d00001801000000070000100000ffff00000000ffffffff" - + "2900001801000000070000100000ffff00000000ffffffff" - + "29000008000040000000000c000040010000000100000000" - + "000000000000000b"; - - private static final String IKE_FRAG_HEX_STRING = - "939ae1251d18eb9077a99551b15c6e9335202320000000010000" - + "00c0000000a400020002fd7c7931705af184b7be76bbd45a" - + "8ecbb3ffd58b9438b93f67e9fe86b06229f80e9b52d2ff6a" - + "fde3f2c13ae93ce55a801f62e1a818c9003880a36bbe986f" - + "e6979ba233b9f4f0ddc992d06dbad5a2b998be18fae947e5" - + "ccfb37775d069344e711fbf499bb289cf4cca245bd450ad8" - + "9d18689207759507ba18d47247e920b9e000a25a7596e413" - + "0929e5cdc37d5c1b0d90bbaae946c260f4d3cf815f6d"; - private static final String ID_INIT_PAYLOAD_HEX_STRING = "2400000c010000000a50500d"; - private static final String ID_RESP_PAYLOAD_HEX_STRING = "0000000c010000000a505050"; - - private static final long INIT_SPI = 0x5f54bf6d8b48e6e1L; - private static final long RESP_SPI = 0x909232b3d1edcb5cL; - private static final String IKE_EMPTY_INFO_MSG_HEX_STRING = - "5f54bf6d8b48e6e1909232b3d1edcb5c2e20252800000000" - + "0000004c00000030e376871750fdba9f7012446c5dc3f97a" - + "f83b48ba0dbc68bcc4a78136832100aa4192f251cd4d1b97" - + "d298e550"; - private static final String IKE_EMPTY_INFO_MSG_IV_HEX_STRING = - "e376871750fdba9f7012446c5dc3f97a"; - private static final String IKE_EMPTY_INFO_MSG_ENCRYPTED_DATA_HEX_STRING = - "f83b48ba0dbc68bcc4a78136832100aa"; - private static final String IKE_EMPTY_INFO_MSG_CHECKSUM_HEX_STRING = "4192f251cd4d1b97d298e550"; - - private static final byte[] FRAGMENT_ONE_UNENCRYPTED_DATA = "fragmentOne".getBytes(); - private static final byte[] FRAGMENT_TWO_UNENCRYPTED_DATA = "fragmentTwo".getBytes(); - - private static final int TOTAL_FRAGMENTS = 2; - private static final int FRAGMENT_NUM_ONE = 1; - private static final int FRAGMENT_NUM_TWO = 2; - - private static final int IKE_FRAG_EXPECTED_MESSAGE_ID = 1; - - private static final int IKE_AUTH_EXPECTED_MESSAGE_ID = 1; - private static final int IKE_AUTH_CIPHER_IV_SIZE = 16; - private static final int IKE_AUTH_CIPHER_BLOCK_SIZE = 16; - private static final int IKE_AUTH_PAYLOAD_SIZE = 8; - - private byte[] mIkeAuthPacket; - private byte[] mUnencryptedPaddedData; - private IkeHeader mIkeAuthHeader; - - private IIkePayloadDecoder mSpyIkePayloadDecoder; - - private IkeMacIntegrity mMockIntegrity; - private IkeNormalModeCipher mMockCipher; - private IkeSaRecord mMockIkeSaRecord; - - private byte[] mIkeFragPacketOne; - private byte[] mIkeFragPacketTwo; - private IkeHeader mFragOneHeader; - private IkeHeader mFragTwoHeader; - - private IkeSkfPayload mDummySkfPayloadOne; - private IkeSkfPayload mDummySkfPayloadTwo; - - private static final int[] EXPECTED_IKE_INIT_PAYLOAD_LIST = { - IkePayload.PAYLOAD_TYPE_SA, - IkePayload.PAYLOAD_TYPE_KE, - IkePayload.PAYLOAD_TYPE_NONCE, - IkePayload.PAYLOAD_TYPE_NOTIFY, - IkePayload.PAYLOAD_TYPE_NOTIFY, - IkePayload.PAYLOAD_TYPE_VENDOR - }; - - class TestIkeSupportedPayload extends IkePayload { - TestIkeSupportedPayload(int payload, boolean critical) { - super(payload, critical); - } - - @Override - protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) { - throw new UnsupportedOperationException( - "It is not supported to encode " + getTypeString()); - } - - @Override - protected int getPayloadLength() { - throw new UnsupportedOperationException( - "It is not supported to get payload length of " + getTypeString()); - } - - @Override - public String getTypeString() { - return "Test(" + payloadType + ")"; - } - } - - @Before - public void setUp() throws Exception { - mSpyIkePayloadDecoder = spy(new IkePayloadFactory.IkePayloadDecoder()); - doAnswer( - (invocation) -> { - int payloadType = (int) invocation.getArguments()[0]; - boolean isCritical = (boolean) invocation.getArguments()[1]; - if (support(payloadType)) { - return new TestIkeSupportedPayload(payloadType, isCritical); - } - return new IkeUnsupportedPayload(payloadType, isCritical); - }) - .when(mSpyIkePayloadDecoder) - .decodeIkePayload(anyInt(), anyBoolean(), anyBoolean(), any()); - - IkePayloadFactory.sDecoderInstance = mSpyIkePayloadDecoder; - - mIkeAuthPacket = TestUtils.hexStringToByteArray(IKE_AUTH_HEX_STRING); - mUnencryptedPaddedData = - TestUtils.hexStringToByteArray(IKE_AUTH_UNENCRYPTED_PADDED_DATA_HEX_STRING); - mIkeAuthHeader = new IkeHeader(mIkeAuthPacket); - - mMockIntegrity = mock(IkeMacIntegrity.class); - byte[] expectedChecksum = - TestUtils.hexStringToByteArray(IKE_AUTH_EXPECTED_CHECKSUM_HEX_STRING); - when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(expectedChecksum); - when(mMockIntegrity.getChecksumLen()).thenReturn(expectedChecksum.length); - - mMockCipher = mock(IkeNormalModeCipher.class); - when(mMockCipher.getIvLen()).thenReturn(IKE_AUTH_CIPHER_IV_SIZE); - when(mMockCipher.getBlockSize()).thenReturn(IKE_AUTH_CIPHER_BLOCK_SIZE); - when(mMockCipher.decrypt(any(), any(), any())).thenReturn(mUnencryptedPaddedData); - - mMockIkeSaRecord = mock(IkeSaRecord.class); - when(mMockIkeSaRecord.getInboundDecryptionKey()).thenReturn(new byte[0]); - when(mMockIkeSaRecord.getInboundIntegrityKey()).thenReturn(new byte[0]); - - mIkeFragPacketOne = makeFragmentBytes(1 /*fragNum*/, 2 /*totalFragments*/); - mIkeFragPacketTwo = makeFragmentBytes(2 /*fragNum*/, 2 /*totalFragments*/); - - mFragOneHeader = new IkeHeader(mIkeFragPacketOne); - mFragTwoHeader = new IkeHeader(mIkeFragPacketTwo); - - mDummySkfPayloadOne = - makeDummySkfPayload( - FRAGMENT_ONE_UNENCRYPTED_DATA, FRAGMENT_NUM_ONE, TOTAL_FRAGMENTS); - mDummySkfPayloadTwo = - makeDummySkfPayload( - FRAGMENT_TWO_UNENCRYPTED_DATA, FRAGMENT_NUM_TWO, TOTAL_FRAGMENTS); - } - - private byte[] makeFragmentBytes(int fragNum, int totalFragments) { - byte[] packet = TestUtils.hexStringToByteArray(IKE_FRAG_HEX_STRING); - ByteBuffer byteBuffer = ByteBuffer.wrap(packet); - byteBuffer.get(new byte[IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH]); - - byteBuffer.putShort((short) fragNum).putShort((short) totalFragments); - return byteBuffer.array(); - } - - @After - public void tearDown() { - IkePayloadFactory.sDecoderInstance = new IkePayloadFactory.IkePayloadDecoder(); - } - - private IkeMessage verifyDecodeResultOkAndGetMessage( - DecodeResult decodeResult, byte[] firstPacket) throws Exception { - assertEquals(DECODE_STATUS_OK, decodeResult.status); - - DecodeResultOk resultOk = (DecodeResultOk) decodeResult; - assertNotNull(resultOk.ikeMessage); - assertArrayEquals(firstPacket, resultOk.firstPacket); - - return resultOk.ikeMessage; - } - - private IkeException verifyDecodeResultErrorAndGetIkeException( - DecodeResult decodeResult, int decodeStatus, byte[] firstPacket) throws Exception { - assertEquals(decodeStatus, decodeResult.status); - - DecodeResultError resultError = (DecodeResultError) decodeResult; - assertNotNull(resultError.ikeException); - - return resultError.ikeException; - } - - @Test - public void testDecodeIkeMessage() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - IkeHeader header = new IkeHeader(inputPacket); - - DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket); - - IkeMessage message = verifyDecodeResultOkAndGetMessage(decodeResult, inputPacket); - - assertEquals(EXPECTED_IKE_INIT_PAYLOAD_LIST.length, message.ikePayloadList.size()); - for (int i = 0; i < EXPECTED_IKE_INIT_PAYLOAD_LIST.length; i++) { - assertEquals( - EXPECTED_IKE_INIT_PAYLOAD_LIST[i], message.ikePayloadList.get(i).payloadType); - } - } - - @Test - public void testDecodeMessageWithUnsupportedUncriticalPayload() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set first payload unsupported uncritical - inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff; - IkeHeader header = new IkeHeader(inputPacket); - - DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket); - - IkeMessage message = verifyDecodeResultOkAndGetMessage(decodeResult, inputPacket); - - assertEquals(EXPECTED_IKE_INIT_PAYLOAD_LIST.length - 1, message.ikePayloadList.size()); - for (int i = 0; i < EXPECTED_IKE_INIT_PAYLOAD_LIST.length - 1; i++) { - assertEquals( - EXPECTED_IKE_INIT_PAYLOAD_LIST[i + 1], - message.ikePayloadList.get(i).payloadType); - } - } - - @Test - public void testThrowUnsupportedCriticalPayloadException() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set first payload unsupported critical - inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff; - inputPacket[IkeHeader.IKE_HEADER_LENGTH + PAYLOAD_CRITICAL_BIT_OFFSET] = (byte) 0x80; - - UnsupportedCriticalPayloadException exception = - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg( - inputPacket, UnsupportedCriticalPayloadException.class); - - assertEquals(1, exception.payloadTypeList.size()); - } - - @Test - public void testDecodeMessageWithTooShortPayloadLength() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Set first payload length to 0 - inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET] = (byte) 0; - inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET + 1] = (byte) 0; - - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class); - } - - @Test - public void testDecodeMessageWithTooLongPayloadLength() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - // Increase last payload length by one byte - inputPacket[IkeHeader.IKE_HEADER_LENGTH + LAST_PAYLOAD_LENGTH_OFFSET]++; - - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class); - } - - @Test - public void testDecodeMessageWithUnexpectedBytesInTheEnd() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET + "0000"); - - IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class); - } - - @Test - public void testDecodeEncryptedMessage() throws Exception { - DecodeResult decodeResult = - IkeMessage.decode( - IKE_AUTH_EXPECTED_MESSAGE_ID, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - mIkeAuthHeader, - mIkeAuthPacket, - null /*collectedFragments*/); - IkeMessage ikeMessage = verifyDecodeResultOkAndGetMessage(decodeResult, mIkeAuthPacket); - - assertEquals(IKE_AUTH_PAYLOAD_SIZE, ikeMessage.ikePayloadList.size()); - } - - @Test - public void testDecodeEncryptedMessageWithWrongId() throws Exception { - DecodeResult decodeResult = - IkeMessage.decode( - 2, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - mIkeAuthHeader, - mIkeAuthPacket, - null /*collectedFragments*/); - IkeException ikeException = - verifyDecodeResultErrorAndGetIkeException( - decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket); - - assertTrue(ikeException instanceof InvalidMessageIdException); - } - - @Test - public void testDecodeEncryptedMessageWithWrongChecksum() throws Exception { - when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(new byte[0]); - - DecodeResult decodeResult = - IkeMessage.decode( - IKE_AUTH_EXPECTED_MESSAGE_ID, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - mIkeAuthHeader, - mIkeAuthPacket, - null /*collectedFragments*/); - IkeException ikeException = - verifyDecodeResultErrorAndGetIkeException( - decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket); - - assertTrue( - ((IkeInternalException) ikeException).getCause() - instanceof GeneralSecurityException); - } - - @Test - public void testDecryptFail() throws Exception { - when(mMockCipher.decrypt(any(), any(), any())).thenThrow(IllegalBlockSizeException.class); - - DecodeResult decodeResult = - IkeMessage.decode( - IKE_AUTH_EXPECTED_MESSAGE_ID, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - mIkeAuthHeader, - mIkeAuthPacket, - null /*collectedFragments*/); - - IkeException ikeException = - verifyDecodeResultErrorAndGetIkeException( - decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket); - assertTrue( - ((IkeInternalException) ikeException).getCause() - instanceof IllegalBlockSizeException); - } - - @Test - public void testParsingErrorInEncryptedMessage() throws Exception { - // Set first payload length to 0 - byte[] decryptedData = - Arrays.copyOfRange(mUnencryptedPaddedData, 0, mUnencryptedPaddedData.length); - decryptedData[FIRST_PAYLOAD_LENGTH_OFFSET] = (byte) 0; - decryptedData[FIRST_PAYLOAD_LENGTH_OFFSET + 1] = (byte) 0; - when(mMockCipher.decrypt(any(), any(), any())).thenReturn(decryptedData); - - DecodeResult decodeResult = - IkeMessage.decode( - IKE_AUTH_EXPECTED_MESSAGE_ID, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - mIkeAuthHeader, - mIkeAuthPacket, - null /*collectedFragments*/); - IkeException ikeException = - verifyDecodeResultErrorAndGetIkeException( - decodeResult, DECODE_STATUS_PROTECTED_ERROR, mIkeAuthPacket); - - assertTrue(ikeException instanceof InvalidSyntaxException); - } - - private boolean support(int payloadType) { - // Supports all payload typs from 33 to 46 - return (payloadType >= 33 && payloadType <= 46); - } - - @Test - public void testAttachEncodedHeader() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET); - byte[] ikeBodyBytes = TestUtils.hexStringToByteArray(IKE_SA_INIT_BODY_RAW_PACKET); - IkeHeader header = new IkeHeader(inputPacket); - IkeMessage message = - ((DecodeResultOk) IkeMessage.decode(0, header, inputPacket)).ikeMessage; - - byte[] encodedIkeMessage = message.attachEncodedHeader(ikeBodyBytes); - assertArrayEquals(inputPacket, encodedIkeMessage); - } - - @Test - public void testEncodeAndEncryptEmptyMsg() throws Exception { - when(mMockCipher.generateIv()) - .thenReturn(TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_IV_HEX_STRING)); - when(mMockCipher.encrypt(any(), any(), any())) - .thenReturn( - TestUtils.hexStringToByteArray( - IKE_EMPTY_INFO_MSG_ENCRYPTED_DATA_HEX_STRING)); - - byte[] checkSum = TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_CHECKSUM_HEX_STRING); - when(mMockIntegrity.getChecksumLen()).thenReturn(checkSum.length); - when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(checkSum); - - IkeHeader ikeHeader = - new IkeHeader( - INIT_SPI, - RESP_SPI, - IkePayload.PAYLOAD_TYPE_SK, - IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, - true /*isResp*/, - true /*fromInit*/, - 0); - IkeMessage ikeMessage = new IkeMessage(ikeHeader, new LinkedList<>()); - - byte[][] ikeMessageBytes = - ikeMessage.encryptAndEncode( - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - true /*supportFragment*/, - 1280 /*fragSize*/); - byte[][] expectedBytes = - new byte[][] {TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_HEX_STRING)}; - - assertArrayEquals(expectedBytes, ikeMessageBytes); - } - - private DecodeResultPartial makeDecodeResultForFragOne(DecodeResultPartial collectedFrags) { - return new DecodeResultPartial( - mFragOneHeader, - mIkeFragPacketOne, - mDummySkfPayloadOne, - PAYLOAD_TYPE_AUTH, - collectedFrags); - } - - private DecodeResultPartial makeDecodeResultForFragTwo(DecodeResultPartial collectedFrags) { - return new DecodeResultPartial( - mFragTwoHeader, - mIkeFragPacketTwo, - mDummySkfPayloadTwo, - PAYLOAD_TYPE_NO_NEXT, - collectedFrags); - } - - @Test - public void testConstructDecodePartialFirstFragArriveFirst() throws Exception { - DecodeResultPartial resultPartial = makeDecodeResultForFragOne(null /*collectedFragments*/); - - assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType); - assertArrayEquals(mIkeFragPacketOne, resultPartial.firstFragBytes); - assertEquals(mFragOneHeader, resultPartial.ikeHeader); - - assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length); - assertArrayEquals( - FRAGMENT_ONE_UNENCRYPTED_DATA, - resultPartial.collectedFragsList[FRAGMENT_NUM_ONE - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - } - - @Test - public void testConstructDecodePartialSecondFragArriveFirst() throws Exception { - DecodeResultPartial resultPartial = makeDecodeResultForFragTwo(null /*collectedFragments*/); - - assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType); - assertNull(resultPartial.firstFragBytes); - assertEquals(mFragTwoHeader, resultPartial.ikeHeader); - - assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length); - assertArrayEquals( - FRAGMENT_TWO_UNENCRYPTED_DATA, - resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - } - - @Test - public void testConstructDecodeResultPartialWithCollectedFrags() throws Exception { - DecodeResultPartial resultPartialIncomplete = - makeDecodeResultForFragTwo(null /*collectedFragments*/); - DecodeResultPartial resultPartialComplete = - makeDecodeResultForFragOne(resultPartialIncomplete); - - assertEquals(PAYLOAD_TYPE_AUTH, resultPartialComplete.firstPayloadType); - assertArrayEquals(mIkeFragPacketOne, resultPartialComplete.firstFragBytes); - assertEquals(mFragTwoHeader, resultPartialComplete.ikeHeader); - - assertEquals(TOTAL_FRAGMENTS, resultPartialComplete.collectedFragsList.length); - assertTrue(resultPartialComplete.isAllFragmentsReceived()); - } - - @Test - public void testReassembleAllFrags() throws Exception { - DecodeResultPartial resultPartialIncomplete = - makeDecodeResultForFragOne(null /*collectedFragments*/); - DecodeResultPartial resultPartialComplete = - makeDecodeResultForFragTwo(resultPartialIncomplete); - - assertEquals(PAYLOAD_TYPE_AUTH, resultPartialIncomplete.firstPayloadType); - assertArrayEquals(mIkeFragPacketOne, resultPartialIncomplete.firstFragBytes); - assertEquals(mFragOneHeader, resultPartialIncomplete.ikeHeader); - - assertEquals(TOTAL_FRAGMENTS, resultPartialIncomplete.collectedFragsList.length); - assertTrue(resultPartialIncomplete.isAllFragmentsReceived()); - - // Verify reassembly result - ByteBuffer expectedBuffer = - ByteBuffer.allocate( - FRAGMENT_ONE_UNENCRYPTED_DATA.length - + FRAGMENT_TWO_UNENCRYPTED_DATA.length); - expectedBuffer.put(FRAGMENT_ONE_UNENCRYPTED_DATA).put(FRAGMENT_TWO_UNENCRYPTED_DATA); - - byte[] reassembledBytes = resultPartialComplete.reassembleAllFrags(); - assertArrayEquals(expectedBuffer.array(), reassembledBytes); - } - - @Test - public void testReassembleIncompleteFragmentsThrows() throws Exception { - DecodeResultPartial resultPartial = makeDecodeResultForFragTwo(null /*collectedFragments*/); - - assertFalse(resultPartial.isAllFragmentsReceived()); - - try { - resultPartial.reassembleAllFrags(); - fail("Expected to fail because reassembly is not done"); - } catch (IllegalStateException expected) { - - } - } - - private void setDecryptSkfPayload(IkeSkfPayload skf) throws Exception { - doReturn(skf) - .when(mSpyIkePayloadDecoder) - .decodeIkeSkPayload( - eq(true), - anyBoolean(), - any(), - eq(mMockIntegrity), - eq(mMockCipher), - any(), - any()); - } - - private DecodeResult decodeSkf( - int expectedMsgId, - IkeHeader header, - byte[] packet, - DecodeResultPartial collectFragments) - throws Exception { - return IkeMessage.decode( - expectedMsgId, - mMockIntegrity, - mMockCipher, - mMockIkeSaRecord, - header, - packet, - collectFragments); - } - - @Test - public void testRcvFirstArrivedFrag() throws Exception { - setDecryptSkfPayload(mDummySkfPayloadTwo); - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID, - mFragTwoHeader, - mIkeFragPacketTwo, - null /* collectedFragments*/); - - // Verify decoding result - assertTrue(decodeResult instanceof DecodeResultPartial); - DecodeResultPartial resultPartial = (DecodeResultPartial) decodeResult; - - assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType); - assertNull(resultPartial.firstFragBytes); - assertEquals(mFragTwoHeader, resultPartial.ikeHeader); - - assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length); - assertArrayEquals( - FRAGMENT_TWO_UNENCRYPTED_DATA, - resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - } - - @Test - public void testRcvLastArrivedFrag() throws Exception { - // Create two dummy SKF Payloads so that the complete unencrypted data is two ID payloads - byte[] idInitPayloadBytes = TestUtils.hexStringToByteArray(ID_INIT_PAYLOAD_HEX_STRING); - byte[] idRespPayloadBytes = TestUtils.hexStringToByteArray(ID_RESP_PAYLOAD_HEX_STRING); - IkeSkfPayload skfOne = - makeDummySkfPayload(idInitPayloadBytes, FRAGMENT_NUM_ONE, TOTAL_FRAGMENTS); - IkeSkfPayload skfTwo = - makeDummySkfPayload(idRespPayloadBytes, FRAGMENT_NUM_TWO, TOTAL_FRAGMENTS); - - DecodeResultPartial resultPartialIncomplete = - new DecodeResultPartial( - mFragOneHeader, - mIkeFragPacketOne, - skfOne, - PAYLOAD_TYPE_ID_INITIATOR, - null /* collectedFragments*/); - - setDecryptSkfPayload(skfTwo); - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID, - mFragTwoHeader, - mIkeFragPacketTwo, - resultPartialIncomplete); - - // Verify fragments reassembly has been finished and complete message has been decoded. - assertTrue(decodeResult instanceof DecodeResultOk); - DecodeResultOk resultOk = (DecodeResultOk) decodeResult; - assertArrayEquals(mIkeFragPacketOne, resultOk.firstPacket); - assertEquals(2, resultOk.ikeMessage.ikePayloadList.size()); - } - - @Test - public void testRcvFirstArrivedFragWithUnprotectedError() throws Exception { - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID + 1, - mFragTwoHeader, - mIkeFragPacketTwo, - null /* collectedFragments*/); - - // Verify that unprotected error was returned - IkeException ikeException = - verifyDecodeResultErrorAndGetIkeException( - decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket); - assertTrue(ikeException instanceof InvalidMessageIdException); - } - - @Test - public void testRcvLastArrivedFragWithUnprotectedError() throws Exception { - DecodeResultPartial resultPartialIncomplete = - makeDecodeResultForFragOne(null /* collectedFragments*/); - - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID + 1, - mFragTwoHeader, - mIkeFragPacketTwo, - resultPartialIncomplete); - - // Verify that newly received fragment was discarded - assertEquals(resultPartialIncomplete, decodeResult); - } - - @Test - public void testRcvFragWithLargerTotalFragments() throws Exception { - DecodeResultPartial resultPartialIncomplete = - new DecodeResultPartial( - mFragOneHeader, - mIkeFragPacketOne, - mDummySkfPayloadOne, - PAYLOAD_TYPE_NO_NEXT, - null /* collectedFragments*/); - - // Set total fragments of inbound fragment to 5 - int totalFragments = 5; - byte[] fragPacket = makeFragmentBytes(2 /*fragNum*/, totalFragments); - - byte[] unencryptedData = "testRcvFragWithLargerTotalFragments".getBytes(); - IkeSkfPayload skfPayload = - makeDummySkfPayload(unencryptedData, FRAGMENT_NUM_TWO, totalFragments); - setDecryptSkfPayload(skfPayload); - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID, - mFragTwoHeader, - fragPacket, - resultPartialIncomplete); - - // Verify that previously collected fragments were all discarded - assertTrue(decodeResult instanceof DecodeResultPartial); - DecodeResultPartial resultPartial = (DecodeResultPartial) decodeResult; - - assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType); - assertNull(resultPartial.firstFragBytes); - assertEquals(mFragTwoHeader, resultPartial.ikeHeader); - - assertEquals(totalFragments, resultPartial.collectedFragsList.length); - assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]); - assertFalse(resultPartial.isAllFragmentsReceived()); - } - - @Test - public void testRcvFragWithSmallerTotalFragments() throws Exception { - int totalFragments = 5; - byte[] unencryptedData = "testRcvFragWithSmallerTotalFragments".getBytes(); - IkeSkfPayload skfPayload = - makeDummySkfPayload(unencryptedData, FRAGMENT_NUM_ONE, totalFragments); - - DecodeResultPartial resultPartialIncomplete = - new DecodeResultPartial( - mFragOneHeader, - mIkeFragPacketOne, - skfPayload, - PAYLOAD_TYPE_AUTH, - null /* collectedFragments*/); - - setDecryptSkfPayload(mDummySkfPayloadTwo); - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID, - mFragTwoHeader, - mIkeFragPacketTwo, - resultPartialIncomplete); - - // Verify that newly received fragment was discarded - assertEquals(resultPartialIncomplete, decodeResult); - } - - @Test - public void testRcvReplayFrag() throws Exception { - DecodeResultPartial resultPartialIncomplete = - makeDecodeResultForFragTwo(null /* collectedFragments*/); - - setDecryptSkfPayload(mDummySkfPayloadTwo); - DecodeResult decodeResult = - decodeSkf( - IKE_FRAG_EXPECTED_MESSAGE_ID, - mFragTwoHeader, - mIkeFragPacketTwo, - resultPartialIncomplete); - - // Verify that newly received fragment was discarded - assertEquals(resultPartialIncomplete, decodeResult); - } - - @Test - public void testRcvCompleteMessageDuringReassembly() throws Exception { - DecodeResultPartial resultPartialIncomplete = - makeDecodeResultForFragTwo(null /* collectedFragments*/); - - DecodeResult decodeResult = - decodeSkf( - IKE_AUTH_EXPECTED_MESSAGE_ID, - mIkeAuthHeader, - mIkeAuthPacket, - resultPartialIncomplete); - - // Verify that newly received IKE message was discarded - assertEquals(resultPartialIncomplete, decodeResult); - } - - @Test - public void testEncodeAndEncryptFragments() throws Exception { - int messageId = 1; - int fragSize = 140; - int expectedTotalFragments = 3; - - byte[] integrityKey = new byte[0]; - byte[] encryptionKey = new byte[0]; - byte[] iv = new byte[IKE_AUTH_CIPHER_IV_SIZE]; - - when(mMockCipher.generateIv()).thenReturn(iv); - when(mMockCipher.encrypt(any(), any(), any())) - .thenAnswer( - (invocation) -> { - return (byte[]) invocation.getArguments()[0]; - }); - - IkeHeader ikeHeader = - new IkeHeader( - INIT_SPI, - RESP_SPI, - IkePayload.PAYLOAD_TYPE_SK, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - true /*isResp*/, - false /*fromInit*/, - messageId); - - byte[][] packetList = - new IkeMessage.IkeMessageHelper() - .encryptAndEncode( - ikeHeader, - IkePayload.PAYLOAD_TYPE_AUTH, - mUnencryptedPaddedData, - mMockIntegrity, - mMockCipher, - integrityKey, - encryptionKey, - true /*supportFragment*/, - fragSize); - - assertEquals(expectedTotalFragments, packetList.length); - - IkeHeader expectedIkeHeader = - new IkeHeader( - INIT_SPI, - RESP_SPI, - IkePayload.PAYLOAD_TYPE_SKF, - IkeHeader.EXCHANGE_TYPE_IKE_AUTH, - true /*isResp*/, - false /*fromInit*/, - messageId); - for (int i = 0; i < packetList.length; i++) { - byte[] p = packetList[i]; - - // Verify fragment length - assertNotNull(p); - assertTrue(p.length <= fragSize); - - ByteBuffer packetBuffer = ByteBuffer.wrap(p); - - // Verify IKE header - byte[] headerBytes = new byte[IkeHeader.IKE_HEADER_LENGTH]; - packetBuffer.get(headerBytes); - - ByteBuffer expectedHeadBuffer = ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH); - expectedIkeHeader.encodeToByteBuffer( - expectedHeadBuffer, p.length - IkeHeader.IKE_HEADER_LENGTH); - - assertArrayEquals(expectedHeadBuffer.array(), headerBytes); - - // Verify fragment payload header - packetBuffer.get(new byte[IkePayload.GENERIC_HEADER_LENGTH]); - assertEquals(i + 1 /*expetced fragNum*/, Short.toUnsignedInt(packetBuffer.getShort())); - assertEquals(expectedTotalFragments, Short.toUnsignedInt(packetBuffer.getShort())); - } - - verify(mMockCipher, times(expectedTotalFragments + 1)) - .encrypt(any(), eq(encryptionKey), eq(iv)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java deleted file mode 100644 index dd92a45e..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; - -import com.android.internal.net.TestUtils; - -import org.junit.Test; - -import java.nio.ByteBuffer; - -public final class IkeNoncePayloadTest { - - private static final String NONCE_PAYLOAD_RAW_HEX_STRING = - "29000024c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; - private static final String NONCE_DATA_RAW_HEX_STRING = - "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; - - @IkePayload.PayloadType - private static final int NEXT_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_NOTIFY; - - @Test - public void testEncode() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(NONCE_DATA_RAW_HEX_STRING); - IkeNoncePayload payload = new IkeNoncePayload(false, inputPacket); - - ByteBuffer byteBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(NEXT_PAYLOAD_TYPE, byteBuffer); - - byte[] expectedNoncePayload = - TestUtils.hexStringToByteArray(NONCE_PAYLOAD_RAW_HEX_STRING); - assertArrayEquals(expectedNoncePayload, byteBuffer.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java deleted file mode 100644 index 884c76eb..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; -import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD; -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 static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import android.net.ipsec.ike.SaProposal; -import android.net.ipsec.ike.exceptions.IkeProtocolException; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.exceptions.UnrecognizedIkeProtocolException; - -import org.junit.Test; - -import java.net.InetAddress; -import java.nio.ByteBuffer; - -public final class IkeNotifyPayloadTest { - private static final String NOTIFY_NAT_DETECTION_PAYLOAD_HEX_STRING = - "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0"; - private static final String NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING = - "00004004e54f73b7d83f6beb881eab2051d8663f421d10b0"; - private static final String NAT_DETECTION_DATA_HEX_STRING = - "e54f73b7d83f6beb881eab2051d8663f421d10b0"; - - private static final String NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING = "030440092ad4c0a2"; - private static final int REKEY_SPI = 0x2ad4c0a2; - - private static final String IKE_INITIATOR_SPI_HEX_STRING = "5f54bf6d8b48e6e1"; - private static final String IKE_RESPODNER_SPI_HEX_STRING = "0000000000000000"; - private static final String IP_ADDR = "10.80.80.13"; - private static final int PORT = 500; - - private static final int PROTOCOL_ID_OFFSET = 0; - - @Test - public void testDecodeNotifyPayloadSpiUnset() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING); - byte[] notifyData = TestUtils.hexStringToByteArray(NAT_DETECTION_DATA_HEX_STRING); - - IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket); - assertEquals(IkePayload.PROTOCOL_ID_UNSET, payload.protocolId); - assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, payload.spiSize); - assertEquals(IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP, payload.notifyType); - assertEquals(IkePayload.SPI_NOT_INCLUDED, payload.spi); - assertArrayEquals(notifyData, payload.notifyData); - } - - @Test - public void testDecodeNotifyPayloadSpiSet() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING); - - IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket); - assertEquals(IkePayload.PROTOCOL_ID_ESP, payload.protocolId); - assertEquals(IkePayload.SPI_LEN_IPSEC, payload.spiSize); - assertEquals(IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA, payload.notifyType); - assertEquals(REKEY_SPI, payload.spi); - assertArrayEquals(new byte[0], payload.notifyData); - } - - @Test - public void testDecodeNotifyPayloadThrowException() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING); - // Change Protocol ID to ESP - inputPacket[PROTOCOL_ID_OFFSET] = (byte) (IkePayload.PROTOCOL_ID_ESP & 0xFF); - try { - IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket); - fail("Expected InvalidSyntaxException: Protocol ID should not be ESP"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testGenerateNatDetectionData() throws Exception { - long initiatorIkeSpi = Long.parseLong(IKE_INITIATOR_SPI_HEX_STRING, 16); - long responderIkespi = Long.parseLong(IKE_RESPODNER_SPI_HEX_STRING, 16); - InetAddress inetAddress = InetAddress.getByName(IP_ADDR); - - byte[] netDetectionData = - IkeNotifyPayload.generateNatDetectionData( - initiatorIkeSpi, responderIkespi, inetAddress, PORT); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(NAT_DETECTION_DATA_HEX_STRING); - assertArrayEquals(expectedBytes, netDetectionData); - } - - @Test - public void testBuildIkeErrorNotifyWithData() throws Exception { - int payloadType = 1; - IkeNotifyPayload notifyPayload = - new IkeNotifyPayload( - IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, - new byte[] {(byte) payloadType}); - - assertArrayEquals(new byte[] {(byte) payloadType}, notifyPayload.notifyData); - assertTrue(notifyPayload.isErrorNotify()); - assertFalse(notifyPayload.isNewChildSaNotify()); - } - - @Test - public void testBuildIkeErrorNotifyWithoutData() throws Exception { - IkeNotifyPayload notifyPayload = - new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX); - - assertArrayEquals(new byte[0], notifyPayload.notifyData); - assertTrue(notifyPayload.isErrorNotify()); - assertFalse(notifyPayload.isNewChildSaNotify()); - } - - @Test - public void testBuildChildConfigNotify() throws Exception { - IkeNotifyPayload notifyPayload = - new IkeNotifyPayload(IkeNotifyPayload.NOTIFY_TYPE_USE_TRANSPORT_MODE); - - assertArrayEquals(new byte[0], notifyPayload.notifyData); - assertFalse(notifyPayload.isErrorNotify()); - assertTrue(notifyPayload.isNewChildSaNotify()); - } - - @Test - public void testBuildChildErrorNotify() throws Exception { - IkeNotifyPayload notifyPayload = - new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE); - - assertArrayEquals(new byte[0], notifyPayload.notifyData); - assertTrue(notifyPayload.isErrorNotify()); - assertTrue(notifyPayload.isNewChildSaNotify()); - } - - @Test - public void testEncodeNotifyPayload() throws Exception { - byte[] inputPacket = - TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING); - IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket); - - ByteBuffer byteBuffer = ByteBuffer.allocate(payload.getPayloadLength()); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NOTIFY, byteBuffer); - - byte[] expectedNoncePayload = - TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedNoncePayload, byteBuffer.array()); - } - - @Test - public void testValidateAndBuildIkeExceptionWithData() throws Exception { - // Invalid Message ID - byte[] dhGroup = new byte[] {(byte) 0x00, (byte) 0x0e}; - int expectedDhGroup = SaProposal.DH_GROUP_2048_BIT_MODP; - - IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_KE_PAYLOAD, dhGroup); - IkeProtocolException exception = payload.validateAndBuildIkeException(); - - assertTrue(exception instanceof InvalidKeException); - assertEquals(ERROR_TYPE_INVALID_KE_PAYLOAD, exception.getErrorType()); - assertArrayEquals(dhGroup, exception.getErrorData()); - assertEquals(expectedDhGroup, ((InvalidKeException) exception).getDhGroup()); - } - - @Test - public void testValidateAndBuildIkeExceptionWithoutData() throws Exception { - // Invalid Syntax - IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED); - IkeProtocolException exception = payload.validateAndBuildIkeException(); - - assertTrue(exception instanceof AuthenticationFailedException); - assertEquals(ERROR_TYPE_AUTHENTICATION_FAILED, exception.getErrorType()); - assertArrayEquals(new byte[0], exception.getErrorData()); - } - - @Test - public void testValidateAndBuildUnrecognizedIkeException() throws Exception { - int unrecognizedType = 0; - IkeNotifyPayload payload = new IkeNotifyPayload(unrecognizedType); - IkeProtocolException exception = payload.validateAndBuildIkeException(); - - assertTrue(exception instanceof UnrecognizedIkeProtocolException); - assertEquals(unrecognizedType, exception.getErrorType()); - assertArrayEquals(new byte[0], exception.getErrorData()); - } - - @Test - public void testValidateAndBuildIkeExceptionWithInvalidPayload() throws Exception { - // Build a invalid notify payload - IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD); - - try { - payload.validateAndBuildIkeException(); - fail("Expected to fail due to invalid error data"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testBuildIkeExceptionWithStatusNotify() throws Exception { - // Rekey notification - byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING); - IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket); - - assertFalse(payload.isErrorNotify()); - - try { - payload.validateAndBuildIkeException(); - fail("Expected to fail because it is not error notification"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testGetNotifyTypeString() throws Exception { - IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED); - - assertEquals("Notify(Authentication failed)", payload.getTypeString()); - } - - @Test - public void testGetNotifyTypeStringForUnrecoginizedNotify() throws Exception { - int unrecognizedType = 0; - IkeNotifyPayload payload = new IkeNotifyPayload(unrecognizedType); - - assertEquals("Notify(0)", payload.getTypeString()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java deleted file mode 100644 index 750ff463..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java +++ /dev/null @@ -1,927 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -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.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.net.IpSecManager; -import android.net.IpSecSpiResponse; -import android.net.ipsec.ike.ChildSaProposal; -import android.net.ipsec.ike.IkeSaProposal; -import android.net.ipsec.ike.SaProposal; -import android.net.ipsec.ike.exceptions.IkeProtocolException; -import android.util.Pair; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Attribute; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.AttributeDecoder; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.ChildProposal; -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.EsnTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IkeProposal; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.KeyLengthAttribute; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Proposal; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.TransformDecoder; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.UnrecognizedAttribute; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.UnrecognizedTransform; -import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils; -import com.android.server.IpSecService; - -import libcore.net.InetAddressUtils; - -import org.junit.Before; -import org.junit.Test; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.LinkedList; -import java.util.List; - -public final class IkeSaPayloadTest { - private static final String OUTBOUND_SA_PAYLOAD_HEADER = "22000030"; - private static final String OUTBOUND_PROPOSAL_RAW_PACKET = - "0000002C010100040300000C0100000C800E0080030000080300000203000008040" - + "000020000000802000002"; - private static final String INBOUND_PROPOSAL_RAW_PACKET = - "0000002c010100040300000c0100000c800e0080030000080300000203000008040" - + "000020000000802000002"; - private static final String INBOUND_TWO_PROPOSAL_RAW_PACKET = - "020000dc010100190300000c0100000c800e00800300000c0100000c800e00c0030" - + "0000c0100000c800e01000300000801000003030000080300000c0300" - + "00080300000d030000080300000e03000008030000020300000803000" - + "005030000080200000503000008020000060300000802000007030000" - + "080200000403000008020000020300000804000013030000080400001" - + "40300000804000015030000080400001c030000080400001d03000008" - + "0400001e030000080400001f030000080400000f03000008040000100" - + "300000804000012000000080400000e000001000201001a0300000c01" - + "000014800e00800300000c01000014800e00c00300000c01000014800" - + "e01000300000c0100001c800e01000300000c01000013800e00800300" - + "000c01000013800e00c00300000c01000013800e01000300000c01000" - + "012800e00800300000c01000012800e00c00300000c01000012800e01" - + "000300000802000005030000080200000603000008020000070300000" - + "802000004030000080200000203000008040000130300000804000014" - + "0300000804000015030000080400001c030000080400001d030000080" - + "400001e030000080400001f030000080400000f030000080400001003" - + "00000804000012000000080400000e"; - private static final String INBOUND_CHILD_PROPOSAL_RAW_PACKET = - "0000002801030403cae7019f0300000c0100000c800e00800300000803000002000" + "0000805000000"; - private static final String INBOUND_CHILD_TWO_PROPOSAL_RAW_PACKET = - "0200002801030403cae7019f0300000c0100000c800e00800300000803000002000" - + "00008050000000000001802030401cae7019e0000000c01000012800e" - + "0080"; - private static final String ENCR_TRANSFORM_RAW_PACKET = "0300000c0100000c800e0080"; - private static final String PRF_TRANSFORM_RAW_PACKET = "0000000802000002"; - private static final String INTEG_TRANSFORM_RAW_PACKET = "0300000803000002"; - private static final String DH_GROUP_TRANSFORM_RAW_PACKET = "0300000804000002"; - private static final String ESN_TRANSFORM_RAW_PACKET = "0000000805000000"; - - private static final int TRANSFORM_TYPE_OFFSET = 4; - private static final int TRANSFORM_ID_OFFSET = 7; - - private static final String ATTRIBUTE_RAW_PACKET = "800e0080"; - - private static final int PROPOSAL_NUMBER = 1; - - private static final int PROPOSAL_NUMBER_OFFSET = 4; - private static final int PROTOCOL_ID_OFFSET = 5; - - // Constants for multiple proposals test - private static final byte[] PROPOSAL_NUMBER_LIST = {1, 2}; - - private static final Inet4Address LOCAL_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.4.4")); - private static final Inet4Address REMOTE_ADDRESS = - (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8")); - - private static final int DUMMY_CHILD_SPI_RESOURCE_ID_LOCAL_ONE = 0x1234; - private static final int DUMMY_CHILD_SPI_RESOURCE_ID_LOCAL_TWO = 0x1235; - private static final int DUMMY_CHILD_SPI_RESOURCE_ID_REMOTE = 0x2234; - - private static final int CHILD_SPI_LOCAL_ONE = 0x2ad4c0a2; - private static final int CHILD_SPI_LOCAL_TWO = 0x2ad4c0a3; - private static final int CHILD_SPI_REMOTE = 0xcae70197; - - private AttributeDecoder mMockedAttributeDecoder; - private KeyLengthAttribute mAttributeKeyLength128; - private List<Attribute> mAttributeListWithKeyLength128; - - private EncryptionTransform mEncrAesCbc128Transform; - private EncryptionTransform mEncrAesGcm8Key128Transform; - private IntegrityTransform mIntegHmacSha1Transform; - private PrfTransform mPrfHmacSha1Transform; - private DhGroupTransform mDhGroup1024Transform; - - private Transform[] mValidNegotiatedTransformSet; - - private IkeSaProposal mIkeSaProposalOne; - private IkeSaProposal mIkeSaProposalTwo; - private IkeSaProposal[] mTwoIkeSaProposalsArray; - - private ChildSaProposal mChildSaProposalOne; - private ChildSaProposal mChildSaProposalTwo; - private ChildSaProposal[] mTwoChildSaProposalsArray; - - private MockIpSecTestUtils mMockIpSecTestUtils; - private IpSecService mMockIpSecService; - private IpSecManager mIpSecManager; - - private IpSecSpiResponse mDummyIpSecSpiResponseLocalOne; - private IpSecSpiResponse mDummyIpSecSpiResponseLocalTwo; - private IpSecSpiResponse mDummyIpSecSpiResponseRemote; - - @Before - public void setUp() throws Exception { - mMockedAttributeDecoder = mock(AttributeDecoder.class); - mAttributeKeyLength128 = new KeyLengthAttribute(SaProposal.KEY_LEN_AES_128); - mAttributeListWithKeyLength128 = new LinkedList<>(); - mAttributeListWithKeyLength128.add(mAttributeKeyLength128); - - mEncrAesCbc128Transform = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128); - mEncrAesGcm8Key128Transform = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_128); - mIntegHmacSha1Transform = - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); - mPrfHmacSha1Transform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1); - mDhGroup1024Transform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP); - - mValidNegotiatedTransformSet = - new Transform[] { - mEncrAesCbc128Transform, - mIntegHmacSha1Transform, - mPrfHmacSha1Transform, - mDhGroup1024Transform - }; - - mIkeSaProposalOne = - new IkeSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) - .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) - .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP) - .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1) - .build(); - - mIkeSaProposalTwo = - new IkeSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, - SaProposal.KEY_LEN_AES_128) - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, - SaProposal.KEY_LEN_AES_128) - .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC) - .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP) - .addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP) - .build(); - mTwoIkeSaProposalsArray = new IkeSaProposal[] {mIkeSaProposalOne, mIkeSaProposalTwo}; - - mChildSaProposalOne = - new ChildSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) - .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) - .build(); - mChildSaProposalTwo = - new ChildSaProposal.Builder() - .addEncryptionAlgorithm( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, - SaProposal.KEY_LEN_AES_128) - .build(); - mTwoChildSaProposalsArray = - new ChildSaProposal[] {mChildSaProposalOne, mChildSaProposalTwo}; - - mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec(); - mIpSecManager = mMockIpSecTestUtils.getIpSecManager(); - - IpSecService mMockIpSecService = mMockIpSecTestUtils.getIpSecService(); - when(mMockIpSecService.allocateSecurityParameterIndex( - eq(LOCAL_ADDRESS.getHostAddress()), anyInt(), anyObject())) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_LOCAL_ONE)) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_LOCAL_TWO)); - - when(mMockIpSecService.allocateSecurityParameterIndex( - eq(REMOTE_ADDRESS.getHostAddress()), anyInt(), anyObject())) - .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_REMOTE)); - } - - // TODO: Add tearDown() to reset Proposal.sTransformDecoder and Transform.sAttributeDecoder. - - @Test - public void testDecodeAttribute() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ATTRIBUTE_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - Pair<Attribute, Integer> pair = Attribute.readFrom(inputBuffer); - Attribute attribute = pair.first; - - assertTrue(attribute instanceof KeyLengthAttribute); - assertEquals(Attribute.ATTRIBUTE_TYPE_KEY_LENGTH, attribute.type); - assertEquals(SaProposal.KEY_LEN_AES_128, ((KeyLengthAttribute) attribute).keyLength); - } - - @Test - public void testEncodeAttribute() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.allocate(mAttributeKeyLength128.getAttributeLength()); - mAttributeKeyLength128.encodeToByteBuffer(byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(ATTRIBUTE_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testDecodeEncryptionTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(mAttributeListWithKeyLength128); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof EncryptionTransform); - assertEquals(Transform.TRANSFORM_TYPE_ENCR, transform.type); - assertEquals(SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, transform.id); - assertTrue(transform.isSupported); - } - - @Test - public void testDecodeEncryptionTransformWithInvalidKeyLength() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - List<Attribute> attributeList = new LinkedList<>(); - Attribute keyLengAttr = new KeyLengthAttribute(SaProposal.KEY_LEN_AES_128 + 1); - attributeList.add(keyLengAttr); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())).thenReturn(attributeList); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - try { - Transform.readFrom(inputBuffer); - fail("Expected InvalidSyntaxException for invalid key length."); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testEncodeEncryptionTransform() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.allocate(mEncrAesCbc128Transform.getTransformLength()); - mEncrAesCbc128Transform.encodeToByteBuffer(false, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testConstructEncryptionTransformWithUnsupportedId() throws Exception { - try { - new EncryptionTransform(-1); - fail("Expected IllegalArgumentException for unsupported Transform ID"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testConstructEncryptionTransformWithInvalidKeyLength() throws Exception { - try { - new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES, 129); - fail("Expected IllegalArgumentException for invalid key length."); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testDecodePrfTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(PRF_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(new LinkedList<Attribute>()); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof PrfTransform); - assertEquals(Transform.TRANSFORM_TYPE_PRF, transform.type); - assertEquals(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1, transform.id); - assertTrue(transform.isSupported); - } - - @Test - public void testEncodePrfTransform() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.allocate(mPrfHmacSha1Transform.getTransformLength()); - mPrfHmacSha1Transform.encodeToByteBuffer(true, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(PRF_TRANSFORM_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testConstructPrfTransformWithUnsupportedId() throws Exception { - try { - new PrfTransform(-1); - fail("Expected IllegalArgumentException for unsupported Transform ID"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testDecodeIntegrityTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INTEG_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(new LinkedList<Attribute>()); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof IntegrityTransform); - assertEquals(Transform.TRANSFORM_TYPE_INTEG, transform.type); - assertEquals(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96, transform.id); - assertTrue(transform.isSupported); - } - - @Test - public void testDecodeIntegrityTransformWithUnrecognizedAttribute() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INTEG_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(mAttributeListWithKeyLength128); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof IntegrityTransform); - assertEquals(Transform.TRANSFORM_TYPE_INTEG, transform.type); - assertEquals(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96, transform.id); - assertFalse(transform.isSupported); - } - - @Test - public void testEncodeIntegrityTransform() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.allocate(mIntegHmacSha1Transform.getTransformLength()); - mIntegHmacSha1Transform.encodeToByteBuffer(false, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(INTEG_TRANSFORM_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testConstructIntegrityTransformWithUnsupportedId() throws Exception { - try { - new IntegrityTransform(-1); - fail("Expected IllegalArgumentException for unsupported Transform ID"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testDecodeDhGroupTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(DH_GROUP_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(new LinkedList<Attribute>()); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof DhGroupTransform); - assertEquals(Transform.TRANSFORM_TYPE_DH, transform.type); - assertEquals(SaProposal.DH_GROUP_1024_BIT_MODP, transform.id); - assertTrue(transform.isSupported); - } - - @Test - public void testEncodeDhGroupTransform() throws Exception { - ByteBuffer byteBuffer = ByteBuffer.allocate(mDhGroup1024Transform.getTransformLength()); - mDhGroup1024Transform.encodeToByteBuffer(false, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(DH_GROUP_TRANSFORM_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testConstructDhGroupTransformWithUnsupportedId() throws Exception { - try { - new DhGroupTransform(-1); - fail("Expected IllegalArgumentException for unsupported Transform ID"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testDecodeEsnTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ESN_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(new LinkedList<Attribute>()); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof EsnTransform); - assertEquals(Transform.TRANSFORM_TYPE_ESN, transform.type); - assertEquals(EsnTransform.ESN_POLICY_NO_EXTENDED, transform.id); - assertTrue(transform.isSupported); - } - - @Test - public void testDecodeEsnTransformWithUnsupportedId() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ESN_TRANSFORM_RAW_PACKET); - inputPacket[TRANSFORM_ID_OFFSET] = -1; - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(new LinkedList<Attribute>()); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof EsnTransform); - assertEquals(Transform.TRANSFORM_TYPE_ESN, transform.type); - assertFalse(transform.isSupported); - } - - @Test - public void testDecodeEsnTransformWithUnrecognizedAttribute() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ESN_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(mAttributeListWithKeyLength128); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - assertTrue(transform instanceof EsnTransform); - assertEquals(Transform.TRANSFORM_TYPE_ESN, transform.type); - assertEquals(EsnTransform.ESN_POLICY_NO_EXTENDED, transform.id); - assertFalse(transform.isSupported); - } - - @Test - public void testEncodeEsnTransform() throws Exception { - EsnTransform mEsnTransform = new EsnTransform(); - ByteBuffer byteBuffer = ByteBuffer.allocate(mEsnTransform.getTransformLength()); - mEsnTransform.encodeToByteBuffer(true, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(ESN_TRANSFORM_RAW_PACKET); - - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testDecodeUnrecognizedTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - inputPacket[TRANSFORM_TYPE_OFFSET] = 6; - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(mAttributeListWithKeyLength128); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - - assertTrue(transform instanceof UnrecognizedTransform); - } - - @Test - public void testDecodeTransformWithRepeatedAttribute() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - List<Attribute> attributeList = new LinkedList<>(); - attributeList.add(mAttributeKeyLength128); - attributeList.add(mAttributeKeyLength128); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())).thenReturn(attributeList); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - try { - Transform.readFrom(inputBuffer); - fail("Expected InvalidSyntaxException for repeated Attribute Type Key Length."); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testDecodeTransformWithUnrecognizedTransformId() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - inputPacket[TRANSFORM_ID_OFFSET] = 1; - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())) - .thenReturn(mAttributeListWithKeyLength128); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - - assertFalse(transform.isSupported); - } - - @Test - public void testDecodeTransformWithUnrecogniedAttributeType() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(ENCR_TRANSFORM_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - - List<Attribute> attributeList = new LinkedList<>(); - attributeList.add(mAttributeKeyLength128); - Attribute attributeUnrecognized = new UnrecognizedAttribute(1, new byte[0]); - attributeList.add(attributeUnrecognized); - - when(mMockedAttributeDecoder.decodeAttributes(anyInt(), any())).thenReturn(attributeList); - Transform.sAttributeDecoder = mMockedAttributeDecoder; - - Transform transform = Transform.readFrom(inputBuffer); - - assertFalse(transform.isSupported); - } - - @Test - public void testTransformEquals() throws Exception { - EncryptionTransform mEncrAesGcm8Key128TransformOther = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_128); - - assertEquals(mEncrAesGcm8Key128Transform, mEncrAesGcm8Key128TransformOther); - - EncryptionTransform mEncrAesGcm8Key192Transform = - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_192); - - assertNotEquals(mEncrAesGcm8Key128Transform, mEncrAesGcm8Key192Transform); - - IntegrityTransform mIntegHmacSha1TransformOther = - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); - - assertNotEquals(mEncrAesGcm8Key128Transform, mIntegHmacSha1Transform); - assertEquals(mIntegHmacSha1Transform, mIntegHmacSha1TransformOther); - } - - private TransformDecoder getDummyTransformDecoder(Transform[] decodedTransforms) { - return new TransformDecoder() { - @Override - public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer) - throws IkeProtocolException { - for (int i = 0; i < count; i++) { - // Read length field and move position - inputBuffer.getShort(); - int length = Short.toUnsignedInt(inputBuffer.getShort()); - byte[] temp = new byte[length - 4]; - inputBuffer.get(temp); - } - return decodedTransforms; - } - }; - } - - @Test - public void testDecodeSingleProposal() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - ByteBuffer inputBuffer = ByteBuffer.wrap(inputPacket); - Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]); - - Proposal proposal = Proposal.readFrom(inputBuffer); - - assertEquals(PROPOSAL_NUMBER, proposal.number); - assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); - assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, proposal.spiSize); - assertEquals(IkePayload.SPI_NOT_INCLUDED, proposal.spi); - assertFalse(proposal.hasUnrecognizedTransform); - assertNotNull(proposal.getSaProposal()); - } - - @Test - public void testDecodeSaRequestWithMultipleProposal() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_TWO_PROPOSAL_RAW_PACKET); - Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]); - - IkeSaPayload payload = new IkeSaPayload(false, false, inputPacket); - - assertEquals(PROPOSAL_NUMBER_LIST.length, payload.proposalList.size()); - for (int i = 0; i < payload.proposalList.size(); i++) { - Proposal proposal = payload.proposalList.get(i); - assertEquals(PROPOSAL_NUMBER_LIST[i], proposal.number); - assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); - assertEquals(0, proposal.spiSize); - } - } - - @Test - public void testEncodeProposal() throws Exception { - // Construct Proposal for IKE INIT exchange. - IkeProposal proposal = - IkeProposal.createIkeProposal( - (byte) PROPOSAL_NUMBER, - IkePayload.SPI_LEN_NOT_INCLUDED, - mIkeSaProposalOne, - LOCAL_ADDRESS); - - ByteBuffer byteBuffer = ByteBuffer.allocate(proposal.getProposalLength()); - proposal.encodeToByteBuffer(true /*is the last*/, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(OUTBOUND_PROPOSAL_RAW_PACKET); - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testDecodeSaResponseWithMultipleProposal() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_TWO_PROPOSAL_RAW_PACKET); - Proposal.sTransformDecoder = getDummyTransformDecoder(new Transform[0]); - - try { - new IkeSaPayload(false, true, inputPacket); - fail("Expected to fail due to more than one proposal in response SA payload."); - } catch (InvalidSyntaxException expected) { - - } - } - - @Test - public void testBuildOutboundIkeRekeySaResponsePayload() throws Exception { - IkeSaPayload saPayload = - IkeSaPayload.createRekeyIkeSaResponsePayload( - (byte) 1, mIkeSaProposalOne, LOCAL_ADDRESS); - - assertTrue(saPayload.isSaResponse); - assertEquals(1, saPayload.proposalList.size()); - - IkeProposal proposal = (IkeProposal) saPayload.proposalList.get(0); - assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); - assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize); - assertEquals(mIkeSaProposalOne, proposal.saProposal); - - assertNotNull(proposal.getIkeSpiResource()); - } - - @Test - public void testBuildOutboundInitialIkeSaRequestPayload() throws Exception { - IkeSaPayload saPayload = IkeSaPayload.createInitialIkeSaPayload(mTwoIkeSaProposalsArray); - - assertFalse(saPayload.isSaResponse); - assertEquals(PROPOSAL_NUMBER_LIST.length, saPayload.proposalList.size()); - - for (int i = 0; i < saPayload.proposalList.size(); i++) { - IkeProposal proposal = (IkeProposal) saPayload.proposalList.get(i); - assertEquals(PROPOSAL_NUMBER_LIST[i], proposal.number); - assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); - assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, proposal.spiSize); - assertEquals(mTwoIkeSaProposalsArray[i], proposal.saProposal); - - // SA Payload for IKE INIT exchange does not include IKE SPIs. - assertNull(proposal.getIkeSpiResource()); - } - } - - @Test - public void testBuildOutboundChildSaRequest() throws Exception { - IkeSaPayload saPayload = - IkeSaPayload.createChildSaRequestPayload( - mTwoChildSaProposalsArray, mIpSecManager, LOCAL_ADDRESS); - - assertFalse(saPayload.isSaResponse); - assertEquals(PROPOSAL_NUMBER_LIST.length, saPayload.proposalList.size()); - - int[] expectedSpis = new int[] {CHILD_SPI_LOCAL_ONE, CHILD_SPI_LOCAL_TWO}; - for (int i = 0; i < saPayload.proposalList.size(); i++) { - ChildProposal proposal = (ChildProposal) saPayload.proposalList.get(i); - assertEquals(PROPOSAL_NUMBER_LIST[i], proposal.number); - assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.protocolId); - assertEquals(IkePayload.SPI_LEN_IPSEC, proposal.spiSize); - assertEquals(mTwoChildSaProposalsArray[i], proposal.saProposal); - - assertEquals(expectedSpis[i], proposal.getChildSpiResource().getSpi()); - } - } - - @Test - public void testEncodeIkeSaPayload() throws Exception { - IkeSaPayload saPayload = - IkeSaPayload.createInitialIkeSaPayload(new IkeSaProposal[] {mIkeSaProposalOne}); - - ByteBuffer byteBuffer = ByteBuffer.allocate(saPayload.getPayloadLength()); - saPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_KE, byteBuffer); - - byte[] expectedBytes = - TestUtils.hexStringToByteArray( - OUTBOUND_SA_PAYLOAD_HEADER + OUTBOUND_PROPOSAL_RAW_PACKET); - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - private void buildAndVerifyIkeSaRespProposal( - byte[] saResponseBytes, Transform[] decodedTransforms) throws Exception { - // Build response SA payload from decoding bytes. - Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms); - IkeSaPayload respPayload = new IkeSaPayload(false, true, saResponseBytes); - - // Build request SA payload for IKE INIT exchange from SaProposal. - IkeSaPayload reqPayload = IkeSaPayload.createInitialIkeSaPayload(mTwoIkeSaProposalsArray); - - Pair<IkeProposal, IkeProposal> negotiatedProposalPair = - IkeSaPayload.getVerifiedNegotiatedIkeProposalPair( - reqPayload, respPayload, REMOTE_ADDRESS); - IkeProposal reqProposal = negotiatedProposalPair.first; - IkeProposal respProposal = negotiatedProposalPair.second; - - assertEquals(respPayload.proposalList.get(0).getSaProposal(), respProposal.getSaProposal()); - - // SA Payload for IKE INIT exchange does not include IKE SPIs. - assertNull(reqProposal.getIkeSpiResource()); - assertNull(respProposal.getIkeSpiResource()); - } - - @Test - public void testGetVerifiedNegotiatedIkeProposal() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - - buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet); - } - - private void verifyChildSaNegotiation( - IkeSaPayload reqPayload, - IkeSaPayload respPayload, - IpSecManager ipSecManager, - InetAddress remoteAddress, - boolean isLocalInit) - throws Exception { - // SA negotiation - Pair<ChildProposal, ChildProposal> negotiatedProposalPair = - IkeSaPayload.getVerifiedNegotiatedChildProposalPair( - reqPayload, respPayload, ipSecManager, remoteAddress); - ChildProposal reqProposal = negotiatedProposalPair.first; - ChildProposal respProposal = negotiatedProposalPair.second; - - // Verify results - assertEquals(respPayload.proposalList.get(0).getSaProposal(), respProposal.getSaProposal()); - - int initSpi = isLocalInit ? CHILD_SPI_LOCAL_ONE : CHILD_SPI_REMOTE; - int respSpi = isLocalInit ? CHILD_SPI_REMOTE : CHILD_SPI_LOCAL_ONE; - assertEquals(initSpi, reqProposal.getChildSpiResource().getSpi()); - assertEquals(respSpi, respProposal.getChildSpiResource().getSpi()); - - // Verify SPIs in unselected Proposals have been released. - for (Proposal proposal : reqPayload.proposalList) { - if (proposal != reqProposal) { - assertNull(((ChildProposal) proposal).getChildSpiResource()); - } - } - } - - @Test - public void testGetVerifiedNegotiatedChildProposalForLocalCreate() throws Exception { - // Build local request - IkeSaPayload reqPayload = - IkeSaPayload.createChildSaRequestPayload( - mTwoChildSaProposalsArray, mIpSecManager, LOCAL_ADDRESS); - - // Build remote response - Proposal.sTransformDecoder = - getDummyTransformDecoder(mChildSaProposalOne.getAllTransforms()); - IkeSaPayload respPayload = - new IkeSaPayload( - false /*critical*/, - true /*isResp*/, - TestUtils.hexStringToByteArray(INBOUND_CHILD_PROPOSAL_RAW_PACKET)); - - verifyChildSaNegotiation( - reqPayload, respPayload, mIpSecManager, REMOTE_ADDRESS, true /*isLocalInit*/); - } - - @Test - public void testGetVerifiedNegotiatedChildProposalForRemoteCreate() throws Exception { - Transform[] transformsOne = mChildSaProposalOne.getAllTransforms(); - Transform[] transformsTwo = mChildSaProposalTwo.getAllTransforms(); - Transform[] decodedTransforms = new Transform[transformsOne.length + transformsTwo.length]; - System.arraycopy(transformsOne, 0, decodedTransforms, 0, transformsOne.length); - System.arraycopy( - transformsTwo, 0, decodedTransforms, transformsOne.length, transformsTwo.length); - - // Build remote request - Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms); - IkeSaPayload reqPayload = - new IkeSaPayload( - false /*critical*/, - false /*isResp*/, - TestUtils.hexStringToByteArray(INBOUND_CHILD_TWO_PROPOSAL_RAW_PACKET)); - - // Build local response - IkeSaPayload respPayload = - IkeSaPayload.createChildSaResponsePayload( - (byte) 1, mChildSaProposalOne, mIpSecManager, LOCAL_ADDRESS); - - verifyChildSaNegotiation( - reqPayload, respPayload, mIpSecManager, REMOTE_ADDRESS, false /*isLocalInit*/); - } - - // Test throwing when negotiated proposal in SA response payload has unrecognized Transform. - @Test - public void testGetVerifiedNegotiatedProposalWithUnrecogTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - - Transform[] negotiatedTransformSet = - Arrays.copyOfRange( - mValidNegotiatedTransformSet, 0, mValidNegotiatedTransformSet.length); - negotiatedTransformSet[0] = new UnrecognizedTransform(-1, 1, new LinkedList<>()); - - try { - buildAndVerifyIkeSaRespProposal(inputPacket, negotiatedTransformSet); - fail("Expected to fail because negotiated proposal has unrecognized Transform."); - } catch (NoValidProposalChosenException expected) { - } - } - - // Test throwing when negotiated proposal has invalid proposal number. - @Test - public void testGetVerifiedNegotiatedProposalWithInvalidNumber() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - inputPacket[PROPOSAL_NUMBER_OFFSET] = (byte) 10; - - try { - buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet); - fail("Expected to fail due to invalid proposal number."); - } catch (NoValidProposalChosenException expected) { - } - } - - // Test throwing when negotiated proposal has mismatched protocol ID. - @Test - public void testGetVerifiedNegotiatedProposalWithMisMatchedProtocol() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - inputPacket[PROTOCOL_ID_OFFSET] = IkePayload.PROTOCOL_ID_ESP; - - try { - buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet); - fail("Expected to fail due to mismatched protocol ID."); - } catch (NoValidProposalChosenException expected) { - } - } - - // Test throwing when negotiated proposal has Transform that was not proposed in request. - @Test - public void testGetVerifiedNegotiatedProposalWithMismatchedTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - - Transform[] negotiatedTransformSet = - Arrays.copyOfRange( - mValidNegotiatedTransformSet, 0, mValidNegotiatedTransformSet.length); - negotiatedTransformSet[0] = mEncrAesGcm8Key128Transform; - - try { - buildAndVerifyIkeSaRespProposal(inputPacket, negotiatedTransformSet); - fail("Expected to fail due to mismatched Transform."); - } catch (NoValidProposalChosenException expected) { - } - } - - // Test throwing when negotiated proposal is lack of a certain type Transform. - @Test - public void testGetVerifiedNegotiatedProposalWithoutTransform() throws Exception { - byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET); - - try { - buildAndVerifyIkeSaRespProposal(inputPacket, new Transform[0]); - fail("Expected to fail due to absence of Transform."); - } catch (NoValidProposalChosenException expected) { - } - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java deleted file mode 100644 index 898db30f..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.Arrays; - -public final class IkeSkPayloadTest { - - private static final String IKE_AUTH_INIT_REQUEST_HEX_STRING = - "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec" - + "230000d0b9132b7bb9f658dfdc648e5017a6322a030c316c" - + "e55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58" - + "46de333ecd3ea2b705d18293b130395300ba92a351041345" - + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f" - + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60" - + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b" - + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423" - + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3" - + "59eb4e81ae6e0f22abdad69ba8007d50"; - - private static final String IKE_AUTH_INIT_REQUEST_DECRYPTED_BODY_HEX_STRING = - "2400000c010000000a50500d2700000c010000000a505050" - + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327" - + "44dfb2c12c00002c00000028010304032ad4c0a20300000c" - + "0100000c800e008003000008030000020000000805000000" - + "2d00001801000000070000100000ffff00000000ffffffff" - + "2900001801000000070000100000ffff00000000ffffffff" - + "29000008000040000000000c0000400100000001"; - - private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1"; - private static final String INTE_KEY_FROM_INIT_TO_RESP = - "554fbf5a05b7f511e05a30ce23d874db9ef55e51"; - - private static final String ENCR_ALGO_AES_CBC = "AES/CBC/NoPadding"; - - private static final int CHECKSUM_LEN = 12; - - private IkeCipher mAesCbcDecryptCipher; - private byte[] mAesCbcDecryptionKey; - - private IkeMacIntegrity mHmacSha1IntegrityMac; - private byte[] mHmacSha1IntegrityKey; - - @Before - public void setUp() throws Exception { - mAesCbcDecryptCipher = - IkeCipher.create( - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, - SaProposal.KEY_LEN_AES_128), - IkeMessage.getSecurityProvider()); - mAesCbcDecryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP); - mHmacSha1IntegrityMac = - IkeMacIntegrity.create( - new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96), - IkeMessage.getSecurityProvider()); - mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP); - } - - @Test - public void testEncode() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_HEX_STRING); - byte[] payloadBytes = - Arrays.copyOfRange(message, IkeHeader.IKE_HEADER_LENGTH, message.length); - - IkeSkPayload payload = - IkePayloadFactory.getIkeSkPayload( - false /*isSkf*/, - message, - mHmacSha1IntegrityMac, - mAesCbcDecryptCipher, - mHmacSha1IntegrityKey, - mAesCbcDecryptionKey) - .first; - int payloadLength = payload.getPayloadLength(); - ByteBuffer buffer = ByteBuffer.allocate(payloadLength); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_ID_INITIATOR, buffer); - assertArrayEquals(payloadBytes, buffer.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java deleted file mode 100644 index 3374a7dc..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java +++ /dev/null @@ -1,201 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.spy; - -import android.net.ipsec.ike.SaProposal; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.crypto.IkeCipher; -import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; -import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher; -import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; -import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; - -import org.junit.Before; -import org.junit.Test; - -import java.nio.ByteBuffer; -import java.util.Arrays; - -public final class IkeSkfPayloadTest { - private static final String IKE_FRAG_MSG_HEX_STRING = - "bb3d5237aa558779db24aeb6c9ea183e352023200000000100000134" - + "0000011800020002c1471fc7714a3b77a2bfd78dd2df4c048dfed913" - + "c5de76cb1f4463ef541df2442b43c65308a47b873502268cc1195f99" - + "4f6f1a945f56cb342969936af97d79c560c8e0f8bb1a0874ebfb5d0e" - + "610b0fcff96d4197c06e7aef07a3a9ae487555bec95c78b87fe6483c" - + "be07e3d132f8594c34dba5b5b463b871d0272af6a1ee701fc6b7b70a" - + "22a1b8f63eed50ce6b2253ee63fe2cf0289a5eb715e56b389f72b5ba" - + "ecfb7340f4abf9253a8c973d281ed62f3516d130fcaaf2c2145b3047" - + "f3a243e60beb2fc28bf05183839caf46bfbfc4f28c9a2224e7d49686" - + "52a236a403ecb203a1de1e2144a6f5ce28acc2f93989608af17381fc" - + "f965cabe1a448274264b22167abfa047dc88e4bfdc5a492847d36d8b"; - - private static final String IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING = - "dc89d82f4fccff8d3f0c4f4848571e57205f7dbdce954203983d2147" - + "3a9e10ba36876b860d33afbdfe6ebf000240e31f2039f4213e882d1f" - + "6f0a24887aed0584f4b50a016d989990fd58297757c7b842cd72b57c" - + "2f68cba8a5f06d899ce3fcfbd0419402a1d59f1c5b5b23bd0a4ed525" - + "27ed6cef9fd238552fcf6e4cd9f794d2b01ba61438fd21714fbc3e3f" - + "443a816751e55d46009ae7fb9f52db0977e453a2d28b0453a9393778" - + "3a0b625c27d186c052a7169807537d97e731a3543fc10dca605ca86d" - + "1496882e1d009a9216d07d0000001801850014120a00000f02000200" - + "0100000d010000"; - - private static final String IKE_FRAG_MSG_CHECKSUM = "7abfa047dc88e4bfdc5a492847d36d8b"; - private static final String IKE_FRAG_MSG_PADDING = "05d925c1b3804aee08"; - - private static final int FRAGMENT_NUM = 2; - private static final int TOTAL_FRAGMENTS = 2; - - private static final int FRAGMENT_NUM_OFFSET = - IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH; - private static final int TOTAL_FRAGMENTS_OFFET = FRAGMENT_NUM_OFFSET + 2; - - private byte[] mDecryptedData; - - private IkeMacIntegrity mSpyHmacSha256IntegrityMac; - private IkeNormalModeCipher mSpyAesCbcCipher; - - @Before - public void setUp() throws Exception { - mDecryptedData = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING); - - // Set up integrity algorithm - mSpyHmacSha256IntegrityMac = - spy( - IkeMacIntegrity.create( - new IntegrityTransform( - SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128), - IkeMessage.getSecurityProvider())); - byte[] expectedChecksum = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_CHECKSUM); - doReturn(expectedChecksum).when(mSpyHmacSha256IntegrityMac).generateChecksum(any(), any()); - - // Set up encryption algorithm - mSpyAesCbcCipher = - spy( - (IkeNormalModeCipher) - IkeCipher.create( - new EncryptionTransform( - SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, - SaProposal.KEY_LEN_AES_128), - IkeMessage.getSecurityProvider())); - byte[] expectedDecryptedPaddedData = - TestUtils.hexStringToByteArray( - IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING + IKE_FRAG_MSG_PADDING); - doReturn(expectedDecryptedPaddedData).when(mSpyAesCbcCipher).decrypt(any(), any(), any()); - } - - private IkeSkfPayload decodeAndDecryptFragMsg(byte[] message) throws Exception { - IkeSkfPayload payload = - (IkeSkfPayload) - IkePayloadFactory.getIkeSkPayload( - true /*isSkf*/, - message, - mSpyHmacSha256IntegrityMac, - mSpyAesCbcCipher, - new byte[0] /*integrityKey*/, - new byte[0] /*decryptionKey*/) - .first; - return payload; - } - - @Test - public void testDecode() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING); - - IkeSkfPayload payload = decodeAndDecryptFragMsg(message); - - assertEquals(IkePayload.PAYLOAD_TYPE_SKF, payload.payloadType); - assertEquals(FRAGMENT_NUM, payload.fragmentNum); - assertEquals(TOTAL_FRAGMENTS, payload.totalFragments); - assertArrayEquals(mDecryptedData, payload.getUnencryptedData()); - } - - @Test - public void testDecodeThrowsForZeroFragNum() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING); - - // Set Fragment Number to zero - message[FRAGMENT_NUM_OFFSET] = 0; - message[FRAGMENT_NUM_OFFSET + 1] = 0; - - try { - decodeAndDecryptFragMsg(message); - fail("Expected to fail because Fragment Number is zero."); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testDecodeThrowsForZeroTotalFragments() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING); - - // Set Total Fragments Number to zero - message[TOTAL_FRAGMENTS_OFFET] = 0; - message[TOTAL_FRAGMENTS_OFFET + 1] = 0; - - try { - decodeAndDecryptFragMsg(message); - fail("Expected to fail because Total Fragments Number is zero."); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testDecodeThrowsWhenFragNumIsLargerThanTotalFragments() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING); - - // Set Fragment Number to 5 - message[FRAGMENT_NUM_OFFSET] = 0; - message[FRAGMENT_NUM_OFFSET + 1] = 5; - - // Set Total Fragments Number to 2 - message[TOTAL_FRAGMENTS_OFFET] = 0; - message[TOTAL_FRAGMENTS_OFFET + 1] = 2; - - try { - decodeAndDecryptFragMsg(message); - fail( - "Expected to fail because Fragment Number is larger than" - + " Total Fragments Number"); - } catch (InvalidSyntaxException expected) { - } - } - - @Test - public void testEncode() throws Exception { - byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING); - IkeSkfPayload payload = decodeAndDecryptFragMsg(message); - - int payloadLength = payload.getPayloadLength(); - ByteBuffer buffer = ByteBuffer.allocate(payloadLength); - payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, buffer); - - byte[] expectedPayloadBytes = - Arrays.copyOfRange(message, IkeHeader.IKE_HEADER_LENGTH, message.length); - assertArrayEquals(expectedPayloadBytes, buffer.array()); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java deleted file mode 100644 index 05474379..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.message; - -import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_UNPROTECTED_ERROR; - -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 static org.mockito.Mockito.when; - -import android.net.ipsec.ike.exceptions.IkeProtocolException; -import android.util.Pair; - -import com.android.internal.net.TestUtils; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult; -import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultError; - -import java.nio.ByteBuffer; - -/** - * IkeTestUtils provides utility methods for testing IKE library. - * - * <p>TODO: Consider moving it under ikev2/ - */ -public final class IkeTestUtils { - public static IkePayload hexStringToIkePayload( - @IkePayload.PayloadType int payloadType, boolean isResp, String payloadHexString) - throws IkeProtocolException { - byte[] payloadBytes = TestUtils.hexStringToByteArray(payloadHexString); - // Returned Pair consists of the IkePayload and the following IkePayload's type. - Pair<IkePayload, Integer> pair = - IkePayloadFactory.getIkePayload(payloadType, isResp, ByteBuffer.wrap(payloadBytes)); - return pair.first; - } - - public static <T extends IkeProtocolException> T decodeAndVerifyUnprotectedErrorMsg( - byte[] inputPacket, Class<T> expectedException) throws Exception { - IkeHeader header = new IkeHeader(inputPacket); - DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket); - - assertEquals(DECODE_STATUS_UNPROTECTED_ERROR, decodeResult.status); - DecodeResultError resultError = (DecodeResultError) decodeResult; - assertNotNull(resultError.ikeException); - assertTrue(expectedException.isInstance(resultError.ikeException)); - - return (T) resultError.ikeException; - } - - public static IkeSkfPayload makeDummySkfPayload( - byte[] unencryptedData, int fragNum, int totalFrags) throws Exception { - IkeEncryptedPayloadBody mockEncryptedBody = mock(IkeEncryptedPayloadBody.class); - when(mockEncryptedBody.getUnencryptedData()).thenReturn(unencryptedData); - return new IkeSkfPayload(mockEncryptedBody, fragNum, totalFrags); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java deleted file mode 100644 index cbd6f930..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.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 android.net.ipsec.ike.IkeTrafficSelector; - -import com.android.internal.net.TestUtils; - -import libcore.net.InetAddressUtils; - -import org.junit.Test; - -import java.net.Inet4Address; -import java.nio.ByteBuffer; - -public final class IkeTsPayloadTest { - private static final String TS_INITIATOR_PAYLOAD_HEX_STRING = - "2d00002802000000070000100010fff0c0000264c0000365070000100000ffffc0000464c0000466"; - - private static final int NUMBER_OF_TS = 2; - - 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 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 IkeTrafficSelector mTsOne; - private IkeTrafficSelector mTsTwo; - - public IkeTsPayloadTest() { - 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 testDecodeTsInitiatorPayload() throws Exception { - ByteBuffer inputBuffer = - ByteBuffer.wrap(TestUtils.hexStringToByteArray(TS_INITIATOR_PAYLOAD_HEX_STRING)); - - IkePayload payload = - IkePayloadFactory.getIkePayload( - IkePayload.PAYLOAD_TYPE_TS_INITIATOR, false, inputBuffer) - .first; - assertTrue(payload instanceof IkeTsPayload); - - IkeTsPayload tsPayload = (IkeTsPayload) payload; - assertEquals(IkePayload.PAYLOAD_TYPE_TS_INITIATOR, tsPayload.payloadType); - assertEquals(NUMBER_OF_TS, tsPayload.numTs); - } - - @Test - public void testBuildAndEncodeTsPayload() throws Exception { - IkeTsPayload tsPayload = - new IkeTsPayload(true /*isInitiator*/, new IkeTrafficSelector[] {mTsOne, mTsTwo}); - - ByteBuffer byteBuffer = ByteBuffer.allocate(tsPayload.getPayloadLength()); - tsPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_TS_RESPONDER, byteBuffer); - - byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_INITIATOR_PAYLOAD_HEX_STRING); - assertArrayEquals(expectedBytes, byteBuffer.array()); - } - - @Test - public void testContains() throws Exception { - IkeTrafficSelector tsOneNarrowPortRange = - 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); - - IkeTrafficSelector tsOneNarrowAddressRange = - new IkeTrafficSelector( - IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, - TS_ONE_START_PORT, - TS_ONE_END_PORT, - (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200")), - TS_ONE_END_ADDRESS); - - IkeTsPayload tsPayload = - new IkeTsPayload(true /*isInitiator*/, new IkeTrafficSelector[] {mTsOne, mTsTwo}); - - IkeTsPayload tsNarrowPortRangePayload = - new IkeTsPayload( - true /*isInitiator*/, - new IkeTrafficSelector[] {tsOneNarrowPortRange, mTsTwo}); - - IkeTsPayload tsNarrowAddressRangePayload = - new IkeTsPayload( - true /*isInitiator*/, - new IkeTrafficSelector[] {tsOneNarrowAddressRange, mTsTwo}); - - assertTrue(tsPayload.contains(tsPayload)); - assertTrue(tsPayload.contains(tsNarrowPortRangePayload)); - assertTrue(tsPayload.contains(tsNarrowAddressRangePayload)); - - assertFalse(tsNarrowPortRangePayload.contains(tsPayload)); - assertFalse(tsNarrowAddressRangePayload.contains(tsPayload)); - assertFalse(tsNarrowAddressRangePayload.contains(tsNarrowPortRangePayload)); - assertFalse(tsNarrowPortRangePayload.contains(tsNarrowAddressRangePayload)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java deleted file mode 100644 index db128c80..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.testutils; - -import android.content.Context; - -import androidx.test.InstrumentationRegistry; - -import com.android.internal.net.ipsec.ike.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 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 { - Context context = InstrumentationRegistry.getContext(); - InputStream inputStream = - context.getResources().getAssets().open(PEM_FOLDER_NAME + "/" + fileName); - - CertificateFactory factory = - 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())); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java deleted file mode 100644 index 742ff240..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.testutils; - -import static android.system.OsConstants.AF_INET; -import static android.system.OsConstants.IPPROTO_UDP; -import static android.system.OsConstants.SOCK_DGRAM; - -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.net.IpSecManager; -import android.net.IpSecSpiResponse; -import android.net.IpSecUdpEncapResponse; -import android.system.Os; - -import androidx.test.InstrumentationRegistry; - -import com.android.server.IpSecService; - -/** This class provides utility methods for mocking IPsec surface. */ -public final class MockIpSecTestUtils { - private static final int DUMMY_CHILD_SPI = 0x2ad4c0a2; - private static final int DUMMY_CHILD_SPI_RESOURCE_ID = 0x1234; - - private static final int DUMMY_UDP_ENCAP_PORT = 34567; - private static final int DUMMY_UDP_ENCAP_RESOURCE_ID = 0x3234; - - private Context mContext; - private IpSecService mMockIpSecService; - private IpSecManager mIpSecManager; - - private MockIpSecTestUtils() throws Exception { - mMockIpSecService = mock(IpSecService.class); - mContext = InstrumentationRegistry.getContext(); - mIpSecManager = new IpSecManager(mContext, mMockIpSecService); - - when(mMockIpSecService.allocateSecurityParameterIndex(anyString(), anyInt(), anyObject())) - .thenReturn( - new IpSecSpiResponse( - IpSecManager.Status.OK, - DUMMY_CHILD_SPI_RESOURCE_ID, - DUMMY_CHILD_SPI)); - - when(mMockIpSecService.openUdpEncapsulationSocket(anyInt(), anyObject())) - .thenReturn( - new IpSecUdpEncapResponse( - IpSecManager.Status.OK, - DUMMY_UDP_ENCAP_RESOURCE_ID, - DUMMY_UDP_ENCAP_PORT, - Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))); - } - - public static MockIpSecTestUtils setUpMockIpSec() throws Exception { - return new MockIpSecTestUtils(); - } - - public static IpSecSpiResponse buildDummyIpSecSpiResponse(int spi) throws Exception { - return new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_CHILD_SPI_RESOURCE_ID, spi); - } - - public Context getContext() { - return mContext; - } - - public IpSecManager getIpSecManager() { - return mIpSecManager; - } - - public IpSecService getIpSecService() { - return mMockIpSecService; - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java deleted file mode 100644 index 1fddb1d9..00000000 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * 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.internal.net.ipsec.ike.utils; - -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RETRANSMIT; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.mockito.Mockito.when; - -import android.os.Handler; -import android.os.Message; - -import com.android.internal.net.ipsec.ike.message.IkeMessage; - -import org.junit.Before; -import org.junit.Test; - -public final class RetransmitterTest { - private Handler mMockHandler; - private IkeMessage mMockIkeMessage; - private TestRetransmitter mRetransmitter; - - private class TestRetransmitter extends Retransmitter { - int mSendCallCount; // Defaults to 0 - boolean mFailed; // Defaults to false - - TestRetransmitter(Handler handler, IkeMessage message) { - super(handler, message); - } - - @Override - public void send(IkeMessage msg) { - mSendCallCount++; - } - - @Override - public void handleRetransmissionFailure() { - mFailed = true; - } - } - - @Before - public void setUp() throws Exception { - mMockHandler = mock(Handler.class); - when(mMockHandler.obtainMessage(eq(CMD_RETRANSMIT), anyObject())) - .thenReturn(mock(Message.class)); - - mMockIkeMessage = mock(IkeMessage.class); - mRetransmitter = new TestRetransmitter(mMockHandler, mMockIkeMessage); - } - - @Test - public void testSendRequestAndQueueRetransmit() throws Exception { - mRetransmitter.retransmit(); - assertEquals(1, mRetransmitter.mSendCallCount); - verify(mMockHandler).obtainMessage(eq(CMD_RETRANSMIT), eq(mRetransmitter)); - verify(mMockHandler) - .sendMessageDelayed(any(Message.class), eq(Retransmitter.RETRANSMIT_TIMEOUT_MS)); - } - - @Test - public void testRetransmitQueuesExponentialRetransmit() throws Exception { - mRetransmitter.retransmit(); - - for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) { - long expectedTimeout = - (long) - (Retransmitter.RETRANSMIT_TIMEOUT_MS - * Math.pow(Retransmitter.RETRANSMIT_BACKOFF_FACTOR, i)); - - assertEquals(i + 1, mRetransmitter.mSendCallCount); - assertFalse(mRetransmitter.mFailed); - - // This call happens with the same arguments each time - verify(mMockHandler, times(i + 1)) - .obtainMessage(eq(CMD_RETRANSMIT), eq(mRetransmitter)); - - // But the expected timeout changes every time - verify(mMockHandler).sendMessageDelayed(any(Message.class), eq(expectedTimeout)); - - verifyNoMoreInteractions(mMockHandler); - - // Trigger next round of retransmissions. - mRetransmitter.retransmit(); - } - } - - @Test - public void testRetransmitterCallsRetranmissionsFailedOnMaxTries() throws Exception { - mRetransmitter.retransmit(); - - // Exhaust all retransmit attempts - for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) { - mRetransmitter.retransmit(); - } - - assertTrue(mRetransmitter.mFailed); - } - - @Test - public void testRetransmitterStopsRetransmitting() throws Exception { - mRetransmitter.stopRetransmitting(); - - verify(mMockHandler).removeMessages(eq(CMD_RETRANSMIT), eq(mRetransmitter)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java b/tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java deleted file mode 100644 index 29bb313d..00000000 --- a/tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * 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.internal.net.utils; - -import static org.junit.Assert.assertArrayEquals; - -import org.junit.Test; - -import java.math.BigInteger; - -public final class BigIntegerUtilsTest { - private static final String TEST_BIGINTEGER_A = "3FFF"; - private static final String TEST_BIGINTEGER_B = "FFFF"; - private static final byte[] EXPECTED_BYTE_ARRAY_A_2 = {(byte) 0x3F, (byte) 0xFF}; - private static final byte[] EXPECTED_BYTE_ARRAY_B_2 = {(byte) 0xFF, (byte) 0xFF}; - private static final byte[] EXPECTED_BYTE_ARRAY_A_3 = {0, (byte) 0x3F, (byte) 0xFF}; - private static final byte[] EXPECTED_BYTE_ARRAY_B_3 = {0, (byte) 0xFF, (byte) 0xFF}; - - @Test - public void testBigIntegerToUnsignedByteArray() throws Exception { - BigInteger bigIntA = new BigInteger(TEST_BIGINTEGER_A, 16); - BigInteger bigIntB = new BigInteger(TEST_BIGINTEGER_B, 16); - - byte[] byteArrayA2 = BigIntegerUtils.bigIntegerToUnsignedByteArray(bigIntA, 2); - assertArrayEquals(EXPECTED_BYTE_ARRAY_A_2, byteArrayA2); - byte[] byteArrayB2 = BigIntegerUtils.bigIntegerToUnsignedByteArray(bigIntB, 2); - assertArrayEquals(EXPECTED_BYTE_ARRAY_B_2, byteArrayB2); - - byte[] byteArrayA3 = BigIntegerUtils.bigIntegerToUnsignedByteArray(bigIntA, 3); - - assertArrayEquals(EXPECTED_BYTE_ARRAY_A_3, byteArrayA3); - byte[] byteArrayB3 = BigIntegerUtils.bigIntegerToUnsignedByteArray(bigIntB, 3); - assertArrayEquals(EXPECTED_BYTE_ARRAY_B_3, byteArrayB3); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java b/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java deleted file mode 100644 index 23305aa7..00000000 --- a/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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.internal.net.utils; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -public class LogTest { - private static final String TAG = "IkeLogTest"; - private static final String PII = "123456789ABCDEF"; // "IMSI" - private static final String HEX_STRING = "00112233445566778899AABBCCDDEEFF"; - private static final byte[] HEX_BYTES = new byte[] { - (byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55, - (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xAA, (byte) 0xBB, - (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF - }; - - @Test - public void testPii() { - // Log(String tag, boolean isEngBuild, boolean logSensitive); - String result = new Log(TAG, false, false).pii(PII); - assertEquals(Integer.toString(PII.hashCode()), result); - - result = new Log(TAG, true, false).pii(PII); - assertEquals(Integer.toString(PII.hashCode()), result); - - result = new Log(TAG, false, true).pii(PII); - assertEquals(Integer.toString(PII.hashCode()), result); - - result = new Log(TAG, true, true).pii(PII); - assertEquals(PII, result); - - result = new Log(TAG, true, true).pii(HEX_BYTES); - assertEquals(HEX_STRING, result); - } - - @Test - public void testByteArrayToHexString() { - assertEquals("", Log.byteArrayToHexString(null)); - - assertEquals("", Log.byteArrayToHexString(new byte[0])); - - assertEquals(HEX_STRING, Log.byteArrayToHexString(HEX_BYTES)); - } -} diff --git a/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java deleted file mode 100644 index 2ee8dc53..00000000 --- a/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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.internal.net.utils; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import com.android.internal.net.utils.SimpleStateMachine.SimpleState; - -import org.junit.Before; -import org.junit.Test; - -public class SimpleStateMachineTest { - private static final String INPUT = "input"; - private static final String OUTPUT = "output"; - - private SimpleStateMachine<String, String> mSimpleStateMachine; - private SimpleState mMockStartState; - private SimpleState mMockFinalState; - - @Before - public void setUp() { - mMockStartState = mock(SimpleState.class); - mMockFinalState = mock(SimpleState.class); - - mSimpleStateMachine = new SimpleStateMachine(){}; - mSimpleStateMachine.transitionTo(mMockStartState); - } - - @Test - public void testProcess() { - when(mMockStartState.process(INPUT)).thenReturn(OUTPUT); - String result = mSimpleStateMachine.process(INPUT); - assertEquals(OUTPUT, result); - verify(mMockStartState).process(INPUT); - } - - @Test - public void testTransitionTo() { - mSimpleStateMachine.transitionTo(mMockFinalState); - assertEquals(mMockFinalState, mSimpleStateMachine.mState); - } - - @Test - public void testTransitionToNull() { - try { - mSimpleStateMachine.transitionTo(null); - fail("IllegalArgumentException expected"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testTransitionAndProcess() { - when(mMockFinalState.process(INPUT)).thenReturn(OUTPUT); - String result = mSimpleStateMachine.transitionAndProcess(mMockFinalState, INPUT); - assertEquals(OUTPUT, result); - verify(mMockFinalState).process(INPUT); - } - - @Test - public void testTransitionAndProcessToNull() { - try { - mSimpleStateMachine.transitionAndProcess(null, INPUT); - fail("IllegalArgumentException expected"); - } catch (IllegalArgumentException expected) { - } - } - - @Test - public void testProcessNullState() { - SimpleStateMachine simpleStateMachine = new SimpleStateMachine() {}; - try { - simpleStateMachine.process(new Object()); - fail("IllegalStateException expected"); - } catch (IllegalStateException expected) { - } - } -} |