diff options
Diffstat (limited to 'tests/iketests')
9 files changed, 430 insertions, 125 deletions
diff --git a/tests/iketests/AndroidManifest.xml b/tests/iketests/AndroidManifest.xml index 0abddbaa..bdcfdb71 100644 --- a/tests/iketests/AndroidManifest.xml +++ b/tests/iketests/AndroidManifest.xml @@ -22,6 +22,8 @@ <uses-permission android:name="android.permission.INTERNET"/> <!--Allow tests to call ConnectivityManager#getActiveNetwork()--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + <!--Allow tests to use wake locks--> + <uses-permission android:name="android.permission.WAKE_LOCK"/> <!-- 'debuggable=true' is required to properly load mockito jvmti dependencies, diff --git a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java index d4efb0c3..0c98bfa0 100644 --- a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java +++ b/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java @@ -16,8 +16,15 @@ package android.net.ipsec.ike; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_1024_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.DH_GROUP_2048_BIT_MODP; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12; +import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8; +import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE; import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128; import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC; +import static android.net.ipsec.ike.SaProposal.PSEUDORANDOM_FUNCTION_SHA2_256; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -318,4 +325,30 @@ public final class SaProposalTest { new Transform[] {mIntegrityNoneTransform}, new Transform[] {mIntegrityHmacSha1Transform})); } + + @Test + public void testIsNegotiatedFromProposalWithIntegrityNone() throws Exception { + SaProposal respProposal = + new IkeSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) + .addDhGroup(DH_GROUP_2048_BIT_MODP) + .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC) + .build(); + + SaProposal reqProposal = + new IkeSaProposal.Builder() + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_12, SaProposal.KEY_LEN_AES_128) + .addEncryptionAlgorithm( + ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_128) + .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_NONE) + .addDhGroup(DH_GROUP_1024_BIT_MODP) + .addDhGroup(DH_GROUP_2048_BIT_MODP) + .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_AES128_XCBC) + .addPseudorandomFunction(PSEUDORANDOM_FUNCTION_SHA2_256) + .build(); + + assertTrue(respProposal.isNegotiatedFrom(reqProposal)); + } } 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 index 20e4b76b..e20d0b1d 100644 --- 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 @@ -22,6 +22,7 @@ import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_T import static android.system.OsConstants.AF_INET; import static com.android.internal.net.TestUtils.createMockRandomFactory; +import static com.android.internal.net.ipsec.ike.AbstractSessionStateMachine.RETRY_INTERVAL_MS; 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; @@ -47,11 +48,9 @@ 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; @@ -77,6 +76,7 @@ import android.net.ipsec.ike.ChildSessionCallback; import android.net.ipsec.ike.ChildSessionConfiguration; import android.net.ipsec.ike.ChildSessionParams; import android.net.ipsec.ike.IkeManager; +import android.net.ipsec.ike.IkeSaProposal; import android.net.ipsec.ike.IkeTrafficSelector; import android.net.ipsec.ike.SaProposal; import android.net.ipsec.ike.TunnelModeChildSessionParams; @@ -224,8 +224,9 @@ public final class ChildSessionStateMachineTest { private ArgumentMatcher<ChildLocalRequest> mRekeyChildLocalReqMatcher = (argument) -> { - return CMD_LOCAL_REQUEST_REKEY_CHILD == argument.procedureType - && mMockChildSessionCallback == argument.childSessionCallback; + return (CMD_LOCAL_REQUEST_REKEY_CHILD == argument.procedureType + && mMockChildSessionCallback == argument.childSessionCallback + || CURRENT_CHILD_SA_SPI_OUT == argument.remoteSpi); }; public ChildSessionStateMachineTest() { @@ -270,19 +271,7 @@ public final class ChildSessionStateMachineTest { // Setup thread and looper mLooper = new TestLooper(); - mChildSessionStateMachine = - new ChildSessionStateMachine( - mLooper.getLooper(), - mContext, - IKE_SESSION_UNIQUE_ID, - mMockAlarmManager, - createMockRandomFactory(), - mMockIpSecManager, - mIpSecSpiGenerator, - mChildSessionParams, - mSpyUserCbExecutor, - mMockChildSessionCallback, - mMockChildSessionSmCallback); + mChildSessionStateMachine = buildChildSession(mChildSessionParams); mChildSessionStateMachine.setDbg(true); SaRecord.setSaRecordHelper(mMockSaRecordHelper); @@ -396,7 +385,6 @@ public final class ChildSessionStateMachineTest { null, mock(IpSecTransform.class), mock(IpSecTransform.class), - mock(ChildLocalRequest.class), mock(SaLifetimeAlarmScheduler.class))); doNothing().when(child).close(); return child; @@ -438,11 +426,7 @@ public final class ChildSessionStateMachineTest { assertFalse(childSaRecordConfig.isTransport); assertEquals(isLocalInit, childSaRecordConfig.isLocalInit); assertTrue(childSaRecordConfig.hasIntegrityAlgo); - assertEquals( - CMD_LOCAL_REQUEST_REKEY_CHILD, childSaRecordConfig.futureRekeyEvent.procedureType); - assertEquals( - mMockChildSessionCallback, - childSaRecordConfig.futureRekeyEvent.childSessionCallback); + assertNotNull(childSaRecordConfig.saLifetimeAlarmScheduler); } private void verifyNotifyUsersCreateIpSecSa( @@ -492,8 +476,6 @@ public final class ChildSessionStateMachineTest { verify(mMockChildSessionSmCallback) .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine); assertTrue( mChildSessionStateMachine.getCurrentState() @@ -951,6 +933,14 @@ public final class ChildSessionStateMachineTest { (IkeSaPayload) (IkeTestUtils.hexStringToIkePayload( IkePayload.PAYLOAD_TYPE_SA, true, inboundSaHexString)); + + return makeInboundRekeyChildPayloads(remoteSpi, saPayload, isLocalInitRekey); + } + + private List<IkePayload> makeInboundRekeyChildPayloads( + int remoteSpi, IkeSaPayload saPayload, boolean isLocalInitRekey) throws Exception { + List<IkePayload> inboundPayloads = new LinkedList<>(); + inboundPayloads.add(saPayload); // Build TS Payloads @@ -1023,8 +1013,6 @@ public final class ChildSessionStateMachineTest { .onChildSaCreated( eq(mSpyLocalInitNewChildSaRecord.getRemoteSpi()), eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); verify(mMockSaRecordHelper) .makeChildSaRecord( @@ -1061,9 +1049,7 @@ public final class ChildSessionStateMachineTest { mLooper.dispatchAll(); // Verify rekey has been rescheduled and Child Session is alive - verify(mMockChildSessionSmCallback) - .scheduleRetryLocalRequest( - (ChildLocalRequest) mSpyCurrentChildSaRecord.getFutureRekeyEvent()); + verify(mSpyCurrentChildSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); assertTrue( mChildSessionStateMachine.getCurrentState() instanceof ChildSessionStateMachine.Idle); @@ -1261,6 +1247,8 @@ public final class ChildSessionStateMachineTest { IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads); mLooper.dispatchAll(); + assertEquals(0, mChildSessionStateMachine.mSaProposal.getDhGroups().size()); + assertTrue( mChildSessionStateMachine.getCurrentState() instanceof ChildSessionStateMachine.RekeyChildRemoteDelete); @@ -1287,8 +1275,6 @@ public final class ChildSessionStateMachineTest { .onChildSaCreated( eq(mSpyRemoteInitNewChildSaRecord.getRemoteSpi()), eq(mChildSessionStateMachine)); - verify(mMockChildSessionSmCallback) - .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong()); verify(mMockSaRecordHelper) .makeChildSaRecord( @@ -1674,4 +1660,123 @@ public final class ChildSessionStateMachineTest { verifyHandleFatalErrorAndQuit(IkeInternalException.class); verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); } + + @Test + public void testFirstChildLocalRekey() throws Exception { + ChildSaProposal saProposal = buildSaProposalWithDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP); + ChildSessionParams childSessionParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(saProposal) + .addInternalAddressRequest(AF_INET) + .addInternalAddressRequest(INTERNAL_ADDRESS) + .build(); + mChildSessionStateMachine = buildChildSession(childSessionParams); + mChildSessionStateMachine.mIsFirstChild = true; + mChildSessionStateMachine.setDbg(true); + mChildSessionStateMachine.start(); + + setupIdleStateMachine(); + + assertEquals(0, mChildSessionStateMachine.mSaProposal.getDhGroups().size()); + + // Send Rekey-Create request + mChildSessionStateMachine.rekeyChildSession(); + mLooper.dispatchAll(); + + assertTrue( + mChildSessionStateMachine.getCurrentState() + instanceof ChildSessionStateMachine.RekeyChildLocalCreate); + + verifyOutboundRekeyKePayload(false /*isResp*/); + } + + private void verifyOutboundRekeyKePayload(boolean isResp) { + verify(mMockChildSessionSmCallback) + .onOutboundPayloadsReady( + eq(EXCHANGE_TYPE_CREATE_CHILD_SA), + eq(isResp), + mPayloadListCaptor.capture(), + eq(mChildSessionStateMachine)); + + // Verify outbound payload list + List<IkePayload> reqPayloadList = mPayloadListCaptor.getValue(); + + assertNotNull( + IkePayload.getPayloadForTypeInProvidedList( + PAYLOAD_TYPE_KE, IkeKePayload.class, reqPayloadList)); + } + + private ChildSessionStateMachine buildChildSession(ChildSessionParams childSessionParams) { + return new ChildSessionStateMachine( + mLooper.getLooper(), + mContext, + IKE_SESSION_UNIQUE_ID, + mMockAlarmManager, + createMockRandomFactory(), + mMockIpSecManager, + mIpSecSpiGenerator, + childSessionParams, + mSpyUserCbExecutor, + mMockChildSessionCallback, + mMockChildSessionSmCallback); + } + + private ChildSaProposal buildSaProposalWithDhGroup(int dhGroup) { + return new ChildSaProposal.Builder() + .addEncryptionAlgorithm( + SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) + .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) + .addDhGroup(dhGroup) + .build(); + } + + @Test + public void testRemoteRekeyWithKePayload() throws Exception { + // Use child session params with dh group to initiate the state machine + ChildSaProposal saProposal = buildSaProposalWithDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP); + ChildSessionParams childSessionParams = + new TunnelModeChildSessionParams.Builder() + .addSaProposal(saProposal) + .addInternalAddressRequest(AF_INET) + .addInternalAddressRequest(INTERNAL_ADDRESS) + .build(); + mChildSessionStateMachine = buildChildSession(childSessionParams); + mChildSessionStateMachine.setDbg(true); + mChildSessionStateMachine.start(); + + 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); + + IkeSaPayload saPayload = + IkeSaPayload.createChildSaRequestPayload( + new ChildSaProposal[] {saProposal}, mIpSecSpiGenerator, LOCAL_ADDRESS); + List<IkePayload> rekeyReqPayloads = + makeInboundRekeyChildPayloads( + REMOTE_INIT_NEW_CHILD_SA_SPI_OUT, saPayload, false /*isLocalInitRekey*/); + + rekeyReqPayloads.add( + new IkeKePayload(IkeSaProposal.DH_GROUP_2048_BIT_MODP, createMockRandomFactory())); + + when(mMockSaRecordHelper.makeChildSaRecord( + eq(rekeyReqPayloads), any(List.class), any(ChildSaRecordConfig.class))) + .thenReturn(mSpyRemoteInitNewChildSaRecord); + + assertEquals(0, mChildSessionStateMachine.mSaProposal.getDhGroups().size()); + + // 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); + + verifyOutboundRekeyKePayload(true /*isResp*/); + + assertEquals(1, mChildSessionStateMachine.mSaProposal.getDhGroups().size()); + } } 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 index 8fb4ebba..6fe4aada 100644 --- 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 @@ -18,7 +18,9 @@ package com.android.internal.net.ipsec.ike; import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND; +import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE; 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; @@ -28,7 +30,7 @@ import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_INET6; import static com.android.internal.net.TestUtils.createMockRandomFactory; -import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE; +import static com.android.internal.net.ipsec.ike.AbstractSessionStateMachine.RETRY_INTERVAL_MS; 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; @@ -67,6 +69,7 @@ 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.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; @@ -641,10 +644,25 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { new byte[KEY_LEN_IKE_ENCR], TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING), TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING), - new IkeLocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE), mock(SaLifetimeAlarmScheduler.class)); } + private void mockScheduleRekey(SaLifetimeAlarmScheduler mockSaLifetimeAlarmScheduler) { + IkeLocalRequest rekeyReq = + new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); + doAnswer( + (invocation) -> { + mIkeSessionStateMachine.sendMessageDelayed( + IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, + rekeyReq, + mIkeSessionStateMachine.mIkeSessionParams + .getSoftLifetimeMsInternal()); + return null; + }) + .when(mockSaLifetimeAlarmScheduler) + .scheduleLifetimeExpiryAlarm(anyString()); + } + @Before public void setUp() throws Exception { super.setUp(); @@ -755,13 +773,11 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { ikeSession.mLocalAddress = LOCAL_ADDRESS; assertEquals(REMOTE_ADDRESS, ikeSession.mRemoteAddress); - // Get socket instances used by the IkeSessionStateMachine by virtue of the caching. - mSpyIkeUdp4Socket = spy(IkeUdp4Socket.getInstance(mMockDefaultNetwork, ikeSession)); - mSpyIkeUdp6Socket = spy(IkeUdp6Socket.getInstance(mMockDefaultNetwork, ikeSession)); - mSpyIkeUdpEncapSocket = - spy( - IkeUdpEncapSocket.getIkeUdpEncapSocket( - mMockDefaultNetwork, mIpSecManager, ikeSession)); + // Setup socket instances used by the IkeSessionStateMachine + // TODO: rename these from spy to mock. + mSpyIkeUdp4Socket = mock(IkeUdp4Socket.class); + mSpyIkeUdp6Socket = mock(IkeUdp6Socket.class); + mSpyIkeUdpEncapSocket = mock(IkeUdpEncapSocket.class); doNothing().when(mSpyIkeUdp4Socket).sendIkePacket(any(), any()); doNothing().when(mSpyIkeUdp6Socket).sendIkePacket(any(), any()); @@ -1182,7 +1198,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { mLooper.dispatchAll(); verify(mSpyCurrentIkeSocket).releaseReference(eq(mIkeSessionStateMachine)); - verify(mSpyCurrentIkeSocket).close(); + verify(mMockBusyWakelock).release(); } @Test @@ -1216,6 +1232,9 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { .thenAnswer( (invocation) -> { captureAndReleaseIkeSpiResource(invocation, 2); + mockScheduleRekey(mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler); + mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler + .scheduleLifetimeExpiryAlarm(anyString()); return mSpyCurrentIkeSaRecord; }); } @@ -1228,6 +1247,9 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { .thenAnswer( (invocation) -> { captureAndReleaseIkeSpiResource(invocation, 4); + mockScheduleRekey(rekeySaRecord.mSaLifetimeAlarmScheduler); + rekeySaRecord.mSaLifetimeAlarmScheduler.scheduleLifetimeExpiryAlarm( + anyString()); return rekeySaRecord; }); } @@ -1268,7 +1290,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { public void testEnableTestMode() throws Exception { doReturn(true) .when(mMockNetworkCapabilities) - .hasCapability(RandomnessFactory.NETWORK_CAPABILITY_TRANSPORT_TEST); + .hasTransport(RandomnessFactory.TRANSPORT_TEST); IkeSessionStateMachine ikeSession = makeAndStartIkeSession(buildIkeSessionParams()); @@ -1281,7 +1303,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { public void testDisableTestMode() throws Exception { doReturn(false) .when(mMockNetworkCapabilities) - .hasCapability(RandomnessFactory.NETWORK_CAPABILITY_TRANSPORT_TEST); + .hasTransport(RandomnessFactory.TRANSPORT_TEST); IkeSessionStateMachine ikeSession = makeAndStartIkeSession(buildIkeSessionParams()); @@ -1331,9 +1353,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { // Validate socket switched assertTrue(mIkeSessionStateMachine.mIkeSocket instanceof IkeUdpEncapSocket); verify(mSpyIkeUdp4Socket).unregisterIke(anyLong()); - - // Validate keepalive has started - verify(mMockSocketKeepalive).start(anyInt()); } @Ignore @@ -1403,7 +1422,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { 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); + assertNotNull(ikeSaRecordConfig.saLifetimeAlarmScheduler); // Validate NAT detection assertTrue(mIkeSessionStateMachine.mIsLocalBehindNat); @@ -1441,6 +1460,8 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { /** Initializes the mIkeSessionStateMachine in the IDLE state. */ private void setupIdleStateMachine() throws Exception { + verify(mMockBusyWakelock).acquire(); + setIkeInitResults(); mIkeSessionStateMachine.sendMessage( @@ -1453,6 +1474,11 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { assertTrue( mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); + + verify(mMockBusyWakelock).release(); + + // For convenience to verify wakelocks in all other places. + reset(mMockBusyWakelock); } private void mockIkeInitAndTransitionToIkeAuth(State authState) throws Exception { @@ -1614,6 +1640,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.ChildProcedureOngoing); verify(mMockChildSessionStateMachine).deleteChildSession(); + verify(mMockBusyWakelock).acquire(); } @Test @@ -1648,6 +1675,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.ChildProcedureOngoing); verify(mMockChildSessionStateMachine).rekeyChildSession(); + verify(mMockBusyWakelock).acquire(); } @Test @@ -1787,6 +1815,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); assertEquals(1, payloadList.size()); assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); + verify(mMockBusyWakelock).acquire(); } @Test @@ -2501,6 +2530,48 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { } @Test + public void testAuthHandlesIkeErrorNotify() throws Exception { + mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); + verifyRetransmissionStarted(); + resetMockIkeMessageHelper(); + + // Mock rejecting IKE AUTH with Authenticatio Failure notification + ReceivedIkePacket mockAuthFailPacket = + makeIkeAuthRespWithoutChildPayloads( + Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED))); + mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); + mLooper.dispatchAll(); + + // Verify IKE Session is closed properly + assertNull(mIkeSessionStateMachine.getCurrentState()); + verify(mMockIkeSessionCallback) + .onClosedExceptionally(any(AuthenticationFailedException.class)); + } + + @Test + public void testAuthHandlesCreateChildErrorNotify() throws Exception { + mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); + verifyRetransmissionStarted(); + resetMockIkeMessageHelper(); + + // Mock rejecting IKE AUTH with a Create Child error notification + ReceivedIkePacket mockAuthFailPacket = + makeIkeAuthRespWithoutChildPayloads( + Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE))); + mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); + mLooper.dispatchAll(); + + // Verify IKE Session is closed properly + assertNull(mIkeSessionStateMachine.getCurrentState()); + + ArgumentCaptor<IkeProtocolException> captor = + ArgumentCaptor.forClass(IkeProtocolException.class); + verify(mMockIkeSessionCallback).onClosedExceptionally(captor.capture()); + IkeProtocolException exception = captor.getValue(); + assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, exception.getErrorType()); + } + + @Test public void testAuthPskHandleRespWithParsingError() throws Exception { mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); verifyRetransmissionStarted(); @@ -3077,17 +3148,10 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); mLooper.dispatchAll(); - // Verify IKE Session goes back to Idle + // Verify IKE Session goes back to Idle and retry is scheduled + verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 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 @@ -3189,6 +3253,40 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); } + private void mockRescheduleRekey(IkeSaRecord spySaRecord) { + IkeLocalRequest rekeyReq = + new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); + doAnswer( + (invocation) -> { + mIkeSessionStateMachine.sendMessageDelayed( + IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, + rekeyReq, + RETRY_INTERVAL_MS); + return null; + }) + .when(spySaRecord) + .rescheduleRekey(eq(RETRY_INTERVAL_MS)); + } + + @Test + public void testRekeyIkeLocalCreateHandleRespWithTempFailure() throws Exception { + setupIdleStateMachine(); + + // Send Rekey-Create request + mIkeSessionStateMachine.sendMessage( + IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, + new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); + mLooper.dispatchAll(); + + // Mock sending TEMPORARY_FAILURE response + mockRcvTempFail(); + mLooper.dispatchAll(); + + verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); + assertTrue( + mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); + } + private void mockCreateAndTransitionToRekeyDeleteLocal() { // Seed fake rekey data and force transition to RekeyIkeLocalDelete mIkeSessionStateMachine.mLocalInitNewIkeSaRecord = mSpyLocalInitIkeSaRecord; @@ -4065,6 +4163,7 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { // Verify state machine quit properly assertNull(mIkeSessionStateMachine.getCurrentState()); + verify(mMockBusyWakelock).release(); } @Test @@ -4392,24 +4491,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { 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(); - } - @Ignore public void disableTestTempFailureHandlerTimeout() throws Exception { long currentTime = 0; @@ -4437,28 +4518,48 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { @Test public void testTempFailureHandlerCancelTimer() throws Exception { - mockSendRekeyChildReq(); + mockRescheduleRekey(mSpyCurrentIkeSaRecord); + setupIdleStateMachine(); + + // Send Rekey-Create request + mIkeSessionStateMachine.sendMessage( + IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, + new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); + mLooper.dispatchAll(); + verifyRetransmissionStarted(); // Mock sending TEMPORARY_FAILURE response mockRcvTempFail(); + mLooper.dispatchAll(); + verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); + assertTrue( + mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); // Move time forward to trigger retry mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); mLooper.dispatchAll(); - verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession(); + assertTrue( + mIkeSessionStateMachine.getCurrentState() + instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); - // 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); + // Prepare "rekeyed" SA + setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); + + // Receive valid Rekey-Create response + ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); mIkeSessionStateMachine.sendMessage( - IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); + IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); mLooper.dispatchAll(); + // Receive Delete response + ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = + makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); + mIkeSessionStateMachine.sendMessage( + IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); + mLooper.dispatchAll(); + assertTrue( + mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); + // Move time forward mLooper.moveTimeForward(IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS); mLooper.dispatchAll(); @@ -4466,8 +4567,6 @@ public final class IkeSessionStateMachineTest extends IkeSessionTestBase { // Validate IKE Session is not closed assertTrue( mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); - // Validate no more retry - verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession(); } @Ignore diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java index 3728f368..e4e83794 100644 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java +++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionTestBase.java @@ -18,8 +18,11 @@ package com.android.internal.net.ipsec.ike; import static org.mockito.Matchers.any; import static org.mockito.Mockito.any; +import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.anyString; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -33,6 +36,7 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.SocketKeepalive; import android.os.Handler; +import android.os.PowerManager; import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils; import com.android.internal.net.ipsec.ike.utils.IkeAlarmReceiver; @@ -50,9 +54,12 @@ public abstract class IkeSessionTestBase { (Inet4Address) (InetAddresses.parseNumericAddress("127.0.0.1")); protected static final String REMOTE_HOSTNAME = "ike.test.android.com"; + protected PowerManager.WakeLock mMockBusyWakelock; + protected MockIpSecTestUtils mMockIpSecTestUtils; protected Context mSpyContext; protected IpSecManager mIpSecManager; + protected PowerManager mPowerManager; protected ConnectivityManager mMockConnectManager; protected Network mMockDefaultNetwork; @@ -74,6 +81,11 @@ public abstract class IkeSessionTestBase { any(Handler.class)); doNothing().when(mSpyContext).unregisterReceiver(any(IkeAlarmReceiver.class)); + mPowerManager = mock(PowerManager.class); + mMockBusyWakelock = mock(PowerManager.WakeLock.class); + doReturn(mPowerManager).when(mSpyContext).getSystemService(eq(PowerManager.class)); + doReturn(mMockBusyWakelock).when(mPowerManager).newWakeLock(anyInt(), anyString()); + mMockConnectManager = mock(ConnectivityManager.class); mMockDefaultNetwork = mock(Network.class); doReturn(mMockDefaultNetwork).when(mMockConnectManager).getActiveNetwork(); @@ -102,6 +114,6 @@ public abstract class IkeSessionTestBase { .getNetworkCapabilities(any(Network.class)); doReturn(false) .when(mMockNetworkCapabilities) - .hasCapability(RandomnessFactory.NETWORK_CAPABILITY_TRANSPORT_TEST); + .hasTransport(RandomnessFactory.TRANSPORT_TEST); } } diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java index 8c0bf4d5..439fa27e 100644 --- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java +++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeUdpEncapSocketTest.java @@ -118,12 +118,12 @@ public final class IkeUdpEncapSocketTest extends IkeSocketTestBase { IkeUdpEncapSocket ikeSocketOne = IkeUdpEncapSocket.getIkeUdpEncapSocket( - mMockNetwork, mSpyIpSecManager, mockIkeSessionOne); + mMockNetwork, mSpyIpSecManager, mockIkeSessionOne, Looper.myLooper()); assertEquals(1, ikeSocketOne.mAliveIkeSessions.size()); IkeUdpEncapSocket ikeSocketTwo = IkeUdpEncapSocket.getIkeUdpEncapSocket( - mMockNetwork, mSpyIpSecManager, mockIkeSessionTwo); + mMockNetwork, mSpyIpSecManager, mockIkeSessionTwo, Looper.myLooper()); assertEquals(2, ikeSocketTwo.mAliveIkeSessions.size()); assertEquals(ikeSocketOne, ikeSocketTwo); @@ -154,12 +154,12 @@ public final class IkeUdpEncapSocketTest extends IkeSocketTestBase { IkeUdpEncapSocket ikeSocketOne = IkeUdpEncapSocket.getIkeUdpEncapSocket( - mockNetworkOne, mSpyIpSecManager, mockIkeSessionOne); + mockNetworkOne, mSpyIpSecManager, mockIkeSessionOne, Looper.myLooper()); assertEquals(1, ikeSocketOne.mAliveIkeSessions.size()); IkeUdpEncapSocket ikeSocketTwo = IkeUdpEncapSocket.getIkeUdpEncapSocket( - mockNetworkTwo, mSpyIpSecManager, mockIkeSessionTwo); + mockNetworkTwo, mSpyIpSecManager, mockIkeSessionTwo, Looper.myLooper()); assertEquals(1, ikeSocketTwo.mAliveIkeSessions.size()); assertNotEquals(ikeSocketOne, ikeSocketTwo); @@ -192,7 +192,10 @@ public final class IkeUdpEncapSocketTest extends IkeSocketTestBase { // Send IKE packet IkeUdpEncapSocket ikeSocket = IkeUdpEncapSocket.getIkeUdpEncapSocket( - mMockNetwork, mSpyIpSecManager, mMockIkeSessionStateMachine); + mMockNetwork, + mSpyIpSecManager, + mMockIkeSessionStateMachine, + Looper.myLooper()); ikeSocket.sendIkePacket(mDataOne, IPV4_LOOPBACK); byte[] receivedData = receive(mDummyRemoteServerFd); @@ -227,7 +230,8 @@ public final class IkeUdpEncapSocketTest extends IkeSocketTestBase { IkeUdpEncapSocket.getIkeUdpEncapSocket( mMockNetwork, mSpyIpSecManager, - mMockIkeSessionStateMachine)); + mMockIkeSessionStateMachine, + mIkeThread.getLooper())); createLatch.countDown(); Log.d("IkeUdpEncapSocketTest", "IkeUdpEncapSocket created."); } catch (ErrnoException @@ -253,20 +257,18 @@ public final class IkeUdpEncapSocketTest extends IkeSocketTestBase { sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataOne, IPV4_LOOPBACK); receiveLatch.await(); - assertEquals(1, ikeSocket.numPacketsReceived()); assertArrayEquals(mDataOne, packetReceiver.mReceivedData); // Send second packet. sendToIkeUdpEncapSocket(mDummyRemoteServerFd, mDataTwo, IPV4_LOOPBACK); receiveLatch.await(); - assertEquals(2, ikeSocket.numPacketsReceived()); assertArrayEquals(mDataTwo, packetReceiver.mReceivedData); // Close IkeUdpEncapSocket. TestCountDownLatch closeLatch = new TestCountDownLatch(); - ikeSocket - .getHandler() + mIkeThread + .getThreadHandler() .post( () -> { ikeSocket.releaseReference(mMockIkeSessionStateMachine); 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 index 644ba066..b193099d 100644 --- 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 @@ -24,6 +24,7 @@ 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.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -38,8 +39,6 @@ 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.SaRecord.ChildSaRecord; import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecordConfig; import com.android.internal.net.ipsec.ike.SaRecord.IIpSecTransformHelper; @@ -148,9 +147,6 @@ public final class SaRecordTest { private IkeMacIntegrity mHmacSha1IntegrityMac; private IkeCipher mAesCbcCipher; - private LocalRequest mMockFutureRekeyIkeEvent; - private ChildLocalRequest mMockFutureRekeyChildEvent; - private SaLifetimeAlarmScheduler mMockLifetimeAlarmScheduler; private SaRecordHelper mSaRecordHelper = new SaRecordHelper(); @@ -168,8 +164,6 @@ public final class SaRecordTest { SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)); - mMockFutureRekeyIkeEvent = mock(LocalRequest.class); - mMockFutureRekeyChildEvent = mock(ChildLocalRequest.class); mMockLifetimeAlarmScheduler = mock(SaLifetimeAlarmScheduler.class); } @@ -192,8 +186,7 @@ public final class SaRecordTest { IKE_AUTH_ALGO_KEY_LEN, IKE_ENCR_ALGO_KEY_LEN, true /*isLocalInit*/, - mMockFutureRekeyIkeEvent, - mock(SaLifetimeAlarmScheduler.class)); + mMockLifetimeAlarmScheduler); int keyMaterialLen = IKE_SK_D_KEY_LEN @@ -225,10 +218,10 @@ public final class SaRecordTest { TestUtils.hexStringToByteArray(IKE_SK_PRF_INIT_HEX_STRING), ikeSaRecord.getSkPi()); assertArrayEquals( TestUtils.hexStringToByteArray(IKE_SK_PRF_RESP_HEX_STRING), ikeSaRecord.getSkPr()); + verify(mMockLifetimeAlarmScheduler).scheduleLifetimeExpiryAlarm(anyString()); ikeSaRecord.close(); - - verify(mMockFutureRekeyIkeEvent).cancel(); + verify(mMockLifetimeAlarmScheduler).cancelLifetimeExpiryAlarm(anyString()); } // Test generating keying material and building IpSecTransform for making Child SA. @@ -306,7 +299,6 @@ public final class SaRecordTest { TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING), false /*isTransport*/, true /*isLocalInit*/, - mMockFutureRekeyChildEvent, mMockLifetimeAlarmScheduler); ChildSaRecord childSaRecord = @@ -332,8 +324,10 @@ public final class SaRecordTest { TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_RESP_HEX_STRING), childSaRecord.getInboundDecryptionKey()); + verify(mMockLifetimeAlarmScheduler).scheduleLifetimeExpiryAlarm(anyString()); + childSaRecord.close(); - verify(mMockFutureRekeyChildEvent).cancel(); + verify(mMockLifetimeAlarmScheduler).cancelLifetimeExpiryAlarm(anyString()); SaRecord.setIpSecTransformHelper(new IpSecTransformHelper()); } diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java new file mode 100644 index 00000000..f859a822 --- /dev/null +++ b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertReqPayloadTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2020 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.IkeCertPayload.CERTIFICATE_ENCODING_X509_CERT_SIGNATURE; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import android.util.Pair; + +import com.android.internal.net.TestUtils; + +import org.junit.Test; + +import java.nio.ByteBuffer; + +public class IkeCertReqPayloadTest { + private static final int CERT_ENCODING_TYPE = CERTIFICATE_ENCODING_X509_CERT_SIGNATURE; + private static final int NEXT_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_AUTH; + private static final byte[] CERT_REQ_PAYLOAD = + TestUtils.hexStringToByteArray("27000019040d0a12bb1f98996563f15b10db95c67eea7990fa"); + private static final byte[] CA_SUBJECT_PUBLIC_KEY_INFO_HASH = + TestUtils.hexStringToByteArray("0d0a12bb1f98996563f15b10db95c67eea7990fa"); + + @Test + public void testDecode() throws Exception { + Pair<IkePayload, Integer> pair = + IkePayloadFactory.getIkePayload( + IkePayload.PAYLOAD_TYPE_CERT_REQUEST, + false /*isResp*/, + ByteBuffer.wrap(CERT_REQ_PAYLOAD)); + + IkeCertReqPayload certPayload = (IkeCertReqPayload) pair.first; + assertEquals(CERT_ENCODING_TYPE, certPayload.certEncodingType); + assertArrayEquals( + CA_SUBJECT_PUBLIC_KEY_INFO_HASH, certPayload.caSubjectPublicKeyInforHashes); + + assertEquals(NEXT_PAYLOAD_TYPE, (int) pair.second); + } + + @Test + public void testEncode() throws Exception { + Pair<IkePayload, Integer> pair = + IkePayloadFactory.getIkePayload( + IkePayload.PAYLOAD_TYPE_CERT_REQUEST, + false /*isResp*/, + ByteBuffer.wrap(CERT_REQ_PAYLOAD)); + IkeCertReqPayload certPayload = (IkeCertReqPayload) pair.first; + + ByteBuffer byteBuffer = ByteBuffer.allocate(CERT_REQ_PAYLOAD.length); + certPayload.encodeToByteBuffer(NEXT_PAYLOAD_TYPE, byteBuffer); + assertArrayEquals(CERT_REQ_PAYLOAD, byteBuffer.array()); + + assertEquals(CERT_REQ_PAYLOAD.length, certPayload.getPayloadLength()); + } +} 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 index 884c76eb..0b3c3583 100644 --- 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 @@ -85,19 +85,6 @@ public final class IkeNotifyPayloadTest { } @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); |