1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.net.ipsec.ike; 18 19 import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; 20 import static android.net.ipsec.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; 21 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; 22 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND; 23 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE; 24 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX; 25 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS; 26 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; 27 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; 28 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD; 29 import static android.system.OsConstants.AF_INET; 30 import static android.system.OsConstants.AF_INET6; 31 32 import static com.android.internal.net.TestUtils.createMockRandomFactory; 33 import static com.android.internal.net.ipsec.ike.AbstractSessionStateMachine.RETRY_INTERVAL_MS; 34 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_FORCE_TRANSITION; 35 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET; 36 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD; 37 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD; 38 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.RETRY_INTERVAL_MS; 39 import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS; 40 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_APPLICATION_VERSION; 41 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS; 42 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK; 43 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS; 44 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_IP4_PCSCF; 45 import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_IP6_PCSCF; 46 import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA; 47 import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; 48 import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_EAP_ONLY_AUTHENTICATION; 49 import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED; 50 import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP; 51 import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP; 52 import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_SIGNATURE_HASH_ALGORITHMS; 53 import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_AUTH; 54 import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY; 55 import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA; 56 57 import static org.junit.Assert.assertArrayEquals; 58 import static org.junit.Assert.assertEquals; 59 import static org.junit.Assert.assertFalse; 60 import static org.junit.Assert.assertNotEquals; 61 import static org.junit.Assert.assertNotNull; 62 import static org.junit.Assert.assertNull; 63 import static org.junit.Assert.assertTrue; 64 import static org.junit.Assert.fail; 65 import static org.mockito.Matchers.any; 66 import static org.mockito.Matchers.anyBoolean; 67 import static org.mockito.Matchers.anyInt; 68 import static org.mockito.Matchers.anyLong; 69 import static org.mockito.Matchers.anyObject; 70 import static org.mockito.Matchers.anyString; 71 import static org.mockito.Matchers.argThat; 72 import static org.mockito.Matchers.eq; 73 import static org.mockito.Mockito.doAnswer; 74 import static org.mockito.Mockito.doNothing; 75 import static org.mockito.Mockito.doReturn; 76 import static org.mockito.Mockito.doThrow; 77 import static org.mockito.Mockito.mock; 78 import static org.mockito.Mockito.never; 79 import static org.mockito.Mockito.reset; 80 import static org.mockito.Mockito.spy; 81 import static org.mockito.Mockito.times; 82 import static org.mockito.Mockito.verify; 83 import static org.mockito.Mockito.when; 84 85 import android.app.AlarmManager; 86 import android.content.Context; 87 import android.net.eap.EapSessionConfig; 88 import android.net.ipsec.ike.ChildSaProposal; 89 import android.net.ipsec.ike.ChildSessionCallback; 90 import android.net.ipsec.ike.ChildSessionParams; 91 import android.net.ipsec.ike.IkeFqdnIdentification; 92 import android.net.ipsec.ike.IkeIdentification; 93 import android.net.ipsec.ike.IkeIpv4AddrIdentification; 94 import android.net.ipsec.ike.IkeManager; 95 import android.net.ipsec.ike.IkeSaProposal; 96 import android.net.ipsec.ike.IkeSessionCallback; 97 import android.net.ipsec.ike.IkeSessionConfiguration; 98 import android.net.ipsec.ike.IkeSessionConnectionInfo; 99 import android.net.ipsec.ike.IkeSessionParams; 100 import android.net.ipsec.ike.SaProposal; 101 import android.net.ipsec.ike.TunnelModeChildSessionParams; 102 import android.net.ipsec.ike.exceptions.IkeException; 103 import android.net.ipsec.ike.exceptions.IkeInternalException; 104 import android.net.ipsec.ike.exceptions.IkeProtocolException; 105 import android.os.Looper; 106 import android.os.test.TestLooper; 107 import android.telephony.TelephonyManager; 108 109 import com.android.internal.net.TestUtils; 110 import com.android.internal.net.eap.EapAuthenticator; 111 import com.android.internal.net.eap.IEapCallback; 112 import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback; 113 import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.ChildSessionFactoryHelper; 114 import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.IChildSessionFactoryHelper; 115 import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest; 116 import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IkeLocalRequest; 117 import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.ReceivedIkePacket; 118 import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper; 119 import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord; 120 import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecordConfig; 121 import com.android.internal.net.ipsec.ike.SaRecord.SaLifetimeAlarmScheduler; 122 import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper; 123 import com.android.internal.net.ipsec.ike.crypto.IkeCipher; 124 import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity; 125 import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf; 126 import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException; 127 import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException; 128 import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException; 129 import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException; 130 import com.android.internal.net.ipsec.ike.message.IkeAuthDigitalSignPayload; 131 import com.android.internal.net.ipsec.ike.message.IkeAuthPayload; 132 import com.android.internal.net.ipsec.ike.message.IkeAuthPskPayload; 133 import com.android.internal.net.ipsec.ike.message.IkeCertX509CertPayload; 134 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload; 135 import com.android.internal.net.ipsec.ike.message.IkeDeletePayload; 136 import com.android.internal.net.ipsec.ike.message.IkeEapPayload; 137 import com.android.internal.net.ipsec.ike.message.IkeHeader; 138 import com.android.internal.net.ipsec.ike.message.IkeIdPayload; 139 import com.android.internal.net.ipsec.ike.message.IkeInformationalPayload; 140 import com.android.internal.net.ipsec.ike.message.IkeKePayload; 141 import com.android.internal.net.ipsec.ike.message.IkeMessage; 142 import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult; 143 import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk; 144 import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial; 145 import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultProtectedError; 146 import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultUnprotectedError; 147 import com.android.internal.net.ipsec.ike.message.IkeMessage.IIkeMessageHelper; 148 import com.android.internal.net.ipsec.ike.message.IkeMessage.IkeMessageHelper; 149 import com.android.internal.net.ipsec.ike.message.IkeNoncePayload; 150 import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload; 151 import com.android.internal.net.ipsec.ike.message.IkePayload; 152 import com.android.internal.net.ipsec.ike.message.IkeSaPayload; 153 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform; 154 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform; 155 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform; 156 import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform; 157 import com.android.internal.net.ipsec.ike.message.IkeSkfPayload; 158 import com.android.internal.net.ipsec.ike.message.IkeTestUtils; 159 import com.android.internal.net.ipsec.ike.message.IkeTsPayload; 160 import com.android.internal.net.ipsec.ike.testmode.DeterministicSecureRandom; 161 import com.android.internal.net.ipsec.ike.testutils.CertUtils; 162 import com.android.internal.net.ipsec.ike.utils.IkeSecurityParameterIndex; 163 import com.android.internal.net.ipsec.ike.utils.IkeSpiGenerator; 164 import com.android.internal.net.ipsec.ike.utils.IpSecSpiGenerator; 165 import com.android.internal.net.ipsec.ike.utils.RandomnessFactory; 166 import com.android.internal.net.ipsec.ike.utils.State; 167 import com.android.internal.net.utils.Log; 168 169 import org.junit.After; 170 import org.junit.Before; 171 import org.junit.Ignore; 172 import org.junit.Test; 173 import org.mockito.ArgumentCaptor; 174 import org.mockito.invocation.InvocationOnMock; 175 176 import java.io.IOException; 177 import java.net.Inet4Address; 178 import java.net.InetAddress; 179 import java.security.GeneralSecurityException; 180 import java.security.PrivateKey; 181 import java.security.SecureRandom; 182 import java.security.cert.X509Certificate; 183 import java.util.Arrays; 184 import java.util.Collections; 185 import java.util.HashMap; 186 import java.util.LinkedList; 187 import java.util.List; 188 import java.util.Map; 189 import java.util.concurrent.Executor; 190 191 public final class IkeSessionStateMachineTest extends IkeSessionTestBase { 192 private static final String TAG = "IkeSessionStateMachineTest"; 193 194 private static final String IKE_INIT_RESP_HEX_STRING = 195 "5f54bf6d8b48e6e1909232b3d1edcb5c21202220000000000000014c220000300000" 196 + "002c010100040300000c0100000c800e008003000008030000020300000802000002" 197 + "00000008040000022800008800020000fe014fefed55a4229928bfa3dad1ea6ffaca" 198 + "abfb5f5bdd71790e99a192530e3f849d3a3d96dc6e0a7a10ff6f72a6162103ac573c" 199 + "acd41d08b7a034cad8f5eab09c14ced5a9e4af5692dff028f21c1119dd75226b6af6" 200 + "b2f009245369c9892cc5742e5c94a254ebff052470771fb2cb4f29a35d8953e18a1a" 201 + "6c6fbc56acc188a5290000249756112ca539f5c25abacc7ee92b73091942a9c06950" 202 + "f98848f1af1694c4ddff2900001c00004004c53f054b976a25d75fde72dbf1c7b6c8" 203 + "c9aa9ca12900001c00004005b16d79b21c1bc89ca7350f42de805be0227e2ed62b00" 204 + "00080000401400000014882fe56d6fd20dbc2251613b2ebe5beb"; 205 private static final String IKE_SA_PAYLOAD_HEX_STRING = 206 "220000300000002c010100040300000c0100000c800e00800300000803000002030" 207 + "00008020000020000000804000002"; 208 private static final String IKE_REKEY_SA_PAYLOAD_HEX_STRING = 209 "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" 210 + "000080300000203000008020000020000000804000002"; 211 private static final String IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING = 212 "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" 213 + "00008030000020300000802000002000000080400000e"; 214 private static final int IKE_REKEY_SA_INITIATOR_SPI = 0xff; 215 private static final String KE_PAYLOAD_HEX_STRING = 216 "2800008800020000b4a2faf4bb54878ae21d638512ece55d9236fc50" 217 + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa" 218 + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd" 219 + "92f46bef84f0be7db860351843858f8acf87056e272377f7" 220 + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" 221 + "6bbeb08214c7071376079587"; 222 private static final String INVALID_KE_PAYLOAD_HEX_STRING = "0000000a00000011000e"; 223 private static final String NONCE_INIT_PAYLOAD_HEX_STRING = 224 "29000024c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; 225 private static final String NONCE_RESP_PAYLOAD_HEX_STRING = 226 "290000249756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; 227 private static final String NONCE_INIT_HEX_STRING = 228 "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; 229 private static final String NONCE_RESP_HEX_STRING = 230 "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; 231 private static final String NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING = 232 "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0"; 233 private static final String NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING = 234 "2900001c00004005d915368ca036004cb578ae3e3fb268509aeab190"; 235 private static final String FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING = "290000080000402e"; 236 private static final String SIGNATURE_HASH_SUPPORTED_PAYLOAD_HEX_STRING = 237 "2b00000F0000402f0001000200030004"; 238 private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000"; 239 private static final String NOTIFY_REKEY_IKE_PAYLOAD_HEX_STRING = "2100000800004009"; 240 private static final String ID_PAYLOAD_INITIATOR_HEX_STRING = 241 "290000180200000031313233343536373839414243444546"; 242 private static final String ID_PAYLOAD_RESPONDER_HEX_STRING = "2700000c010000007f000001"; 243 private static final String ID_PAYLOAD_RESPONDER_FQDN_HEX_STRING = 244 "2700001702000000696B652E616E64726F69642E6E6574"; 245 private static final String PSK_AUTH_RESP_PAYLOAD_HEX_STRING = 246 "2100001c0200000058f36412e9b7b38df817a9f7779b7a008dacdd25"; 247 private static final String GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING = 248 "300000580e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d413" 249 + "6b9f69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8e" 250 + "12c5d982aa4efdaeac36a02b222aa96242cc424"; 251 private static final String CHILD_SA_PAYLOAD_HEX_STRING = 252 "2c00002c0000002801030403cae7019f0300000c0100000c800e008003000008030" 253 + "000020000000805000000"; 254 private static final String TS_INIT_PAYLOAD_HEX_STRING = 255 "2d00001801000000070000100000ffff00000000ffffffff"; 256 private static final String TS_RESP_PAYLOAD_HEX_STRING = 257 "2900001801000000070000100000ffff000000000fffffff"; 258 private static final String VENDOR_ID_PAYLOAD_HEX_STRING = 259 "0000001852656d6f74652056656e646f72204944204f6e65"; 260 261 private static final String PSK_HEX_STRING = "6A756E69706572313233"; 262 263 private static final String PRF_KEY_INIT_HEX_STRING = 264 "094787780EE466E2CB049FA327B43908BC57E485"; 265 private static final String PRF_KEY_RESP_HEX_STRING = 266 "A30E6B08BE56C0E6BFF4744143C75219299E1BEB"; 267 268 private static final String CP_PAYLOAD_HEX_STRING = 269 "210000810200000000080011260010111067a17d000000000a" 270 + "f68e8640000a0010200148880067ff000643000d000000000" 271 + "00a0010200148880066ff000645000d0000000000150010200" 272 + "148880006713a00f10104000000050015001020014888000671" 273 + "3a00f101040000008900150010200148880005713a00e00104000000c9"; 274 private static final String PCSCF_IPV6_ADDRESS1 = "2001:4888:6:713a:f1:104:0:5"; 275 private static final String PCSCF_IPV6_ADDRESS2 = "2001:4888:6:713a:f1:104:0:89"; 276 private static final String PCSCF_IPV6_ADDRESS3 = "2001:4888:5:713a:e0:104:0:c9"; 277 278 private static final byte[] EAP_DUMMY_MSG = "EAP Message".getBytes(); 279 private static final byte[] REMOTE_VENDOR_ID_ONE = "Remote Vendor ID One".getBytes(); 280 private static final byte[] REMOTE_VENDOR_ID_TWO = "Remote Vendor ID Two".getBytes(); 281 282 private static final IkeIdentification LOCAL_ID_IPV4 = 283 new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS); 284 private static final IkeIdentification REMOTE_ID_FQDN = 285 new IkeFqdnIdentification("server.test.android.net"); 286 private static final IkeIdentification REMOTE_ID_IPV4 = 287 new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS); 288 289 private static final int KEY_LEN_IKE_INTE = 20; 290 private static final int KEY_LEN_IKE_ENCR = 16; 291 private static final int KEY_LEN_IKE_PRF = 20; 292 private static final int KEY_LEN_IKE_SKD = KEY_LEN_IKE_PRF; 293 294 private static final int CHILD_SPI_LOCAL = 0x2ad4c0a2; 295 private static final int CHILD_SPI_REMOTE = 0xcae7019f; 296 297 private static final int EAP_SIM_SUB_ID = 1; 298 299 private static final int PAYLOAD_TYPE_UNSUPPORTED = 127; 300 301 private static final long RETRANSMIT_BACKOFF_TIMEOUT_MS = 5000L; 302 303 private static final IkeSpiGenerator IKE_SPI_GENERATOR = 304 new IkeSpiGenerator(createMockRandomFactory()); 305 306 private IkeUdpEncapSocket mSpyIkeUdpEncapSocket; 307 private IkeUdp4Socket mSpyIkeUdp4Socket; 308 private IkeUdp6Socket mSpyIkeUdp6Socket; 309 private IkeSocket mSpyCurrentIkeSocket; 310 311 private TestLooper mLooper; 312 private IkeSessionStateMachine mIkeSessionStateMachine; 313 314 private byte[] mPsk; 315 316 private ChildSessionParams mChildSessionParams; 317 318 private Executor mSpyUserCbExecutor; 319 private IkeSessionCallback mMockIkeSessionCallback; 320 private ChildSessionCallback mMockChildSessionCallback; 321 322 private EncryptionTransform mIkeEncryptionTransform; 323 private IntegrityTransform mIkeIntegrityTransform; 324 private PrfTransform mIkePrfTransform; 325 private DhGroupTransform mIkeDhGroupTransform; 326 327 private IIkeMessageHelper mMockIkeMessageHelper; 328 private ISaRecordHelper mMockSaRecordHelper; 329 330 private ChildSessionStateMachine mMockChildSessionStateMachine; 331 private IChildSessionFactoryHelper mMockChildSessionFactoryHelper; 332 private IChildSessionSmCallback mDummyChildSmCallback; 333 334 private IkeSaRecord mSpyCurrentIkeSaRecord; 335 private IkeSaRecord mSpyLocalInitIkeSaRecord; 336 private IkeSaRecord mSpyRemoteInitIkeSaRecord; 337 338 private Log mSpyIkeLog; 339 340 private int mExpectedCurrentSaLocalReqMsgId; 341 private int mExpectedCurrentSaRemoteReqMsgId; 342 343 private EapSessionConfig mEapSessionConfig; 344 private IkeEapAuthenticatorFactory mMockEapAuthenticatorFactory; 345 private EapAuthenticator mMockEapAuthenticator; 346 347 private X509Certificate mRootCertificate; 348 private X509Certificate mServerEndCertificate; 349 private PrivateKey mUserPrivateKey; 350 private X509Certificate mUserEndCert; 351 352 private ArgumentCaptor<IkeMessage> mIkeMessageCaptor = 353 ArgumentCaptor.forClass(IkeMessage.class); 354 private ArgumentCaptor<IkeSaRecordConfig> mIkeSaRecordConfigCaptor = 355 ArgumentCaptor.forClass(IkeSaRecordConfig.class); 356 private ArgumentCaptor<IChildSessionSmCallback> mChildSessionSmCbCaptor = 357 ArgumentCaptor.forClass(IChildSessionSmCallback.class); 358 private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor = 359 ArgumentCaptor.forClass(List.class); 360 makeDummyReceivedIkeInitRespPacket( long initiatorSpi, long responderSpi, @IkeHeader.ExchangeType int eType, boolean isResp, boolean fromIkeInit, List<Integer> payloadTypeList, List<String> payloadHexStringList)361 private ReceivedIkePacket makeDummyReceivedIkeInitRespPacket( 362 long initiatorSpi, 363 long responderSpi, 364 @IkeHeader.ExchangeType int eType, 365 boolean isResp, 366 boolean fromIkeInit, 367 List<Integer> payloadTypeList, 368 List<String> payloadHexStringList) 369 throws Exception { 370 371 List<IkePayload> payloadList = 372 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); 373 // Build a remotely generated NAT_DETECTION_SOURCE_IP payload to mock a remote node's 374 // network that is not behind NAT. 375 IkePayload sourceNatPayload = 376 new IkeNotifyPayload( 377 NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP, 378 IkeNotifyPayload.generateNatDetectionData( 379 initiatorSpi, 380 responderSpi, 381 REMOTE_ADDRESS, 382 IkeSocket.SERVER_PORT_UDP_ENCAPSULATED)); 383 payloadList.add(sourceNatPayload); 384 return makeDummyUnencryptedReceivedIkePacket( 385 initiatorSpi, responderSpi, eType, isResp, fromIkeInit, payloadList); 386 } 387 makeDummyUnencryptedReceivedIkePacket( long initiatorSpi, long responderSpi, @IkeHeader.ExchangeType int eType, boolean isResp, boolean fromIkeInit, List<IkePayload> payloadList)388 private ReceivedIkePacket makeDummyUnencryptedReceivedIkePacket( 389 long initiatorSpi, 390 long responderSpi, 391 @IkeHeader.ExchangeType int eType, 392 boolean isResp, 393 boolean fromIkeInit, 394 List<IkePayload> payloadList) 395 throws Exception { 396 IkeMessage dummyIkeMessage = 397 makeDummyIkeMessageForTest( 398 initiatorSpi, 399 responderSpi, 400 eType, 401 isResp, 402 fromIkeInit, 403 0, 404 false /*isEncrypted*/, 405 payloadList); 406 407 byte[] dummyIkePacketBytes = new byte[0]; 408 doReturn(new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)) 409 .when(mMockIkeMessageHelper) 410 .decode(0, dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 411 412 return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 413 } 414 makeDummyEncryptedReceivedIkePacket( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, List<Integer> payloadTypeList, List<String> payloadHexStringList)415 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacket( 416 IkeSaRecord ikeSaRecord, 417 @IkeHeader.ExchangeType int eType, 418 boolean isResp, 419 List<Integer> payloadTypeList, 420 List<String> payloadHexStringList) 421 throws Exception { 422 List<IkePayload> payloadList = 423 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); 424 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 425 ikeSaRecord, eType, isResp, payloadList); 426 } 427 makeDummyEncryptedReceivedIkePacketWithPayloadList( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, List<IkePayload> payloadList)428 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( 429 IkeSaRecord ikeSaRecord, 430 @IkeHeader.ExchangeType int eType, 431 boolean isResp, 432 List<IkePayload> payloadList) 433 throws Exception { 434 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 435 ikeSaRecord, 436 eType, 437 isResp, 438 isResp 439 ? ikeSaRecord.getLocalRequestMessageId() 440 : ikeSaRecord.getRemoteRequestMessageId(), 441 payloadList, 442 new byte[0] /*dummyIkePacketBytes*/); 443 } 444 makeDummyEncryptedReceivedIkePacketWithPayloadList( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, int msgId, List<IkePayload> payloadList, byte[] dummyIkePacketBytes)445 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( 446 IkeSaRecord ikeSaRecord, 447 @IkeHeader.ExchangeType int eType, 448 boolean isResp, 449 int msgId, 450 List<IkePayload> payloadList, 451 byte[] dummyIkePacketBytes) 452 throws Exception { 453 boolean fromIkeInit = !ikeSaRecord.isLocalInit; 454 IkeMessage dummyIkeMessage = 455 makeDummyIkeMessageForTest( 456 ikeSaRecord.getInitiatorSpi(), 457 ikeSaRecord.getResponderSpi(), 458 eType, 459 isResp, 460 fromIkeInit, 461 msgId, 462 true /*isEncyprted*/, 463 payloadList); 464 465 setDecodeEncryptedPacketResult( 466 ikeSaRecord, 467 dummyIkeMessage.ikeHeader, 468 null /*collectedFrags*/, 469 new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)); 470 471 return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 472 } 473 makeDummyReceivedIkePacketWithInvalidSyntax( IkeSaRecord ikeSaRecord, boolean isResp, int eType)474 private ReceivedIkePacket makeDummyReceivedIkePacketWithInvalidSyntax( 475 IkeSaRecord ikeSaRecord, boolean isResp, int eType) { 476 return makeDummyReceivedIkePacketWithDecodingError( 477 ikeSaRecord, isResp, eType, new InvalidSyntaxException("IkeStateMachineTest")); 478 } 479 makeDummyReceivedIkePacketWithDecodingError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception)480 private ReceivedIkePacket makeDummyReceivedIkePacketWithDecodingError( 481 IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception) { 482 IkeHeader header = 483 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); 484 byte[] dummyPacket = new byte[0]; 485 doReturn(new DecodeResultProtectedError(exception, dummyPacket)) 486 .when(mMockIkeMessageHelper) 487 .decode(anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()); 488 489 return new ReceivedIkePacket(header, dummyPacket); 490 } 491 makeDummyReceivedIkePacketWithUnprotectedError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception)492 private ReceivedIkePacket makeDummyReceivedIkePacketWithUnprotectedError( 493 IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception) { 494 IkeHeader header = 495 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); 496 byte[] dummyPacket = new byte[0]; 497 doReturn(new DecodeResultUnprotectedError(exception)) 498 .when(mMockIkeMessageHelper) 499 .decode(anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()); 500 501 return new ReceivedIkePacket(header, dummyPacket); 502 } 503 makeDummyReceivedIkeFragmentPacket( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeSkfPayload skfPayload, int nextPayloadType, DecodeResultPartial collectedFrags)504 private ReceivedIkePacket makeDummyReceivedIkeFragmentPacket( 505 IkeSaRecord ikeSaRecord, 506 boolean isResp, 507 int eType, 508 IkeSkfPayload skfPayload, 509 int nextPayloadType, 510 DecodeResultPartial collectedFrags) { 511 IkeHeader header = 512 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 513 514 byte[] dummyPacket = new byte[0]; 515 DecodeResultPartial resultFrags = 516 new DecodeResultPartial( 517 header, dummyPacket, skfPayload, nextPayloadType, collectedFrags); 518 setDecodeEncryptedPacketResult(ikeSaRecord, header, collectedFrags, resultFrags); 519 520 return new ReceivedIkePacket(header, dummyPacket); 521 } 522 makeDummyReceivedLastIkeFragmentPacketOk( IkeSaRecord ikeSaRecord, boolean isResp, int eType, DecodeResultPartial collectedFrags, List<IkePayload> payloadList, byte[] firstFragBytes)523 private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketOk( 524 IkeSaRecord ikeSaRecord, 525 boolean isResp, 526 int eType, 527 DecodeResultPartial collectedFrags, 528 List<IkePayload> payloadList, 529 byte[] firstFragBytes) { 530 IkeHeader header = 531 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 532 533 IkeMessage completeMessage = new IkeMessage(header, payloadList); 534 535 setDecodeEncryptedPacketResult( 536 ikeSaRecord, 537 header, 538 collectedFrags, 539 new DecodeResultOk(completeMessage, firstFragBytes)); 540 541 return new ReceivedIkePacket(header, new byte[0] /*dummyIkePacketBytes*/); 542 } 543 makeDummyReceivedLastIkeFragmentPacketError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, DecodeResultPartial collectedFrags, IkeException exception)544 private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketError( 545 IkeSaRecord ikeSaRecord, 546 boolean isResp, 547 int eType, 548 DecodeResultPartial collectedFrags, 549 IkeException exception) { 550 IkeHeader header = 551 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 552 553 byte[] dummyIkePacketBytes = new byte[0]; 554 setDecodeEncryptedPacketResult( 555 ikeSaRecord, 556 header, 557 collectedFrags, 558 new DecodeResultProtectedError(exception, dummyIkePacketBytes)); 559 560 return new ReceivedIkePacket(header, dummyIkePacketBytes); 561 } 562 makeDummyIkeHeader( IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType)563 private IkeHeader makeDummyIkeHeader( 564 IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType) { 565 return new IkeHeader( 566 ikeSaRecord.getInitiatorSpi(), 567 ikeSaRecord.getResponderSpi(), 568 firstPayloadType, 569 eType, 570 isResp, 571 !ikeSaRecord.isLocalInit, 572 isResp 573 ? ikeSaRecord.getLocalRequestMessageId() 574 : ikeSaRecord.getRemoteRequestMessageId()); 575 } 576 setDecodeEncryptedPacketResult( IkeSaRecord ikeSaRecord, IkeHeader header, DecodeResultPartial collectedFrags, DecodeResult result)577 private void setDecodeEncryptedPacketResult( 578 IkeSaRecord ikeSaRecord, 579 IkeHeader header, 580 DecodeResultPartial collectedFrags, 581 DecodeResult result) { 582 doReturn(result) 583 .when(mMockIkeMessageHelper) 584 .decode( 585 anyInt(), 586 any(), 587 any(), 588 eq(ikeSaRecord), 589 eq(header), 590 any(), 591 eq(collectedFrags)); 592 } 593 makeDummyIkeMessageForTest( long initSpi, long respSpi, @IkeHeader.ExchangeType int eType, boolean isResp, boolean fromikeInit, int messageId, boolean isEncrypted, List<IkePayload> payloadList)594 private IkeMessage makeDummyIkeMessageForTest( 595 long initSpi, 596 long respSpi, 597 @IkeHeader.ExchangeType int eType, 598 boolean isResp, 599 boolean fromikeInit, 600 int messageId, 601 boolean isEncrypted, 602 List<IkePayload> payloadList) 603 throws Exception { 604 int firstPayloadType = 605 isEncrypted ? IkePayload.PAYLOAD_TYPE_SK : IkePayload.PAYLOAD_TYPE_NO_NEXT; 606 607 IkeHeader header = 608 new IkeHeader( 609 initSpi, respSpi, firstPayloadType, eType, isResp, fromikeInit, messageId); 610 611 return new IkeMessage(header, payloadList); 612 } 613 hexStrListToIkePayloadList( List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp)614 private static List<IkePayload> hexStrListToIkePayloadList( 615 List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp) 616 throws Exception { 617 List<IkePayload> payloadList = new LinkedList<>(); 618 for (int i = 0; i < payloadTypeList.size(); i++) { 619 payloadList.add( 620 IkeTestUtils.hexStringToIkePayload( 621 payloadTypeList.get(i), isResp, payloadHexStringList.get(i))); 622 } 623 return payloadList; 624 } 625 verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket)626 private void verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket) 627 throws Exception { 628 verify(mMockIkeMessageHelper) 629 .decode( 630 anyInt(), 631 any(), 632 any(), 633 eq(record), 634 eq(rcvPacket.ikeHeader), 635 eq(rcvPacket.ikePacketBytes), 636 eq(null)); 637 } 638 makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit)639 private static IkeSaRecord makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit) 640 throws IOException { 641 Inet4Address initAddress = isLocalInit ? LOCAL_ADDRESS : REMOTE_ADDRESS; 642 Inet4Address respAddress = isLocalInit ? REMOTE_ADDRESS : LOCAL_ADDRESS; 643 644 return new IkeSaRecord( 645 IKE_SPI_GENERATOR.allocateSpi(initAddress, initSpi), 646 IKE_SPI_GENERATOR.allocateSpi(respAddress, respSpi), 647 isLocalInit, 648 TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING), 649 TestUtils.hexStringToByteArray(NONCE_RESP_HEX_STRING), 650 new byte[KEY_LEN_IKE_SKD], 651 new byte[KEY_LEN_IKE_INTE], 652 new byte[KEY_LEN_IKE_INTE], 653 new byte[KEY_LEN_IKE_ENCR], 654 new byte[KEY_LEN_IKE_ENCR], 655 TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING), 656 TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING), 657 mock(SaLifetimeAlarmScheduler.class)); 658 } 659 mockScheduleRekey(SaLifetimeAlarmScheduler mockSaLifetimeAlarmScheduler)660 private void mockScheduleRekey(SaLifetimeAlarmScheduler mockSaLifetimeAlarmScheduler) { 661 IkeLocalRequest rekeyReq = 662 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); 663 doAnswer( 664 (invocation) -> { 665 mIkeSessionStateMachine.sendMessageDelayed( 666 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 667 rekeyReq, 668 mIkeSessionStateMachine.mIkeSessionParams 669 .getSoftLifetimeMsInternal()); 670 return null; 671 }) 672 .when(mockSaLifetimeAlarmScheduler) 673 .scheduleLifetimeExpiryAlarm(anyString()); 674 } 675 676 @Before setUp()677 public void setUp() throws Exception { 678 super.setUp(); 679 680 mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG); 681 IkeManager.setIkeLog(mSpyIkeLog); 682 683 mEapSessionConfig = 684 new EapSessionConfig.Builder() 685 .setEapSimConfig(EAP_SIM_SUB_ID, TelephonyManager.APPTYPE_USIM) 686 .build(); 687 688 mMockEapAuthenticatorFactory = mock(IkeEapAuthenticatorFactory.class); 689 mMockEapAuthenticator = mock(EapAuthenticator.class); 690 doReturn(mMockEapAuthenticator) 691 .when(mMockEapAuthenticatorFactory) 692 .newEapAuthenticator( 693 any(Looper.class), 694 any(IEapCallback.class), 695 any(Context.class), 696 any(EapSessionConfig.class), 697 any(RandomnessFactory.class)); 698 699 mRootCertificate = CertUtils.createCertFromPemFile("self-signed-ca-a.pem"); 700 mServerEndCertificate = CertUtils.createCertFromPemFile("end-cert-a.pem"); 701 mUserEndCert = CertUtils.createCertFromPemFile("end-cert-b.pem"); 702 mUserPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("end-cert-key-b.key"); 703 704 mPsk = TestUtils.hexStringToByteArray(PSK_HEX_STRING); 705 706 mChildSessionParams = buildChildSessionParams(); 707 708 mIkeEncryptionTransform = 709 new EncryptionTransform( 710 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128); 711 mIkeIntegrityTransform = 712 new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); 713 mIkePrfTransform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1); 714 mIkeDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP); 715 716 mSpyUserCbExecutor = 717 spy( 718 (command) -> { 719 command.run(); 720 }); 721 722 mMockIkeSessionCallback = mock(IkeSessionCallback.class); 723 mMockChildSessionCallback = mock(ChildSessionCallback.class); 724 725 mLooper = new TestLooper(); 726 727 mMockChildSessionStateMachine = mock(ChildSessionStateMachine.class); 728 mMockChildSessionFactoryHelper = mock(IChildSessionFactoryHelper.class); 729 ChildSessionStateMachineFactory.setChildSessionFactoryHelper( 730 mMockChildSessionFactoryHelper); 731 setupChildStateMachineFactory(mMockChildSessionStateMachine); 732 733 // Setup state machine 734 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsPsk(mPsk)); 735 736 mMockIkeMessageHelper = mock(IkeMessage.IIkeMessageHelper.class); 737 IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper); 738 resetMockIkeMessageHelper(); 739 740 mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class); 741 SaRecord.setSaRecordHelper(mMockSaRecordHelper); 742 743 mSpyCurrentIkeSaRecord = spy(makeDummyIkeSaRecord(11, 12, true)); 744 mSpyLocalInitIkeSaRecord = spy(makeDummyIkeSaRecord(21, 22, true)); 745 mSpyRemoteInitIkeSaRecord = spy(makeDummyIkeSaRecord(31, 32, false)); 746 747 mExpectedCurrentSaLocalReqMsgId = 0; 748 mExpectedCurrentSaRemoteReqMsgId = 0; 749 } 750 751 @After tearDown()752 public void tearDown() throws Exception { 753 mIkeSessionStateMachine.killSession(); 754 mLooper.dispatchAll(); 755 mIkeSessionStateMachine.setDbg(false); 756 757 mSpyCurrentIkeSaRecord.close(); 758 mSpyLocalInitIkeSaRecord.close(); 759 mSpyRemoteInitIkeSaRecord.close(); 760 761 IkeManager.resetIkeLog(); 762 IkeMessage.setIkeMessageHelper(new IkeMessageHelper()); 763 SaRecord.setSaRecordHelper(new SaRecordHelper()); 764 ChildSessionStateMachineFactory.setChildSessionFactoryHelper( 765 new ChildSessionFactoryHelper()); 766 } 767 makeAndStartIkeSession(IkeSessionParams ikeParams)768 private IkeSessionStateMachine makeAndStartIkeSession(IkeSessionParams ikeParams) 769 throws Exception { 770 IkeSessionStateMachine ikeSession = 771 new IkeSessionStateMachine( 772 mLooper.getLooper(), 773 mSpyContext, 774 mIpSecManager, 775 ikeParams, 776 mChildSessionParams, 777 mSpyUserCbExecutor, 778 mMockIkeSessionCallback, 779 mMockChildSessionCallback, 780 mMockEapAuthenticatorFactory); 781 ikeSession.setDbg(true); 782 783 mLooper.dispatchAll(); 784 ikeSession.mLocalAddress = LOCAL_ADDRESS; 785 assertEquals(REMOTE_ADDRESS, ikeSession.mRemoteAddress); 786 787 // Setup socket instances used by the IkeSessionStateMachine 788 // TODO: rename these from spy to mock. 789 mSpyIkeUdp4Socket = mock(IkeUdp4Socket.class); 790 mSpyIkeUdp6Socket = mock(IkeUdp6Socket.class); 791 mSpyIkeUdpEncapSocket = mock(IkeUdpEncapSocket.class); 792 793 doNothing().when(mSpyIkeUdp4Socket).sendIkePacket(any(), any()); 794 doNothing().when(mSpyIkeUdp6Socket).sendIkePacket(any(), any()); 795 doNothing().when(mSpyIkeUdpEncapSocket).sendIkePacket(any(), any()); 796 797 // Always start with unencap'd socket. 798 mSpyCurrentIkeSocket = mSpyIkeUdp4Socket; 799 ikeSession.mIkeSocket = mSpyCurrentIkeSocket; 800 return ikeSession; 801 } 802 buildSaProposal()803 public static IkeSaProposal buildSaProposal() throws Exception { 804 return buildSaProposalCommon().addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP).build(); 805 } 806 buildNegotiatedSaProposal()807 private static IkeSaProposal buildNegotiatedSaProposal() throws Exception { 808 return buildSaProposalCommon().build(); 809 } 810 buildSaProposalCommon()811 private static IkeSaProposal.Builder buildSaProposalCommon() throws Exception { 812 return new IkeSaProposal.Builder() 813 .addEncryptionAlgorithm( 814 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) 815 .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) 816 .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1) 817 .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP); 818 } 819 buildIkeSessionParamsCommon()820 private IkeSessionParams.Builder buildIkeSessionParamsCommon() throws Exception { 821 return new IkeSessionParams.Builder(mMockConnectManager) 822 .setServerHostname(REMOTE_ADDRESS.getHostAddress()) 823 .addSaProposal(buildSaProposal()) 824 .setLocalIdentification(LOCAL_ID_IPV4) 825 .setRemoteIdentification(REMOTE_ID_FQDN) 826 .addPcscfServerRequest(AF_INET) 827 .addPcscfServerRequest(AF_INET6) 828 .setRetransmissionTimeoutsMillis( 829 new int[] {5000, 10000, 20000, 30000, 40000, 50000}); 830 } 831 buildIkeSessionParams()832 private IkeSessionParams buildIkeSessionParams() throws Exception { 833 return buildIkeSessionParamsCommon().setAuthPsk(mPsk).build(); 834 } 835 buildIkeSessionParamsPsk(byte[] psk)836 private IkeSessionParams buildIkeSessionParamsPsk(byte[] psk) throws Exception { 837 return buildIkeSessionParamsCommon().setAuthPsk(psk).build(); 838 } 839 buildIkeSessionParamsEap()840 private IkeSessionParams buildIkeSessionParamsEap() throws Exception { 841 return buildIkeSessionParamsCommon() 842 .setAuthEap(mRootCertificate, mEapSessionConfig) 843 .build(); 844 } 845 buildIkeSessionParamsDigitalSignature()846 private IkeSessionParams buildIkeSessionParamsDigitalSignature() throws Exception { 847 return buildIkeSessionParamsCommon() 848 .setAuthDigitalSignature(mRootCertificate, mUserEndCert, mUserPrivateKey) 849 .build(); 850 } 851 buildChildSessionParams()852 private ChildSessionParams buildChildSessionParams() throws Exception { 853 ChildSaProposal saProposal = 854 new ChildSaProposal.Builder() 855 .addEncryptionAlgorithm( 856 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) 857 .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) 858 .build(); 859 860 return new TunnelModeChildSessionParams.Builder() 861 .addSaProposal(saProposal) 862 .addInternalAddressRequest(AF_INET) 863 .addInternalAddressRequest(AF_INET6) 864 .build(); 865 } 866 makeIkeInitResponse()867 private ReceivedIkePacket makeIkeInitResponse() throws Exception { 868 // TODO: Build real IKE INIT response when IKE INIT response validation is implemented. 869 List<Integer> payloadTypeList = new LinkedList<>(); 870 List<String> payloadHexStringList = new LinkedList<>(); 871 872 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 873 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 874 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 875 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 876 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 877 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 878 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 879 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_VENDOR); 880 881 payloadHexStringList.add(IKE_SA_PAYLOAD_HEX_STRING); 882 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 883 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 884 payloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING); 885 payloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING); 886 payloadHexStringList.add(FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING); 887 payloadHexStringList.add(SIGNATURE_HASH_SUPPORTED_PAYLOAD_HEX_STRING); 888 payloadHexStringList.add(VENDOR_ID_PAYLOAD_HEX_STRING); 889 890 // In each test assign different IKE responder SPI in IKE INIT response to avoid remote SPI 891 // collision during response validation. 892 // STOPSHIP: b/131617794 allow #mockIkeSetup to be independent in each test after we can 893 // support IkeSession cleanup. 894 return makeDummyReceivedIkeInitRespPacket( 895 1L /*initiator SPI*/, 896 2L /*responder SPI*/, 897 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 898 true /*isResp*/, 899 false /*fromIkeInit*/, 900 payloadTypeList, 901 payloadHexStringList); 902 } 903 getIkeAuthPayloadListWithChildPayloads( List<IkePayload> authRelatedPayloads)904 private List<IkePayload> getIkeAuthPayloadListWithChildPayloads( 905 List<IkePayload> authRelatedPayloads) throws Exception { 906 List<Integer> payloadTypeList = new LinkedList<>(); 907 List<String> payloadHexStringList = new LinkedList<>(); 908 909 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 910 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 911 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 912 913 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 914 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 915 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 916 917 List<IkePayload> payloadList = 918 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, true /*isResp*/); 919 payloadList.addAll(authRelatedPayloads); 920 921 return payloadList; 922 } 923 makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads)924 private ReceivedIkePacket makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads) 925 throws Exception { 926 List<IkePayload> payloadList = getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); 927 928 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 929 mSpyCurrentIkeSaRecord, 930 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 931 true /*isResp*/, 932 payloadList); 933 } 934 makeIkeAuthRespWithoutChildPayloads( List<IkePayload> authRelatedPayloads)935 private ReceivedIkePacket makeIkeAuthRespWithoutChildPayloads( 936 List<IkePayload> authRelatedPayloads) throws Exception { 937 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 938 mSpyCurrentIkeSaRecord, 939 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 940 true /*isResp*/, 941 authRelatedPayloads); 942 } 943 makeCreateChildCreateMessage(boolean isResp)944 private ReceivedIkePacket makeCreateChildCreateMessage(boolean isResp) throws Exception { 945 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 946 mSpyCurrentIkeSaRecord, 947 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 948 isResp, 949 makeCreateChildPayloadList(isResp)); 950 } 951 makeRekeyChildCreateMessage(boolean isResp, int spi)952 private ReceivedIkePacket makeRekeyChildCreateMessage(boolean isResp, int spi) 953 throws Exception { 954 IkeNotifyPayload rekeyPayload = 955 new IkeNotifyPayload( 956 IkePayload.PROTOCOL_ID_ESP, 957 spi, 958 IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA, 959 new byte[0]); 960 961 List<IkePayload> payloadList = makeCreateChildPayloadList(isResp); 962 payloadList.add(rekeyPayload); 963 964 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 965 mSpyCurrentIkeSaRecord, 966 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 967 isResp, 968 payloadList); 969 } 970 makeCreateChildPayloadList(boolean isResp)971 private List<IkePayload> makeCreateChildPayloadList(boolean isResp) throws Exception { 972 List<Integer> payloadTypeList = new LinkedList<>(); 973 List<String> payloadHexStringList = new LinkedList<>(); 974 975 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 976 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 977 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 978 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 979 980 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 981 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 982 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 983 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 984 985 return hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); 986 } 987 makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp)988 private ReceivedIkePacket makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp) 989 throws Exception { 990 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 991 mSpyCurrentIkeSaRecord, 992 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 993 isResp, 994 Arrays.asList(payloads)); 995 } 996 makeRekeyIkeResponse()997 private ReceivedIkePacket makeRekeyIkeResponse() throws Exception { 998 List<Integer> payloadTypeList = new LinkedList<>(); 999 List<String> payloadHexStringList = new LinkedList<>(); 1000 1001 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 1002 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 1003 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1004 1005 payloadHexStringList.add(IKE_REKEY_SA_PAYLOAD_HEX_STRING); 1006 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 1007 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 1008 1009 return makeDummyEncryptedReceivedIkePacket( 1010 mSpyCurrentIkeSaRecord, 1011 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1012 true /*isResp*/, 1013 payloadTypeList, 1014 payloadHexStringList); 1015 } 1016 makeDeleteIkeResponse(IkeSaRecord ikeSaRecord)1017 private ReceivedIkePacket makeDeleteIkeResponse(IkeSaRecord ikeSaRecord) throws Exception { 1018 return makeDummyEncryptedReceivedIkePacket( 1019 ikeSaRecord, 1020 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1021 true /*isResp*/, 1022 new LinkedList<>(), 1023 new LinkedList<>()); 1024 } 1025 makeDpdIkeRequest(IkeSaRecord saRecord)1026 private ReceivedIkePacket makeDpdIkeRequest(IkeSaRecord saRecord) throws Exception { 1027 return makeDummyEncryptedReceivedIkePacket( 1028 saRecord, 1029 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1030 false /*isResp*/, 1031 new LinkedList<>(), 1032 new LinkedList<>()); 1033 } 1034 makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes)1035 private ReceivedIkePacket makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes) 1036 throws Exception { 1037 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1038 mSpyCurrentIkeSaRecord, 1039 EXCHANGE_TYPE_INFORMATIONAL, 1040 false /*isResp*/, 1041 msgId, 1042 new LinkedList<>(), 1043 dummyIkePacketBytes); 1044 } 1045 makeRekeyIkeRequest()1046 private ReceivedIkePacket makeRekeyIkeRequest() throws Exception { 1047 IkeSaPayload saPayload = 1048 (IkeSaPayload) 1049 IkeTestUtils.hexStringToIkePayload( 1050 IkePayload.PAYLOAD_TYPE_SA, 1051 false /*isResp*/, 1052 IKE_REKEY_SA_PAYLOAD_HEX_STRING); 1053 return makeRekeyIkeRequest(saPayload); 1054 } 1055 makeRekeyIkeRequestWithUnacceptableProposal()1056 private ReceivedIkePacket makeRekeyIkeRequestWithUnacceptableProposal() throws Exception { 1057 IkeSaPayload saPayload = 1058 (IkeSaPayload) 1059 IkeTestUtils.hexStringToIkePayload( 1060 IkePayload.PAYLOAD_TYPE_SA, 1061 false /*isResp*/, 1062 IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING); 1063 return makeRekeyIkeRequest(saPayload); 1064 } 1065 makeRekeyIkeRequest(IkeSaPayload saPayload)1066 private ReceivedIkePacket makeRekeyIkeRequest(IkeSaPayload saPayload) throws Exception { 1067 List<Integer> payloadTypeList = new LinkedList<>(); 1068 List<String> payloadHexStringList = new LinkedList<>(); 1069 1070 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 1071 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1072 1073 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 1074 payloadHexStringList.add(NONCE_INIT_PAYLOAD_HEX_STRING); 1075 1076 List<IkePayload> payloadList = 1077 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/); 1078 payloadList.add(saPayload); 1079 1080 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1081 mSpyCurrentIkeSaRecord, 1082 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1083 false /*isResp*/, 1084 payloadList); 1085 } 1086 makeDeleteIkeRequest(IkeSaRecord saRecord)1087 private ReceivedIkePacket makeDeleteIkeRequest(IkeSaRecord saRecord) throws Exception { 1088 List<Integer> payloadTypeList = new LinkedList<>(); 1089 List<String> payloadHexStringList = new LinkedList<>(); 1090 1091 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_DELETE); 1092 1093 payloadHexStringList.add(DELETE_IKE_PAYLOAD_HEX_STRING); 1094 1095 return makeDummyEncryptedReceivedIkePacket( 1096 saRecord, 1097 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1098 false /*isResp*/, 1099 payloadTypeList, 1100 payloadHexStringList); 1101 } 1102 makeResponseWithErrorNotify(IkeNotifyPayload notify)1103 private ReceivedIkePacket makeResponseWithErrorNotify(IkeNotifyPayload notify) 1104 throws Exception { 1105 List<IkePayload> payloads = new LinkedList<>(); 1106 payloads.add(notify); 1107 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1108 mSpyCurrentIkeSaRecord, EXCHANGE_TYPE_INFORMATIONAL, true /*isResp*/, payloads); 1109 } 1110 isIkePayloadExist( List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType)1111 private static boolean isIkePayloadExist( 1112 List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType) { 1113 for (IkePayload payload : payloadList) { 1114 if (payload.payloadType == payloadType) return true; 1115 } 1116 return false; 1117 } 1118 isNotifyExist( List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType)1119 private static boolean isNotifyExist( 1120 List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType) { 1121 for (IkeNotifyPayload notify : 1122 IkePayload.getPayloadListForTypeInProvidedList( 1123 PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, payloadList)) { 1124 if (notify.notifyType == notifyType) return true; 1125 } 1126 return false; 1127 } 1128 assertByteArrayListEquals( List<byte[]> expectedList, List<byte[]> resultList)1129 private static void assertByteArrayListEquals( 1130 List<byte[]> expectedList, List<byte[]> resultList) { 1131 assertEquals(expectedList.size(), resultList.size()); 1132 for (int i = 0; i < expectedList.size(); i++) { 1133 assertArrayEquals(expectedList.get(i), resultList.get(i)); 1134 } 1135 } 1136 verifyIncrementLocaReqMsgId()1137 private void verifyIncrementLocaReqMsgId() { 1138 assertEquals( 1139 ++mExpectedCurrentSaLocalReqMsgId, 1140 mSpyCurrentIkeSaRecord.getLocalRequestMessageId()); 1141 } 1142 verifyIncrementRemoteReqMsgId()1143 private void verifyIncrementRemoteReqMsgId() { 1144 assertEquals( 1145 ++mExpectedCurrentSaRemoteReqMsgId, 1146 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId()); 1147 } 1148 verifyRetransmissionStarted()1149 private void verifyRetransmissionStarted() { 1150 assertTrue( 1151 mIkeSessionStateMachine 1152 .getHandler() 1153 .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); 1154 } 1155 verifyRetransmissionStopped()1156 private void verifyRetransmissionStopped() { 1157 assertFalse( 1158 mIkeSessionStateMachine 1159 .getHandler() 1160 .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); 1161 } 1162 verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord)1163 private IkeMessage verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord) { 1164 verify(mMockIkeMessageHelper) 1165 .encryptAndEncode( 1166 anyObject(), 1167 anyObject(), 1168 eq(ikeSaRecord), 1169 mIkeMessageCaptor.capture(), 1170 anyBoolean(), 1171 anyInt()); 1172 return mIkeMessageCaptor.getValue(); 1173 } 1174 verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord)1175 private void verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord) { 1176 verify(mMockIkeMessageHelper, never()) 1177 .encryptAndEncode( 1178 anyObject(), 1179 anyObject(), 1180 eq(ikeSaRecord), 1181 any(IkeMessage.class), 1182 anyBoolean(), 1183 anyInt()); 1184 } 1185 verifyEncryptAndEncodeNeverCalled()1186 private void verifyEncryptAndEncodeNeverCalled() { 1187 verify(mMockIkeMessageHelper, never()) 1188 .encryptAndEncode( 1189 anyObject(), 1190 anyObject(), 1191 any(IkeSaRecord.class), 1192 any(IkeMessage.class), 1193 anyBoolean(), 1194 anyInt()); 1195 } 1196 resetMockIkeMessageHelper()1197 private void resetMockIkeMessageHelper() { 1198 reset(mMockIkeMessageHelper); 1199 doReturn(new byte[0]).when(mMockIkeMessageHelper).encode(any()); 1200 doReturn(new byte[1][0]) 1201 .when(mMockIkeMessageHelper) 1202 .encryptAndEncode(any(), any(), any(), any(), anyBoolean(), anyInt()); 1203 } 1204 1205 @Test testQuit()1206 public void testQuit() { 1207 mIkeSessionStateMachine.quit(); 1208 mLooper.dispatchAll(); 1209 1210 verify(mSpyCurrentIkeSocket).releaseReference(eq(mIkeSessionStateMachine)); 1211 verify(mMockBusyWakelock).release(); 1212 } 1213 1214 @Test testAllocateIkeSpi()1215 public void testAllocateIkeSpi() throws Exception { 1216 // Test randomness. 1217 IkeSecurityParameterIndex ikeSpiOne = IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS); 1218 IkeSecurityParameterIndex ikeSpiTwo = IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS); 1219 1220 assertNotEquals(ikeSpiOne.getSpi(), ikeSpiTwo.getSpi()); 1221 ikeSpiTwo.close(); 1222 1223 // Test duplicate SPIs. 1224 long spiValue = ikeSpiOne.getSpi(); 1225 try { 1226 IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS, spiValue); 1227 fail("Expected to fail because duplicate SPI was assigned to the same address."); 1228 } catch (IOException expected) { 1229 1230 } 1231 1232 ikeSpiOne.close(); 1233 IkeSecurityParameterIndex ikeSpiThree = 1234 IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS, spiValue); 1235 ikeSpiThree.close(); 1236 } 1237 setupFirstIkeSa()1238 private void setupFirstIkeSa() throws Exception { 1239 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1240 // later. 1241 when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any(), any())) 1242 .thenAnswer( 1243 (invocation) -> { 1244 captureAndReleaseIkeSpiResource(invocation, 2); 1245 mockScheduleRekey(mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler); 1246 mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler 1247 .scheduleLifetimeExpiryAlarm(anyString()); 1248 return mSpyCurrentIkeSaRecord; 1249 }); 1250 } 1251 setupRekeyedIkeSa(IkeSaRecord rekeySaRecord)1252 private void setupRekeyedIkeSa(IkeSaRecord rekeySaRecord) throws Exception { 1253 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1254 // later. 1255 when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( 1256 eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) 1257 .thenAnswer( 1258 (invocation) -> { 1259 captureAndReleaseIkeSpiResource(invocation, 4); 1260 mockScheduleRekey(rekeySaRecord.mSaLifetimeAlarmScheduler); 1261 rekeySaRecord.mSaLifetimeAlarmScheduler.scheduleLifetimeExpiryAlarm( 1262 anyString()); 1263 return rekeySaRecord; 1264 }); 1265 } 1266 throwExceptionWhenMakeRekeyIkeSa(Exception exception)1267 private void throwExceptionWhenMakeRekeyIkeSa(Exception exception) throws Exception { 1268 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1269 // later. 1270 when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( 1271 eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) 1272 .thenAnswer( 1273 (invocation) -> { 1274 captureAndReleaseIkeSpiResource(invocation, 4); 1275 throw exception; 1276 }); 1277 } 1278 captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex)1279 private void captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex) { 1280 IkeSaRecordConfig config = (IkeSaRecordConfig) invocation.getArguments()[ikeConfigIndex]; 1281 config.initSpi.close(); 1282 config.respSpi.close(); 1283 } 1284 1285 @Test testResolveRemoteHostName()1286 public void testResolveRemoteHostName() throws Exception { 1287 mIkeSessionStateMachine.quitNow(); 1288 1289 IkeSessionParams ikeParams = 1290 buildIkeSessionParamsCommon() 1291 .setAuthPsk(mPsk) 1292 .setServerHostname(REMOTE_HOSTNAME) 1293 .build(); 1294 mIkeSessionStateMachine = makeAndStartIkeSession(ikeParams); 1295 1296 verify(mMockDefaultNetwork).getByName(REMOTE_HOSTNAME); 1297 } 1298 1299 @Test testEnableTestMode()1300 public void testEnableTestMode() throws Exception { 1301 doReturn(true) 1302 .when(mMockNetworkCapabilities) 1303 .hasTransport(RandomnessFactory.TRANSPORT_TEST); 1304 1305 IkeSessionStateMachine ikeSession = makeAndStartIkeSession(buildIkeSessionParams()); 1306 1307 SecureRandom random = ikeSession.mRandomFactory.getRandom(); 1308 assertNotNull(random); 1309 assertTrue(random instanceof DeterministicSecureRandom); 1310 } 1311 1312 @Test testDisableTestMode()1313 public void testDisableTestMode() throws Exception { 1314 doReturn(false) 1315 .when(mMockNetworkCapabilities) 1316 .hasTransport(RandomnessFactory.TRANSPORT_TEST); 1317 1318 IkeSessionStateMachine ikeSession = makeAndStartIkeSession(buildIkeSessionParams()); 1319 1320 SecureRandom random = ikeSession.mRandomFactory.getRandom(); 1321 assertNull(random); 1322 } 1323 1324 @Test testCreateIkeLocalIkeInitNegotiatesDhGroup()1325 public void testCreateIkeLocalIkeInitNegotiatesDhGroup() throws Exception { 1326 setupFirstIkeSa(); 1327 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1328 mLooper.dispatchAll(); 1329 1330 // Verify we started with the top proposed DH group 1331 assertEquals( 1332 SaProposal.DH_GROUP_1024_BIT_MODP, mIkeSessionStateMachine.mPeerSelectedDhGroup); 1333 1334 // Send back a INVALID_KE_PAYLOAD, and verify that the selected DH group changes 1335 ReceivedIkePacket resp = 1336 makeDummyReceivedIkeInitRespPacket( 1337 1L /*initiator SPI*/, 1338 2L /*responder SPI*/, 1339 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 1340 true /*isResp*/, 1341 false /*fromIkeInit*/, 1342 Arrays.asList(IkePayload.PAYLOAD_TYPE_NOTIFY), 1343 Arrays.asList(INVALID_KE_PAYLOAD_HEX_STRING)); 1344 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 1345 mLooper.dispatchAll(); 1346 1347 assertEquals( 1348 SaProposal.DH_GROUP_2048_BIT_MODP, mIkeSessionStateMachine.mPeerSelectedDhGroup); 1349 } 1350 1351 @Test testCreateIkeLocalIkeInitSwitchesToEncapPorts()1352 public void testCreateIkeLocalIkeInitSwitchesToEncapPorts() throws Exception { 1353 setupFirstIkeSa(); 1354 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1355 mLooper.dispatchAll(); 1356 1357 // Receive IKE INIT response 1358 ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); 1359 mIkeSessionStateMachine.sendMessage( 1360 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 1361 mLooper.dispatchAll(); 1362 1363 // Validate socket switched 1364 assertTrue(mIkeSessionStateMachine.mIkeSocket instanceof IkeUdpEncapSocket); 1365 verify(mSpyIkeUdp4Socket).unregisterIke(anyLong()); 1366 } 1367 1368 @Ignore disableTestCreateIkeLocalIkeInit()1369 public void disableTestCreateIkeLocalIkeInit() throws Exception { 1370 setupFirstIkeSa(); 1371 1372 // Send IKE INIT request 1373 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1374 mLooper.dispatchAll(); 1375 verifyRetransmissionStarted(); 1376 1377 // Receive IKE INIT response 1378 ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); 1379 mIkeSessionStateMachine.sendMessage( 1380 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 1381 mLooper.dispatchAll(); 1382 verifyIncrementLocaReqMsgId(); 1383 1384 // Validate outbound IKE INIT request 1385 verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture()); 1386 IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue(); 1387 1388 IkeHeader ikeHeader = ikeInitReqMessage.ikeHeader; 1389 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, ikeHeader.exchangeType); 1390 assertFalse(ikeHeader.isResponseMsg); 1391 assertTrue(ikeHeader.fromIkeInitiator); 1392 1393 List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList; 1394 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_SA)); 1395 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_KE)); 1396 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_NONCE)); 1397 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP)); 1398 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP)); 1399 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED)); 1400 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_SIGNATURE_HASH_ALGORITHMS)); 1401 1402 verify(mSpyCurrentIkeSocket) 1403 .registerIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); 1404 1405 verify(mMockIkeMessageHelper) 1406 .decode(0, dummyReceivedIkePacket.ikeHeader, dummyReceivedIkePacket.ikePacketBytes); 1407 assertTrue( 1408 mIkeSessionStateMachine.getCurrentState() 1409 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 1410 verifyRetransmissionStarted(); 1411 1412 // Validate negotiated SA proposal. 1413 IkeSaProposal negotiatedProposal = mIkeSessionStateMachine.mSaProposal; 1414 assertNotNull(negotiatedProposal); 1415 1416 assertEquals( 1417 new EncryptionTransform[] {mIkeEncryptionTransform}, 1418 negotiatedProposal.getEncryptionTransforms()); 1419 assertEquals( 1420 new IntegrityTransform[] {mIkeIntegrityTransform}, 1421 negotiatedProposal.getIntegrityTransforms()); 1422 assertEquals(new PrfTransform[] {mIkePrfTransform}, negotiatedProposal.getPrfTransforms()); 1423 1424 // Validate current IkeSaRecord. 1425 verify(mMockSaRecordHelper) 1426 .makeFirstIkeSaRecord( 1427 any(IkeMessage.class), 1428 any(IkeMessage.class), 1429 mIkeSaRecordConfigCaptor.capture()); 1430 1431 IkeSaRecordConfig ikeSaRecordConfig = mIkeSaRecordConfigCaptor.getValue(); 1432 assertEquals(KEY_LEN_IKE_PRF, ikeSaRecordConfig.prf.getKeyLength()); 1433 assertEquals(KEY_LEN_IKE_INTE, ikeSaRecordConfig.integrityKeyLength); 1434 assertEquals(KEY_LEN_IKE_ENCR, ikeSaRecordConfig.encryptionKeyLength); 1435 assertNotNull(ikeSaRecordConfig.saLifetimeAlarmScheduler); 1436 1437 // Validate NAT detection 1438 assertTrue(mIkeSessionStateMachine.mIsLocalBehindNat); 1439 assertFalse(mIkeSessionStateMachine.mIsRemoteBehindNat); 1440 1441 // Validate vendor IDs 1442 assertByteArrayListEquals( 1443 Arrays.asList(REMOTE_VENDOR_ID_ONE), mIkeSessionStateMachine.mRemoteVendorIds); 1444 1445 // Validate fragmentation support negotiation 1446 assertTrue(mIkeSessionStateMachine.mSupportFragment); 1447 assertEquals( 1448 Arrays.asList(EXTENSION_TYPE_FRAGMENTATION), 1449 mIkeSessionStateMachine.mEnabledExtensions); 1450 } 1451 setIkeInitResults()1452 private void setIkeInitResults() throws Exception { 1453 mIkeSessionStateMachine.mIkeCipher = mock(IkeCipher.class); 1454 mIkeSessionStateMachine.mIkeIntegrity = mock(IkeMacIntegrity.class); 1455 mIkeSessionStateMachine.mIkePrf = mock(IkeMacPrf.class); 1456 mIkeSessionStateMachine.mSaProposal = buildNegotiatedSaProposal(); 1457 mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyCurrentIkeSaRecord; 1458 mIkeSessionStateMachine.mLocalAddress = LOCAL_ADDRESS; 1459 mIkeSessionStateMachine.mIsLocalBehindNat = true; 1460 mIkeSessionStateMachine.mIsRemoteBehindNat = false; 1461 mIkeSessionStateMachine.mSupportFragment = true; 1462 mIkeSessionStateMachine.mRemoteVendorIds = 1463 Arrays.asList(REMOTE_VENDOR_ID_ONE, REMOTE_VENDOR_ID_TWO); 1464 mIkeSessionStateMachine.mEnabledExtensions = Arrays.asList(EXTENSION_TYPE_FRAGMENTATION); 1465 mIkeSessionStateMachine.addIkeSaRecord(mSpyCurrentIkeSaRecord); 1466 1467 mSpyCurrentIkeSocket = mSpyIkeUdpEncapSocket; 1468 mIkeSessionStateMachine.mIkeSocket = mSpyCurrentIkeSocket; 1469 } 1470 1471 /** Initializes the mIkeSessionStateMachine in the IDLE state. */ setupIdleStateMachine()1472 private void setupIdleStateMachine() throws Exception { 1473 verify(mMockBusyWakelock).acquire(); 1474 1475 setIkeInitResults(); 1476 1477 mIkeSessionStateMachine.sendMessage( 1478 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 1479 mLooper.dispatchAll(); 1480 1481 mDummyChildSmCallback = 1482 createChildAndGetChildSessionSmCallback( 1483 mMockChildSessionStateMachine, CHILD_SPI_REMOTE, mMockChildSessionCallback); 1484 1485 assertTrue( 1486 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 1487 1488 verify(mMockBusyWakelock).release(); 1489 1490 // For convenience to verify wakelocks in all other places. 1491 reset(mMockBusyWakelock); 1492 } 1493 mockIkeInitAndTransitionToIkeAuth(State authState)1494 private void mockIkeInitAndTransitionToIkeAuth(State authState) throws Exception { 1495 setIkeInitResults(); 1496 1497 // Need to create a real IkeMacPrf instance for authentication because we cannot inject a 1498 // method stub for IkeMacPrf#signBytes. IkeMacPrf#signBytes is inheritted from a package 1499 // protected class IkePrf. We don't have the visibility to mock it. 1500 mIkeSessionStateMachine.mIkePrf = 1501 IkeMacPrf.create(new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)); 1502 1503 mIkeSessionStateMachine.mIkeInitRequestBytes = new byte[0]; 1504 mIkeSessionStateMachine.mIkeInitResponseBytes = new byte[0]; 1505 mIkeSessionStateMachine.mIkeInitNoncePayload = 1506 new IkeNoncePayload(createMockRandomFactory()); 1507 mIkeSessionStateMachine.mIkeRespNoncePayload = 1508 new IkeNoncePayload(createMockRandomFactory()); 1509 1510 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_FORCE_TRANSITION, authState); 1511 mLooper.dispatchAll(); 1512 } 1513 setupChildStateMachineFactory(ChildSessionStateMachine child)1514 private void setupChildStateMachineFactory(ChildSessionStateMachine child) { 1515 // After state machine start, add to the callback->statemachine map 1516 when(mMockChildSessionFactoryHelper.makeChildSessionStateMachine( 1517 eq(mLooper.getLooper()), 1518 eq(mSpyContext), 1519 anyInt(), 1520 any(AlarmManager.class), 1521 any(RandomnessFactory.class), 1522 any(IpSecSpiGenerator.class), 1523 eq(mChildSessionParams), 1524 eq(mSpyUserCbExecutor), 1525 any(ChildSessionCallback.class), 1526 any(IChildSessionSmCallback.class))) 1527 .thenReturn(child); 1528 } 1529 1530 /** 1531 * Utility to register a new callback -> state machine mapping. 1532 * 1533 * <p>Must be used if IkeSessionStateMachine.openChildSession() is not called, but commands 1534 * injected instead. 1535 * 1536 * @param callback The callback to be used for the mapping 1537 * @param sm The ChildSessionStateMachine instance to be used. 1538 */ registerChildStateMachine( ChildSessionCallback callback, ChildSessionStateMachine sm)1539 private void registerChildStateMachine( 1540 ChildSessionCallback callback, ChildSessionStateMachine sm) { 1541 setupChildStateMachineFactory(sm); 1542 mIkeSessionStateMachine.registerChildSessionCallback( 1543 mChildSessionParams, callback, false /*isFirstChild*/); 1544 } 1545 1546 @Test testCreateAdditionalChild()1547 public void testCreateAdditionalChild() throws Exception { 1548 setupIdleStateMachine(); 1549 1550 ChildSessionCallback childCallback = mock(ChildSessionCallback.class); 1551 ChildSessionStateMachine childStateMachine = mock(ChildSessionStateMachine.class); 1552 registerChildStateMachine(childCallback, childStateMachine); 1553 1554 mIkeSessionStateMachine.sendMessage( 1555 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 1556 new ChildLocalRequest( 1557 IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_CHILD, 1558 childCallback, 1559 mChildSessionParams)); 1560 mLooper.dispatchAll(); 1561 1562 assertTrue( 1563 mIkeSessionStateMachine.getCurrentState() 1564 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1565 verify(childStateMachine) 1566 .createChildSession( 1567 eq(LOCAL_ADDRESS), 1568 eq(REMOTE_ADDRESS), 1569 any(), // udpEncapSocket 1570 eq(mIkeSessionStateMachine.mIkePrf), 1571 any()); // sk_d 1572 1573 // Once for initial child, a second time for the additional child. 1574 verify(mMockChildSessionFactoryHelper) 1575 .makeChildSessionStateMachine( 1576 eq(mLooper.getLooper()), 1577 eq(mSpyContext), 1578 anyInt(), 1579 any(AlarmManager.class), 1580 any(RandomnessFactory.class), 1581 any(IpSecSpiGenerator.class), 1582 eq(mChildSessionParams), 1583 eq(mSpyUserCbExecutor), 1584 eq(childCallback), 1585 mChildSessionSmCbCaptor.capture()); 1586 IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue(); 1587 1588 // Mocking sending request 1589 cb.onOutboundPayloadsReady( 1590 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1591 false /*isResp*/, 1592 new LinkedList<>(), 1593 childStateMachine); 1594 mLooper.dispatchAll(); 1595 verifyRetransmissionStarted(); 1596 1597 IkeMessage createChildRequest = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 1598 1599 IkeHeader ikeHeader = createChildRequest.ikeHeader; 1600 assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); 1601 assertFalse(ikeHeader.isResponseMsg); 1602 assertTrue(ikeHeader.fromIkeInitiator); 1603 assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); 1604 assertTrue(createChildRequest.ikePayloadList.isEmpty()); 1605 1606 assertTrue( 1607 mIkeSessionStateMachine.getCurrentState() 1608 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1609 1610 // Mocking receiving response 1611 ReceivedIkePacket dummyCreateChildResp = makeCreateChildCreateMessage(true /*isResp*/); 1612 mIkeSessionStateMachine.sendMessage( 1613 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyCreateChildResp); 1614 mLooper.dispatchAll(); 1615 1616 verifyIncrementLocaReqMsgId(); 1617 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyCreateChildResp); 1618 1619 verify(childStateMachine) 1620 .receiveResponse( 1621 eq(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA), mPayloadListCaptor.capture()); 1622 1623 List<IkePayload> childRespList = mPayloadListCaptor.getValue(); 1624 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); 1625 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 1626 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 1627 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); 1628 1629 // Mock finishing procedure 1630 cb.onProcedureFinished(childStateMachine); 1631 mLooper.dispatchAll(); 1632 assertTrue( 1633 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 1634 verifyRetransmissionStopped(); 1635 } 1636 1637 @Test testTriggerDeleteChildLocal()1638 public void testTriggerDeleteChildLocal() throws Exception { 1639 setupIdleStateMachine(); 1640 1641 mIkeSessionStateMachine.sendMessage( 1642 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 1643 new ChildLocalRequest( 1644 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, 1645 mMockChildSessionCallback, 1646 null /*childParams*/)); 1647 mLooper.dispatchAll(); 1648 1649 assertTrue( 1650 mIkeSessionStateMachine.getCurrentState() 1651 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1652 verify(mMockChildSessionStateMachine).deleteChildSession(); 1653 verify(mMockBusyWakelock).acquire(); 1654 } 1655 1656 @Test testHandleDeleteChildBeforeCreation()1657 public void testHandleDeleteChildBeforeCreation() throws Exception { 1658 setupIdleStateMachine(); 1659 1660 mIkeSessionStateMachine.sendMessage( 1661 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 1662 new ChildLocalRequest( 1663 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, 1664 mock(ChildSessionCallback.class), 1665 null /*childParams*/)); 1666 mLooper.dispatchAll(); 1667 1668 assertTrue( 1669 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 1670 } 1671 1672 @Test testTriggerRekeyChildLocal()1673 public void testTriggerRekeyChildLocal() throws Exception { 1674 setupIdleStateMachine(); 1675 1676 mIkeSessionStateMachine.sendMessage( 1677 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 1678 new ChildLocalRequest( 1679 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, 1680 mMockChildSessionCallback, 1681 null /*childParams*/)); 1682 mLooper.dispatchAll(); 1683 1684 assertTrue( 1685 mIkeSessionStateMachine.getCurrentState() 1686 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1687 verify(mMockChildSessionStateMachine).rekeyChildSession(); 1688 verify(mMockBusyWakelock).acquire(); 1689 } 1690 createChildAndGetChildSessionSmCallback( ChildSessionStateMachine child, int remoteSpi)1691 private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( 1692 ChildSessionStateMachine child, int remoteSpi) throws Exception { 1693 return createChildAndGetChildSessionSmCallback( 1694 child, remoteSpi, mock(ChildSessionCallback.class)); 1695 } 1696 createChildAndGetChildSessionSmCallback( ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback)1697 private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( 1698 ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback) 1699 throws Exception { 1700 registerChildStateMachine(childCallback, child); 1701 1702 IChildSessionSmCallback cb = mIkeSessionStateMachine.new ChildSessionSmCallback(); 1703 cb.onChildSaCreated(remoteSpi, child); 1704 mLooper.dispatchAll(); 1705 1706 return cb; 1707 } 1708 transitionToChildProcedureOngoing()1709 private void transitionToChildProcedureOngoing() { 1710 mIkeSessionStateMachine.sendMessage( 1711 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 1712 mIkeSessionStateMachine.mChildProcedureOngoing); 1713 mLooper.dispatchAll(); 1714 assertTrue( 1715 mIkeSessionStateMachine.getCurrentState() 1716 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1717 } 1718 verifyChildReceiveDeleteRequest( ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads)1719 private void verifyChildReceiveDeleteRequest( 1720 ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads) { 1721 verify(child) 1722 .receiveRequest( 1723 eq(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD), 1724 eq(EXCHANGE_TYPE_INFORMATIONAL), 1725 mPayloadListCaptor.capture()); 1726 List<IkePayload> reqPayloads = mPayloadListCaptor.getValue(); 1727 1728 int numExpectedDelPayloads = expectedDelPayloads.length; 1729 assertEquals(numExpectedDelPayloads, reqPayloads.size()); 1730 1731 for (int i = 0; i < numExpectedDelPayloads; i++) { 1732 assertEquals(expectedDelPayloads[i], (IkeDeletePayload) reqPayloads.get(i)); 1733 } 1734 } 1735 outboundDeleteChildPayloadsReady( IChildSessionSmCallback childSmCb, IkeDeletePayload delPayload, boolean isResp, ChildSessionStateMachine child)1736 private void outboundDeleteChildPayloadsReady( 1737 IChildSessionSmCallback childSmCb, 1738 IkeDeletePayload delPayload, 1739 boolean isResp, 1740 ChildSessionStateMachine child) { 1741 List<IkePayload> outPayloadList = new LinkedList<>(); 1742 outPayloadList.add(delPayload); 1743 childSmCb.onOutboundPayloadsReady( 1744 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, isResp, outPayloadList, child); 1745 mLooper.dispatchAll(); 1746 } 1747 verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp)1748 private List<IkePayload> verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp) { 1749 IkeMessage deleteChildMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 1750 1751 IkeHeader ikeHeader = deleteChildMessage.ikeHeader; 1752 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); 1753 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); 1754 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 1755 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 1756 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 1757 assertEquals(isResp, ikeHeader.isResponseMsg); 1758 1759 return deleteChildMessage.ikePayloadList; 1760 } 1761 1762 @Test testDeferChildRequestToChildProcedureOngoing()1763 public void testDeferChildRequestToChildProcedureOngoing() throws Exception { 1764 setupIdleStateMachine(); 1765 1766 IkeDeletePayload[] inboundDelPayloads = 1767 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 1768 mIkeSessionStateMachine.sendMessage( 1769 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1770 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1771 mLooper.dispatchAll(); 1772 1773 assertTrue( 1774 mIkeSessionStateMachine.getCurrentState() 1775 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1776 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 1777 } 1778 1779 @Test testRemoteDeleteOneChild()1780 public void testRemoteDeleteOneChild() throws Exception { 1781 setupIdleStateMachine(); 1782 transitionToChildProcedureOngoing(); 1783 1784 // Receive Delete Child Request 1785 IkeDeletePayload[] inboundDelPayloads = 1786 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 1787 mIkeSessionStateMachine.sendMessage( 1788 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1789 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1790 mLooper.dispatchAll(); 1791 1792 // Verify received payloads 1793 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 1794 1795 // Outbound payload list ready 1796 IkeDeletePayload outDelPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); 1797 outboundDeleteChildPayloadsReady( 1798 mDummyChildSmCallback, 1799 outDelPayload, 1800 true /*isResp*/, 1801 mMockChildSessionStateMachine); 1802 1803 // Verify outbound response 1804 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1805 assertEquals(1, payloadList.size()); 1806 assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); 1807 verify(mMockBusyWakelock).acquire(); 1808 } 1809 1810 @Test testRemoteDeleteMultipleChildSession()1811 public void testRemoteDeleteMultipleChildSession() throws Exception { 1812 ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); 1813 int childOneRemoteSpi = 11; 1814 int childOneLocalSpi = 12; 1815 1816 ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); 1817 int childTwoRemoteSpi = 21; 1818 int childTwoLocalSpi = 22; 1819 1820 setupIdleStateMachine(); 1821 IChildSessionSmCallback childSmCbOne = 1822 createChildAndGetChildSessionSmCallback(childOne, childOneRemoteSpi); 1823 IChildSessionSmCallback childSmCbTwo = 1824 createChildAndGetChildSessionSmCallback(childTwo, childTwoRemoteSpi); 1825 1826 transitionToChildProcedureOngoing(); 1827 1828 // Receive Delete Child Request 1829 IkeDeletePayload[] inboundDelPayloads = 1830 new IkeDeletePayload[] { 1831 new IkeDeletePayload(new int[] {childOneRemoteSpi, childTwoRemoteSpi}) 1832 }; 1833 mIkeSessionStateMachine.sendMessage( 1834 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1835 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1836 mLooper.dispatchAll(); 1837 1838 // Verify received payloads 1839 verifyChildReceiveDeleteRequest(childOne, inboundDelPayloads); 1840 verifyChildReceiveDeleteRequest(childTwo, inboundDelPayloads); 1841 1842 // childOne outbound payload list ready 1843 IkeDeletePayload outDelPayloadOne = new IkeDeletePayload(new int[] {childOneLocalSpi}); 1844 outboundDeleteChildPayloadsReady(childSmCbOne, outDelPayloadOne, true /*isResp*/, childOne); 1845 mLooper.dispatchAll(); 1846 1847 // Verify that no response is sent 1848 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 1849 1850 // childTwo outbound payload list ready 1851 IkeDeletePayload outDelPayloadTwo = new IkeDeletePayload(new int[] {childTwoLocalSpi}); 1852 outboundDeleteChildPayloadsReady(childSmCbTwo, outDelPayloadTwo, true /*isResp*/, childTwo); 1853 mLooper.dispatchAll(); 1854 1855 // Verify outbound response 1856 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1857 assertEquals(2, payloadList.size()); 1858 assertEquals(outDelPayloadOne, ((IkeDeletePayload) payloadList.get(0))); 1859 assertEquals(outDelPayloadTwo, ((IkeDeletePayload) payloadList.get(1))); 1860 } 1861 1862 @Test testRemoteDeleteMultipleChildSaInSameSession()1863 public void testRemoteDeleteMultipleChildSaInSameSession() throws Exception { 1864 int newChildRemoteSpi = 21; 1865 int newChildLocalSpi = 22; 1866 1867 setupIdleStateMachine(); 1868 mDummyChildSmCallback.onChildSaCreated(newChildRemoteSpi, mMockChildSessionStateMachine); 1869 1870 transitionToChildProcedureOngoing(); 1871 1872 // Receive Delete Child Request 1873 IkeDeletePayload[] inboundDelPayloads = 1874 new IkeDeletePayload[] { 1875 new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE}), 1876 new IkeDeletePayload(new int[] {newChildRemoteSpi}) 1877 }; 1878 mIkeSessionStateMachine.sendMessage( 1879 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1880 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1881 mLooper.dispatchAll(); 1882 1883 // Verify received payloads 1884 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 1885 1886 // child outbound payload list ready 1887 IkeDeletePayload outDelPayload = 1888 new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL, newChildLocalSpi}); 1889 outboundDeleteChildPayloadsReady( 1890 mDummyChildSmCallback, 1891 outDelPayload, 1892 true /*isResp*/, 1893 mMockChildSessionStateMachine); 1894 mLooper.dispatchAll(); 1895 1896 // Verify outbound response 1897 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1898 assertEquals(1, payloadList.size()); 1899 assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); 1900 } 1901 1902 @Test testIgnoreUnrecognizedChildSpi()1903 public void testIgnoreUnrecognizedChildSpi() throws Exception { 1904 int unrecognizedSpi = 2; 1905 1906 setupIdleStateMachine(); 1907 transitionToChildProcedureOngoing(); 1908 1909 // Receive Delete Child Request 1910 IkeDeletePayload[] inboundDelPayloads = 1911 new IkeDeletePayload[] { 1912 new IkeDeletePayload(new int[] {unrecognizedSpi, CHILD_SPI_REMOTE}) 1913 }; 1914 mIkeSessionStateMachine.sendMessage( 1915 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1916 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1917 mLooper.dispatchAll(); 1918 1919 // Verify received payloads 1920 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 1921 1922 // child outbound payload list ready 1923 IkeDeletePayload outPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); 1924 outboundDeleteChildPayloadsReady( 1925 mDummyChildSmCallback, outPayload, true /*isResp*/, mMockChildSessionStateMachine); 1926 mLooper.dispatchAll(); 1927 1928 // Verify outbound response 1929 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1930 assertEquals(1, payloadList.size()); 1931 assertEquals(outPayload, ((IkeDeletePayload) payloadList.get(0))); 1932 } 1933 1934 @Test testRemoteDeleteChildHandlesReqWithNoRecognizedSpi()1935 public void testRemoteDeleteChildHandlesReqWithNoRecognizedSpi() throws Exception { 1936 int unrecognizedSpi = 2; 1937 1938 setupIdleStateMachine(); 1939 1940 // Receive Delete Child Request without any recognized SPI 1941 IkeDeletePayload[] inboundDelPayloads = 1942 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {unrecognizedSpi})}; 1943 mIkeSessionStateMachine.sendMessage( 1944 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 1945 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 1946 mLooper.dispatchAll(); 1947 1948 // Verify outbound empty response was sent 1949 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1950 assertTrue(payloadList.isEmpty()); 1951 1952 // Verify IKE Session was back to Idle 1953 assertTrue( 1954 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 1955 } 1956 1957 @Test testRemoteCreateChild()1958 public void testRemoteCreateChild() throws Exception { 1959 setupIdleStateMachine(); 1960 1961 mIkeSessionStateMachine.sendMessage( 1962 CMD_RECEIVE_IKE_PACKET, makeCreateChildCreateMessage(false /*isResp*/)); 1963 1964 mLooper.dispatchAll(); 1965 1966 assertTrue( 1967 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 1968 1969 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 1970 assertEquals(1, ikePayloadList.size()); 1971 assertEquals( 1972 ERROR_TYPE_NO_ADDITIONAL_SAS, 1973 ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 1974 } 1975 1976 @Test testTriggerRemoteRekeyChild()1977 public void testTriggerRemoteRekeyChild() throws Exception { 1978 setupIdleStateMachine(); 1979 1980 mIkeSessionStateMachine.sendMessage( 1981 CMD_RECEIVE_IKE_PACKET, 1982 makeRekeyChildCreateMessage(false /*isResp*/, CHILD_SPI_REMOTE)); 1983 mLooper.dispatchAll(); 1984 1985 verify(mMockChildSessionStateMachine) 1986 .receiveRequest( 1987 eq(IKE_EXCHANGE_SUBTYPE_REKEY_CHILD), 1988 eq(EXCHANGE_TYPE_CREATE_CHILD_SA), 1989 any(List.class)); 1990 assertTrue( 1991 mIkeSessionStateMachine.getCurrentState() 1992 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 1993 } 1994 1995 @Test testHandleRekeyChildReqWithUnrecognizedSpi()1996 public void testHandleRekeyChildReqWithUnrecognizedSpi() throws Exception { 1997 int unrecognizedSpi = 2; 1998 1999 setupIdleStateMachine(); 2000 2001 mIkeSessionStateMachine.sendMessage( 2002 CMD_RECEIVE_IKE_PACKET, 2003 makeRekeyChildCreateMessage(false /*isResp*/, unrecognizedSpi)); 2004 mLooper.dispatchAll(); 2005 2006 verify(mMockChildSessionStateMachine, never()).receiveRequest(anyInt(), anyInt(), any()); 2007 assertTrue( 2008 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2009 2010 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2011 assertEquals(1, ikePayloadList.size()); 2012 IkeNotifyPayload notifyPayload = (IkeNotifyPayload) ikePayloadList.get(0); 2013 assertEquals(ERROR_TYPE_CHILD_SA_NOT_FOUND, notifyPayload.notifyType); 2014 assertEquals(unrecognizedSpi, notifyPayload.spi); 2015 } 2016 verifyNotifyUserCloseSession()2017 private void verifyNotifyUserCloseSession() { 2018 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 2019 verify(mMockIkeSessionCallback).onClosed(); 2020 } 2021 2022 @Test testRcvRemoteDeleteIkeWhenChildProcedureOngoing()2023 public void testRcvRemoteDeleteIkeWhenChildProcedureOngoing() throws Exception { 2024 setupIdleStateMachine(); 2025 transitionToChildProcedureOngoing(); 2026 2027 mIkeSessionStateMachine.sendMessage( 2028 CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 2029 2030 mLooper.dispatchAll(); 2031 2032 verifyNotifyUserCloseSession(); 2033 2034 // Verify state machine quit properly 2035 assertNull(mIkeSessionStateMachine.getCurrentState()); 2036 2037 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2038 assertTrue(ikePayloadList.isEmpty()); 2039 } 2040 2041 @Test testRcvRemoteRekeyIkeWhenChildProcedureOngoing()2042 public void testRcvRemoteRekeyIkeWhenChildProcedureOngoing() throws Exception { 2043 setupIdleStateMachine(); 2044 transitionToChildProcedureOngoing(); 2045 2046 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest()); 2047 2048 mLooper.dispatchAll(); 2049 2050 // Since we have forced state machine to transition to ChildProcedureOngoing state without 2051 // really starting any Child procedure, it should transition to Idle at this time. 2052 assertTrue( 2053 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2054 2055 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2056 assertEquals(1, ikePayloadList.size()); 2057 assertEquals( 2058 ERROR_TYPE_TEMPORARY_FAILURE, 2059 ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 2060 } 2061 2062 @Test testKillChildSessions()2063 public void testKillChildSessions() throws Exception { 2064 setupIdleStateMachine(); 2065 2066 ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); 2067 ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); 2068 registerChildStateMachine(mock(ChildSessionCallback.class), childOne); 2069 registerChildStateMachine(mock(ChildSessionCallback.class), childTwo); 2070 2071 mIkeSessionStateMachine.mCurrentIkeSaRecord = null; 2072 2073 mIkeSessionStateMachine.quitNow(); 2074 2075 mLooper.dispatchAll(); 2076 2077 verify(childOne).killSession(); 2078 verify(childTwo).killSession(); 2079 } 2080 verifyAuthReqAndGetMsg()2081 private IkeMessage verifyAuthReqAndGetMsg() { 2082 IkeMessage ikeAuthReqMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 2083 2084 IkeHeader ikeHeader = ikeAuthReqMessage.ikeHeader; 2085 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); 2086 assertFalse(ikeHeader.isResponseMsg); 2087 assertTrue(ikeHeader.fromIkeInitiator); 2088 2089 return ikeAuthReqMessage; 2090 } 2091 verifyAuthReqWithChildPayloadsAndGetMsg()2092 private IkeMessage verifyAuthReqWithChildPayloadsAndGetMsg() { 2093 IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 2094 2095 assertNotNull( 2096 ikeAuthReqMessage.getPayloadForType( 2097 IkePayload.PAYLOAD_TYPE_ID_INITIATOR, IkeIdPayload.class)); 2098 assertNotNull( 2099 ikeAuthReqMessage.getPayloadForType( 2100 IkePayload.PAYLOAD_TYPE_ID_RESPONDER, IkeIdPayload.class)); 2101 assertNotNull( 2102 ikeAuthReqMessage.getPayloadForType( 2103 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); 2104 assertNotNull( 2105 ikeAuthReqMessage.getPayloadForType( 2106 IkePayload.PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class)); 2107 assertNotNull( 2108 ikeAuthReqMessage.getPayloadForType( 2109 IkePayload.PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class)); 2110 2111 IkeConfigPayload configPayload = 2112 ikeAuthReqMessage.getPayloadForType( 2113 IkePayload.PAYLOAD_TYPE_CP, IkeConfigPayload.class); 2114 assertNotNull(configPayload); 2115 2116 Map<Integer, Integer> expectedAttributes = 2117 Map.of( 2118 CONFIG_ATTR_IP4_PCSCF, 2119 1, 2120 CONFIG_ATTR_IP6_PCSCF, 2121 1, 2122 CONFIG_ATTR_INTERNAL_IP4_ADDRESS, 2123 1, 2124 CONFIG_ATTR_INTERNAL_IP6_ADDRESS, 2125 1, 2126 CONFIG_ATTR_APPLICATION_VERSION, 2127 1, 2128 CONFIG_ATTR_INTERNAL_IP4_NETMASK, 2129 1); 2130 Map<Integer, Integer> actualAttributes = 2131 buildAttributeMap(configPayload.recognizedAttributeList); 2132 assertEquals(expectedAttributes, actualAttributes); 2133 2134 IkeNoncePayload noncePayload = 2135 ikeAuthReqMessage.getPayloadForType( 2136 IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class); 2137 assertNull(noncePayload); 2138 2139 return ikeAuthReqMessage; 2140 } 2141 buildAttributeMap( List<IkeConfigPayload.ConfigAttribute> recognizedAttributeList)2142 private Map<Integer, Integer> buildAttributeMap( 2143 List<IkeConfigPayload.ConfigAttribute> recognizedAttributeList) { 2144 Map<Integer, Integer> attrCountMap = new HashMap<>(); 2145 for (IkeConfigPayload.ConfigAttribute attr : recognizedAttributeList) { 2146 attrCountMap.compute(attr.attributeType, (key, val) -> (val == null) ? 1 : val + 1); 2147 } 2148 2149 return attrCountMap; 2150 } 2151 verifyDigitalSignatureAuthentication( IkeAuthDigitalSignPayload spyAuthPayload, X509Certificate certificate, IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp)2152 private void verifyDigitalSignatureAuthentication( 2153 IkeAuthDigitalSignPayload spyAuthPayload, 2154 X509Certificate certificate, 2155 IkeIdPayload respIdPayload, 2156 List<IkePayload> authRelatedPayloads, 2157 boolean hasChildPayloads, 2158 boolean hasConfigPayloadInResp) 2159 throws Exception { 2160 IkeMessage ikeAuthReqMessage = 2161 verifyAuthenticationCommonAndGetIkeMessage( 2162 respIdPayload, 2163 authRelatedPayloads, 2164 hasChildPayloads, 2165 hasConfigPayloadInResp); 2166 2167 verify(spyAuthPayload) 2168 .verifyInboundSignature( 2169 certificate, 2170 mIkeSessionStateMachine.mIkeInitRequestBytes, 2171 mSpyCurrentIkeSaRecord.nonceInitiator, 2172 respIdPayload.getEncodedPayloadBody(), 2173 mIkeSessionStateMachine.mIkePrf, 2174 mSpyCurrentIkeSaRecord.getSkPr()); 2175 2176 assertNotNull( 2177 ikeAuthReqMessage.getPayloadForType( 2178 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthDigitalSignPayload.class)); 2179 } 2180 verifySharedKeyAuthentication( IkeAuthPskPayload spyAuthPayload, IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp)2181 private void verifySharedKeyAuthentication( 2182 IkeAuthPskPayload spyAuthPayload, 2183 IkeIdPayload respIdPayload, 2184 List<IkePayload> authRelatedPayloads, 2185 boolean hasChildPayloads, 2186 boolean hasConfigPayloadInResp) 2187 throws Exception { 2188 IkeMessage ikeAuthReqMessage = 2189 verifyAuthenticationCommonAndGetIkeMessage( 2190 respIdPayload, 2191 authRelatedPayloads, 2192 hasChildPayloads, 2193 hasConfigPayloadInResp); 2194 2195 // Validate authentication is done. Cannot use matchers because IkeAuthPskPayload is final. 2196 verify(spyAuthPayload) 2197 .verifyInboundSignature( 2198 mPsk, 2199 mIkeSessionStateMachine.mIkeInitRequestBytes, 2200 mSpyCurrentIkeSaRecord.nonceInitiator, 2201 respIdPayload.getEncodedPayloadBody(), 2202 mIkeSessionStateMachine.mIkePrf, 2203 mSpyCurrentIkeSaRecord.getSkPr()); 2204 2205 assertNotNull( 2206 ikeAuthReqMessage.getPayloadForType( 2207 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPskPayload.class)); 2208 } 2209 verifyAuthenticationCommonAndGetIkeMessage( IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp)2210 private IkeMessage verifyAuthenticationCommonAndGetIkeMessage( 2211 IkeIdPayload respIdPayload, 2212 List<IkePayload> authRelatedPayloads, 2213 boolean hasChildPayloads, 2214 boolean hasConfigPayloadInResp) 2215 throws Exception { 2216 // Send IKE AUTH response to IKE state machine 2217 ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads); 2218 mIkeSessionStateMachine.sendMessage( 2219 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp); 2220 mLooper.dispatchAll(); 2221 2222 // Validate outbound IKE AUTH request 2223 IkeMessage ikeAuthReqMessage; 2224 if (hasChildPayloads) { 2225 ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); 2226 } else { 2227 ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 2228 } 2229 2230 // Validate that there is no EAP only notify payload 2231 List<IkeNotifyPayload> notifyPayloads = 2232 ikeAuthReqMessage.getPayloadListForType( 2233 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 2234 assertFalse(hasEapOnlyNotifyPayload(notifyPayloads)); 2235 2236 // Validate inbound IKE AUTH response 2237 verifyIncrementLocaReqMsgId(); 2238 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, authResp); 2239 2240 // Validate that user has been notified 2241 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 2242 2243 // Verify IkeSessionConfiguration 2244 ArgumentCaptor<IkeSessionConfiguration> ikeSessionConfigurationArgumentCaptor = 2245 ArgumentCaptor.forClass(IkeSessionConfiguration.class); 2246 verify(mMockIkeSessionCallback).onOpened(ikeSessionConfigurationArgumentCaptor.capture()); 2247 2248 IkeSessionConfiguration sessionConfig = ikeSessionConfigurationArgumentCaptor.getValue(); 2249 assertNotNull(sessionConfig); 2250 if (hasConfigPayloadInResp) { 2251 List<InetAddress> pcscfAddressList = sessionConfig.getPcscfServers(); 2252 assertEquals(3, pcscfAddressList.size()); 2253 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS1))); 2254 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS2))); 2255 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS3))); 2256 } else { 2257 assertTrue(sessionConfig.getPcscfServers().size() == 0); 2258 } 2259 2260 assertEquals( 2261 "" /*expected application version*/, sessionConfig.getRemoteApplicationVersion()); 2262 assertByteArrayListEquals( 2263 Arrays.asList(REMOTE_VENDOR_ID_ONE, REMOTE_VENDOR_ID_TWO), 2264 sessionConfig.getRemoteVendorIds()); 2265 assertTrue( 2266 sessionConfig.isIkeExtensionEnabled( 2267 IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION)); 2268 2269 IkeSessionConnectionInfo ikeConnInfo = sessionConfig.getIkeSessionConnectionInfo(); 2270 assertEquals(LOCAL_ADDRESS, ikeConnInfo.getLocalAddress()); 2271 assertEquals(REMOTE_ADDRESS, ikeConnInfo.getRemoteAddress()); 2272 assertEquals(mMockDefaultNetwork, ikeConnInfo.getNetwork()); 2273 2274 // Verify payload list pair for first Child negotiation 2275 ArgumentCaptor<List<IkePayload>> mReqPayloadListCaptor = 2276 ArgumentCaptor.forClass(List.class); 2277 ArgumentCaptor<List<IkePayload>> mRespPayloadListCaptor = 2278 ArgumentCaptor.forClass(List.class); 2279 verify(mMockChildSessionStateMachine) 2280 .handleFirstChildExchange( 2281 mReqPayloadListCaptor.capture(), 2282 mRespPayloadListCaptor.capture(), 2283 eq(LOCAL_ADDRESS), 2284 eq(REMOTE_ADDRESS), 2285 any(), // udpEncapSocket 2286 eq(mIkeSessionStateMachine.mIkePrf), 2287 any()); // sk_d 2288 List<IkePayload> childReqList = mReqPayloadListCaptor.getValue(); 2289 List<IkePayload> childRespList = mRespPayloadListCaptor.getValue(); 2290 2291 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_SA)); 2292 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 2293 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 2294 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_NONCE)); 2295 IkeSaPayload reqSaPayload = 2296 IkePayload.getPayloadForTypeInProvidedList( 2297 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childReqList); 2298 assertFalse(reqSaPayload.isSaResponse); 2299 2300 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); 2301 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 2302 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 2303 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); 2304 if (hasConfigPayloadInResp) { 2305 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_CP)); 2306 } else { 2307 assertFalse(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_CP)); 2308 } 2309 IkeSaPayload respSaPayload = 2310 IkePayload.getPayloadForTypeInProvidedList( 2311 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childRespList); 2312 assertTrue(respSaPayload.isSaResponse); 2313 2314 // Mock finishing first Child SA negotiation. 2315 assertTrue( 2316 mIkeSessionStateMachine.getCurrentState() 2317 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2318 2319 verify(mMockChildSessionFactoryHelper) 2320 .makeChildSessionStateMachine( 2321 eq(mLooper.getLooper()), 2322 eq(mSpyContext), 2323 anyInt(), 2324 any(AlarmManager.class), 2325 any(RandomnessFactory.class), 2326 any(IpSecSpiGenerator.class), 2327 eq(mChildSessionParams), 2328 eq(mSpyUserCbExecutor), 2329 eq(mMockChildSessionCallback), 2330 mChildSessionSmCbCaptor.capture()); 2331 IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue(); 2332 2333 cb.onProcedureFinished(mMockChildSessionStateMachine); 2334 mLooper.dispatchAll(); 2335 assertTrue( 2336 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2337 2338 return ikeAuthReqMessage; 2339 } 2340 makeSpyRespPskPayload()2341 private IkeAuthPskPayload makeSpyRespPskPayload() throws Exception { 2342 IkeAuthPskPayload spyAuthPayload = 2343 spy( 2344 (IkeAuthPskPayload) 2345 IkeTestUtils.hexStringToIkePayload( 2346 IkePayload.PAYLOAD_TYPE_AUTH, 2347 true /*isResp*/, 2348 PSK_AUTH_RESP_PAYLOAD_HEX_STRING)); 2349 2350 doNothing() 2351 .when(spyAuthPayload) 2352 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 2353 return spyAuthPayload; 2354 } 2355 makeSpyDigitalSignAuthPayload()2356 private IkeAuthDigitalSignPayload makeSpyDigitalSignAuthPayload() throws Exception { 2357 IkeAuthDigitalSignPayload spyAuthPayload = 2358 spy( 2359 (IkeAuthDigitalSignPayload) 2360 IkeTestUtils.hexStringToIkePayload( 2361 IkePayload.PAYLOAD_TYPE_AUTH, 2362 true /*isResp*/, 2363 GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING)); 2364 doNothing() 2365 .when(spyAuthPayload) 2366 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 2367 return spyAuthPayload; 2368 } 2369 makeRespIdPayload()2370 private IkeIdPayload makeRespIdPayload() { 2371 return makeRespIdPayload(REMOTE_ID_FQDN); 2372 } 2373 makeRespIdPayload(IkeIdentification ikeId)2374 private IkeIdPayload makeRespIdPayload(IkeIdentification ikeId) { 2375 return new IkeIdPayload(false /* isInitiator */, ikeId); 2376 } 2377 verifyEmptyInformationalSent(int count, boolean expectedResp)2378 private void verifyEmptyInformationalSent(int count, boolean expectedResp) { 2379 verify(mMockIkeMessageHelper, times(count)) 2380 .encryptAndEncode( 2381 anyObject(), 2382 anyObject(), 2383 eq(mSpyCurrentIkeSaRecord), 2384 argThat( 2385 msg -> { 2386 return msg.ikePayloadList.isEmpty() 2387 && msg.ikeHeader.isResponseMsg == expectedResp 2388 && msg.ikeHeader.fromIkeInitiator 2389 && msg.ikeHeader.exchangeType 2390 == IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; 2391 }), 2392 anyBoolean(), 2393 anyInt()); 2394 } 2395 2396 @Test testCreateIkeLocalIkeAuthDefersOtherMessages()2397 public void testCreateIkeLocalIkeAuthDefersOtherMessages() throws Exception { 2398 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2399 verifyRetransmissionStarted(); 2400 2401 // Build IKE AUTH response with Auth-PSK, ID-Responder and config payloads. 2402 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2403 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2404 authRelatedPayloads.add(spyAuthPayload); 2405 2406 ReceivedIkePacket req = 2407 makeDummyEncryptedReceivedIkePacket( 2408 mSpyCurrentIkeSaRecord, 2409 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 2410 false, 2411 Collections.emptyList(), 2412 Collections.emptyList()); 2413 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, req); 2414 2415 verifyEmptyInformationalSent(0, true /* expcetedResp*/); 2416 2417 // Send IKE AUTH response to IKE state machine to trigger moving to next state 2418 IkeIdPayload respIdPayload = makeRespIdPayload(); 2419 authRelatedPayloads.add(respIdPayload); 2420 authRelatedPayloads.add(makeConfigPayload()); 2421 2422 ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads); 2423 mIkeSessionStateMachine.sendMessage( 2424 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp); 2425 mLooper.dispatchAll(); 2426 2427 verifyEmptyInformationalSent(1, true /* expcetedResp*/); 2428 assertTrue( 2429 mIkeSessionStateMachine.getCurrentState() 2430 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2431 } 2432 2433 @Test testCreateIkeLocalIkeAuthDigitalSignature()2434 public void testCreateIkeLocalIkeAuthDigitalSignature() throws Exception { 2435 // Quit and restart IKE Session with Digital Signature Auth params 2436 mIkeSessionStateMachine.quitNow(); 2437 reset(mMockChildSessionFactoryHelper); 2438 setupChildStateMachineFactory(mMockChildSessionStateMachine); 2439 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsDigitalSignature()); 2440 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2441 2442 // Build IKE AUTH response with Digital Signature Auth, ID-Responder and config payloads. 2443 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2444 IkeAuthDigitalSignPayload spyAuthPayload = makeSpyDigitalSignAuthPayload(); 2445 authRelatedPayloads.add(spyAuthPayload); 2446 authRelatedPayloads.add(new IkeCertX509CertPayload(mServerEndCertificate)); 2447 2448 IkeIdPayload respIdPayload = makeRespIdPayload(); 2449 authRelatedPayloads.add(respIdPayload); 2450 authRelatedPayloads.add(makeConfigPayload()); 2451 2452 verifyDigitalSignatureAuthentication( 2453 spyAuthPayload, 2454 mServerEndCertificate, 2455 respIdPayload, 2456 authRelatedPayloads, 2457 true /*hasChildPayloads*/, 2458 true /*hasConfigPayloadInResp*/); 2459 verifyRetransmissionStopped(); 2460 } 2461 2462 @Test testCreateIkeLocalIkeAuthPsk()2463 public void testCreateIkeLocalIkeAuthPsk() throws Exception { 2464 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2465 verifyRetransmissionStarted(); 2466 2467 // Build IKE AUTH response with Auth-PSK, ID-Responder and config payloads. 2468 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2469 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2470 authRelatedPayloads.add(spyAuthPayload); 2471 2472 IkeIdPayload respIdPayload = makeRespIdPayload(); 2473 authRelatedPayloads.add(respIdPayload); 2474 authRelatedPayloads.add(makeConfigPayload()); 2475 2476 verifySharedKeyAuthentication( 2477 spyAuthPayload, 2478 respIdPayload, 2479 authRelatedPayloads, 2480 true /*hasChildPayloads*/, 2481 true /*hasConfigPayloadInResp*/); 2482 verifyRetransmissionStopped(); 2483 } 2484 2485 @Test testCreateIkeLocalIkeAuthDigitalSignatureIdMismatch()2486 public void testCreateIkeLocalIkeAuthDigitalSignatureIdMismatch() throws Exception { 2487 // Quit and restart IKE Session with Digital Signature Auth params 2488 mIkeSessionStateMachine.quitNow(); 2489 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsDigitalSignature()); 2490 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2491 resetMockIkeMessageHelper(); 2492 2493 // Build IKE AUTH response with Digital Signature Auth, ID-Responder and config payloads. 2494 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2495 IkeAuthDigitalSignPayload spyAuthPayload = makeSpyDigitalSignAuthPayload(); 2496 authRelatedPayloads.add(spyAuthPayload); 2497 authRelatedPayloads.add(new IkeCertX509CertPayload(mServerEndCertificate)); 2498 2499 authRelatedPayloads.add(makeRespIdPayload(REMOTE_ID_IPV4)); 2500 2501 sendAuthFailRespAndVerifyCloseIke(makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 2502 } 2503 2504 @Test testCreateIkeLocalIkeAuthPskVerifyFail()2505 public void testCreateIkeLocalIkeAuthPskVerifyFail() throws Exception { 2506 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2507 verifyRetransmissionStarted(); 2508 resetMockIkeMessageHelper(); 2509 2510 // Build IKE AUTH response with invalid Auth-PSK Payload and ID-Responder Payload. 2511 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2512 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2513 doThrow(new AuthenticationFailedException("DummyAuthFailException")) 2514 .when(spyAuthPayload) 2515 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 2516 authRelatedPayloads.add(spyAuthPayload); 2517 2518 IkeIdPayload respIdPayload = makeRespIdPayload(); 2519 authRelatedPayloads.add(respIdPayload); 2520 2521 sendAuthFailRespAndVerifyCloseIke(makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 2522 } 2523 sendAuthFailRespAndVerifyCloseIke(ReceivedIkePacket authFailResp)2524 private void sendAuthFailRespAndVerifyCloseIke(ReceivedIkePacket authFailResp) 2525 throws Exception { 2526 // Send response to IKE state machine 2527 mIkeSessionStateMachine.sendMessage( 2528 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authFailResp); 2529 mLooper.dispatchAll(); 2530 2531 // Verify Delete request was sent 2532 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 2533 assertEquals(1, payloads.size()); 2534 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 2535 2536 // Verify IKE Session was closed properly 2537 assertNull(mIkeSessionStateMachine.getCurrentState()); 2538 verify(mMockIkeSessionCallback) 2539 .onClosedExceptionally(any(AuthenticationFailedException.class)); 2540 } 2541 2542 @Test testAuthHandlesIkeErrorNotify()2543 public void testAuthHandlesIkeErrorNotify() throws Exception { 2544 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2545 verifyRetransmissionStarted(); 2546 resetMockIkeMessageHelper(); 2547 2548 // Mock rejecting IKE AUTH with Authenticatio Failure notification 2549 ReceivedIkePacket mockAuthFailPacket = 2550 makeIkeAuthRespWithoutChildPayloads( 2551 Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED))); 2552 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); 2553 mLooper.dispatchAll(); 2554 2555 // Verify IKE Session is closed properly 2556 assertNull(mIkeSessionStateMachine.getCurrentState()); 2557 verify(mMockIkeSessionCallback) 2558 .onClosedExceptionally(any(AuthenticationFailedException.class)); 2559 } 2560 2561 @Test testAuthHandlesCreateChildErrorNotify()2562 public void testAuthHandlesCreateChildErrorNotify() throws Exception { 2563 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2564 verifyRetransmissionStarted(); 2565 resetMockIkeMessageHelper(); 2566 2567 // Mock rejecting IKE AUTH with a Create Child error notification 2568 ReceivedIkePacket mockAuthFailPacket = 2569 makeIkeAuthRespWithoutChildPayloads( 2570 Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE))); 2571 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); 2572 mLooper.dispatchAll(); 2573 2574 // Verify IKE Session is closed properly 2575 assertNull(mIkeSessionStateMachine.getCurrentState()); 2576 2577 ArgumentCaptor<IkeProtocolException> captor = 2578 ArgumentCaptor.forClass(IkeProtocolException.class); 2579 verify(mMockIkeSessionCallback).onClosedExceptionally(captor.capture()); 2580 IkeProtocolException exception = captor.getValue(); 2581 assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, exception.getErrorType()); 2582 } 2583 2584 @Test testAuthPskHandleRespWithParsingError()2585 public void testAuthPskHandleRespWithParsingError() throws Exception { 2586 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2587 verifyRetransmissionStarted(); 2588 resetMockIkeMessageHelper(); 2589 2590 // Mock receiving packet with syntax error 2591 ReceivedIkePacket mockInvalidPacket = 2592 makeDummyReceivedIkePacketWithInvalidSyntax( 2593 mSpyCurrentIkeSaRecord, true /*isResp*/, IkeHeader.EXCHANGE_TYPE_IKE_AUTH); 2594 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 2595 mLooper.dispatchAll(); 2596 2597 // Verify Delete request was sent 2598 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 2599 assertEquals(1, payloads.size()); 2600 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 2601 2602 // Verify IKE Session is closed properly 2603 assertNull(mIkeSessionStateMachine.getCurrentState()); 2604 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 2605 } 2606 2607 @Test testAuthWithOptionAcceptAnyRemoteId()2608 public void testAuthWithOptionAcceptAnyRemoteId() throws Exception { 2609 mIkeSessionStateMachine.quitNow(); 2610 reset(mMockChildSessionFactoryHelper); 2611 setupChildStateMachineFactory(mMockChildSessionStateMachine); 2612 2613 IkeSessionParams ikeSessionParams = 2614 buildIkeSessionParamsCommon() 2615 .setAuthPsk(mPsk) 2616 .addIkeOption(IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID) 2617 .build(); 2618 mIkeSessionStateMachine = makeAndStartIkeSession(ikeSessionParams); 2619 2620 // Mock IKE INIT 2621 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2622 verifyRetransmissionStarted(); 2623 2624 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload that is different 2625 // from configured ID-Responder. 2626 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2627 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2628 authRelatedPayloads.add(spyAuthPayload); 2629 2630 IkeIdPayload respIdPayload = makeRespIdPayload(REMOTE_ID_IPV4); 2631 authRelatedPayloads.add(respIdPayload); 2632 2633 // Send response to IKE state machine and verify authentication is done. 2634 verifySharedKeyAuthentication( 2635 spyAuthPayload, 2636 respIdPayload, 2637 authRelatedPayloads, 2638 true /*hasChildPayloads*/, 2639 false /*hasConfigPayloadInResp*/); 2640 verifyRetransmissionStopped(); 2641 } 2642 2643 @Test testAuthRejectOtherResponderId()2644 public void testAuthRejectOtherResponderId() throws Exception { 2645 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2646 verifyRetransmissionStarted(); 2647 2648 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload that is different 2649 // from configured ID-Responder. 2650 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2651 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2652 authRelatedPayloads.add(spyAuthPayload); 2653 2654 IkeIdPayload respIdPayload = makeRespIdPayload(REMOTE_ID_IPV4); 2655 authRelatedPayloads.add(respIdPayload); 2656 2657 // Send response to IKE state machine 2658 mIkeSessionStateMachine.sendMessage( 2659 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2660 makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 2661 mLooper.dispatchAll(); 2662 2663 // Verify IKE Session is closed properly 2664 assertNull(mIkeSessionStateMachine.getCurrentState()); 2665 verify(mMockIkeSessionCallback) 2666 .onClosedExceptionally(any(AuthenticationFailedException.class)); 2667 } 2668 2669 @Test testCreateIkeLocalIkeAuthPreEap()2670 public void testCreateIkeLocalIkeAuthPreEap() throws Exception { 2671 mIkeSessionStateMachine.quitNow(); 2672 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2673 2674 // Mock IKE INIT 2675 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2676 verifyRetransmissionStarted(); 2677 2678 // Build IKE AUTH response with EAP. Auth, ID-Resp and Cert payloads. 2679 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2680 2681 authRelatedPayloads.add(new IkeEapPayload(EAP_DUMMY_MSG)); 2682 authRelatedPayloads.add(makeSpyDigitalSignAuthPayload()); 2683 authRelatedPayloads.add(makeRespIdPayload()); 2684 2685 IkeCertX509CertPayload certPayload = new IkeCertX509CertPayload(mServerEndCertificate); 2686 authRelatedPayloads.add(certPayload); 2687 2688 // Send IKE AUTH response to IKE state machine 2689 mIkeSessionStateMachine.sendMessage( 2690 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2691 makeIkeAuthRespWithoutChildPayloads(authRelatedPayloads)); 2692 mLooper.dispatchAll(); 2693 2694 // Validate outbound IKE AUTH request 2695 IkeMessage ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); 2696 assertNull( 2697 ikeAuthReqMessage.getPayloadForType( 2698 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPayload.class)); 2699 2700 assertTrue( 2701 mIkeSessionStateMachine.getCurrentState() 2702 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap); 2703 verifyRetransmissionStopped(); 2704 assertNotNull(mIkeSessionStateMachine.mInitIdPayload); 2705 assertNotNull(mIkeSessionStateMachine.mRespIdPayload); 2706 } 2707 verifyEapAuthenticatorCreatedAndGetCallback()2708 private IEapCallback verifyEapAuthenticatorCreatedAndGetCallback() { 2709 ArgumentCaptor<IEapCallback> captor = ArgumentCaptor.forClass(IEapCallback.class); 2710 2711 verify(mMockEapAuthenticatorFactory) 2712 .newEapAuthenticator( 2713 eq(mIkeSessionStateMachine.getHandler().getLooper()), 2714 captor.capture(), 2715 eq(mSpyContext), 2716 eq(mEapSessionConfig), 2717 any(RandomnessFactory.class)); 2718 2719 return captor.getValue(); 2720 } 2721 2722 @Test testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage()2723 public void testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage() 2724 throws Exception { 2725 mIkeSessionStateMachine.quitNow(); 2726 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2727 2728 // Setup state and go to IN_EAP state 2729 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2730 mLooper.dispatchAll(); 2731 2732 mIkeSessionStateMachine.sendMessage( 2733 IkeSessionStateMachine.CMD_EAP_START_EAP_AUTH, new IkeEapPayload(EAP_DUMMY_MSG)); 2734 mLooper.dispatchAll(); 2735 2736 verifyEapAuthenticatorCreatedAndGetCallback(); 2737 2738 verify(mMockEapAuthenticator).processEapMessage(eq(EAP_DUMMY_MSG)); 2739 } 2740 2741 @Test testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse()2742 public void testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse() throws Exception { 2743 mIkeSessionStateMachine.quitNow(); 2744 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2745 2746 // Setup state and go to IN_EAP state 2747 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2748 mLooper.dispatchAll(); 2749 2750 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); 2751 callback.onResponse(EAP_DUMMY_MSG); 2752 mLooper.dispatchAll(); 2753 verifyRetransmissionStarted(); 2754 2755 // Verify EAP response 2756 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 2757 IkeHeader ikeHeader = resp.ikeHeader; 2758 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 2759 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); 2760 assertFalse(ikeHeader.isResponseMsg); 2761 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 2762 2763 assertEquals(1, resp.ikePayloadList.size()); 2764 assertArrayEquals(EAP_DUMMY_MSG, ((IkeEapPayload) resp.ikePayloadList.get(0)).eapMessage); 2765 } 2766 2767 @Test testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket()2768 public void testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket() throws Exception { 2769 mIkeSessionStateMachine.quitNow(); 2770 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2771 2772 // Setup state and go to IN_EAP state 2773 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2774 mLooper.dispatchAll(); 2775 2776 // Mock sending IKE_AUTH{EAP} request 2777 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); 2778 callback.onResponse(EAP_DUMMY_MSG); 2779 mLooper.dispatchAll(); 2780 verifyRetransmissionStarted(); 2781 2782 // Send IKE AUTH response with no EAP Payload to IKE state machine 2783 mIkeSessionStateMachine.sendMessage( 2784 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2785 makeIkeAuthRespWithoutChildPayloads(new LinkedList<>())); 2786 mLooper.dispatchAll(); 2787 2788 // Verify state machine quit properly 2789 verify(mMockIkeSessionCallback) 2790 .onClosedExceptionally(any(AuthenticationFailedException.class)); 2791 assertNull(mIkeSessionStateMachine.getCurrentState()); 2792 } 2793 2794 @Test testCreateIkeLocalIkeAuthInEapHandlesSuccess()2795 public void testCreateIkeLocalIkeAuthInEapHandlesSuccess() throws Exception { 2796 mIkeSessionStateMachine.quitNow(); 2797 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2798 2799 // Setup state and go to IN_EAP state 2800 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2801 mLooper.dispatchAll(); 2802 2803 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); 2804 2805 // Setup dummy initIdPayload for next state. 2806 mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class); 2807 doReturn(new byte[0]).when(mIkeSessionStateMachine.mInitIdPayload).getEncodedPayloadBody(); 2808 2809 callback.onSuccess(mPsk, new byte[0]); // use mPsk as MSK, eMSK does not matter 2810 mLooper.dispatchAll(); 2811 2812 assertTrue( 2813 mIkeSessionStateMachine.getCurrentState() 2814 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthPostEap); 2815 } 2816 2817 @Test testCreateIkeLocalIkeAuthInEapHandlesError()2818 public void testCreateIkeLocalIkeAuthInEapHandlesError() throws Exception { 2819 mIkeSessionStateMachine.quitNow(); 2820 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2821 2822 // Setup state and go to IN_EAP state 2823 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2824 mLooper.dispatchAll(); 2825 2826 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); 2827 2828 Throwable error = new IllegalArgumentException(); 2829 callback.onError(error); 2830 mLooper.dispatchAll(); 2831 2832 // Fires user error callbacks 2833 verify(mMockIkeSessionCallback) 2834 .onClosedExceptionally(argThat(err -> err.getCause() == error)); 2835 2836 // Verify state machine quit properly 2837 verify(mSpyCurrentIkeSaRecord).close(); 2838 assertNull(mIkeSessionStateMachine.getCurrentState()); 2839 } 2840 2841 @Test testCreateIkeLocalIkeAuthInEapHandlesFailure()2842 public void testCreateIkeLocalIkeAuthInEapHandlesFailure() throws Exception { 2843 mIkeSessionStateMachine.quitNow(); 2844 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2845 2846 // Setup state and go to IN_EAP state 2847 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2848 mLooper.dispatchAll(); 2849 2850 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(); 2851 callback.onFail(); 2852 mLooper.dispatchAll(); 2853 2854 // Fires user error callbacks 2855 verify(mMockIkeSessionCallback) 2856 .onClosedExceptionally(any(AuthenticationFailedException.class)); 2857 2858 // Verify state machine quit properly 2859 verify(mSpyCurrentIkeSaRecord).close(); 2860 assertNull(mIkeSessionStateMachine.getCurrentState()); 2861 } 2862 2863 @Test testCreateIkeLocalIkeAuthPostEap()2864 public void testCreateIkeLocalIkeAuthPostEap() throws Exception { 2865 mIkeSessionStateMachine.quitNow(); 2866 reset(mMockChildSessionFactoryHelper); 2867 setupChildStateMachineFactory(mMockChildSessionStateMachine); 2868 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 2869 2870 // Setup dummy state from IkeAuthPreEap for next state. 2871 mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class); 2872 doReturn(new byte[0]).when(mIkeSessionStateMachine.mInitIdPayload).getEncodedPayloadBody(); 2873 mIkeSessionStateMachine.mRespIdPayload = makeRespIdPayload(); 2874 2875 List<Integer> payloadTypeList = new LinkedList<>(); 2876 List<String> payloadHexStringList = new LinkedList<>(); 2877 2878 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 2879 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 2880 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 2881 2882 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 2883 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 2884 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 2885 2886 mIkeSessionStateMachine.mFirstChildReqList = 2887 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/); 2888 2889 // Setup state and go to IN_EAP state 2890 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap); 2891 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_EAP_FINISH_EAP_AUTH, mPsk); 2892 mLooper.dispatchAll(); 2893 verifyRetransmissionStarted(); 2894 2895 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. 2896 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2897 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2898 authRelatedPayloads.add(spyAuthPayload); 2899 2900 IkeIdPayload respIdPayload = makeRespIdPayload(); 2901 2902 verifySharedKeyAuthentication( 2903 spyAuthPayload, 2904 respIdPayload, 2905 authRelatedPayloads, 2906 false /*hasChildPayloads*/, 2907 false /*hasConfigPayloadInResp*/); 2908 verifyRetransmissionStopped(); 2909 } 2910 2911 @Test testCreateIkeLocalIkeAuthHandlesFirstFrag()2912 public void testCreateIkeLocalIkeAuthHandlesFirstFrag() throws Exception { 2913 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2914 verifyRetransmissionStarted(); 2915 2916 // Received IKE fragment 2917 byte[] unencryptedData = "testCreateIkeLocalIkeAuthHandlesFrag".getBytes(); 2918 int fragNum = 1; 2919 int totalFragments = 2; 2920 IkeSkfPayload skfPayload = 2921 IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); 2922 2923 ReceivedIkePacket packet = 2924 makeDummyReceivedIkeFragmentPacket( 2925 mSpyCurrentIkeSaRecord, 2926 true /*isResp*/, 2927 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 2928 skfPayload, 2929 PAYLOAD_TYPE_AUTH, 2930 null /* collectedFrags*/); 2931 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 2932 mLooper.dispatchAll(); 2933 2934 // Verify state doesn't change 2935 assertTrue( 2936 mIkeSessionStateMachine.getCurrentState() 2937 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 2938 2939 // Verify the IkeSaRecord has stored the fragment. 2940 DecodeResultPartial resultPartial = 2941 mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/); 2942 assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType); 2943 assertEquals(totalFragments, resultPartial.collectedFragsList.length); 2944 assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); 2945 assertFalse(resultPartial.isAllFragmentsReceived()); 2946 2947 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(false /*isResp*/)); 2948 } 2949 2950 @Test testCreateIkeLocalIkeAuthHandlesLastFragOk()2951 public void testCreateIkeLocalIkeAuthHandlesLastFragOk() throws Exception { 2952 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2953 verifyRetransmissionStarted(); 2954 2955 // Set previously collected IKE fragments 2956 DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); 2957 mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); 2958 2959 // Build reassembled IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. 2960 List<IkePayload> authRelatedPayloads = new LinkedList<>(); 2961 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 2962 authRelatedPayloads.add(spyAuthPayload); 2963 2964 IkeIdPayload respIdPayload = makeRespIdPayload(); 2965 authRelatedPayloads.add(respIdPayload); 2966 2967 List<IkePayload> authPayloadList = 2968 getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); 2969 2970 // Receive last auth response and do IKE_AUTH 2971 ReceivedIkePacket packet = 2972 makeDummyReceivedLastIkeFragmentPacketOk( 2973 mSpyCurrentIkeSaRecord, 2974 true /*isResp*/, 2975 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 2976 mockCollectedFrags, 2977 authPayloadList, 2978 "FirstFrag".getBytes()); 2979 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 2980 mLooper.dispatchAll(); 2981 2982 // Verify IKE AUTH is done 2983 assertTrue( 2984 mIkeSessionStateMachine.getCurrentState() 2985 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2986 2987 // Verify collected response fragments are cleared. 2988 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); 2989 verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); 2990 } 2991 2992 @Test testCreateIkeLocalIkeAuthHandlesLastFragError()2993 public void testCreateIkeLocalIkeAuthHandlesLastFragError() throws Exception { 2994 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2995 verifyRetransmissionStarted(); 2996 resetMockIkeMessageHelper(); 2997 2998 // Set previously collected IKE fragments 2999 DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); 3000 mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); 3001 3002 // Receive last auth response with syntax error 3003 ReceivedIkePacket packet = 3004 makeDummyReceivedLastIkeFragmentPacketError( 3005 mSpyCurrentIkeSaRecord, 3006 true /*isResp*/, 3007 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 3008 mockCollectedFrags, 3009 new InvalidSyntaxException("IkeStateMachineTest")); 3010 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 3011 mLooper.dispatchAll(); 3012 3013 // Verify Delete request is sent 3014 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3015 assertEquals(1, payloads.size()); 3016 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3017 3018 // Verify IKE Session is closed properly 3019 assertNull(mIkeSessionStateMachine.getCurrentState()); 3020 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 3021 3022 // Collected response fragments are cleared 3023 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); 3024 verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); 3025 } 3026 3027 @Test testRekeyIkeLocalCreateSendsRequest()3028 public void testRekeyIkeLocalCreateSendsRequest() throws Exception { 3029 setupIdleStateMachine(); 3030 3031 // Send Rekey-Create request 3032 mIkeSessionStateMachine.sendMessage( 3033 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3034 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3035 mLooper.dispatchAll(); 3036 assertTrue( 3037 mIkeSessionStateMachine.getCurrentState() 3038 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 3039 verifyRetransmissionStarted(); 3040 3041 // Verify outbound message 3042 IkeMessage rekeyMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3043 3044 IkeHeader ikeHeader = rekeyMsg.ikeHeader; 3045 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 3046 assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); 3047 assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); 3048 assertFalse(ikeHeader.isResponseMsg); 3049 assertTrue(ikeHeader.fromIkeInitiator); 3050 3051 // Verify SA payload & proposals 3052 IkeSaPayload saPayload = 3053 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class); 3054 assertFalse(saPayload.isSaResponse); 3055 assertEquals(1, saPayload.proposalList.size()); 3056 3057 IkeSaPayload.IkeProposal proposal = 3058 (IkeSaPayload.IkeProposal) saPayload.proposalList.get(0); 3059 assertEquals(1, proposal.number); // Must be 1-indexed 3060 assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); 3061 assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize); 3062 assertEquals(mIkeSessionStateMachine.mSaProposal, proposal.saProposal); 3063 3064 // Verify Nonce and KE payloads exist. 3065 assertNotNull( 3066 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); 3067 3068 IkeKePayload kePayload = 3069 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class); 3070 assertNotNull(kePayload); 3071 assertTrue(kePayload.isOutbound); 3072 } 3073 3074 @Test testRekeyIkeLocalCreateHandlesResponse()3075 public void testRekeyIkeLocalCreateHandlesResponse() throws Exception { 3076 setupIdleStateMachine(); 3077 3078 // Send Rekey-Create request 3079 mIkeSessionStateMachine.sendMessage( 3080 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3081 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3082 mLooper.dispatchAll(); 3083 verifyRetransmissionStarted(); 3084 3085 // Prepare "rekeyed" SA 3086 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 3087 3088 // Receive Rekey response 3089 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 3090 mIkeSessionStateMachine.sendMessage( 3091 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 3092 mLooper.dispatchAll(); 3093 verifyIncrementLocaReqMsgId(); 3094 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); 3095 3096 // Verify in delete state, and new SA record was saved: 3097 assertTrue( 3098 mIkeSessionStateMachine.getCurrentState() 3099 instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); 3100 verifyRetransmissionStarted(); 3101 assertEquals(mSpyLocalInitIkeSaRecord, mIkeSessionStateMachine.mLocalInitNewIkeSaRecord); 3102 verify(mSpyCurrentIkeSocket) 3103 .registerIke( 3104 eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); 3105 } 3106 3107 @Test testRekeyIkeLocalCreateHandleRespWithParsingError()3108 public void testRekeyIkeLocalCreateHandleRespWithParsingError() throws Exception { 3109 setupIdleStateMachine(); 3110 3111 // Send Rekey-Create request 3112 mIkeSessionStateMachine.sendMessage( 3113 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3114 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3115 mLooper.dispatchAll(); 3116 verifyRetransmissionStarted(); 3117 resetMockIkeMessageHelper(); 3118 3119 // Mock receiving packet with syntax error 3120 ReceivedIkePacket mockInvalidPacket = 3121 makeDummyReceivedIkePacketWithInvalidSyntax( 3122 mSpyCurrentIkeSaRecord, 3123 true /*isResp*/, 3124 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 3125 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 3126 mLooper.dispatchAll(); 3127 3128 // Verify Delete request was sent 3129 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3130 assertEquals(1, payloads.size()); 3131 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3132 3133 // Verify IKE Session is closed properly 3134 assertNull(mIkeSessionStateMachine.getCurrentState()); 3135 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 3136 } 3137 3138 @Test testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify()3139 public void testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify() throws Exception { 3140 setupIdleStateMachine(); 3141 3142 // Send Rekey-Create request 3143 mIkeSessionStateMachine.sendMessage( 3144 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3145 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3146 mLooper.dispatchAll(); 3147 3148 // Mock receiving packet with NO_PROPOSAL_CHOSEN 3149 ReceivedIkePacket resp = 3150 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN)); 3151 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 3152 mLooper.dispatchAll(); 3153 3154 // Verify IKE Session goes back to Idle and retry is scheduled 3155 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 3156 assertTrue( 3157 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3158 } 3159 3160 @Test testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify()3161 public void testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify() throws Exception { 3162 setupIdleStateMachine(); 3163 3164 // Send Rekey-Create request 3165 mIkeSessionStateMachine.sendMessage( 3166 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3167 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3168 mLooper.dispatchAll(); 3169 resetMockIkeMessageHelper(); 3170 3171 // Mock receiving packet with NO_PROPOSAL_CHOSEN 3172 ReceivedIkePacket resp = 3173 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX)); 3174 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 3175 mLooper.dispatchAll(); 3176 3177 // Verify no message was sent because a fatal error notification was received 3178 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 3179 3180 // Verify IKE Session is closed properly 3181 assertNull(mIkeSessionStateMachine.getCurrentState()); 3182 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 3183 } 3184 3185 @Test testRekeyIkeLocalCreateSaCreationFail()3186 public void testRekeyIkeLocalCreateSaCreationFail() throws Exception { 3187 // Throw error when building new IKE SA 3188 throwExceptionWhenMakeRekeyIkeSa( 3189 new GeneralSecurityException("testRekeyIkeLocalCreateSaCreationFail")); 3190 3191 setupIdleStateMachine(); 3192 3193 // Send Rekey-Create request 3194 mIkeSessionStateMachine.sendMessage( 3195 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3196 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3197 mLooper.dispatchAll(); 3198 resetMockIkeMessageHelper(); 3199 3200 // Receive Rekey response 3201 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 3202 mIkeSessionStateMachine.sendMessage( 3203 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 3204 mLooper.dispatchAll(); 3205 3206 // Verify Delete request was sent 3207 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3208 assertEquals(1, payloads.size()); 3209 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3210 3211 // Verify IKE Session is closed properly 3212 assertNull(mIkeSessionStateMachine.getCurrentState()); 3213 verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); 3214 } 3215 3216 @Test testRekeyIkeLocalCreateHandleReqWithNonFatalError()3217 public void testRekeyIkeLocalCreateHandleReqWithNonFatalError() throws Exception { 3218 setupIdleStateMachine(); 3219 3220 // Send Rekey-Create request 3221 mIkeSessionStateMachine.sendMessage( 3222 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3223 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3224 mLooper.dispatchAll(); 3225 verifyRetransmissionStarted(); 3226 resetMockIkeMessageHelper(); 3227 3228 // Build protocol exception 3229 List<Integer> unsupportedPayloads = new LinkedList<>(); 3230 unsupportedPayloads.add(PAYLOAD_TYPE_UNSUPPORTED); 3231 UnsupportedCriticalPayloadException exception = 3232 new UnsupportedCriticalPayloadException(unsupportedPayloads); 3233 3234 // Mock receiving packet with unsupported critical payload 3235 ReceivedIkePacket mockInvalidPacket = 3236 makeDummyReceivedIkePacketWithDecodingError( 3237 mSpyCurrentIkeSaRecord, 3238 false /*isResp*/, 3239 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 3240 exception); 3241 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 3242 mLooper.dispatchAll(); 3243 3244 // Verify error notification was sent 3245 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 3246 assertEquals(1, payloads.size()); 3247 3248 IkePayload payload = payloads.get(0); 3249 assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); 3250 assertEquals( 3251 ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, ((IkeNotifyPayload) payload).notifyType); 3252 3253 // Verify IKE Session stays in the same state 3254 assertTrue( 3255 mIkeSessionStateMachine.getCurrentState() 3256 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 3257 } 3258 mockRescheduleRekey(IkeSaRecord spySaRecord)3259 private void mockRescheduleRekey(IkeSaRecord spySaRecord) { 3260 IkeLocalRequest rekeyReq = 3261 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); 3262 doAnswer( 3263 (invocation) -> { 3264 mIkeSessionStateMachine.sendMessageDelayed( 3265 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 3266 rekeyReq, 3267 RETRY_INTERVAL_MS); 3268 return null; 3269 }) 3270 .when(spySaRecord) 3271 .rescheduleRekey(eq(RETRY_INTERVAL_MS)); 3272 } 3273 3274 @Test testRekeyIkeLocalCreateHandleRespWithTempFailure()3275 public void testRekeyIkeLocalCreateHandleRespWithTempFailure() throws Exception { 3276 setupIdleStateMachine(); 3277 3278 // Send Rekey-Create request 3279 mIkeSessionStateMachine.sendMessage( 3280 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3281 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3282 mLooper.dispatchAll(); 3283 3284 // Mock sending TEMPORARY_FAILURE response 3285 mockRcvTempFail(); 3286 mLooper.dispatchAll(); 3287 3288 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 3289 assertTrue( 3290 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3291 } 3292 mockCreateAndTransitionToRekeyDeleteLocal()3293 private void mockCreateAndTransitionToRekeyDeleteLocal() { 3294 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 3295 mIkeSessionStateMachine.mLocalInitNewIkeSaRecord = mSpyLocalInitIkeSaRecord; 3296 mIkeSessionStateMachine.addIkeSaRecord(mSpyLocalInitIkeSaRecord); 3297 mIkeSessionStateMachine.sendMessage( 3298 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3299 mIkeSessionStateMachine.mRekeyIkeLocalDelete); 3300 mLooper.dispatchAll(); 3301 verifyRetransmissionStarted(); 3302 } 3303 3304 @Test testRekeyIkeLocalDeleteSendsRequest()3305 public void testRekeyIkeLocalDeleteSendsRequest() throws Exception { 3306 setupIdleStateMachine(); 3307 mockCreateAndTransitionToRekeyDeleteLocal(); 3308 3309 // Verify Rekey-Delete request 3310 assertTrue( 3311 mIkeSessionStateMachine.getCurrentState() 3312 instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); 3313 verifyRetransmissionStarted(); 3314 3315 // Verify outbound message 3316 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3317 3318 IkeHeader ikeHeader = delMsg.ikeHeader; 3319 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); 3320 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); 3321 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 3322 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 3323 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 3324 assertFalse(ikeHeader.isResponseMsg); 3325 3326 List<IkeDeletePayload> deletePayloadList = 3327 delMsg.getPayloadListForType( 3328 IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); 3329 assertEquals(1, deletePayloadList.size()); 3330 3331 IkeDeletePayload deletePayload = deletePayloadList.get(0); 3332 assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); 3333 assertEquals(0, deletePayload.numSpi); 3334 assertEquals(0, deletePayload.spiSize); 3335 assertArrayEquals(new int[0], deletePayload.spisToDelete); 3336 } 3337 verifyRekeyReplaceSa(IkeSaRecord newSaRecord)3338 private void verifyRekeyReplaceSa(IkeSaRecord newSaRecord) { 3339 verify(mSpyCurrentIkeSaRecord).close(); 3340 verify(mSpyCurrentIkeSocket).unregisterIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi())); 3341 verify(mSpyCurrentIkeSocket, never()).unregisterIke(eq(newSaRecord.getLocalSpi())); 3342 3343 assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, newSaRecord); 3344 3345 verify(mMockChildSessionStateMachine).setSkD(newSaRecord.getSkD()); 3346 } 3347 3348 @Test testRekeyIkeLocalDeleteHandlesResponse()3349 public void testRekeyIkeLocalDeleteHandlesResponse() throws Exception { 3350 setupIdleStateMachine(); 3351 mockCreateAndTransitionToRekeyDeleteLocal(); 3352 3353 // Receive Delete response 3354 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 3355 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 3356 mIkeSessionStateMachine.sendMessage( 3357 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 3358 mLooper.dispatchAll(); 3359 verifyIncrementLocaReqMsgId(); 3360 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); 3361 3362 // Verify final state - Idle, with new SA, and old SA closed. 3363 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 3364 verify(mMockIkeSessionCallback, never()).onClosed(); 3365 assertTrue( 3366 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3367 verifyRetransmissionStopped(); 3368 } 3369 3370 @Ignore disableTestRekeyIkeLocalDeleteHandlesRespWithParsingError()3371 public void disableTestRekeyIkeLocalDeleteHandlesRespWithParsingError() throws Exception { 3372 setupIdleStateMachine(); 3373 mockCreateAndTransitionToRekeyDeleteLocal(); 3374 resetMockIkeMessageHelper(); 3375 3376 // Mock receiving packet with syntax error 3377 ReceivedIkePacket mockInvalidPacket = 3378 makeDummyReceivedIkePacketWithInvalidSyntax( 3379 mSpyCurrentIkeSaRecord, 3380 true /*isResp*/, 3381 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 3382 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 3383 mLooper.dispatchAll(); 3384 3385 // Verify no more request out 3386 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 3387 3388 // Verify final state - Idle, with new SA, and old SA closed. 3389 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 3390 assertTrue( 3391 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3392 verifyRetransmissionStopped(); 3393 } 3394 3395 @Test testRekeyIkeLocalDeleteWithRequestOnNewSa()3396 public void testRekeyIkeLocalDeleteWithRequestOnNewSa() throws Exception { 3397 setupIdleStateMachine(); 3398 mockCreateAndTransitionToRekeyDeleteLocal(); 3399 3400 // Receive an empty (DPD) request on the new IKE SA 3401 mIkeSessionStateMachine.sendMessage( 3402 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3403 makeDpdIkeRequest(mSpyLocalInitIkeSaRecord)); 3404 mLooper.dispatchAll(); 3405 3406 // Verify final state - Idle, with new SA, and old SA closed. 3407 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 3408 assertTrue( 3409 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3410 verifyRetransmissionStopped(); 3411 } 3412 3413 @Test testRekeyIkeLocalDeleteWithRequestFragOnNewSa()3414 public void testRekeyIkeLocalDeleteWithRequestFragOnNewSa() throws Exception { 3415 setupIdleStateMachine(); 3416 mockCreateAndTransitionToRekeyDeleteLocal(); 3417 3418 // Received IKE fragment 3419 byte[] unencryptedData = "testRekeyIkeLocalDeleteWithRequestFragOnNewSa".getBytes(); 3420 int fragNum = 1; 3421 int totalFragments = 2; 3422 IkeSkfPayload skfPayload = 3423 IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); 3424 3425 ReceivedIkePacket packet = 3426 makeDummyReceivedIkeFragmentPacket( 3427 mSpyLocalInitIkeSaRecord, 3428 false /*isResp*/, 3429 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 3430 skfPayload, 3431 PAYLOAD_TYPE_SA, 3432 null /* collectedFrags*/); 3433 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 3434 mLooper.dispatchAll(); 3435 3436 // Verify rekey is done. 3437 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 3438 verifyRetransmissionStopped(); 3439 3440 // Verify the IkeSaRecord has stored the new fragment. 3441 DecodeResultPartial resultPartial = 3442 mSpyLocalInitIkeSaRecord.getCollectedFragments(false /*isResp*/); 3443 assertEquals(PAYLOAD_TYPE_SA, resultPartial.firstPayloadType); 3444 assertEquals(totalFragments, resultPartial.collectedFragsList.length); 3445 assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); 3446 assertFalse(resultPartial.isAllFragmentsReceived()); 3447 } 3448 3449 @Test testRekeyIkeRemoteDeleteWithRequestOnNewSa()3450 public void testRekeyIkeRemoteDeleteWithRequestOnNewSa() throws Exception { 3451 setupIdleStateMachine(); 3452 3453 // Seed fake rekey data and force transition to RekeyIkeRemoteDelete 3454 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 3455 mIkeSessionStateMachine.addIkeSaRecord(mSpyRemoteInitIkeSaRecord); 3456 mIkeSessionStateMachine.sendMessage( 3457 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3458 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 3459 mLooper.dispatchAll(); 3460 3461 // Receive an empty (DPD) request on the new IKE SA 3462 mIkeSessionStateMachine.sendMessage( 3463 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3464 makeDpdIkeRequest(mSpyRemoteInitIkeSaRecord)); 3465 mLooper.dispatchAll(); 3466 3467 // Verify final state - Idle, with new SA, and old SA closed. 3468 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 3469 assertTrue( 3470 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3471 } 3472 3473 @Test testRekeyIkeRemoteCreate()3474 public void testRekeyIkeRemoteCreate() throws Exception { 3475 setupIdleStateMachine(); 3476 3477 setupRekeyedIkeSa(mSpyRemoteInitIkeSaRecord); 3478 3479 // Receive Rekey request 3480 ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); 3481 mIkeSessionStateMachine.sendMessage( 3482 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); 3483 mLooper.dispatchAll(); 3484 verifyIncrementRemoteReqMsgId(); 3485 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); 3486 3487 // Verify SA created with correct parameters 3488 ArgumentCaptor<SaRecord.IkeSaRecordConfig> recordConfigCaptor = 3489 ArgumentCaptor.forClass(SaRecord.IkeSaRecordConfig.class); 3490 verify(mMockSaRecordHelper) 3491 .makeRekeyedIkeSaRecord(any(), any(), any(), any(), recordConfigCaptor.capture()); 3492 assertEquals(IKE_REKEY_SA_INITIATOR_SPI, recordConfigCaptor.getValue().initSpi.getSpi()); 3493 3494 // Verify outbound CREATE_CHILD_SA message 3495 IkeMessage rekeyCreateResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3496 IkeHeader rekeyCreateRespHeader = rekeyCreateResp.ikeHeader; 3497 assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyCreateRespHeader.nextPayloadType); 3498 assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyCreateRespHeader.exchangeType); 3499 assertTrue(rekeyCreateRespHeader.isResponseMsg); 3500 assertTrue(rekeyCreateRespHeader.fromIkeInitiator); 3501 assertNotNull( 3502 rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); 3503 assertNotNull( 3504 rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class)); 3505 assertNotNull( 3506 rekeyCreateResp.getPayloadForType( 3507 IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); 3508 3509 // Verify SA, StateMachine state 3510 assertEquals(mSpyCurrentIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordAwaitingRemoteDel); 3511 assertEquals(mSpyRemoteInitIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordSurviving); 3512 assertTrue( 3513 mIkeSessionStateMachine.getCurrentState() 3514 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 3515 verify(mSpyCurrentIkeSocket) 3516 .registerIke( 3517 eq(mSpyRemoteInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); 3518 } 3519 3520 @Ignore disableTestRekeyIkeRemoteCreateHandlesInvalidReq()3521 public void disableTestRekeyIkeRemoteCreateHandlesInvalidReq() throws Exception { 3522 setupIdleStateMachine(); 3523 3524 // Receive Rekey request 3525 ReceivedIkePacket request = makeRekeyIkeRequestWithUnacceptableProposal(); 3526 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 3527 mLooper.dispatchAll(); 3528 3529 verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); 3530 } 3531 3532 @Ignore disableTestRekeyIkeRemoteCreateSaCreationFailure()3533 public void disableTestRekeyIkeRemoteCreateSaCreationFailure() throws Exception { 3534 // Throw error when building new IKE SA 3535 throwExceptionWhenMakeRekeyIkeSa( 3536 new GeneralSecurityException("testRekeyIkeRemoteCreateSaCreationFailure")); 3537 setupIdleStateMachine(); 3538 3539 // Receive Rekey request 3540 ReceivedIkePacket request = makeRekeyIkeRequest(); 3541 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 3542 mLooper.dispatchAll(); 3543 3544 verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); 3545 } 3546 verifyProcessRekeyReqFailure(int expectedErrorCode)3547 private void verifyProcessRekeyReqFailure(int expectedErrorCode) { 3548 // Verify IKE Session is back to Idle 3549 assertTrue( 3550 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3551 3552 // Verify error notification was sent 3553 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 3554 assertEquals(1, payloads.size()); 3555 IkeNotifyPayload notify = (IkeNotifyPayload) payloads.get(0); 3556 assertEquals(expectedErrorCode, notify.notifyType); 3557 } 3558 3559 @Test testRekeyIkeRemoteDelete()3560 public void testRekeyIkeRemoteDelete() throws Exception { 3561 setupIdleStateMachine(); 3562 3563 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 3564 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 3565 mIkeSessionStateMachine.sendMessage( 3566 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3567 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 3568 mLooper.dispatchAll(); 3569 3570 // Rekey Delete request 3571 ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket = 3572 makeDeleteIkeRequest(mSpyCurrentIkeSaRecord); 3573 mIkeSessionStateMachine.sendMessage( 3574 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket); 3575 mLooper.dispatchAll(); 3576 verifyIncrementRemoteReqMsgId(); 3577 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); 3578 3579 // Verify outbound DELETE_IKE_SA message 3580 IkeMessage rekeyDeleteResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3581 IkeHeader rekeyDeleteRespHeader = rekeyDeleteResp.ikeHeader; 3582 assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyDeleteRespHeader.nextPayloadType); 3583 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, rekeyDeleteRespHeader.exchangeType); 3584 assertTrue(rekeyDeleteRespHeader.isResponseMsg); 3585 assertTrue(rekeyDeleteRespHeader.fromIkeInitiator); 3586 assertTrue(rekeyDeleteResp.ikePayloadList.isEmpty()); 3587 3588 // Verify final state - Idle, with new SA, and old SA closed. 3589 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 3590 3591 verify(mMockIkeSessionCallback, never()).onClosed(); 3592 3593 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); 3594 assertTrue( 3595 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3596 } 3597 3598 @Test testRekeyIkeRemoteDeleteExitAndRenter()3599 public void testRekeyIkeRemoteDeleteExitAndRenter() throws Exception { 3600 setupIdleStateMachine(); 3601 3602 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 3603 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 3604 mIkeSessionStateMachine.sendMessage( 3605 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3606 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 3607 mLooper.dispatchAll(); 3608 3609 // Trigger a timeout, and immediately re-enter remote-delete 3610 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); 3611 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE); 3612 mIkeSessionStateMachine.sendMessage( 3613 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3614 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 3615 mLooper.dispatchAll(); 3616 3617 // Shift time forward, and assert the previous timeout was NOT fired. 3618 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); 3619 mLooper.dispatchAll(); 3620 3621 // Verify no request received, or response sent. 3622 verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject()); 3623 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 3624 3625 // Verify final state has not changed - signal was not sent. 3626 assertTrue( 3627 mIkeSessionStateMachine.getCurrentState() 3628 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 3629 } 3630 3631 @Test testRekeyIkeRemoteDeleteTimedOut()3632 public void testRekeyIkeRemoteDeleteTimedOut() throws Exception { 3633 setupIdleStateMachine(); 3634 3635 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 3636 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 3637 mIkeSessionStateMachine.sendMessage( 3638 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 3639 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 3640 mLooper.dispatchAll(); 3641 3642 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS); 3643 mLooper.dispatchAll(); 3644 3645 // Verify no request received, or response sent. 3646 verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject()); 3647 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 3648 3649 // Verify final state - Idle, with new SA, and old SA closed. 3650 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 3651 3652 assertTrue( 3653 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3654 } 3655 3656 @Ignore disableTestSimulRekey()3657 public void disableTestSimulRekey() throws Exception { 3658 setupIdleStateMachine(); 3659 3660 // Prepare "rekeyed" SA 3661 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 3662 doReturn(1).when(mSpyLocalInitIkeSaRecord).compareTo(mSpyRemoteInitIkeSaRecord); 3663 3664 // Send Rekey request on mSpyCurrentIkeSaRecord 3665 mIkeSessionStateMachine.sendMessage( 3666 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3667 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3668 3669 // Receive Rekey request on mSpyCurrentIkeSaRecord 3670 ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); 3671 mIkeSessionStateMachine.sendMessage( 3672 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); 3673 mLooper.dispatchAll(); 3674 verifyIncrementRemoteReqMsgId(); 3675 3676 // Receive Rekey response on mSpyCurrentIkeSaRecord 3677 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 3678 mIkeSessionStateMachine.sendMessage( 3679 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 3680 mLooper.dispatchAll(); 3681 verifyIncrementLocaReqMsgId(); 3682 verify(mSpyCurrentIkeSocket) 3683 .registerIke( 3684 eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine)); 3685 3686 // Receive Delete response on mSpyCurrentIkeSaRecord 3687 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 3688 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 3689 mIkeSessionStateMachine.sendMessage( 3690 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 3691 mLooper.dispatchAll(); 3692 verifyIncrementLocaReqMsgId(); 3693 3694 // Verify 3695 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); 3696 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); 3697 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); 3698 assertTrue( 3699 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3700 3701 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 3702 verify(mMockIkeSessionCallback, never()).onClosed(); 3703 } 3704 3705 @Test testOpenIkeSession()3706 public void testOpenIkeSession() throws Exception { 3707 assertTrue( 3708 mIkeSessionStateMachine.getCurrentState() 3709 instanceof IkeSessionStateMachine.Initial); 3710 3711 mIkeSessionStateMachine.openSession(); 3712 mLooper.dispatchAll(); 3713 3714 assertTrue( 3715 mIkeSessionStateMachine.getCurrentState() 3716 instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit); 3717 } 3718 3719 @Test testIkeInitSchedulesRekey()3720 public void testIkeInitSchedulesRekey() throws Exception { 3721 setupFirstIkeSa(); 3722 3723 // Send IKE INIT request 3724 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 3725 3726 // Receive IKE INIT response 3727 ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); 3728 mIkeSessionStateMachine.sendMessage( 3729 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 3730 3731 // Mock IKE AUTH and transition to Idle 3732 mIkeSessionStateMachine.sendMessage( 3733 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 3734 mLooper.dispatchAll(); 3735 mIkeSessionStateMachine.mSaProposal = buildSaProposal(); 3736 3737 // Move time forward to trigger rekey 3738 mLooper.moveTimeForward( 3739 mIkeSessionStateMachine.mIkeSessionParams.getSoftLifetimeMsInternal()); 3740 mLooper.dispatchAll(); 3741 3742 assertTrue( 3743 mIkeSessionStateMachine.getCurrentState() 3744 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 3745 } 3746 3747 @Test testRekeyCreateIkeSchedulesRekey()3748 public void testRekeyCreateIkeSchedulesRekey() throws Exception { 3749 setupIdleStateMachine(); 3750 3751 // Send Rekey-Create request 3752 mIkeSessionStateMachine.sendMessage( 3753 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3754 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 3755 mLooper.dispatchAll(); 3756 3757 // Prepare "rekeyed" SA 3758 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 3759 3760 // Receive Rekey response 3761 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 3762 mIkeSessionStateMachine.sendMessage( 3763 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 3764 mLooper.dispatchAll(); 3765 3766 // Mock rekey delete and transition to Idle 3767 mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyLocalInitIkeSaRecord; 3768 mIkeSessionStateMachine.sendMessage( 3769 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 3770 mLooper.dispatchAll(); 3771 3772 // Move time forward to trigger rekey 3773 mLooper.moveTimeForward( 3774 mIkeSessionStateMachine.mIkeSessionParams.getSoftLifetimeMsInternal()); 3775 mLooper.dispatchAll(); 3776 3777 assertTrue( 3778 mIkeSessionStateMachine.getCurrentState() 3779 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 3780 } 3781 3782 @Test testBuildEncryptedInformationalMessage()3783 public void testBuildEncryptedInformationalMessage() throws Exception { 3784 IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX, new byte[0]); 3785 3786 boolean isResp = false; 3787 IkeMessage generated = 3788 mIkeSessionStateMachine.buildEncryptedInformationalMessage( 3789 mSpyCurrentIkeSaRecord, new IkeInformationalPayload[] {payload}, isResp, 0); 3790 3791 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), generated.ikeHeader.ikeInitiatorSpi); 3792 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), generated.ikeHeader.ikeResponderSpi); 3793 assertEquals( 3794 mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), generated.ikeHeader.messageId); 3795 assertEquals(isResp, generated.ikeHeader.isResponseMsg); 3796 assertEquals(IkePayload.PAYLOAD_TYPE_SK, generated.ikeHeader.nextPayloadType); 3797 3798 List<IkeNotifyPayload> generatedPayloads = 3799 generated.getPayloadListForType( 3800 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 3801 assertEquals(1, generatedPayloads.size()); 3802 3803 IkeNotifyPayload generatedPayload = generatedPayloads.get(0); 3804 assertArrayEquals(new byte[0], generatedPayload.notifyData); 3805 assertEquals(ERROR_TYPE_INVALID_SYNTAX, generatedPayload.notifyType); 3806 } 3807 verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord)3808 private void verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord) { 3809 if (expectedPackets == null) { 3810 assertNull(saRecord.getLastSentRespAllPackets()); 3811 return; 3812 } 3813 3814 assertEquals(expectedPackets.length, saRecord.getLastSentRespAllPackets().size()); 3815 for (int i = 0; i < expectedPackets.length; i++) { 3816 assertArrayEquals(expectedPackets[i], saRecord.getLastSentRespAllPackets().get(i)); 3817 } 3818 } 3819 3820 @Test testEncryptedRetransmitterImmediatelySendsRequest()3821 public void testEncryptedRetransmitterImmediatelySendsRequest() throws Exception { 3822 setupIdleStateMachine(); 3823 byte[][] dummyLastRespBytes = 3824 new byte[][] {"testRetransmitterSendsRequestLastResp".getBytes()}; 3825 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyLastRespBytes)); 3826 3827 IkeMessage spyIkeReqMessage = 3828 spy( 3829 new IkeMessage( 3830 new IkeHeader( 3831 mSpyCurrentIkeSaRecord.getInitiatorSpi(), 3832 mSpyCurrentIkeSaRecord.getResponderSpi(), 3833 IkePayload.PAYLOAD_TYPE_SK, 3834 EXCHANGE_TYPE_INFORMATIONAL, 3835 false /*isResp*/, 3836 mSpyCurrentIkeSaRecord.isLocalInit, 3837 mSpyCurrentIkeSaRecord.getLocalRequestMessageId()), 3838 new LinkedList<>())); 3839 3840 // Use something unique as a sentinel value 3841 byte[][] dummyReqBytesList = 3842 new byte[][] { 3843 "testRetransmitterSendsReqFrag1".getBytes(), 3844 "testRetransmitterSendsReqFrag2".getBytes() 3845 }; 3846 3847 doReturn(dummyReqBytesList) 3848 .when(spyIkeReqMessage) 3849 .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); 3850 3851 IkeSessionStateMachine.EncryptedRetransmitter retransmitter = 3852 mIkeSessionStateMachine.new EncryptedRetransmitter(spyIkeReqMessage); 3853 3854 // Verify message is sent out, and that request does not change cached retransmit-response 3855 // mLastSentIkeResp. 3856 verify(mSpyCurrentIkeSocket).sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS)); 3857 verify(mSpyCurrentIkeSocket).sendIkePacket(eq(dummyReqBytesList[1]), eq(REMOTE_ADDRESS)); 3858 verifyLastSentRespAllPackets(dummyLastRespBytes, mSpyCurrentIkeSaRecord); 3859 } 3860 3861 // TODO: b/141275871 Test retransmisstions are fired for correct times within certain time. 3862 3863 @Test testCacheLastRequestAndResponse()3864 public void testCacheLastRequestAndResponse() throws Exception { 3865 setupIdleStateMachine(); 3866 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(null /*reqPacket*/); 3867 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(null /*respPacketList*/); 3868 3869 byte[] dummyIkeReqFirstPacket = "testLastSentRequest".getBytes(); 3870 byte[][] dummyIkeResp = 3871 new byte[][] { 3872 "testLastSentRespFrag1".getBytes(), "testLastSentRespFrag2".getBytes() 3873 }; 3874 3875 doReturn(dummyIkeResp) 3876 .when(mMockIkeMessageHelper) 3877 .encryptAndEncode( 3878 any(), 3879 any(), 3880 eq(mSpyCurrentIkeSaRecord), 3881 any(IkeMessage.class), 3882 anyBoolean(), 3883 anyInt()); 3884 3885 // Receive a DPD request, expect to send dummyIkeResp 3886 ReceivedIkePacket dummyDpdRequest = 3887 makeDpdIkeRequest( 3888 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId(), dummyIkeReqFirstPacket); 3889 mIkeSessionStateMachine.sendMessage( 3890 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 3891 mLooper.dispatchAll(); 3892 3893 verify(mSpyCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); 3894 verify(mSpyCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[1]), eq(REMOTE_ADDRESS)); 3895 3896 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 3897 assertTrue(mSpyCurrentIkeSaRecord.isRetransmittedRequest(dummyIkeReqFirstPacket)); 3898 3899 assertTrue( 3900 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3901 } 3902 3903 @Test testReplyRetransmittedRequest()3904 public void testReplyRetransmittedRequest() throws Exception { 3905 setupIdleStateMachine(); 3906 3907 // Mock last sent request and response 3908 byte[] dummyIkeReqFirstPacket = "testRcvRetransmittedRequestReq".getBytes(); 3909 byte[][] dummyIkeResp = new byte[][] {"testRcvRetransmittedRequestResp".getBytes()}; 3910 3911 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); 3912 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp)); 3913 mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId(); 3914 3915 // Build request with last validated message ID 3916 ReceivedIkePacket request = 3917 makeDpdIkeRequest( 3918 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, 3919 dummyIkeReqFirstPacket); 3920 3921 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 3922 3923 mLooper.dispatchAll(); 3924 3925 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 3926 verify(mSpyCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); 3927 3928 assertTrue( 3929 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3930 } 3931 3932 @Test testDiscardFakeRetransmittedRequest()3933 public void testDiscardFakeRetransmittedRequest() throws Exception { 3934 setupIdleStateMachine(); 3935 3936 // Mock last sent request and response 3937 byte[] dummyIkeReqFirstPacket = "testDiscardFakeRetransmittedRequestReq".getBytes(); 3938 byte[][] dummyIkeResp = new byte[][] {"testDiscardFakeRetransmittedRequestResp".getBytes()}; 3939 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); 3940 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp)); 3941 mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId(); 3942 3943 // Build request with last validated message ID but different bytes 3944 ReceivedIkePacket request = 3945 makeDpdIkeRequest( 3946 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, new byte[0]); 3947 3948 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 3949 3950 mLooper.dispatchAll(); 3951 3952 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 3953 verify(mSpyCurrentIkeSocket, never()).sendIkePacket(any(), any()); 3954 3955 assertTrue( 3956 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3957 } 3958 3959 @Test testDiscardRetransmittedResponse()3960 public void testDiscardRetransmittedResponse() throws Exception { 3961 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 3962 verifyRetransmissionStarted(); 3963 3964 // Build and send fake response with last validated message ID to IKE state machine 3965 ReceivedIkePacket resp = 3966 makeDummyEncryptedReceivedIkePacketWithPayloadList( 3967 mSpyCurrentIkeSaRecord, 3968 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 3969 true /*isResp*/, 3970 mSpyCurrentIkeSaRecord.getLocalRequestMessageId() - 1, 3971 new LinkedList<>(), 3972 new byte[0]); 3973 3974 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 3975 mLooper.dispatchAll(); 3976 3977 // Verify current state does not change 3978 verifyRetransmissionStarted(); 3979 assertTrue( 3980 mIkeSessionStateMachine.getCurrentState() 3981 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 3982 } 3983 3984 @Test testDeleteIkeLocalDeleteRequest()3985 public void testDeleteIkeLocalDeleteRequest() throws Exception { 3986 setupIdleStateMachine(); 3987 3988 mIkeSessionStateMachine.sendMessage( 3989 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 3990 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 3991 mLooper.dispatchAll(); 3992 verifyRetransmissionStarted(); 3993 3994 // Verify outbound message 3995 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3996 3997 IkeHeader ikeHeader = delMsg.ikeHeader; 3998 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 3999 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4000 assertFalse(ikeHeader.isResponseMsg); 4001 assertTrue(ikeHeader.fromIkeInitiator); 4002 4003 List<IkeDeletePayload> deletePayloadList = 4004 delMsg.getPayloadListForType( 4005 IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); 4006 assertEquals(1, deletePayloadList.size()); 4007 4008 IkeDeletePayload deletePayload = deletePayloadList.get(0); 4009 assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); 4010 assertEquals(0, deletePayload.numSpi); 4011 assertEquals(0, deletePayload.spiSize); 4012 assertArrayEquals(new int[0], deletePayload.spisToDelete); 4013 } 4014 4015 @Test testDeleteIkeLocalDeleteResponse()4016 public void testDeleteIkeLocalDeleteResponse() throws Exception { 4017 setupIdleStateMachine(); 4018 4019 mIkeSessionStateMachine.sendMessage( 4020 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4021 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 4022 mLooper.dispatchAll(); 4023 verifyRetransmissionStarted(); 4024 4025 ReceivedIkePacket received = makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 4026 mIkeSessionStateMachine.sendMessage( 4027 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); 4028 mLooper.dispatchAll(); 4029 verifyIncrementLocaReqMsgId(); 4030 4031 verifyNotifyUserCloseSession(); 4032 4033 // Verify state machine quit properly 4034 assertNull(mIkeSessionStateMachine.getCurrentState()); 4035 } 4036 4037 @Test testDeleteIkeLocalDeleteResponseWithParsingError()4038 public void testDeleteIkeLocalDeleteResponseWithParsingError() throws Exception { 4039 setupIdleStateMachine(); 4040 4041 mIkeSessionStateMachine.sendMessage( 4042 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4043 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 4044 mLooper.dispatchAll(); 4045 verifyRetransmissionStarted(); 4046 resetMockIkeMessageHelper(); 4047 4048 // Mock receiving response with syntax error 4049 ReceivedIkePacket mockInvalidPacket = 4050 makeDummyReceivedIkePacketWithInvalidSyntax( 4051 mSpyCurrentIkeSaRecord, 4052 true /*isResp*/, 4053 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 4054 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 4055 mLooper.dispatchAll(); 4056 4057 // Verify no more request out 4058 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 4059 4060 // Verify state machine quit properly 4061 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 4062 assertNull(mIkeSessionStateMachine.getCurrentState()); 4063 } 4064 4065 @Test testDeleteIkeLocalDeleteHandlesInvalidResp()4066 public void testDeleteIkeLocalDeleteHandlesInvalidResp() throws Exception { 4067 setupIdleStateMachine(); 4068 4069 // Send delete request 4070 mIkeSessionStateMachine.sendMessage( 4071 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4072 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 4073 mLooper.dispatchAll(); 4074 4075 // Receive response with wrong exchange type 4076 ReceivedIkePacket resp = 4077 makeDummyReceivedIkePacketWithInvalidSyntax( 4078 mSpyCurrentIkeSaRecord, 4079 true /*isResp*/, 4080 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 4081 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 4082 mLooper.dispatchAll(); 4083 4084 // Verify state machine quit properly 4085 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 4086 assertNull(mIkeSessionStateMachine.getCurrentState()); 4087 } 4088 4089 @Test testDeleteIkeLocalDeleteReceivedNonDeleteRequest()4090 public void testDeleteIkeLocalDeleteReceivedNonDeleteRequest() throws Exception { 4091 setupIdleStateMachine(); 4092 4093 mIkeSessionStateMachine.sendMessage( 4094 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4095 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 4096 mLooper.dispatchAll(); 4097 verifyRetransmissionStarted(); 4098 4099 // Verify delete sent out. 4100 verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4101 4102 resetMockIkeMessageHelper(); // Discard value. 4103 4104 ReceivedIkePacket received = makeRekeyIkeRequest(); 4105 mIkeSessionStateMachine.sendMessage( 4106 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); 4107 4108 mLooper.dispatchAll(); 4109 verifyRetransmissionStarted(); 4110 verifyIncrementRemoteReqMsgId(); 4111 4112 verifySendTempFailResponse(); 4113 } 4114 verifySendTempFailResponse()4115 private void verifySendTempFailResponse() { 4116 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4117 4118 IkeHeader ikeHeader = resp.ikeHeader; 4119 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4120 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4121 assertTrue(ikeHeader.isResponseMsg); 4122 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 4123 4124 List<IkeNotifyPayload> notificationPayloadList = 4125 resp.getPayloadListForType(IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 4126 assertEquals(1, notificationPayloadList.size()); 4127 4128 IkeNotifyPayload notifyPayload = notificationPayloadList.get(0); 4129 assertEquals(IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType); 4130 } 4131 4132 @Test testDeleteIkeRemoteDelete()4133 public void testDeleteIkeRemoteDelete() throws Exception { 4134 setupIdleStateMachine(); 4135 mIkeSessionStateMachine.sendMessage( 4136 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 4137 makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 4138 4139 mLooper.dispatchAll(); 4140 verifyIncrementRemoteReqMsgId(); 4141 4142 // Verify outbound message 4143 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4144 4145 IkeHeader ikeHeader = delMsg.ikeHeader; 4146 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4147 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4148 assertTrue(ikeHeader.isResponseMsg); 4149 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 4150 4151 assertTrue(delMsg.ikePayloadList.isEmpty()); 4152 4153 verifyNotifyUserCloseSession(); 4154 4155 // Verify state machine quit properly 4156 assertNull(mIkeSessionStateMachine.getCurrentState()); 4157 } 4158 4159 @Test testKillSessionDeleteIkeRequestSent()4160 public void testKillSessionDeleteIkeRequestSent() throws Exception { 4161 setupIdleStateMachine(); 4162 4163 mIkeSessionStateMachine.killSession(); 4164 mLooper.dispatchAll(); 4165 4166 verify(mSpyCurrentIkeSaRecord).close(); 4167 verify(mSpyCurrentIkeSocket).unregisterIke(mSpyCurrentIkeSaRecord.getInitiatorSpi()); 4168 verifyNotifyUserCloseSession(); 4169 4170 // Verify outbound request 4171 IkeMessage req = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4172 IkeHeader ikeHeader = req.ikeHeader; 4173 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4174 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4175 assertFalse(ikeHeader.isResponseMsg); 4176 assertEquals(1, req.ikePayloadList.size()); 4177 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, req.ikePayloadList.get(0).payloadType); 4178 4179 // Verify state machine quit properly 4180 assertNull(mIkeSessionStateMachine.getCurrentState()); 4181 verify(mMockBusyWakelock).release(); 4182 } 4183 4184 @Test testKillSessionNoDeleteIkeRequestSent()4185 public void testKillSessionNoDeleteIkeRequestSent() throws Exception { 4186 setupIdleStateMachine(); 4187 4188 // Transition to state that does not send IKE delete requests 4189 mIkeSessionStateMachine.sendMessage( 4190 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4191 mIkeSessionStateMachine.mCreateIkeLocalIkeInit); 4192 4193 mIkeSessionStateMachine.killSession(); 4194 mLooper.dispatchAll(); 4195 4196 verify(mSpyCurrentIkeSaRecord).close(); 4197 verify(mSpyCurrentIkeSocket).unregisterIke(mSpyCurrentIkeSaRecord.getInitiatorSpi()); 4198 verifyNotifyUserCloseSession(); 4199 4200 // Verify no outbound request 4201 verifyEncryptAndEncodeNeverCalled(); 4202 4203 // Verify state machine quit properly 4204 assertNull(mIkeSessionStateMachine.getCurrentState()); 4205 verify(mMockBusyWakelock).release(); 4206 } 4207 4208 @Test testReceiveDpd()4209 public void testReceiveDpd() throws Exception { 4210 setupIdleStateMachine(); 4211 4212 // Receive a DPD request, expect to stay in IDLE state 4213 ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); 4214 mIkeSessionStateMachine.sendMessage( 4215 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 4216 mLooper.dispatchAll(); 4217 assertTrue( 4218 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4219 4220 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); 4221 4222 // Verify outbound response 4223 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4224 IkeHeader ikeHeader = resp.ikeHeader; 4225 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4226 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4227 assertTrue(ikeHeader.isResponseMsg); 4228 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 4229 assertTrue(resp.ikePayloadList.isEmpty()); 4230 } 4231 4232 @Test testReceiveDpdNonIdle()4233 public void testReceiveDpdNonIdle() throws Exception { 4234 setupIdleStateMachine(); 4235 4236 // Move to a non-idle state. Use RekeyIkeRemoteDelete, as it doesn't send out any requests. 4237 mIkeSessionStateMachine.sendMessage( 4238 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4239 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4240 mLooper.dispatchAll(); 4241 4242 // In a rekey state, receiving (and handling) a DPD should not result in a change of states 4243 ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); 4244 mIkeSessionStateMachine.sendMessage( 4245 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 4246 mLooper.dispatchAll(); 4247 assertTrue( 4248 mIkeSessionStateMachine.getCurrentState() 4249 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 4250 4251 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); 4252 4253 // Verify outbound response 4254 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4255 IkeHeader ikeHeader = resp.ikeHeader; 4256 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4257 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4258 assertTrue(ikeHeader.isResponseMsg); 4259 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 4260 assertTrue(resp.ikePayloadList.isEmpty()); 4261 } 4262 executeAndVerifySendLocalDPD()4263 private void executeAndVerifySendLocalDPD() throws Exception { 4264 setupIdleStateMachine(); 4265 4266 mIkeSessionStateMachine.sendMessage( 4267 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mDpdIkeLocalInfo); 4268 mLooper.dispatchAll(); 4269 4270 verifyEmptyInformationalSent(1, false /* expectedResp*/); 4271 resetMockIkeMessageHelper(); 4272 } 4273 4274 @Test testDpdIkeLocalInfoRcvDpdReq()4275 public void testDpdIkeLocalInfoRcvDpdReq() throws Exception { 4276 executeAndVerifySendLocalDPD(); 4277 mIkeSessionStateMachine.sendMessage( 4278 CMD_RECEIVE_IKE_PACKET, makeDpdIkeRequest(mSpyCurrentIkeSaRecord)); 4279 mLooper.dispatchAll(); 4280 4281 verifyEmptyInformationalSent(1, true /* expectedResp*/); 4282 assertTrue( 4283 mIkeSessionStateMachine.getCurrentState() 4284 instanceof IkeSessionStateMachine.DpdIkeLocalInfo); 4285 } 4286 4287 @Test testDpdIkeLocalInfoRcvDeleteIkeReq()4288 public void testDpdIkeLocalInfoRcvDeleteIkeReq() throws Exception { 4289 executeAndVerifySendLocalDPD(); 4290 mIkeSessionStateMachine.sendMessage( 4291 CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 4292 mLooper.dispatchAll(); 4293 4294 verifyEmptyInformationalSent(1, true /* expectedResp*/); 4295 assertNull(mIkeSessionStateMachine.getCurrentState()); 4296 } 4297 4298 @Test testDpdIkeLocalInfoRcvRekeyIkeReq()4299 public void testDpdIkeLocalInfoRcvRekeyIkeReq() throws Exception { 4300 executeAndVerifySendLocalDPD(); 4301 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest()); 4302 mLooper.dispatchAll(); 4303 4304 verifySendTempFailResponse(); 4305 assertTrue( 4306 mIkeSessionStateMachine.getCurrentState() 4307 instanceof IkeSessionStateMachine.DpdIkeLocalInfo); 4308 } 4309 4310 @Test testIdleTriggersNewRequests()4311 public void testIdleTriggersNewRequests() throws Exception { 4312 setupIdleStateMachine(); 4313 4314 mIkeSessionStateMachine.sendMessage( 4315 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4316 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4317 mLooper.dispatchAll(); 4318 4319 // Verify that the command is executed, and the state machine transitions to the right state 4320 assertTrue( 4321 mIkeSessionStateMachine.getCurrentState() 4322 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4323 verifyRetransmissionStarted(); 4324 } 4325 4326 @Test testNonIdleStateDoesNotTriggerNewRequests()4327 public void testNonIdleStateDoesNotTriggerNewRequests() throws Exception { 4328 setupIdleStateMachine(); 4329 4330 // Force ourselves into a non-idle state 4331 mIkeSessionStateMachine.sendMessage( 4332 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving); 4333 mLooper.dispatchAll(); 4334 verifyEncryptAndEncodeNeverCalled(); 4335 4336 // Queue a local request, and expect that it is not run (yet) 4337 mIkeSessionStateMachine.sendMessage( 4338 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 4339 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4340 mLooper.dispatchAll(); 4341 4342 // Verify that the state machine is still in the Receiving state 4343 verifyEncryptAndEncodeNeverCalled(); 4344 assertTrue( 4345 mIkeSessionStateMachine.getCurrentState() 4346 instanceof IkeSessionStateMachine.Receiving); 4347 4348 // Go back to Idle, and expect to immediately transition to RekeyIkeLocalCreate from the 4349 // queued request 4350 mIkeSessionStateMachine.sendMessage( 4351 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 4352 mLooper.dispatchAll(); 4353 assertTrue( 4354 mIkeSessionStateMachine.getCurrentState() 4355 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4356 verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4357 } 4358 4359 @Test testOpenChildSessionValidatesArgs()4360 public void testOpenChildSessionValidatesArgs() throws Exception { 4361 setupIdleStateMachine(); 4362 4363 // Expect failure - no callbacks provided 4364 try { 4365 mIkeSessionStateMachine.openChildSession(mChildSessionParams, null); 4366 } catch (IllegalArgumentException expected) { 4367 } 4368 4369 // Expect failure - callbacks already registered 4370 try { 4371 mIkeSessionStateMachine.openChildSession( 4372 mChildSessionParams, mMockChildSessionCallback); 4373 } catch (IllegalArgumentException expected) { 4374 } 4375 } 4376 4377 @Test testOpenChildSession()4378 public void testOpenChildSession() throws Exception { 4379 setupIdleStateMachine(); 4380 4381 ChildSessionCallback cb = mock(ChildSessionCallback.class); 4382 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 4383 4384 // Test that inserting the same cb returns an error, even before the state 4385 // machine has a chance to process it. 4386 try { 4387 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 4388 } catch (IllegalArgumentException expected) { 4389 } 4390 4391 verify(mMockChildSessionFactoryHelper) 4392 .makeChildSessionStateMachine( 4393 eq(mLooper.getLooper()), 4394 eq(mSpyContext), 4395 anyInt(), 4396 any(AlarmManager.class), 4397 any(RandomnessFactory.class), 4398 any(IpSecSpiGenerator.class), 4399 eq(mChildSessionParams), 4400 eq(mSpyUserCbExecutor), 4401 eq(cb), 4402 any()); 4403 4404 // Verify state in IkeSessionStateMachine 4405 mLooper.dispatchAll(); 4406 assertTrue( 4407 mIkeSessionStateMachine.getCurrentState() 4408 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 4409 4410 synchronized (mIkeSessionStateMachine.mChildCbToSessions) { 4411 assertTrue(mIkeSessionStateMachine.mChildCbToSessions.containsKey(cb)); 4412 } 4413 } 4414 4415 @Test testCloseChildSessionValidatesArgs()4416 public void testCloseChildSessionValidatesArgs() throws Exception { 4417 setupIdleStateMachine(); 4418 4419 // Expect failure - callbacks not registered 4420 try { 4421 mIkeSessionStateMachine.closeChildSession(mock(ChildSessionCallback.class)); 4422 } catch (IllegalArgumentException expected) { 4423 } 4424 } 4425 4426 @Test testCloseChildSession()4427 public void testCloseChildSession() throws Exception { 4428 setupIdleStateMachine(); 4429 4430 mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); 4431 mLooper.dispatchAll(); 4432 4433 assertTrue( 4434 mIkeSessionStateMachine.getCurrentState() 4435 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 4436 } 4437 4438 @Test testCloseImmediatelyAfterOpenChildSession()4439 public void testCloseImmediatelyAfterOpenChildSession() throws Exception { 4440 setupIdleStateMachine(); 4441 4442 ChildSessionCallback cb = mock(ChildSessionCallback.class); 4443 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 4444 4445 // Verify that closing the session immediately still picks up the child callback 4446 // even before the looper has a chance to run. 4447 mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); 4448 } 4449 4450 @Test testOnChildSessionClosed()4451 public void testOnChildSessionClosed() throws Exception { 4452 setupIdleStateMachine(); 4453 4454 mDummyChildSmCallback.onChildSessionClosed(mMockChildSessionCallback); 4455 4456 synchronized (mIkeSessionStateMachine.mChildCbToSessions) { 4457 assertFalse( 4458 mIkeSessionStateMachine.mChildCbToSessions.containsKey( 4459 mMockChildSessionCallback)); 4460 } 4461 } 4462 4463 @Test testHandleUnexpectedExceptionInEnterState()4464 public void testHandleUnexpectedExceptionInEnterState() throws Exception { 4465 Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); 4466 IkeManager.setIkeLog(spyIkeLog); 4467 4468 IkeSessionParams mockSessionParams = mock(IkeSessionParams.class); 4469 when(mockSessionParams.getSaProposalsInternal()).thenThrow(mock(RuntimeException.class)); 4470 4471 DhGroupTransform dhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_2048_BIT_MODP); 4472 IkeSaProposal mockSaProposal = mock(IkeSaProposal.class); 4473 when(mockSaProposal.getDhGroupTransforms()) 4474 .thenReturn(new DhGroupTransform[] {dhGroupTransform}); 4475 when(mockSessionParams.getSaProposals()).thenReturn(Arrays.asList(mockSaProposal)); 4476 IkeSessionStateMachine ikeSession = 4477 new IkeSessionStateMachine( 4478 mLooper.getLooper(), 4479 mSpyContext, 4480 mIpSecManager, 4481 mockSessionParams, 4482 mChildSessionParams, 4483 mSpyUserCbExecutor, 4484 mMockIkeSessionCallback, 4485 mMockChildSessionCallback, 4486 mMockEapAuthenticatorFactory); 4487 // Send IKE INIT request 4488 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 4489 mLooper.dispatchAll(); 4490 4491 assertNull(ikeSession.getCurrentState()); 4492 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 4493 verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); 4494 verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); 4495 } 4496 4497 @Test testHandleUnexpectedExceptionInProcessStateMsg()4498 public void testHandleUnexpectedExceptionInProcessStateMsg() throws Exception { 4499 Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); 4500 IkeManager.setIkeLog(spyIkeLog); 4501 4502 setupIdleStateMachine(); 4503 mIkeSessionStateMachine.sendMessage( 4504 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, null /*receivedIkePacket*/); 4505 mLooper.dispatchAll(); 4506 4507 assertNull(mIkeSessionStateMachine.getCurrentState()); 4508 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 4509 verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); 4510 verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); 4511 } 4512 4513 @Test testCreateIkeLocalIkeInitRcvErrorNotify()4514 public void testCreateIkeLocalIkeInitRcvErrorNotify() throws Exception { 4515 // Send IKE INIT request 4516 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 4517 mLooper.dispatchAll(); 4518 verifyRetransmissionStarted(); 4519 4520 // Receive IKE INIT response with erro notification. 4521 List<IkePayload> payloads = new LinkedList<>(); 4522 payloads.add(new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN)); 4523 ReceivedIkePacket resp = 4524 makeDummyUnencryptedReceivedIkePacket( 4525 1L /*initiator SPI*/, 4526 2L /*respodner SPI*/, 4527 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 4528 true /*isResp*/, 4529 false /*fromIkeInit*/, 4530 payloads); 4531 4532 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 4533 mLooper.dispatchAll(); 4534 4535 // Fires user error callbacks 4536 verify(mMockIkeSessionCallback) 4537 .onClosedExceptionally( 4538 argThat(err -> err instanceof NoValidProposalChosenException)); 4539 // Verify state machine quit properly 4540 assertNull(mIkeSessionStateMachine.getCurrentState()); 4541 } 4542 mockSendRekeyChildReq()4543 private void mockSendRekeyChildReq() throws Exception { 4544 setupIdleStateMachine(); 4545 4546 ChildLocalRequest childLocalRequest = 4547 new ChildLocalRequest( 4548 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, 4549 mMockChildSessionCallback, 4550 null /*childParams*/); 4551 4552 mIkeSessionStateMachine.sendMessage( 4553 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, childLocalRequest); 4554 mLooper.dispatchAll(); 4555 4556 assertTrue( 4557 mIkeSessionStateMachine.getCurrentState() 4558 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 4559 verify(mMockChildSessionStateMachine).rekeyChildSession(); 4560 4561 // Mocking sending request 4562 mDummyChildSmCallback.onOutboundPayloadsReady( 4563 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 4564 false /*isResp*/, 4565 new LinkedList<>(), 4566 mMockChildSessionStateMachine); 4567 mLooper.dispatchAll(); 4568 } 4569 mockRcvTempFail()4570 private void mockRcvTempFail() throws Exception { 4571 ReceivedIkePacket resp = 4572 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_TEMPORARY_FAILURE)); 4573 4574 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 4575 mIkeSessionStateMachine.sendMessage( 4576 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 4577 mLooper.dispatchAll(); 4578 } 4579 4580 @Ignore disableTestTempFailureHandlerTimeout()4581 public void disableTestTempFailureHandlerTimeout() throws Exception { 4582 long currentTime = 0; 4583 int retryCnt = 0; 4584 4585 mockSendRekeyChildReq(); 4586 4587 while (currentTime + RETRY_INTERVAL_MS < TEMP_FAILURE_RETRY_TIMEOUT_MS) { 4588 mockRcvTempFail(); 4589 4590 mLooper.moveTimeForward(RETRY_INTERVAL_MS); 4591 currentTime += RETRY_INTERVAL_MS; 4592 mLooper.dispatchAll(); 4593 4594 retryCnt++; 4595 verify(mMockChildSessionStateMachine, times(1 + retryCnt)).rekeyChildSession(); 4596 } 4597 4598 mLooper.moveTimeForward(RETRY_INTERVAL_MS); 4599 mLooper.dispatchAll(); 4600 4601 assertNull(mIkeSessionStateMachine.getCurrentState()); 4602 verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class)); 4603 } 4604 4605 @Test testTempFailureHandlerCancelTimer()4606 public void testTempFailureHandlerCancelTimer() throws Exception { 4607 mockRescheduleRekey(mSpyCurrentIkeSaRecord); 4608 setupIdleStateMachine(); 4609 4610 // Send Rekey-Create request 4611 mIkeSessionStateMachine.sendMessage( 4612 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4613 new IkeLocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4614 mLooper.dispatchAll(); 4615 verifyRetransmissionStarted(); 4616 4617 // Mock sending TEMPORARY_FAILURE response 4618 mockRcvTempFail(); 4619 mLooper.dispatchAll(); 4620 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 4621 assertTrue( 4622 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4623 4624 // Move time forward to trigger retry 4625 mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); 4626 mLooper.dispatchAll(); 4627 assertTrue( 4628 mIkeSessionStateMachine.getCurrentState() 4629 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4630 4631 // Prepare "rekeyed" SA 4632 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 4633 4634 // Receive valid Rekey-Create response 4635 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 4636 mIkeSessionStateMachine.sendMessage( 4637 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 4638 mLooper.dispatchAll(); 4639 4640 // Receive Delete response 4641 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 4642 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 4643 mIkeSessionStateMachine.sendMessage( 4644 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 4645 mLooper.dispatchAll(); 4646 assertTrue( 4647 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4648 4649 // Move time forward 4650 mLooper.moveTimeForward(IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS); 4651 mLooper.dispatchAll(); 4652 4653 // Validate IKE Session is not closed 4654 assertTrue( 4655 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4656 } 4657 4658 @Ignore disableTestIdleReceiveRequestWithFatalError()4659 public void disableTestIdleReceiveRequestWithFatalError() throws Exception { 4660 setupIdleStateMachine(); 4661 4662 // Mock receiving packet with syntax error 4663 ReceivedIkePacket mockInvalidPacket = 4664 makeDummyReceivedIkePacketWithInvalidSyntax( 4665 mSpyCurrentIkeSaRecord, 4666 false /*isResp*/, 4667 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 4668 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 4669 mLooper.dispatchAll(); 4670 4671 // Verify Delete request was sent 4672 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 4673 assertEquals(1, payloads.size()); 4674 4675 IkePayload payload = payloads.get(0); 4676 assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); 4677 assertEquals(ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) payload).notifyType); 4678 4679 // Verify IKE Session is closed properly 4680 assertNull(mIkeSessionStateMachine.getCurrentState()); 4681 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 4682 } 4683 4684 @Test testHandlesInvalidRequest()4685 public void testHandlesInvalidRequest() throws Exception { 4686 setupIdleStateMachine(); 4687 4688 mIkeSessionStateMachine.sendMessage( 4689 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4690 mIkeSessionStateMachine.mChildProcedureOngoing); 4691 4692 // Receive an IKE AUTH request 4693 ReceivedIkePacket request = 4694 makeDummyEncryptedReceivedIkePacketWithPayloadList( 4695 mSpyCurrentIkeSaRecord, 4696 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 4697 false /*isResp*/, 4698 new LinkedList<IkePayload>()); 4699 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4700 mLooper.dispatchAll(); 4701 4702 // Verify error notification was sent 4703 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 4704 assertEquals(1, ikePayloadList.size()); 4705 assertEquals( 4706 ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 4707 4708 // Verify IKE Session has quit 4709 assertNull(mIkeSessionStateMachine.getCurrentState()); 4710 verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class)); 4711 } 4712 4713 @Test testIdleHandlesDecryptPacketFailed()4714 public void testIdleHandlesDecryptPacketFailed() throws Exception { 4715 setupIdleStateMachine(); 4716 4717 ReceivedIkePacket packet = 4718 makeDummyReceivedIkePacketWithUnprotectedError( 4719 mSpyCurrentIkeSaRecord, 4720 false /*isResp*/, 4721 EXCHANGE_TYPE_INFORMATIONAL, 4722 mock(IkeException.class)); 4723 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 4724 mLooper.dispatchAll(); 4725 4726 assertTrue( 4727 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4728 } 4729 4730 @Test testHandlesUnencryptedPacket()4731 public void testHandlesUnencryptedPacket() throws Exception { 4732 setupIdleStateMachine(); 4733 IkeMessage.setIkeMessageHelper(new IkeMessageHelper()); 4734 4735 ReceivedIkePacket packet = 4736 makeDummyUnencryptedReceivedIkePacket( 4737 mSpyCurrentIkeSaRecord.getLocalSpi(), 4738 mSpyCurrentIkeSaRecord.getRemoteSpi(), 4739 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 4740 false /*isResp*/, 4741 false /*fromIkeInit*/, 4742 new LinkedList<>()); 4743 4744 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 4745 mLooper.dispatchAll(); 4746 4747 assertTrue( 4748 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4749 4750 // Reset the IkeMessageHelper to be a mock. This is needed for #killSession (called in 4751 // #tearDown), which attempts to notify the remote about the IKE session dying in the Idle 4752 // state. 4753 IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper); 4754 resetMockIkeMessageHelper(); 4755 } 4756 4757 @Test testEapOnlyOption()4758 public void testEapOnlyOption() throws Exception { 4759 mIkeSessionStateMachine.quitNow(); 4760 IkeSessionParams ikeSessionParams = 4761 buildIkeSessionParamsCommon() 4762 .setAuthEap(mRootCertificate, mEapSessionConfig) 4763 .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) 4764 .build(); 4765 mIkeSessionStateMachine = makeAndStartIkeSession(ikeSessionParams); 4766 4767 mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 4768 4769 IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 4770 List<IkeNotifyPayload> notifyPayloads = 4771 ikeAuthReqMessage.getPayloadListForType( 4772 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 4773 assertTrue(hasEapOnlyNotifyPayload(notifyPayloads)); 4774 } 4775 makeConfigPayload()4776 private IkeConfigPayload makeConfigPayload() throws Exception { 4777 return (IkeConfigPayload) 4778 IkeTestUtils.hexStringToIkePayload( 4779 IkePayload.PAYLOAD_TYPE_CP, true /*isResp*/, CP_PAYLOAD_HEX_STRING); 4780 } 4781 hasEapOnlyNotifyPayload(List<IkeNotifyPayload> notifyPayloads)4782 private boolean hasEapOnlyNotifyPayload(List<IkeNotifyPayload> notifyPayloads) { 4783 for (IkeNotifyPayload payload : notifyPayloads) { 4784 if (payload.notifyType == NOTIFY_TYPE_EAP_ONLY_AUTHENTICATION) { 4785 return true; 4786 } 4787 } 4788 4789 return false; 4790 } 4791 4792 @Test testAcquireAndReleaseLocalReqWakeLock()4793 public void testAcquireAndReleaseLocalReqWakeLock() throws Exception { 4794 setupIdleStateMachine(); 4795 4796 ChildSessionCallback cb = mock(ChildSessionCallback.class); 4797 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 4798 4799 mLooper.dispatchAll(); 4800 assertTrue( 4801 mIkeSessionStateMachine.getCurrentState() 4802 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 4803 verify(mMockLocalRequestWakelock).acquire(); 4804 verify(mMockLocalRequestWakelock).release(); 4805 } 4806 4807 @Test testQuitClearAllLocalReqWakeLocks()4808 public void testQuitClearAllLocalReqWakeLocks() throws Exception { 4809 final int localReqCnt = 3; 4810 setupIdleStateMachine(); 4811 4812 // Leave a Idle state so that the LocalRequest won't be executed 4813 mIkeSessionStateMachine.sendMessage( 4814 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving); 4815 mLooper.dispatchAll(); 4816 4817 // Only in test that all local requests will get the same WakeLock instance but in function 4818 // code each local request will have a separate WakeLock. 4819 for (int i = 0; i < localReqCnt; i++) { 4820 mIkeSessionStateMachine.openChildSession( 4821 mChildSessionParams, mock(ChildSessionCallback.class)); 4822 } 4823 mLooper.dispatchAll(); 4824 verify(mMockLocalRequestWakelock, times(localReqCnt)).acquire(); 4825 4826 mIkeSessionStateMachine.killSession(); 4827 mLooper.dispatchAll(); 4828 verify(mMockLocalRequestWakelock, times(localReqCnt)).release(); 4829 } 4830 } 4831