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.test.ike; 18 19 import static android.net.ipsec.ike.IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE; 20 import static android.net.ipsec.test.ike.IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION; 21 import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_EAP_ONLY_AUTH; 22 import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_FORCE_DNS_RESOLUTION; 23 import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_FORCE_PORT_4500; 24 import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_MOBIKE; 25 import static android.net.ipsec.test.ike.IkeSessionParams.IKE_OPTION_REKEY_MOBILITY; 26 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED; 27 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND; 28 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE; 29 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD; 30 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX; 31 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS; 32 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN; 33 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE; 34 import static android.net.ipsec.test.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD; 35 import static android.net.ipsec.test.ike.ike3gpp.Ike3gppBackoffTimer.ERROR_TYPE_NETWORK_FAILURE; 36 import static android.net.ipsec.test.ike.ike3gpp.Ike3gppBackoffTimer.ERROR_TYPE_NO_APN_SUBSCRIPTION; 37 import static android.system.OsConstants.AF_INET; 38 import static android.system.OsConstants.AF_INET6; 39 40 import static com.android.internal.net.TestUtils.createMockRandomFactory; 41 import static com.android.internal.net.eap.test.EapResult.EapResponse.RESPONSE_FLAG_EAP_AKA_SERVER_AUTHENTICATED; 42 import static com.android.internal.net.ipsec.test.ike.AbstractSessionStateMachine.RETRY_INTERVAL_MS; 43 import static com.android.internal.net.ipsec.test.ike.IkeContext.CONFIG_USE_CACHED_ADDRS; 44 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_ALARM_FIRED; 45 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_FORCE_TRANSITION; 46 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET; 47 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CMD_SEND_KEEPALIVE; 48 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.IkeAuthData; 49 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.IkeInitData; 50 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.InitialSetupData; 51 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.RETRY_INTERVAL_MS; 52 import static com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS; 53 import static com.android.internal.net.ipsec.test.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_BACKOFF_TIMER; 54 import static com.android.internal.net.ipsec.test.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_DEVICE_IDENTITY; 55 import static com.android.internal.net.ipsec.test.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_N1_MODE_CAPABILITY; 56 import static com.android.internal.net.ipsec.test.ike.ike3gpp.Ike3gppExtensionExchange.NOTIFY_TYPE_N1_MODE_INFORMATION; 57 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_APPLICATION_VERSION; 58 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS; 59 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK; 60 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS; 61 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_IP4_PCSCF; 62 import static com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload.CONFIG_ATTR_IP6_PCSCF; 63 import static com.android.internal.net.ipsec.test.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA; 64 import static com.android.internal.net.ipsec.test.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; 65 import static com.android.internal.net.ipsec.test.ike.message.IkeMessage.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD; 66 import static com.android.internal.net.ipsec.test.ike.message.IkeMessage.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD; 67 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_COOKIE; 68 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_COOKIE2; 69 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_EAP_ONLY_AUTHENTICATION; 70 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED; 71 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_INITIAL_CONTACT; 72 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_MOBIKE_SUPPORTED; 73 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP; 74 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP; 75 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_SIGNATURE_HASH_ALGORITHMS; 76 import static com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload.NOTIFY_TYPE_UPDATE_SA_ADDRESSES; 77 import static com.android.internal.net.ipsec.test.ike.message.IkePayload.PAYLOAD_TYPE_AUTH; 78 import static com.android.internal.net.ipsec.test.ike.message.IkePayload.PAYLOAD_TYPE_KE; 79 import static com.android.internal.net.ipsec.test.ike.message.IkePayload.PAYLOAD_TYPE_NONCE; 80 import static com.android.internal.net.ipsec.test.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY; 81 import static com.android.internal.net.ipsec.test.ike.message.IkePayload.PAYLOAD_TYPE_SA; 82 import static com.android.internal.net.ipsec.test.ike.net.IkeConnectionController.NAT_DETECTED; 83 import static com.android.internal.net.ipsec.test.ike.net.IkeConnectionController.NAT_TRAVERSAL_SUPPORT_NOT_CHECKED; 84 import static com.android.internal.net.ipsec.test.ike.net.IkeConnectionController.NAT_TRAVERSAL_UNSUPPORTED; 85 86 import static org.junit.Assert.assertArrayEquals; 87 import static org.junit.Assert.assertEquals; 88 import static org.junit.Assert.assertFalse; 89 import static org.junit.Assert.assertNotEquals; 90 import static org.junit.Assert.assertNotNull; 91 import static org.junit.Assert.assertNull; 92 import static org.junit.Assert.assertSame; 93 import static org.junit.Assert.assertTrue; 94 import static org.junit.Assert.fail; 95 import static org.mockito.ArgumentMatchers.any; 96 import static org.mockito.ArgumentMatchers.anyBoolean; 97 import static org.mockito.ArgumentMatchers.anyInt; 98 import static org.mockito.ArgumentMatchers.anyLong; 99 import static org.mockito.ArgumentMatchers.anyString; 100 import static org.mockito.ArgumentMatchers.argThat; 101 import static org.mockito.ArgumentMatchers.eq; 102 import static org.mockito.Mockito.atLeast; 103 import static org.mockito.Mockito.atLeastOnce; 104 import static org.mockito.Mockito.doAnswer; 105 import static org.mockito.Mockito.doNothing; 106 import static org.mockito.Mockito.doReturn; 107 import static org.mockito.Mockito.doThrow; 108 import static org.mockito.Mockito.mock; 109 import static org.mockito.Mockito.never; 110 import static org.mockito.Mockito.reset; 111 import static org.mockito.Mockito.spy; 112 import static org.mockito.Mockito.times; 113 import static org.mockito.Mockito.verify; 114 import static org.mockito.Mockito.when; 115 116 import android.annotation.Nullable; 117 import android.net.LinkAddress; 118 import android.net.LinkProperties; 119 import android.net.Network; 120 import android.net.NetworkCapabilities; 121 import android.net.eap.test.EapAkaInfo; 122 import android.net.eap.test.EapSessionConfig; 123 import android.net.ipsec.test.ike.ChildSaProposal; 124 import android.net.ipsec.test.ike.ChildSessionCallback; 125 import android.net.ipsec.test.ike.ChildSessionParams; 126 import android.net.ipsec.test.ike.IkeFqdnIdentification; 127 import android.net.ipsec.test.ike.IkeIdentification; 128 import android.net.ipsec.test.ike.IkeIpv4AddrIdentification; 129 import android.net.ipsec.test.ike.IkeManager; 130 import android.net.ipsec.test.ike.IkeSaProposal; 131 import android.net.ipsec.test.ike.IkeSessionCallback; 132 import android.net.ipsec.test.ike.IkeSessionConfiguration; 133 import android.net.ipsec.test.ike.IkeSessionConnectionInfo; 134 import android.net.ipsec.test.ike.IkeSessionParams; 135 import android.net.ipsec.test.ike.SaProposal; 136 import android.net.ipsec.test.ike.TransportModeChildSessionParams; 137 import android.net.ipsec.test.ike.TunnelModeChildSessionParams; 138 import android.net.ipsec.test.ike.exceptions.AuthenticationFailedException; 139 import android.net.ipsec.test.ike.exceptions.IkeException; 140 import android.net.ipsec.test.ike.exceptions.IkeIOException; 141 import android.net.ipsec.test.ike.exceptions.IkeInternalException; 142 import android.net.ipsec.test.ike.exceptions.IkeNetworkLostException; 143 import android.net.ipsec.test.ike.exceptions.IkeProtocolException; 144 import android.net.ipsec.test.ike.exceptions.IkeTimeoutException; 145 import android.net.ipsec.test.ike.exceptions.InvalidSyntaxException; 146 import android.net.ipsec.test.ike.exceptions.NoValidProposalChosenException; 147 import android.net.ipsec.test.ike.exceptions.UnrecognizedIkeProtocolException; 148 import android.net.ipsec.test.ike.exceptions.UnsupportedCriticalPayloadException; 149 import android.net.ipsec.test.ike.ike3gpp.Ike3gppBackoffTimer; 150 import android.net.ipsec.test.ike.ike3gpp.Ike3gppData; 151 import android.net.ipsec.test.ike.ike3gpp.Ike3gppExtension; 152 import android.net.ipsec.test.ike.ike3gpp.Ike3gppExtension.Ike3gppDataListener; 153 import android.net.ipsec.test.ike.ike3gpp.Ike3gppN1ModeInformation; 154 import android.net.ipsec.test.ike.ike3gpp.Ike3gppParams; 155 import android.os.Build; 156 import android.os.Handler; 157 import android.os.test.TestLooper; 158 import android.telephony.TelephonyManager; 159 160 import androidx.test.filters.SdkSuppress; 161 162 import com.android.internal.net.TestUtils; 163 import com.android.internal.net.eap.test.EapAuthenticator; 164 import com.android.internal.net.eap.test.IEapCallback; 165 import com.android.internal.net.ipsec.test.ike.ChildSessionStateMachine.IChildSessionSmCallback; 166 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.ChildLocalRequest; 167 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.IkeLocalRequest; 168 import com.android.internal.net.ipsec.test.ike.IkeLocalRequestScheduler.LocalRequestFactory; 169 import com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CreateIkeLocalIkeAuth; 170 import com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap; 171 import com.android.internal.net.ipsec.test.ike.IkeSessionStateMachine.ReceivedIkePacket; 172 import com.android.internal.net.ipsec.test.ike.SaRecord.ISaRecordHelper; 173 import com.android.internal.net.ipsec.test.ike.SaRecord.IkeSaRecord; 174 import com.android.internal.net.ipsec.test.ike.SaRecord.IkeSaRecordConfig; 175 import com.android.internal.net.ipsec.test.ike.SaRecord.SaLifetimeAlarmScheduler; 176 import com.android.internal.net.ipsec.test.ike.SaRecord.SaRecordHelper; 177 import com.android.internal.net.ipsec.test.ike.crypto.IkeCipher; 178 import com.android.internal.net.ipsec.test.ike.crypto.IkeMacIntegrity; 179 import com.android.internal.net.ipsec.test.ike.crypto.IkeMacPrf; 180 import com.android.internal.net.ipsec.test.ike.keepalive.IkeNattKeepalive; 181 import com.android.internal.net.ipsec.test.ike.message.IkeAuthDigitalSignPayload; 182 import com.android.internal.net.ipsec.test.ike.message.IkeAuthPayload; 183 import com.android.internal.net.ipsec.test.ike.message.IkeAuthPskPayload; 184 import com.android.internal.net.ipsec.test.ike.message.IkeCertX509CertPayload; 185 import com.android.internal.net.ipsec.test.ike.message.IkeConfigPayload; 186 import com.android.internal.net.ipsec.test.ike.message.IkeDeletePayload; 187 import com.android.internal.net.ipsec.test.ike.message.IkeEapPayload; 188 import com.android.internal.net.ipsec.test.ike.message.IkeHeader; 189 import com.android.internal.net.ipsec.test.ike.message.IkeIdPayload; 190 import com.android.internal.net.ipsec.test.ike.message.IkeInformationalPayload; 191 import com.android.internal.net.ipsec.test.ike.message.IkeKePayload; 192 import com.android.internal.net.ipsec.test.ike.message.IkeMessage; 193 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.DecodeResult; 194 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.DecodeResultOk; 195 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.DecodeResultPartial; 196 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.DecodeResultProtectedError; 197 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.DecodeResultUnprotectedError; 198 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.IIkeMessageHelper; 199 import com.android.internal.net.ipsec.test.ike.message.IkeMessage.IkeMessageHelper; 200 import com.android.internal.net.ipsec.test.ike.message.IkeNoncePayload; 201 import com.android.internal.net.ipsec.test.ike.message.IkeNotifyPayload; 202 import com.android.internal.net.ipsec.test.ike.message.IkePayload; 203 import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload; 204 import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.DhGroupTransform; 205 import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.EncryptionTransform; 206 import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.IntegrityTransform; 207 import com.android.internal.net.ipsec.test.ike.message.IkeSaPayload.PrfTransform; 208 import com.android.internal.net.ipsec.test.ike.message.IkeSkfPayload; 209 import com.android.internal.net.ipsec.test.ike.message.IkeTestUtils; 210 import com.android.internal.net.ipsec.test.ike.message.IkeTsPayload; 211 import com.android.internal.net.ipsec.test.ike.net.IkeConnectionController; 212 import com.android.internal.net.ipsec.test.ike.net.IkeDefaultNetworkCallback; 213 import com.android.internal.net.ipsec.test.ike.net.IkeNetworkCallbackBase; 214 import com.android.internal.net.ipsec.test.ike.net.IkeSpecificNetworkCallback; 215 import com.android.internal.net.ipsec.test.ike.testmode.DeterministicSecureRandom; 216 import com.android.internal.net.ipsec.test.ike.testutils.CertUtils; 217 import com.android.internal.net.ipsec.test.ike.utils.IState; 218 import com.android.internal.net.ipsec.test.ike.utils.IkeAlarm.IkeAlarmConfig; 219 import com.android.internal.net.ipsec.test.ike.utils.IkeMetrics; 220 import com.android.internal.net.ipsec.test.ike.utils.IkeSecurityParameterIndex; 221 import com.android.internal.net.ipsec.test.ike.utils.IkeSpiGenerator; 222 import com.android.internal.net.ipsec.test.ike.utils.RandomnessFactory; 223 import com.android.internal.net.ipsec.test.ike.utils.State; 224 import com.android.internal.net.utils.test.Log; 225 import com.android.internal.util.HexDump; 226 import com.android.modules.utils.build.SdkLevel; 227 228 import org.junit.After; 229 import org.junit.Before; 230 import org.junit.Ignore; 231 import org.junit.Test; 232 import org.mockito.ArgumentCaptor; 233 import org.mockito.invocation.InvocationOnMock; 234 import org.mockito.stubbing.Answer; 235 236 import java.io.IOException; 237 import java.net.Inet4Address; 238 import java.net.InetAddress; 239 import java.net.UnknownHostException; 240 import java.nio.ByteBuffer; 241 import java.nio.charset.StandardCharsets; 242 import java.security.GeneralSecurityException; 243 import java.security.PrivateKey; 244 import java.security.SecureRandom; 245 import java.security.cert.X509Certificate; 246 import java.util.ArrayList; 247 import java.util.Arrays; 248 import java.util.Collections; 249 import java.util.HashMap; 250 import java.util.HashSet; 251 import java.util.List; 252 import java.util.Map; 253 import java.util.Random; 254 import java.util.Set; 255 import java.util.concurrent.Executor; 256 import java.util.concurrent.TimeUnit; 257 258 public final class IkeSessionStateMachineTest extends IkeSessionTestBase { 259 private static final String TAG = "IkeSessionStateMachineTest"; 260 261 private static final String IKE_INIT_RESP_HEX_STRING = 262 "5f54bf6d8b48e6e1909232b3d1edcb5c21202220000000000000014c220000300000" 263 + "002c010100040300000c0100000c800e008003000008030000020300000802000002" 264 + "00000008040000022800008800020000fe014fefed55a4229928bfa3dad1ea6ffaca" 265 + "abfb5f5bdd71790e99a192530e3f849d3a3d96dc6e0a7a10ff6f72a6162103ac573c" 266 + "acd41d08b7a034cad8f5eab09c14ced5a9e4af5692dff028f21c1119dd75226b6af6" 267 + "b2f009245369c9892cc5742e5c94a254ebff052470771fb2cb4f29a35d8953e18a1a" 268 + "6c6fbc56acc188a5290000249756112ca539f5c25abacc7ee92b73091942a9c06950" 269 + "f98848f1af1694c4ddff2900001c00004004c53f054b976a25d75fde72dbf1c7b6c8" 270 + "c9aa9ca12900001c00004005b16d79b21c1bc89ca7350f42de805be0227e2ed62b00" 271 + "00080000401400000014882fe56d6fd20dbc2251613b2ebe5beb"; 272 private static final String IKE_SA_PAYLOAD_HEX_STRING = 273 "220000300000002c010100040300000c0100000c800e00800300000803000002030" 274 + "00008020000020000000804000002"; 275 private static final String IKE_REKEY_SA_PAYLOAD_HEX_STRING = 276 "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" 277 + "000080300000203000008020000020000000804000002"; 278 private static final String IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING = 279 "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" 280 + "00008030000020300000802000002000000080400000e"; 281 private static final int IKE_REKEY_SA_INITIATOR_SPI = 0xff; 282 private static final String KE_PAYLOAD_HEX_STRING = 283 "2800008800020000b4a2faf4bb54878ae21d638512ece55d9236fc50" 284 + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa" 285 + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd" 286 + "92f46bef84f0be7db860351843858f8acf87056e272377f7" 287 + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" 288 + "6bbeb08214c7071376079587"; 289 private static final String INVALID_KE_PAYLOAD_HEX_STRING = "0000000a00000011000e"; 290 private static final String NONCE_INIT_PAYLOAD_HEX_STRING = 291 "29000024c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; 292 private static final String NONCE_RESP_PAYLOAD_HEX_STRING = 293 "290000249756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; 294 private static final String NONCE_INIT_HEX_STRING = 295 "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412"; 296 private static final String NONCE_RESP_HEX_STRING = 297 "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff"; 298 private static final String NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING = 299 "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0"; 300 private static final String NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING = 301 "2900001c00004005d915368ca036004cb578ae3e3fb268509aeab190"; 302 private static final String FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING = "290000080000402e"; 303 private static final String SIGNATURE_HASH_SUPPORTED_PAYLOAD_HEX_STRING = 304 "2b0000100000402f0001000200030004"; 305 private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000"; 306 private static final String NOTIFY_REKEY_IKE_PAYLOAD_HEX_STRING = "2100000800004009"; 307 private static final String ID_PAYLOAD_INITIATOR_HEX_STRING = 308 "290000180200000031313233343536373839414243444546"; 309 private static final String ID_PAYLOAD_RESPONDER_HEX_STRING = "2700000c010000007f000001"; 310 private static final String ID_PAYLOAD_RESPONDER_FQDN_HEX_STRING = 311 "2700001702000000696B652E616E64726F69642E6E6574"; 312 private static final String PSK_AUTH_RESP_PAYLOAD_HEX_STRING = 313 "2100001c0200000058f36412e9b7b38df817a9f7779b7a008dacdd25"; 314 private static final String GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING = 315 "300000580e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d413" 316 + "6b9f69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8e" 317 + "12c5d982aa4efdaeac36a02b222aa96242cc424"; 318 private static final String CHILD_SA_PAYLOAD_HEX_STRING = 319 "2c00002c0000002801030403cae7019f0300000c0100000c800e008003000008030" 320 + "000020000000805000000"; 321 private static final String TS_INIT_PAYLOAD_HEX_STRING = 322 "2d00001801000000070000100000ffff00000000ffffffff"; 323 private static final String TS_RESP_PAYLOAD_HEX_STRING = 324 "2900001801000000070000100000ffff000000000fffffff"; 325 private static final String VENDOR_ID_PAYLOAD_HEX_STRING = 326 "0000001852656d6f74652056656e646f72204944204f6e65"; 327 328 private static final String PSK_HEX_STRING = "6A756E69706572313233"; 329 330 private static final String PRF_KEY_INIT_HEX_STRING = 331 "094787780EE466E2CB049FA327B43908BC57E485"; 332 private static final String PRF_KEY_RESP_HEX_STRING = 333 "A30E6B08BE56C0E6BFF4744143C75219299E1BEB"; 334 335 private static final String CP_PAYLOAD_HEX_STRING = 336 "210000810200000000080011260010111067a17d000000000a" 337 + "f68e8640000a0010200148880067ff000643000d000000000" 338 + "00a0010200148880066ff000645000d0000000000150010200" 339 + "148880006713a00f10104000000050015001020014888000671" 340 + "3a00f101040000008900150010200148880005713a00e00104000000c9"; 341 private static final String PCSCF_IPV6_ADDRESS1 = "2001:4888:6:713a:f1:104:0:5"; 342 private static final String PCSCF_IPV6_ADDRESS2 = "2001:4888:6:713a:f1:104:0:89"; 343 private static final String PCSCF_IPV6_ADDRESS3 = "2001:4888:5:713a:e0:104:0:c9"; 344 345 private static final byte[] EAP_DUMMY_MSG = "EAP Message".getBytes(); 346 private static final int EAP_RESPONSE_FLAG_MASK_WITH_EAP_AKA_SERVER_AUTHENTICATED = 347 (1 << RESPONSE_FLAG_EAP_AKA_SERVER_AUTHENTICATED); 348 private static final int EAP_RESPONSE_FLAGS_NOT_SET = 0; 349 private static final byte[] REMOTE_VENDOR_ID_ONE = "Remote Vendor ID One".getBytes(); 350 private static final byte[] REMOTE_VENDOR_ID_TWO = "Remote Vendor ID Two".getBytes(); 351 352 private static final IkeIdentification LOCAL_ID_IPV4 = 353 new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS); 354 private static final IkeIdentification REMOTE_ID_FQDN = 355 new IkeFqdnIdentification("server.test.android.net"); 356 private static final IkeIdentification REMOTE_ID_IPV4 = 357 new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS); 358 359 private static final byte PDU_SESSION_ID = (byte) 0x7B; 360 private static final String N1_MODE_CAPABILITY_PAYLOAD_DATA = "017B"; 361 private static final byte[] SNSSAI = {(byte) 456}; 362 363 private static final byte BACKOFF_TIMER = (byte) 0xAF; 364 private static final byte[] BACKOFF_TIMER_DATA = {0x01, BACKOFF_TIMER}; 365 366 private static final int KEY_LEN_IKE_INTE = 20; 367 private static final int KEY_LEN_IKE_ENCR = 16; 368 private static final int KEY_LEN_IKE_PRF = 20; 369 private static final int KEY_LEN_IKE_SKD = KEY_LEN_IKE_PRF; 370 371 private static final int CHILD_SPI_LOCAL = 0x2ad4c0a2; 372 private static final int CHILD_SPI_REMOTE = 0xcae7019f; 373 374 private static final int EAP_SIM_SUB_ID = 1; 375 376 private static final int PAYLOAD_TYPE_UNSUPPORTED = 127; 377 378 private static final int COOKIE_DATA_LEN = 64; 379 private static final int COOKIE2_DATA_LEN = 64; 380 381 private static final byte[] COOKIE_DATA = new byte[COOKIE_DATA_LEN]; 382 private static final byte[] COOKIE2_DATA = new byte[COOKIE2_DATA_LEN]; 383 384 private static final int FAKE_SESSION_ID = 0; 385 386 private static final int NATT_KEEPALIVE_DELAY = 20; 387 388 private static final String DEVICE_IDENTITY_IMEI = "123456789123456"; 389 private static final byte[] DEVICE_IDENTITY_PAYLOAD_IMEI = 390 HexDump.hexStringToByteArray("00090121436587193254F6"); 391 392 static { 393 new Random().nextBytes(COOKIE_DATA); 394 new Random().nextBytes(COOKIE2_DATA); 395 } 396 397 private static final long RETRANSMIT_BACKOFF_TIMEOUT_MS = 5000L; 398 399 private static final IkeSpiGenerator IKE_SPI_GENERATOR = 400 new IkeSpiGenerator(createMockRandomFactory()); 401 402 private static final Ike3gppParams IKE_3GPP_PARAMS = 403 new Ike3gppParams.Builder().setPduSessionId(PDU_SESSION_ID).build(); 404 405 private static final byte[] REAUTH_ID_BYTES = 406 "4OLUpQCqFyhm1/UgD56anTzYTqJDckibqjU6PlS4sZaiuLc=".getBytes(StandardCharsets.UTF_8); 407 408 private IkeUdpEncapSocket mMockIkeUdpEncapSocket; 409 private IkeUdp6WithEncapPortSocket mMockIkeUdp6WithEncapPortSocket; 410 private IkeUdp4Socket mMockIkeUdp4Socket; 411 private IkeUdp6Socket mMockIkeUdp6Socket; 412 private IkeSocket mMockCurrentIkeSocket; 413 414 private IkeNattKeepalive mMockIkeNattKeepalive; 415 416 private TestLooper mLooper; 417 private IkeSessionStateMachine mIkeSessionStateMachine; 418 419 private byte[] mPsk; 420 421 private ChildSessionParams mChildSessionParams; 422 423 private Executor mSpyUserCbExecutor; 424 private IkeSessionCallback mMockIkeSessionCallback; 425 private ChildSessionCallback mMockChildSessionCallback; 426 427 private EncryptionTransform mIkeEncryptionTransform; 428 private IntegrityTransform mIkeIntegrityTransform; 429 private PrfTransform mIkePrfTransform; 430 private DhGroupTransform mIkeDhGroupTransform; 431 432 private IIkeMessageHelper mMockIkeMessageHelper; 433 private ISaRecordHelper mMockSaRecordHelper; 434 435 private ChildSessionStateMachine mMockChildSessionStateMachine; 436 private IChildSessionSmCallback mDummyChildSmCallback; 437 438 private IkeSaRecord mSpyCurrentIkeSaRecord; 439 private IkeSaRecord mSpyLocalInitIkeSaRecord; 440 private IkeSaRecord mSpyRemoteInitIkeSaRecord; 441 442 private Log mSpyIkeLog; 443 444 private int mExpectedCurrentSaLocalReqMsgId; 445 private int mExpectedCurrentSaRemoteReqMsgId; 446 447 private IkeSessionStateMachine.Dependencies mSpyDeps; 448 449 private EapSessionConfig mEapSessionConfig; 450 private EapSessionConfig mEapSessionConfigEapAka; 451 private EapAuthenticator mMockEapAuthenticator; 452 453 private IkeConnectionController mSpyIkeConnectionCtrl; 454 private IkeSpiGenerator mSpyIkeSpiGenerator; 455 456 private Ike3gppDataListener mMockIke3gppDataListener; 457 private Ike3gppExtension mIke3gppExtension; 458 459 private X509Certificate mRootCertificate; 460 private X509Certificate mServerEndCertificate; 461 private PrivateKey mUserPrivateKey; 462 private X509Certificate mUserEndCert; 463 464 private LocalRequestFactory mLocalRequestFactory; 465 466 private ArgumentCaptor<IkeMessage> mIkeMessageCaptor = 467 ArgumentCaptor.forClass(IkeMessage.class); 468 private ArgumentCaptor<IkeSaRecordConfig> mIkeSaRecordConfigCaptor = 469 ArgumentCaptor.forClass(IkeSaRecordConfig.class); 470 private ArgumentCaptor<IChildSessionSmCallback> mChildSessionSmCbCaptor = 471 ArgumentCaptor.forClass(IChildSessionSmCallback.class); 472 private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor = 473 ArgumentCaptor.forClass(List.class); 474 makeDummyReceivedIkeInitRespPacket(List<IkePayload> payloadList)475 private ReceivedIkePacket makeDummyReceivedIkeInitRespPacket(List<IkePayload> payloadList) 476 throws Exception { 477 long dummyInitSpi = 1L; 478 long dummyRespSpi = 2L; 479 480 return makeDummyUnencryptedReceivedIkePacket( 481 dummyInitSpi, 482 dummyRespSpi, 483 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 484 true /*isResp*/, 485 false /*fromIkeInit*/, 486 payloadList); 487 } 488 makeDummyReceivedIkeInitRespPacket( List<Integer> payloadTypeList, List<String> payloadHexStringList)489 private ReceivedIkePacket makeDummyReceivedIkeInitRespPacket( 490 List<Integer> payloadTypeList, List<String> payloadHexStringList) throws Exception { 491 492 List<IkePayload> payloadList = 493 hexStrListToIkePayloadList( 494 payloadTypeList, payloadHexStringList, true /* isResp */); 495 return makeDummyReceivedIkeInitRespPacket(payloadList); 496 } 497 makeDummyUnencryptedReceivedIkePacket( long initiatorSpi, long responderSpi, @IkeHeader.ExchangeType int eType, boolean isResp, boolean fromIkeInit, List<IkePayload> payloadList)498 private ReceivedIkePacket makeDummyUnencryptedReceivedIkePacket( 499 long initiatorSpi, 500 long responderSpi, 501 @IkeHeader.ExchangeType int eType, 502 boolean isResp, 503 boolean fromIkeInit, 504 List<IkePayload> payloadList) 505 throws Exception { 506 IkeMessage dummyIkeMessage = 507 makeDummyIkeMessageForTest( 508 initiatorSpi, 509 responderSpi, 510 eType, 511 isResp, 512 fromIkeInit, 513 0, 514 false /*isEncrypted*/, 515 payloadList); 516 517 byte[] dummyIkePacketBytes = new byte[0]; 518 doReturn(new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)) 519 .when(mMockIkeMessageHelper) 520 .decode(0, dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 521 522 return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 523 } 524 makeDummyEncryptedReceivedIkePacket( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, List<Integer> payloadTypeList, List<String> payloadHexStringList)525 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacket( 526 IkeSaRecord ikeSaRecord, 527 @IkeHeader.ExchangeType int eType, 528 boolean isResp, 529 List<Integer> payloadTypeList, 530 List<String> payloadHexStringList) 531 throws Exception { 532 List<IkePayload> payloadList = 533 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); 534 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 535 ikeSaRecord, eType, isResp, payloadList); 536 } 537 makeDummyEncryptedReceivedIkePacketWithPayloadList( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, List<IkePayload> payloadList)538 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( 539 IkeSaRecord ikeSaRecord, 540 @IkeHeader.ExchangeType int eType, 541 boolean isResp, 542 List<IkePayload> payloadList) 543 throws Exception { 544 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 545 ikeSaRecord, 546 eType, 547 isResp, 548 isResp 549 ? ikeSaRecord.getLocalRequestMessageId() 550 : ikeSaRecord.getRemoteRequestMessageId(), 551 payloadList, 552 new byte[0] /*dummyIkePacketBytes*/); 553 } 554 makeDummyEncryptedReceivedIkePacketWithPayloadList( IkeSaRecord ikeSaRecord, @IkeHeader.ExchangeType int eType, boolean isResp, int msgId, List<IkePayload> payloadList, byte[] dummyIkePacketBytes)555 private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList( 556 IkeSaRecord ikeSaRecord, 557 @IkeHeader.ExchangeType int eType, 558 boolean isResp, 559 int msgId, 560 List<IkePayload> payloadList, 561 byte[] dummyIkePacketBytes) 562 throws Exception { 563 boolean fromIkeInit = !ikeSaRecord.isLocalInit; 564 IkeMessage dummyIkeMessage = 565 makeDummyIkeMessageForTest( 566 ikeSaRecord.getInitiatorSpi(), 567 ikeSaRecord.getResponderSpi(), 568 eType, 569 isResp, 570 fromIkeInit, 571 msgId, 572 true /*isEncyprted*/, 573 payloadList); 574 575 setDecodeEncryptedPacketResult( 576 ikeSaRecord, 577 dummyIkeMessage.ikeHeader, 578 null /*collectedFrags*/, 579 new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes)); 580 581 return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes); 582 } 583 makeDummyReceivedIkePacketWithInvalidSyntax( IkeSaRecord ikeSaRecord, boolean isResp, int eType)584 private ReceivedIkePacket makeDummyReceivedIkePacketWithInvalidSyntax( 585 IkeSaRecord ikeSaRecord, boolean isResp, int eType) { 586 return makeDummyReceivedIkePacketWithDecodingError( 587 ikeSaRecord, isResp, eType, new InvalidSyntaxException("IkeStateMachineTest")); 588 } 589 makeDummyReceivedIkePacketWithDecodingError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception)590 private ReceivedIkePacket makeDummyReceivedIkePacketWithDecodingError( 591 IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception) { 592 IkeHeader header = 593 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); 594 byte[] dummyPacket = new byte[0]; 595 doReturn(new DecodeResultProtectedError(exception, dummyPacket)) 596 .when(mMockIkeMessageHelper) 597 .decode(anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()); 598 599 return new ReceivedIkePacket(header, dummyPacket); 600 } 601 makeDummyReceivedIkePacketWithUnprotectedError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception)602 private ReceivedIkePacket makeDummyReceivedIkePacketWithUnprotectedError( 603 IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception) { 604 IkeHeader header = 605 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK); 606 byte[] dummyPacket = new byte[0]; 607 doReturn(new DecodeResultUnprotectedError(exception)) 608 .when(mMockIkeMessageHelper) 609 .decode(anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()); 610 611 return new ReceivedIkePacket(header, dummyPacket); 612 } 613 makeDummyReceivedIkeFragmentPacket( IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeSkfPayload skfPayload, int nextPayloadType, DecodeResultPartial collectedFrags)614 private ReceivedIkePacket makeDummyReceivedIkeFragmentPacket( 615 IkeSaRecord ikeSaRecord, 616 boolean isResp, 617 int eType, 618 IkeSkfPayload skfPayload, 619 int nextPayloadType, 620 DecodeResultPartial collectedFrags) { 621 IkeHeader header = 622 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 623 624 byte[] dummyPacket = new byte[0]; 625 DecodeResultPartial resultFrags = 626 new DecodeResultPartial( 627 header, dummyPacket, skfPayload, nextPayloadType, collectedFrags); 628 setDecodeEncryptedPacketResult(ikeSaRecord, header, collectedFrags, resultFrags); 629 630 return new ReceivedIkePacket(header, dummyPacket); 631 } 632 makeDummyReceivedLastIkeFragmentPacketOk( IkeSaRecord ikeSaRecord, boolean isResp, int eType, DecodeResultPartial collectedFrags, List<IkePayload> payloadList, byte[] firstFragBytes)633 private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketOk( 634 IkeSaRecord ikeSaRecord, 635 boolean isResp, 636 int eType, 637 DecodeResultPartial collectedFrags, 638 List<IkePayload> payloadList, 639 byte[] firstFragBytes) { 640 IkeHeader header = 641 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 642 643 IkeMessage completeMessage = new IkeMessage(header, payloadList); 644 645 setDecodeEncryptedPacketResult( 646 ikeSaRecord, 647 header, 648 collectedFrags, 649 new DecodeResultOk(completeMessage, firstFragBytes)); 650 651 return new ReceivedIkePacket(header, new byte[0] /*dummyIkePacketBytes*/); 652 } 653 makeDummyReceivedLastIkeFragmentPacketError( IkeSaRecord ikeSaRecord, boolean isResp, int eType, DecodeResultPartial collectedFrags, IkeException exception)654 private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketError( 655 IkeSaRecord ikeSaRecord, 656 boolean isResp, 657 int eType, 658 DecodeResultPartial collectedFrags, 659 IkeException exception) { 660 IkeHeader header = 661 makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF); 662 663 byte[] dummyIkePacketBytes = new byte[0]; 664 setDecodeEncryptedPacketResult( 665 ikeSaRecord, 666 header, 667 collectedFrags, 668 new DecodeResultProtectedError(exception, dummyIkePacketBytes)); 669 670 return new ReceivedIkePacket(header, dummyIkePacketBytes); 671 } 672 makeDummyIkeHeader( IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType)673 private IkeHeader makeDummyIkeHeader( 674 IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType) { 675 return new IkeHeader( 676 ikeSaRecord.getInitiatorSpi(), 677 ikeSaRecord.getResponderSpi(), 678 firstPayloadType, 679 eType, 680 isResp, 681 !ikeSaRecord.isLocalInit, 682 isResp 683 ? ikeSaRecord.getLocalRequestMessageId() 684 : ikeSaRecord.getRemoteRequestMessageId()); 685 } 686 setDecodeEncryptedPacketResult( IkeSaRecord ikeSaRecord, IkeHeader header, DecodeResultPartial collectedFrags, DecodeResult result)687 private void setDecodeEncryptedPacketResult( 688 IkeSaRecord ikeSaRecord, 689 IkeHeader header, 690 DecodeResultPartial collectedFrags, 691 DecodeResult result) { 692 doReturn(result) 693 .when(mMockIkeMessageHelper) 694 .decode( 695 anyInt(), 696 any(), 697 any(), 698 eq(ikeSaRecord), 699 eq(header), 700 any(), 701 eq(collectedFrags)); 702 } 703 makeDummyIkeMessageForTest( long initSpi, long respSpi, @IkeHeader.ExchangeType int eType, boolean isResp, boolean fromikeInit, int messageId, boolean isEncrypted, List<IkePayload> payloadList)704 private IkeMessage makeDummyIkeMessageForTest( 705 long initSpi, 706 long respSpi, 707 @IkeHeader.ExchangeType int eType, 708 boolean isResp, 709 boolean fromikeInit, 710 int messageId, 711 boolean isEncrypted, 712 List<IkePayload> payloadList) 713 throws Exception { 714 int firstPayloadType = 715 isEncrypted ? IkePayload.PAYLOAD_TYPE_SK : IkePayload.PAYLOAD_TYPE_NO_NEXT; 716 717 IkeHeader header = 718 new IkeHeader( 719 initSpi, respSpi, firstPayloadType, eType, isResp, fromikeInit, messageId); 720 721 return new IkeMessage(header, payloadList); 722 } 723 hexStrListToIkePayloadList( List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp)724 private static List<IkePayload> hexStrListToIkePayloadList( 725 List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp) 726 throws Exception { 727 List<IkePayload> payloadList = new ArrayList<>(); 728 for (int i = 0; i < payloadTypeList.size(); i++) { 729 payloadList.add( 730 IkeTestUtils.hexStringToIkePayload( 731 payloadTypeList.get(i), isResp, payloadHexStringList.get(i))); 732 } 733 return payloadList; 734 } 735 verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket)736 private void verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket) 737 throws Exception { 738 verify(mMockIkeMessageHelper) 739 .decode( 740 anyInt(), 741 any(), 742 any(), 743 eq(record), 744 eq(rcvPacket.ikeHeader), 745 eq(rcvPacket.ikePacketBytes), 746 eq(null)); 747 } 748 makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit)749 private static IkeSaRecord makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit) 750 throws IOException { 751 Inet4Address initAddress = isLocalInit ? LOCAL_ADDRESS : REMOTE_ADDRESS; 752 Inet4Address respAddress = isLocalInit ? REMOTE_ADDRESS : LOCAL_ADDRESS; 753 754 return new IkeSaRecord( 755 IKE_SPI_GENERATOR.allocateSpi(initAddress, initSpi), 756 IKE_SPI_GENERATOR.allocateSpi(respAddress, respSpi), 757 isLocalInit, 758 TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING), 759 TestUtils.hexStringToByteArray(NONCE_RESP_HEX_STRING), 760 new byte[KEY_LEN_IKE_SKD], 761 new byte[KEY_LEN_IKE_INTE], 762 new byte[KEY_LEN_IKE_INTE], 763 new byte[KEY_LEN_IKE_ENCR], 764 new byte[KEY_LEN_IKE_ENCR], 765 TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING), 766 TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING), 767 mock(SaLifetimeAlarmScheduler.class)); 768 } 769 mockScheduleRekey(SaLifetimeAlarmScheduler mockSaLifetimeAlarmScheduler)770 private void mockScheduleRekey(SaLifetimeAlarmScheduler mockSaLifetimeAlarmScheduler) { 771 IkeLocalRequest rekeyReq = 772 mLocalRequestFactory.getIkeLocalRequest( 773 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); 774 doAnswer( 775 (invocation) -> { 776 mIkeSessionStateMachine.sendMessageDelayed( 777 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 778 rekeyReq, 779 mIkeSessionStateMachine.mIkeSessionParams 780 .getSoftLifetimeMsInternal()); 781 return null; 782 }) 783 .when(mockSaLifetimeAlarmScheduler) 784 .scheduleLifetimeExpiryAlarm(anyString()); 785 } 786 787 @Override 788 @Before setUp()789 public void setUp() throws Exception { 790 super.setUp(); 791 792 mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG); 793 IkeManager.setIkeLog(mSpyIkeLog); 794 795 mEapSessionConfig = 796 new EapSessionConfig.Builder() 797 .setEapSimConfig(EAP_SIM_SUB_ID, TelephonyManager.APPTYPE_USIM) 798 .build(); 799 setupLocalAddressForNetwork(mMockDefaultNetwork, LOCAL_ADDRESS, LOCAL_ADDRESS_V6); 800 801 mMockEapAuthenticator = mock(EapAuthenticator.class); 802 mMockChildSessionStateMachine = mock(ChildSessionStateMachine.class); 803 804 mRootCertificate = CertUtils.createCertFromPemFile("self-signed-ca-a.pem"); 805 mServerEndCertificate = CertUtils.createCertFromPemFile("end-cert-a.pem"); 806 mUserEndCert = CertUtils.createCertFromPemFile("end-cert-b.pem"); 807 mUserPrivateKey = CertUtils.createRsaPrivateKeyFromKeyFile("end-cert-key-b.key"); 808 809 mPsk = TestUtils.hexStringToByteArray(PSK_HEX_STRING); 810 811 mChildSessionParams = buildChildSessionParams(); 812 813 mIkeEncryptionTransform = 814 new EncryptionTransform( 815 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128); 816 mIkeIntegrityTransform = 817 new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96); 818 mIkePrfTransform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1); 819 mIkeDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP); 820 821 mSpyUserCbExecutor = 822 spy( 823 (command) -> { 824 command.run(); 825 }); 826 827 mMockIkeSessionCallback = mock(IkeSessionCallback.class); 828 mMockChildSessionCallback = mock(ChildSessionCallback.class); 829 mLocalRequestFactory = new LocalRequestFactory(); 830 831 mLooper = new TestLooper(); 832 833 // Setup state machine 834 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsPsk(mPsk)); 835 836 mMockIkeMessageHelper = mock(IkeMessage.IIkeMessageHelper.class); 837 IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper); 838 resetMockIkeMessageHelper(); 839 840 mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class); 841 SaRecord.setSaRecordHelper(mMockSaRecordHelper); 842 843 mSpyCurrentIkeSaRecord = spy(makeDummyIkeSaRecord(11, 12, true)); 844 mSpyLocalInitIkeSaRecord = spy(makeDummyIkeSaRecord(21, 22, true)); 845 mSpyRemoteInitIkeSaRecord = spy(makeDummyIkeSaRecord(31, 32, false)); 846 847 mExpectedCurrentSaLocalReqMsgId = 0; 848 mExpectedCurrentSaRemoteReqMsgId = 0; 849 850 mMockIke3gppDataListener = mock(Ike3gppDataListener.class); 851 } 852 853 @After tearDown()854 public void tearDown() throws Exception { 855 mIkeSessionStateMachine.killSession(); 856 mLooper.dispatchAll(); 857 mIkeSessionStateMachine.setDbg(false); 858 859 mSpyCurrentIkeSaRecord.close(); 860 mSpyLocalInitIkeSaRecord.close(); 861 mSpyRemoteInitIkeSaRecord.close(); 862 863 IkeManager.resetIkeLog(); 864 IkeMessage.setIkeMessageHelper(new IkeMessageHelper()); 865 SaRecord.setSaRecordHelper(new SaRecordHelper()); 866 } 867 injectChildSessionInSpyDeps( IkeSessionStateMachine.Dependencies spyDeps, ChildSessionStateMachine child, ChildSessionCallback childCb)868 private void injectChildSessionInSpyDeps( 869 IkeSessionStateMachine.Dependencies spyDeps, 870 ChildSessionStateMachine child, 871 ChildSessionCallback childCb) { 872 doReturn(child) 873 .when(spyDeps) 874 .newChildSessionStateMachine( 875 any(IkeContext.class), 876 any(ChildSessionStateMachine.Config.class), 877 eq(childCb), 878 any(IChildSessionSmCallback.class)); 879 } 880 buildSpyDepsWithChildSession( ChildSessionStateMachine child, ChildSessionCallback childCb)881 private IkeSessionStateMachine.Dependencies buildSpyDepsWithChildSession( 882 ChildSessionStateMachine child, ChildSessionCallback childCb) { 883 IkeSessionStateMachine.Dependencies spyDeps = 884 spy(new IkeSessionStateMachine.Dependencies()); 885 886 doReturn(mMockEapAuthenticator) 887 .when(spyDeps) 888 .newEapAuthenticator( 889 any(IkeContext.class), 890 any(IEapCallback.class), 891 any(EapSessionConfig.class)); 892 doReturn(mSpyIkeConnectionCtrl) 893 .when(spyDeps) 894 .newIkeConnectionController( 895 any(IkeContext.class), any(IkeConnectionController.Config.class)); 896 doReturn(mSpyIkeSpiGenerator) 897 .when(spyDeps) 898 .newIkeSpiGenerator(any(RandomnessFactory.class)); 899 injectChildSessionInSpyDeps(spyDeps, child, childCb); 900 901 902 return spyDeps; 903 } 904 makeAndStartIkeSession(IkeSessionParams ikeParams)905 private IkeSessionStateMachine makeAndStartIkeSession(IkeSessionParams ikeParams) 906 throws Exception { 907 return makeAndStartIkeSession(ikeParams, LOCAL_ADDRESS, REMOTE_ADDRESS); 908 } 909 setupIkeConnectionCtrlCbWithIkeSession( IkeConnectionController.Callback mockCallback, IkeSessionStateMachine ikeSession)910 private void setupIkeConnectionCtrlCbWithIkeSession( 911 IkeConnectionController.Callback mockCallback, IkeSessionStateMachine ikeSession) { 912 doAnswer( 913 (invocation) -> { 914 ikeSession.onUnderlyingNetworkUpdated(); 915 return null; 916 }) 917 .when(mockCallback) 918 .onUnderlyingNetworkUpdated(); 919 920 doAnswer( 921 (invocation) -> { 922 ikeSession.onUnderlyingNetworkDied(invocation.getArgument(0)); 923 return null; 924 }) 925 .when(mockCallback) 926 .onUnderlyingNetworkDied(any()); 927 928 doAnswer( 929 (invocation) -> { 930 ikeSession.onError(invocation.getArgument(0)); 931 return null; 932 }) 933 .when(mockCallback) 934 .onError(any()); 935 } 936 makeAndStartIkeSession( IkeSessionParams ikeParams, InetAddress localAddress, InetAddress expectedRemoteAddress)937 private IkeSessionStateMachine makeAndStartIkeSession( 938 IkeSessionParams ikeParams, 939 InetAddress localAddress, 940 InetAddress expectedRemoteAddress) 941 throws Exception { 942 IkeContext ikeContext = 943 spy( 944 new IkeSessionStateMachine.Dependencies() 945 .newIkeContext( 946 mLooper.getLooper(), 947 mSpyContext, 948 ikeParams.getConfiguredNetwork())); 949 IkeConnectionController.Callback mockIkeConnectionCtrlCb = 950 mock(IkeConnectionController.Callback.class); 951 IkeConnectionController.Dependencies spyIkeConnectionCtrlDeps = 952 spy(new IkeConnectionController.Dependencies()); 953 doReturn(mMockIkeLocalAddressGenerator) 954 .when(spyIkeConnectionCtrlDeps) 955 .newIkeLocalAddressGenerator(); 956 mMockIkeNattKeepalive = mock(IkeNattKeepalive.class); 957 doAnswer( 958 (invocation) -> { 959 mMockIkeNattKeepalive.start(); 960 return mMockIkeNattKeepalive; 961 }) 962 .when(spyIkeConnectionCtrlDeps) 963 .newIkeNattKeepalive(any(), any()); 964 965 // Setup socket instances used by the IkeSessionStateMachine 966 mMockIkeUdp4Socket = newMockIkeSocket(IkeUdp4Socket.class); 967 mMockIkeUdp6Socket = newMockIkeSocket(IkeUdp6Socket.class); 968 mMockIkeUdpEncapSocket = newMockIkeSocket(IkeUdpEncapSocket.class); 969 mMockIkeUdp6WithEncapPortSocket = newMockIkeSocket(IkeUdp6WithEncapPortSocket.class); 970 971 doReturn(mMockIkeUdp4Socket) 972 .when(spyIkeConnectionCtrlDeps) 973 .newIkeUdp4Socket(any(), any(), any()); 974 doReturn(mMockIkeUdp6Socket) 975 .when(spyIkeConnectionCtrlDeps) 976 .newIkeUdp6Socket(any(), any(), any()); 977 doReturn(mMockIkeUdpEncapSocket) 978 .when(spyIkeConnectionCtrlDeps) 979 .newIkeUdpEncapSocket(any(), any(), any(), any()); 980 doReturn(mMockIkeUdp6WithEncapPortSocket) 981 .when(spyIkeConnectionCtrlDeps) 982 .newIkeUdp6WithEncapPortSocket(any(), any(), any()); 983 984 // Can't use a mock object because delayMs must be nonzero. Otherwise, setNetwork will 985 // spuriously restart keepalives, thinking that the current delay is zero. 986 final IkeAlarmConfig alarmConfig = spy(new IkeAlarmConfig(mSpyContext, 987 "mock", NATT_KEEPALIVE_DELAY * 1_000, null, null)); 988 989 doReturn(true) 990 .when(ikeContext) 991 .getDeviceConfigPropertyBoolean(eq(CONFIG_USE_CACHED_ADDRS), anyBoolean()); 992 mSpyIkeConnectionCtrl = 993 spy( 994 new IkeConnectionController( 995 ikeContext, 996 new IkeConnectionController.Config( 997 new Handler(mLooper.getLooper()), 998 ikeParams, 999 FAKE_SESSION_ID, 1000 CMD_ALARM_FIRED, 1001 CMD_SEND_KEEPALIVE, 1002 mockIkeConnectionCtrlCb), 1003 spyIkeConnectionCtrlDeps)); 1004 1005 mSpyIkeSpiGenerator = spy(new IkeSpiGenerator(createMockRandomFactory())); 1006 1007 mSpyDeps = 1008 buildSpyDepsWithChildSession( 1009 mMockChildSessionStateMachine, mMockChildSessionCallback); 1010 1011 IkeSessionStateMachine ikeSession = 1012 new IkeSessionStateMachine( 1013 mLooper.getLooper(), 1014 mSpyContext, 1015 mIpSecManager, 1016 mMockConnectManager, 1017 ikeParams, 1018 mChildSessionParams, 1019 mSpyUserCbExecutor, 1020 mMockIkeSessionCallback, 1021 mMockChildSessionCallback, 1022 mSpyDeps); 1023 setupIkeConnectionCtrlCbWithIkeSession(mockIkeConnectionCtrlCb, ikeSession); 1024 1025 ikeSession.setDbg(true); 1026 1027 mLooper.dispatchAll(); 1028 1029 mMockCurrentIkeSocket = mSpyIkeConnectionCtrl.getIkeSocket(); 1030 assertEquals(expectedRemoteAddress, mSpyIkeConnectionCtrl.getRemoteAddress()); 1031 1032 if (ikeParams.getConfiguredNetwork() == null) { 1033 verify(mMockConnectManager, atLeast(1)).getActiveNetwork(); 1034 } else { 1035 verify(mMockConnectManager, never()).getActiveNetwork(); 1036 } 1037 return ikeSession; 1038 } 1039 buildSaProposal()1040 public static IkeSaProposal buildSaProposal() throws Exception { 1041 return buildSaProposalCommon().addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP).build(); 1042 } 1043 buildNegotiatedSaProposal()1044 private static IkeSaProposal buildNegotiatedSaProposal() throws Exception { 1045 return buildSaProposalCommon().build(); 1046 } 1047 buildSaProposalCommon()1048 private static IkeSaProposal.Builder buildSaProposalCommon() throws Exception { 1049 return new IkeSaProposal.Builder() 1050 .addEncryptionAlgorithm( 1051 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) 1052 .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) 1053 .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1) 1054 .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP); 1055 } 1056 buildIkeSessionParamsCommon()1057 private IkeSessionParams.Builder buildIkeSessionParamsCommon() throws Exception { 1058 return new IkeSessionParams.Builder(mMockConnectManager) 1059 .setServerHostname(REMOTE_HOSTNAME) 1060 .addIkeOption(IKE_OPTION_FORCE_DNS_RESOLUTION) 1061 .addSaProposal(buildSaProposal()) 1062 .setLocalIdentification(LOCAL_ID_IPV4) 1063 .setRemoteIdentification(REMOTE_ID_FQDN) 1064 .setNattKeepAliveDelaySeconds(NATT_KEEPALIVE_DELAY) 1065 .addPcscfServerRequest(AF_INET) 1066 .addPcscfServerRequest(AF_INET6) 1067 .setRetransmissionTimeoutsMillis( 1068 new int[] {5000, 10000, 20000, 30000, 40000, 50000}) 1069 .setLivenessRetransmissionTimeoutsMillis( 1070 new int[] {1000, 1000, 1000, 1000, 5000, 5000, 10000}); 1071 } 1072 buildIkeSessionParams()1073 private IkeSessionParams buildIkeSessionParams() throws Exception { 1074 return buildIkeSessionParamsCommon().setAuthPsk(mPsk).build(); 1075 } 1076 buildIkeSessionParamsPsk(byte[] psk)1077 private IkeSessionParams buildIkeSessionParamsPsk(byte[] psk) throws Exception { 1078 return buildIkeSessionParamsCommon().setAuthPsk(psk).build(); 1079 } 1080 buildIkeSessionParamsEap()1081 private IkeSessionParams buildIkeSessionParamsEap() throws Exception { 1082 return buildIkeSessionParamsCommon() 1083 .setAuthEap(mRootCertificate, mEapSessionConfig) 1084 .build(); 1085 } 1086 buildIkeSessionParamsEapAkaWithDeviceIdentity()1087 private IkeSessionParams buildIkeSessionParamsEapAkaWithDeviceIdentity() throws Exception { 1088 Ike3gppParams ike3gppParams = 1089 new Ike3gppParams.Builder().setMobileDeviceIdentity(DEVICE_IDENTITY_IMEI).build(); 1090 Ike3gppExtension ike3gppExtension = 1091 new Ike3gppExtension(ike3gppParams, mock(Ike3gppDataListener.class)); 1092 mEapSessionConfigEapAka = 1093 new EapSessionConfig.Builder() 1094 .setEapAkaConfig(0, TelephonyManager.APPTYPE_ISIM) 1095 .build(); 1096 1097 return buildIkeSessionParamsCommon() 1098 .setAuthEap(mock(X509Certificate.class), mEapSessionConfigEapAka) 1099 .setIke3gppExtension(ike3gppExtension) 1100 .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) 1101 .build(); 1102 } 1103 buildIkeSessionParamsDigitalSignature()1104 private IkeSessionParams buildIkeSessionParamsDigitalSignature() throws Exception { 1105 return buildIkeSessionParamsCommon() 1106 .setAuthDigitalSignature(mRootCertificate, mUserEndCert, mUserPrivateKey) 1107 .build(); 1108 } 1109 buildIkeSessionParamsIke3gppExtension(byte pduSessionId)1110 private IkeSessionParams buildIkeSessionParamsIke3gppExtension(byte pduSessionId) 1111 throws Exception { 1112 Ike3gppExtension ike3gppExtension = 1113 new Ike3gppExtension( 1114 new Ike3gppParams.Builder().setPduSessionId(pduSessionId).build(), 1115 mMockIke3gppDataListener); 1116 return buildIkeSessionParamsCommon() 1117 .setAuthPsk(mPsk) 1118 .setIke3gppExtension(ike3gppExtension) 1119 .build(); 1120 } 1121 buildIkeSessionParamsWithIkeOptions(int... ikeOptions)1122 private IkeSessionParams buildIkeSessionParamsWithIkeOptions(int... ikeOptions) 1123 throws Exception { 1124 IkeSessionParams.Builder builder = buildIkeSessionParamsCommon().setAuthPsk(mPsk); 1125 for (int option : ikeOptions) { 1126 builder.addIkeOption(option); 1127 } 1128 1129 return builder.build(); 1130 } 1131 buildChildSessionParams()1132 private ChildSessionParams buildChildSessionParams() throws Exception { 1133 ChildSaProposal saProposal = 1134 new ChildSaProposal.Builder() 1135 .addEncryptionAlgorithm( 1136 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128) 1137 .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96) 1138 .build(); 1139 1140 return new TunnelModeChildSessionParams.Builder() 1141 .addSaProposal(saProposal) 1142 .addInternalAddressRequest(AF_INET) 1143 .addInternalAddressRequest(AF_INET6) 1144 .build(); 1145 } 1146 1147 // Common IKE INIT response makeIkeInitResponse()1148 private ReceivedIkePacket makeIkeInitResponse() throws Exception { 1149 List<Integer> payloadTypeList = new ArrayList<>(); 1150 List<String> payloadHexStringList = new ArrayList<>(); 1151 1152 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 1153 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 1154 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 1155 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY); 1156 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_VENDOR); 1157 1158 payloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING); 1159 payloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING); 1160 payloadHexStringList.add(FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING); 1161 payloadHexStringList.add(SIGNATURE_HASH_SUPPORTED_PAYLOAD_HEX_STRING); 1162 payloadHexStringList.add(VENDOR_ID_PAYLOAD_HEX_STRING); 1163 1164 return makeIkeInitResponseWithRequiredPayloads(payloadTypeList, payloadHexStringList); 1165 } 1166 1167 // Simplest IKE INIT response that does not include any optional payloads makeIkeInitResponseWithRequiredPayloads( List<Integer> optionalPayloadTypes, List<String> optionalPayloadHexStrings)1168 private ReceivedIkePacket makeIkeInitResponseWithRequiredPayloads( 1169 List<Integer> optionalPayloadTypes, List<String> optionalPayloadHexStrings) 1170 throws Exception { 1171 List<Integer> payloadTypeList = new ArrayList<>(); 1172 List<String> payloadHexStringList = new ArrayList<>(); 1173 1174 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 1175 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 1176 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1177 payloadTypeList.addAll(optionalPayloadTypes); 1178 1179 payloadHexStringList.add(IKE_SA_PAYLOAD_HEX_STRING); 1180 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 1181 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 1182 payloadHexStringList.addAll(optionalPayloadHexStrings); 1183 1184 return makeDummyReceivedIkeInitRespPacket( 1185 payloadTypeList, 1186 payloadHexStringList); 1187 } 1188 getIkeAuthPayloadListWithChildPayloads( List<IkePayload> authRelatedPayloads)1189 private List<IkePayload> getIkeAuthPayloadListWithChildPayloads( 1190 List<IkePayload> authRelatedPayloads) throws Exception { 1191 List<Integer> payloadTypeList = new ArrayList<>(); 1192 List<String> payloadHexStringList = new ArrayList<>(); 1193 1194 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 1195 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 1196 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 1197 1198 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 1199 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 1200 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 1201 1202 List<IkePayload> payloadList = 1203 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, true /*isResp*/); 1204 payloadList.addAll(authRelatedPayloads); 1205 1206 return payloadList; 1207 } 1208 makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads)1209 private ReceivedIkePacket makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads) 1210 throws Exception { 1211 List<IkePayload> payloadList = getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); 1212 1213 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1214 mSpyCurrentIkeSaRecord, 1215 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 1216 true /*isResp*/, 1217 payloadList); 1218 } 1219 makeIkeAuthRespWithoutChildPayloads( List<IkePayload> authRelatedPayloads)1220 private ReceivedIkePacket makeIkeAuthRespWithoutChildPayloads( 1221 List<IkePayload> authRelatedPayloads) throws Exception { 1222 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1223 mSpyCurrentIkeSaRecord, 1224 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 1225 true /*isResp*/, 1226 authRelatedPayloads); 1227 } 1228 makeCreateChildCreateMessage(boolean isResp)1229 private ReceivedIkePacket makeCreateChildCreateMessage(boolean isResp) throws Exception { 1230 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1231 mSpyCurrentIkeSaRecord, 1232 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1233 isResp, 1234 makeCreateChildPayloadList(isResp)); 1235 } 1236 makeRekeyChildCreateMessage(boolean isResp, int spi)1237 private ReceivedIkePacket makeRekeyChildCreateMessage(boolean isResp, int spi) 1238 throws Exception { 1239 IkeNotifyPayload rekeyPayload = 1240 new IkeNotifyPayload( 1241 IkePayload.PROTOCOL_ID_ESP, 1242 spi, 1243 IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA, 1244 new byte[0]); 1245 1246 List<IkePayload> payloadList = makeCreateChildPayloadList(isResp); 1247 payloadList.add(rekeyPayload); 1248 1249 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1250 mSpyCurrentIkeSaRecord, 1251 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1252 isResp, 1253 payloadList); 1254 } 1255 makeCreateChildPayloadList(boolean isResp)1256 private List<IkePayload> makeCreateChildPayloadList(boolean isResp) throws Exception { 1257 List<Integer> payloadTypeList = new ArrayList<>(); 1258 List<String> payloadHexStringList = new ArrayList<>(); 1259 1260 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 1261 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1262 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 1263 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 1264 1265 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 1266 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 1267 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 1268 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 1269 1270 return hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp); 1271 } 1272 makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp)1273 private ReceivedIkePacket makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp) 1274 throws Exception { 1275 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1276 mSpyCurrentIkeSaRecord, 1277 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1278 isResp, 1279 Arrays.asList(payloads)); 1280 } 1281 makeRekeyIkeResponse()1282 private ReceivedIkePacket makeRekeyIkeResponse() throws Exception { 1283 List<Integer> payloadTypeList = new ArrayList<>(); 1284 List<String> payloadHexStringList = new ArrayList<>(); 1285 1286 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 1287 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 1288 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1289 1290 payloadHexStringList.add(IKE_REKEY_SA_PAYLOAD_HEX_STRING); 1291 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 1292 payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING); 1293 1294 return makeDummyEncryptedReceivedIkePacket( 1295 mSpyCurrentIkeSaRecord, 1296 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1297 true /*isResp*/, 1298 payloadTypeList, 1299 payloadHexStringList); 1300 } 1301 makeDeleteIkeResponse(IkeSaRecord ikeSaRecord)1302 private ReceivedIkePacket makeDeleteIkeResponse(IkeSaRecord ikeSaRecord) throws Exception { 1303 return makeDummyEncryptedReceivedIkePacket( 1304 ikeSaRecord, 1305 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1306 true /*isResp*/, 1307 new ArrayList<>(), 1308 new ArrayList<>()); 1309 } 1310 makeDpdIkeRequest(IkeSaRecord saRecord)1311 private ReceivedIkePacket makeDpdIkeRequest(IkeSaRecord saRecord) throws Exception { 1312 return makeDummyEncryptedReceivedIkePacket( 1313 saRecord, 1314 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1315 false /*isResp*/, 1316 new ArrayList<>(), 1317 new ArrayList<>()); 1318 } 1319 makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes)1320 private ReceivedIkePacket makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes) 1321 throws Exception { 1322 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1323 mSpyCurrentIkeSaRecord, 1324 EXCHANGE_TYPE_INFORMATIONAL, 1325 false /*isResp*/, 1326 msgId, 1327 new ArrayList<>(), 1328 dummyIkePacketBytes); 1329 } 1330 makeDeviceIdentityIkeRequest()1331 private ReceivedIkePacket makeDeviceIdentityIkeRequest() throws Exception { 1332 IkeNotifyPayload deviceIdentity = 1333 new IkeNotifyPayload( 1334 NOTIFY_TYPE_DEVICE_IDENTITY, HexDump.hexStringToByteArray("01")); 1335 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1336 mSpyCurrentIkeSaRecord, 1337 EXCHANGE_TYPE_INFORMATIONAL, 1338 false /*isResp*/, 1339 Arrays.asList(deviceIdentity)); 1340 } 1341 makeRoutabilityCheckIkeRequest()1342 private ReceivedIkePacket makeRoutabilityCheckIkeRequest() throws Exception { 1343 IkeNotifyPayload cookie2Notify = new IkeNotifyPayload(NOTIFY_TYPE_COOKIE2, COOKIE2_DATA); 1344 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1345 mSpyCurrentIkeSaRecord, 1346 EXCHANGE_TYPE_INFORMATIONAL, 1347 false /*isResp*/, 1348 Arrays.asList(cookie2Notify)); 1349 } 1350 makeRekeyIkeRequest()1351 private ReceivedIkePacket makeRekeyIkeRequest() throws Exception { 1352 IkeSaPayload saPayload = 1353 (IkeSaPayload) 1354 IkeTestUtils.hexStringToIkePayload( 1355 IkePayload.PAYLOAD_TYPE_SA, 1356 false /*isResp*/, 1357 IKE_REKEY_SA_PAYLOAD_HEX_STRING); 1358 return makeRekeyIkeRequest(saPayload); 1359 } 1360 makeRekeyIkeRequestWithUnacceptableProposal()1361 private ReceivedIkePacket makeRekeyIkeRequestWithUnacceptableProposal() throws Exception { 1362 IkeSaPayload saPayload = 1363 (IkeSaPayload) 1364 IkeTestUtils.hexStringToIkePayload( 1365 IkePayload.PAYLOAD_TYPE_SA, 1366 false /*isResp*/, 1367 IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING); 1368 return makeRekeyIkeRequest(saPayload); 1369 } 1370 makeRekeyIkeRequestWithPayloads(List<IkePayload> payloads)1371 private ReceivedIkePacket makeRekeyIkeRequestWithPayloads(List<IkePayload> payloads) 1372 throws Exception { 1373 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1374 mSpyCurrentIkeSaRecord, 1375 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 1376 false /*isResp*/, 1377 payloads); 1378 } 1379 makeRekeyIkeRequest(IkeSaPayload saPayload)1380 private ReceivedIkePacket makeRekeyIkeRequest(IkeSaPayload saPayload) throws Exception { 1381 List<Integer> payloadTypeList = new ArrayList<>(); 1382 List<String> payloadHexStringList = new ArrayList<>(); 1383 1384 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE); 1385 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE); 1386 1387 payloadHexStringList.add(KE_PAYLOAD_HEX_STRING); 1388 payloadHexStringList.add(NONCE_INIT_PAYLOAD_HEX_STRING); 1389 1390 List<IkePayload> payloadList = 1391 hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/); 1392 payloadList.add(saPayload); 1393 1394 return makeRekeyIkeRequestWithPayloads(payloadList); 1395 } 1396 makeDeleteIkeRequest(IkeSaRecord saRecord)1397 private ReceivedIkePacket makeDeleteIkeRequest(IkeSaRecord saRecord) throws Exception { 1398 List<Integer> payloadTypeList = new ArrayList<>(); 1399 List<String> payloadHexStringList = new ArrayList<>(); 1400 1401 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_DELETE); 1402 1403 payloadHexStringList.add(DELETE_IKE_PAYLOAD_HEX_STRING); 1404 1405 return makeDummyEncryptedReceivedIkePacket( 1406 saRecord, 1407 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 1408 false /*isResp*/, 1409 payloadTypeList, 1410 payloadHexStringList); 1411 } 1412 makeResponseWithErrorNotify(IkeNotifyPayload notify)1413 private ReceivedIkePacket makeResponseWithErrorNotify(IkeNotifyPayload notify) 1414 throws Exception { 1415 List<IkePayload> payloads = new ArrayList<>(); 1416 payloads.add(notify); 1417 return makeDummyEncryptedReceivedIkePacketWithPayloadList( 1418 mSpyCurrentIkeSaRecord, EXCHANGE_TYPE_INFORMATIONAL, true /*isResp*/, payloads); 1419 } 1420 isIkePayloadExist( List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType)1421 private static boolean isIkePayloadExist( 1422 List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType) { 1423 for (IkePayload payload : payloadList) { 1424 if (payload.payloadType == payloadType) return true; 1425 } 1426 return false; 1427 } 1428 isNotifyExist( List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType)1429 private static boolean isNotifyExist( 1430 List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType) { 1431 for (IkeNotifyPayload notify : 1432 IkePayload.getPayloadListForTypeInProvidedList( 1433 PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, payloadList)) { 1434 if (notify.notifyType == notifyType) return true; 1435 } 1436 return false; 1437 } 1438 assertByteArrayListEquals( List<byte[]> expectedList, List<byte[]> resultList)1439 private static void assertByteArrayListEquals( 1440 List<byte[]> expectedList, List<byte[]> resultList) { 1441 assertEquals(expectedList.size(), resultList.size()); 1442 for (int i = 0; i < expectedList.size(); i++) { 1443 assertArrayEquals(expectedList.get(i), resultList.get(i)); 1444 } 1445 } 1446 verifyIncrementLocaReqMsgId()1447 private void verifyIncrementLocaReqMsgId() { 1448 assertEquals( 1449 ++mExpectedCurrentSaLocalReqMsgId, 1450 mSpyCurrentIkeSaRecord.getLocalRequestMessageId()); 1451 } 1452 verifyIncrementRemoteReqMsgId()1453 private void verifyIncrementRemoteReqMsgId() { 1454 assertEquals( 1455 ++mExpectedCurrentSaRemoteReqMsgId, 1456 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId()); 1457 } 1458 verifyRetransmissionStarted()1459 private void verifyRetransmissionStarted() { 1460 assertTrue( 1461 mIkeSessionStateMachine 1462 .getHandler() 1463 .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); 1464 } 1465 verifyRetransmissionStopped()1466 private void verifyRetransmissionStopped() { 1467 assertFalse( 1468 mIkeSessionStateMachine 1469 .getHandler() 1470 .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT)); 1471 } 1472 verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord)1473 private IkeMessage verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord) { 1474 verify(mMockIkeMessageHelper) 1475 .encryptAndEncode( 1476 any(), 1477 any(), 1478 eq(ikeSaRecord), 1479 mIkeMessageCaptor.capture(), 1480 anyBoolean(), 1481 anyInt()); 1482 return mIkeMessageCaptor.getValue(); 1483 } 1484 verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord)1485 private void verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord) { 1486 verify(mMockIkeMessageHelper, never()) 1487 .encryptAndEncode( 1488 any(), 1489 any(), 1490 eq(ikeSaRecord), 1491 any(IkeMessage.class), 1492 anyBoolean(), 1493 anyInt()); 1494 } 1495 verifyEncryptAndEncodeNeverCalled()1496 private void verifyEncryptAndEncodeNeverCalled() { 1497 verify(mMockIkeMessageHelper, never()) 1498 .encryptAndEncode( 1499 any(), 1500 any(), 1501 any(IkeSaRecord.class), 1502 any(IkeMessage.class), 1503 anyBoolean(), 1504 anyInt()); 1505 } 1506 resetMockIkeMessageHelper()1507 private void resetMockIkeMessageHelper() { 1508 reset(mMockIkeMessageHelper); 1509 doReturn(new byte[0]).when(mMockIkeMessageHelper).encode(any()); 1510 doReturn(new byte[1][0]) 1511 .when(mMockIkeMessageHelper) 1512 .encryptAndEncode(any(), any(), any(), any(), anyBoolean(), anyInt()); 1513 } 1514 resetSpyUserCbExecutor()1515 private void resetSpyUserCbExecutor() { 1516 reset(mSpyUserCbExecutor); 1517 } 1518 1519 @Test testQuit()1520 public void testQuit() { 1521 mIkeSessionStateMachine.quit(); 1522 mLooper.dispatchAll(); 1523 1524 verify(mMockCurrentIkeSocket).releaseReference(eq(mSpyIkeConnectionCtrl)); 1525 verify(mMockBusyWakelock).release(); 1526 } 1527 1528 @Test testAllocateIkeSpi()1529 public void testAllocateIkeSpi() throws Exception { 1530 // Test randomness. 1531 IkeSecurityParameterIndex ikeSpiOne = IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS); 1532 IkeSecurityParameterIndex ikeSpiTwo = IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS); 1533 1534 assertNotEquals(ikeSpiOne.getSpi(), ikeSpiTwo.getSpi()); 1535 ikeSpiTwo.close(); 1536 1537 // Test duplicate SPIs. 1538 long spiValue = ikeSpiOne.getSpi(); 1539 try { 1540 IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS, spiValue); 1541 fail("Expected to fail because duplicate SPI was assigned to the same address."); 1542 } catch (IOException expected) { 1543 1544 } 1545 1546 ikeSpiOne.close(); 1547 IkeSecurityParameterIndex ikeSpiThree = 1548 IKE_SPI_GENERATOR.allocateSpi(LOCAL_ADDRESS, spiValue); 1549 ikeSpiThree.close(); 1550 } 1551 setupFirstIkeSa()1552 private void setupFirstIkeSa() throws Exception { 1553 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1554 // later. 1555 when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any(), any())) 1556 .thenAnswer( 1557 (invocation) -> { 1558 captureAndReleaseIkeSpiResource(invocation, 2); 1559 mockScheduleRekey(mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler); 1560 mSpyCurrentIkeSaRecord.mSaLifetimeAlarmScheduler 1561 .scheduleLifetimeExpiryAlarm(anyString()); 1562 return mSpyCurrentIkeSaRecord; 1563 }); 1564 } 1565 setupRekeyedIkeSa(IkeSaRecord rekeySaRecord)1566 private void setupRekeyedIkeSa(IkeSaRecord rekeySaRecord) throws Exception { 1567 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1568 // later. 1569 when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( 1570 eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) 1571 .thenAnswer( 1572 (invocation) -> { 1573 captureAndReleaseIkeSpiResource(invocation, 4); 1574 mockScheduleRekey(rekeySaRecord.mSaLifetimeAlarmScheduler); 1575 rekeySaRecord.mSaLifetimeAlarmScheduler.scheduleLifetimeExpiryAlarm( 1576 anyString()); 1577 return rekeySaRecord; 1578 }); 1579 } 1580 throwExceptionWhenMakeRekeyIkeSa(Exception exception)1581 private void throwExceptionWhenMakeRekeyIkeSa(Exception exception) throws Exception { 1582 // Inject IkeSaRecord and release IKE SPI resource since we will lose their references 1583 // later. 1584 when(mMockSaRecordHelper.makeRekeyedIkeSaRecord( 1585 eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any())) 1586 .thenAnswer( 1587 (invocation) -> { 1588 captureAndReleaseIkeSpiResource(invocation, 4); 1589 throw exception; 1590 }); 1591 } 1592 captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex)1593 private void captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex) { 1594 IkeSaRecordConfig config = (IkeSaRecordConfig) invocation.getArguments()[ikeConfigIndex]; 1595 config.initSpi.close(); 1596 config.respSpi.close(); 1597 } 1598 setupDnsResolutionForNetwork( Network network, int dnsLookupsForSuccess, InetAddress remoteAddress)1599 private void setupDnsResolutionForNetwork( 1600 Network network, int dnsLookupsForSuccess, InetAddress remoteAddress) 1601 throws Exception { 1602 doAnswer(new Answer() { 1603 private int mAttempedDnsLookups = 0; 1604 1605 public Object answer(InvocationOnMock invocation) throws IOException { 1606 mAttempedDnsLookups++; 1607 if (mAttempedDnsLookups < dnsLookupsForSuccess) { 1608 throw new UnknownHostException("DNS failed"); 1609 } else { 1610 return new InetAddress[] {remoteAddress}; 1611 } 1612 } 1613 }).when(network).getAllByName(REMOTE_HOSTNAME); 1614 } 1615 verifyIkeMetricsLogged(int stateCode, int exceptionCode)1616 private void verifyIkeMetricsLogged(int stateCode, int exceptionCode) { 1617 verifyMetricsLogged(IkeMetrics.IKE_SESSION_TYPE_IKE, stateCode, exceptionCode); 1618 } 1619 verifyFireCallbackOnDnsFailure(IkeSessionCallback callback, IState expectedState)1620 private void verifyFireCallbackOnDnsFailure(IkeSessionCallback callback, IState expectedState) { 1621 if (SdkLevel.isAtLeastT()) { 1622 verify(callback).onClosedWithException( 1623 argThat(e -> e instanceof IkeIOException 1624 && e.getCause() instanceof UnknownHostException)); 1625 verifyIkeMetricsLogged( 1626 getStateCode(expectedState), IkeMetrics.IKE_ERROR_IO_DNS_FAILURE); 1627 } else { 1628 verify(callback).onClosedWithException( 1629 argThat(e -> e instanceof IkeInternalException 1630 && e.getCause() instanceof IOException)); 1631 verifyIkeMetricsLogged(getStateCode(expectedState), IkeMetrics.IKE_ERROR_INTERNAL); 1632 } 1633 } 1634 setupAndVerifyDnsResolutionForIkeSession( int dnsLookupsForSuccess, int expectedDnsLookups, boolean expectSessionClosed)1635 private void setupAndVerifyDnsResolutionForIkeSession( 1636 int dnsLookupsForSuccess, int expectedDnsLookups, boolean expectSessionClosed) 1637 throws Exception { 1638 mIkeSessionStateMachine.quitNow(); 1639 1640 // Reset the network to ignore DNS resolution from mIkeSessionStateMachine creation in 1641 // setUp() 1642 resetDefaultNetwork(); 1643 1644 setupDnsResolutionForNetwork(mMockDefaultNetwork, dnsLookupsForSuccess, REMOTE_ADDRESS); 1645 1646 IkeSessionParams ikeParams = 1647 buildIkeSessionParamsCommon() 1648 .setAuthPsk(mPsk) 1649 .setServerHostname(REMOTE_HOSTNAME) 1650 .build(); 1651 mIkeSessionStateMachine = 1652 makeAndStartIkeSession( 1653 ikeParams, 1654 LOCAL_ADDRESS, 1655 expectSessionClosed ? null : REMOTE_ADDRESS); 1656 1657 verify(mMockDefaultNetwork, times(expectedDnsLookups)).getAllByName(REMOTE_HOSTNAME); 1658 if (expectSessionClosed) { 1659 assertNull(mIkeSessionStateMachine.getCurrentState()); 1660 verifyFireCallbackOnDnsFailure( 1661 mMockIkeSessionCallback, mIkeSessionStateMachine.mInitial); 1662 } 1663 } 1664 1665 @Test testResolveRemoteHostName()1666 public void testResolveRemoteHostName() throws Exception { 1667 setupAndVerifyDnsResolutionForIkeSession( 1668 1 /* dnsLookupsForSuccess */, 1669 1 /* expectedDnsLookups */, 1670 false /* expectSessionClosed */); 1671 } 1672 1673 @Test testResolveRemoteHostNameWithDnsRetries()1674 public void testResolveRemoteHostNameWithDnsRetries() throws Exception { 1675 setupAndVerifyDnsResolutionForIkeSession( 1676 2 /* dnsLookupsForSuccess */, 1677 2 /* expectedDnsLookups */, 1678 false /* expectSessionClosed */); 1679 } 1680 1681 @Test testResolveRemoteHostNameWithDnsFailure()1682 public void testResolveRemoteHostNameWithDnsFailure() throws Exception { 1683 // Require more lookups for successful DNS than IKE allows to force failure 1684 setupAndVerifyDnsResolutionForIkeSession( 1685 4 /* dnsLookupsForSuccess */, 1686 3 /* expectedDnsLookups */, 1687 true /* expectSessionClosed */); 1688 } 1689 verifyTestMode(boolean isTestNetwork)1690 private void verifyTestMode(boolean isTestNetwork) throws Exception { 1691 doReturn(isTestNetwork) 1692 .when(mMockNetworkCapabilities) 1693 .hasTransport(RandomnessFactory.TRANSPORT_TEST); 1694 1695 Network network = mockNewNetworkAndAddress(true /*isIpv4*/); 1696 IkeSessionParams ikeParams = 1697 buildIkeSessionParamsCommon() 1698 .setNetwork(network) 1699 .setAuthPsk("psk".getBytes()) 1700 .build(); 1701 1702 // Clear #getActiveNetwork() call in #setUp() to pass the verification in 1703 // #makeAndStartIkeSession() 1704 resetMockConnectManager(); 1705 setupLocalAddressForNetwork(network, LOCAL_ADDRESS); 1706 setupRemoteAddressForNetwork(network, REMOTE_ADDRESS); 1707 IkeSessionStateMachine ikeSession = makeAndStartIkeSession(ikeParams); 1708 1709 SecureRandom random = ikeSession.mIkeContext.getRandomnessFactory().getRandom(); 1710 if (isTestNetwork) { 1711 assertNotNull(random); 1712 assertTrue(random instanceof DeterministicSecureRandom); 1713 } else { 1714 assertNull(random); 1715 } 1716 } 1717 1718 @Test testEnableTestMode()1719 public void testEnableTestMode() throws Exception { 1720 verifyTestMode(true /* isTestNetwork */); 1721 } 1722 1723 @Test testDisableTestMode()1724 public void testDisableTestMode() throws Exception { 1725 verifyTestMode(false /* isTestNetwork */); 1726 } 1727 verifyOutboundKePayload(int expectedDhGroup)1728 private void verifyOutboundKePayload(int expectedDhGroup) { 1729 verify(mMockIkeMessageHelper, atLeastOnce()).encode(mIkeMessageCaptor.capture()); 1730 IkeMessage reqMsg = mIkeMessageCaptor.getValue(); 1731 IkeKePayload kePayload = 1732 reqMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class); 1733 assertEquals(expectedDhGroup, kePayload.dhGroup); 1734 } 1735 1736 @Test testCreateIkeLocalIkeInit_closeSpi_ikeTerminated()1737 public void testCreateIkeLocalIkeInit_closeSpi_ikeTerminated() throws Exception { 1738 // Setup 1739 final IkeSecurityParameterIndex mockIkeSpi = mock(IkeSecurityParameterIndex.class); 1740 doReturn(mockIkeSpi).when(mSpyIkeSpiGenerator).allocateSpi(any(InetAddress.class)); 1741 1742 // Send out IKE INIT request 1743 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1744 mLooper.dispatchAll(); 1745 1746 // Verifications 1747 verify(mSpyIkeSpiGenerator).allocateSpi(any(InetAddress.class)); 1748 1749 mIkeSessionStateMachine.killSession(); 1750 mLooper.dispatchAll(); 1751 1752 verify(mockIkeSpi).close(); 1753 } 1754 1755 @Test testRekeyIkeLocalCreate_closeSpi_ikeTerminated()1756 public void testRekeyIkeLocalCreate_closeSpi_ikeTerminated() throws Exception { 1757 // Setup 1758 setupIdleStateMachine(); 1759 final IkeSecurityParameterIndex mockIkeSpi = mock(IkeSecurityParameterIndex.class); 1760 doReturn(mockIkeSpi).when(mSpyIkeSpiGenerator).allocateSpi(any(InetAddress.class)); 1761 1762 // Send Rekey-Create request 1763 mIkeSessionStateMachine.sendMessage( 1764 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 1765 mLocalRequestFactory.getIkeLocalRequest( 1766 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 1767 mLooper.dispatchAll(); 1768 1769 // Verifications 1770 verify(mSpyIkeSpiGenerator).allocateSpi(any(InetAddress.class)); 1771 1772 mIkeSessionStateMachine.killSession(); 1773 mLooper.dispatchAll(); 1774 1775 verify(mockIkeSpi).close(); 1776 } 1777 1778 @Test testCreateIkeLocalIkeInitNegotiatesDhGroup()1779 public void testCreateIkeLocalIkeInitNegotiatesDhGroup() throws Exception { 1780 // Clear the calls triggered by starting IkeSessionStateMachine in #setup() 1781 reset(mSpyIkeConnectionCtrl); 1782 1783 setupFirstIkeSa(); 1784 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1785 mLooper.dispatchAll(); 1786 1787 // Verify we started with the top proposed DH group 1788 verifyOutboundKePayload(SaProposal.DH_GROUP_1024_BIT_MODP); 1789 1790 // Send back a INVALID_KE_PAYLOAD, and verify that the selected DH group changes 1791 resetMockIkeMessageHelper(); 1792 ReceivedIkePacket resp = 1793 makeDummyReceivedIkeInitRespPacket( 1794 Arrays.asList(IkePayload.PAYLOAD_TYPE_NOTIFY), 1795 Arrays.asList(INVALID_KE_PAYLOAD_HEX_STRING)); 1796 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 1797 mLooper.dispatchAll(); 1798 1799 verifyOutboundKePayload(SaProposal.DH_GROUP_2048_BIT_MODP); 1800 verify(mSpyIkeConnectionCtrl, atLeast(1)).tearDown(); 1801 verifyIkeSaMetricsLogged( 1802 1, 1803 IkeMetrics.IKE_CALLER_UNKNOWN, 1804 IkeMetrics.IKE_SESSION_TYPE_IKE, 1805 IkeMetrics.IKE_STATE_IKE_CREATE_LOCAL_IKE_INIT, 1806 SaProposal.DH_GROUP_2048_BIT_MODP, 1807 IkeMetrics.ENCRYPTION_ALGORITHM_UNSPECIFIED, 1808 IkeMetrics.KEY_LEN_UNSPECIFIED, 1809 IkeMetrics.INTEGRITY_ALGORITHM_NONE, 1810 IkeMetrics.PSEUDORANDOM_FUNCTION_UNSPECIFIED, 1811 IkeMetrics.IKE_ERROR_PROTOCOL_INVALID_KE_PAYLOAD); 1812 } 1813 getIkeInitRespWithCookie()1814 private ReceivedIkePacket getIkeInitRespWithCookie() throws Exception { 1815 IkeNotifyPayload inCookieNotify = new IkeNotifyPayload(NOTIFY_TYPE_COOKIE, COOKIE_DATA); 1816 List<IkePayload> payloads = new ArrayList<>(); 1817 payloads.add(inCookieNotify); 1818 return makeDummyReceivedIkeInitRespPacket(payloads); 1819 } 1820 1821 @Test testCreateIkeLocalIkeInitReceivesCookie()1822 public void testCreateIkeLocalIkeInitReceivesCookie() throws Exception { 1823 setupFirstIkeSa(); 1824 1825 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1826 mLooper.dispatchAll(); 1827 1828 // Encode 2 times: one for mIkeInitRequestBytes and one for sending packets 1829 verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture()); 1830 IkeMessage originalReqMsg = mIkeMessageCaptor.getValue(); 1831 List<IkePayload> originalPayloadList = originalReqMsg.ikePayloadList; 1832 1833 // Reset to forget sending original IKE INIT request 1834 resetMockIkeMessageHelper(); 1835 1836 // Send back a Notify-Cookie 1837 ReceivedIkePacket resp = getIkeInitRespWithCookie(); 1838 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 1839 mLooper.dispatchAll(); 1840 1841 // Verify retry IKE INIT request 1842 verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture()); 1843 IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue(); 1844 List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList; 1845 1846 IkeNotifyPayload outCookieNotify = (IkeNotifyPayload) payloadList.get(0); 1847 assertEquals(NOTIFY_TYPE_COOKIE, outCookieNotify.notifyType); 1848 assertArrayEquals(COOKIE_DATA, outCookieNotify.notifyData); 1849 1850 // First 4 payloads MUST follow RFC 4306 so that IKE library can be compatible with old 1851 // implementations. 1852 int[] expectedPayloadType = 1853 new int[] { 1854 PAYLOAD_TYPE_NOTIFY, PAYLOAD_TYPE_SA, PAYLOAD_TYPE_KE, PAYLOAD_TYPE_NONCE 1855 }; 1856 int len = expectedPayloadType.length; 1857 for (int i = 0; i < len; i++) { 1858 assertEquals(expectedPayloadType[i], payloadList.get(i).payloadType); 1859 } 1860 1861 assertEquals(originalPayloadList, payloadList.subList(1, payloadList.size())); 1862 1863 assertTrue( 1864 mIkeSessionStateMachine.getCurrentState() 1865 instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit); 1866 } 1867 1868 @Test testCreateIkeLocalIkeInitRcvRespAfterRcvCookie()1869 public void testCreateIkeLocalIkeInitRcvRespAfterRcvCookie() throws Exception { 1870 setupFirstIkeSa(); 1871 1872 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1873 mLooper.dispatchAll(); 1874 1875 // Receive IKE INIT response with Cookie 1876 mIkeSessionStateMachine.sendMessage( 1877 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, getIkeInitRespWithCookie()); 1878 1879 // Receive IKE INIT response 1880 mIkeSessionStateMachine.sendMessage( 1881 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, makeIkeInitResponse()); 1882 mLooper.dispatchAll(); 1883 1884 assertTrue( 1885 mIkeSessionStateMachine.getCurrentState() 1886 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 1887 verifyIkeSaNegotiationResult(); 1888 } 1889 1890 @Test testCreateIkeLocalIkeInitSwitchesToEncapPortsIpv4()1891 public void testCreateIkeLocalIkeInitSwitchesToEncapPortsIpv4() throws Exception { 1892 setupFirstIkeSa(); 1893 assertFalse(mSpyIkeConnectionCtrl.useUdpEncapSocket()); 1894 1895 triggerAndVerifyIkeInitReq(true /* expectingNatDetection */, true /* expectingFakedNatd */); 1896 1897 receiveAndGetIkeInitResp(); 1898 1899 assertTrue(mSpyIkeConnectionCtrl.useUdpEncapSocket()); 1900 assertEquals(NAT_DETECTED, mSpyIkeConnectionCtrl.getNatStatus()); 1901 1902 verify(mMockIkeUdp4Socket).unregisterIke(anyLong()); 1903 } 1904 restartIkeSessionWithEnforcePort4500AndVerifyIkeSocket()1905 private void restartIkeSessionWithEnforcePort4500AndVerifyIkeSocket() throws Exception { 1906 // Quit and start a new IKE Session with IKE_OPTION_FORCE_PORT_4500 1907 mIkeSessionStateMachine.quitNow(); 1908 IkeSessionParams ikeParams = 1909 buildIkeSessionParamsWithIkeOptions(IKE_OPTION_FORCE_PORT_4500); 1910 mIkeSessionStateMachine = makeAndStartIkeSession(ikeParams); 1911 mLooper.dispatchAll(); 1912 1913 assertTrue(mSpyIkeConnectionCtrl.useUdpEncapSocket()); 1914 } 1915 1916 @Test testInitialStateWithEnforcePort4500()1917 public void testInitialStateWithEnforcePort4500() throws Exception { 1918 restartIkeSessionWithEnforcePort4500AndVerifyIkeSocket(); 1919 } 1920 1921 @Test testCreateIkeLocalIkeInitNatTraversalWithEnforcePort4500()1922 public void testCreateIkeLocalIkeInitNatTraversalWithEnforcePort4500() throws Exception { 1923 restartIkeSessionWithEnforcePort4500AndVerifyIkeSocket(); 1924 setupFirstIkeSa(); 1925 assertTrue(mSpyIkeConnectionCtrl.useUdpEncapSocket()); 1926 1927 triggerAndVerifyIkeInitReq(true /* expectingNatDetection */, true /* expectingFakedNatd */); 1928 1929 receiveAndGetIkeInitResp(); 1930 1931 assertTrue(mSpyIkeConnectionCtrl.useUdpEncapSocket()); 1932 assertEquals(NAT_DETECTED, mSpyIkeConnectionCtrl.getNatStatus()); 1933 } 1934 1935 @Test testCreateIkeLocalIkeInitNatTraversalNotSupported()1936 public void testCreateIkeLocalIkeInitNatTraversalNotSupported() throws Exception { 1937 setupFirstIkeSa(); 1938 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1939 mLooper.dispatchAll(); 1940 1941 // Receive IKE INIT response 1942 ReceivedIkePacket dummyReceivedIkePacket = 1943 makeIkeInitResponseWithRequiredPayloads( 1944 Collections.emptyList(), Collections.emptyList()); 1945 mIkeSessionStateMachine.sendMessage( 1946 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 1947 mLooper.dispatchAll(); 1948 1949 // Validate socket switched 1950 assertEquals(mMockIkeUdp4Socket, mSpyIkeConnectionCtrl.getIkeSocket()); 1951 assertEquals(NAT_TRAVERSAL_UNSUPPORTED, mSpyIkeConnectionCtrl.getNatStatus()); 1952 verify(mMockIkeUdp4Socket, never()).unregisterIke(anyLong()); 1953 } 1954 verifyNatdSrcIpFromIkeInitReqMessage(IkeMessage ikeInitReqMessag)1955 private void verifyNatdSrcIpFromIkeInitReqMessage(IkeMessage ikeInitReqMessag) { 1956 verifyNatdSrcIpFromIkeInitReqMessage(ikeInitReqMessag, false /* expectingFakedNatd */); 1957 } 1958 verifyNatdSrcIpFromIkeInitReqMessage( IkeMessage ikeInitReqMessage, boolean expectingFakedNatd)1959 private void verifyNatdSrcIpFromIkeInitReqMessage( 1960 IkeMessage ikeInitReqMessage, boolean expectingFakedNatd) { 1961 List<IkeNotifyPayload> notifyPayloads = 1962 ikeInitReqMessage.getPayloadListForType( 1963 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 1964 IkeNotifyPayload natdSrcIpPayload = null; 1965 for (IkeNotifyPayload notifyPayload : notifyPayloads) { 1966 if (notifyPayload.notifyType == NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP) { 1967 natdSrcIpPayload = notifyPayload; 1968 } 1969 } 1970 assertNotNull(natdSrcIpPayload); 1971 1972 byte[] localNatDataNotFaked = 1973 IkeNotifyPayload.generateNatDetectionData( 1974 ikeInitReqMessage.ikeHeader.ikeInitiatorSpi, 1975 ikeInitReqMessage.ikeHeader.ikeResponderSpi, 1976 mSpyIkeConnectionCtrl.getLocalAddress(), 1977 mSpyIkeConnectionCtrl.getLocalPort()); 1978 1979 assertEquals( 1980 !expectingFakedNatd, 1981 Arrays.equals(localNatDataNotFaked, natdSrcIpPayload.notifyData)); 1982 } 1983 triggerAndVerifyIkeInitReq(boolean expectingNatDetection)1984 private void triggerAndVerifyIkeInitReq(boolean expectingNatDetection) throws Exception { 1985 triggerAndVerifyIkeInitReq(expectingNatDetection, false); 1986 } 1987 triggerAndVerifyIkeInitReq( boolean expectingNatDetection, boolean expectingFakedNatd)1988 private void triggerAndVerifyIkeInitReq( 1989 boolean expectingNatDetection, boolean expectingFakedNatd) throws Exception { 1990 // Send IKE INIT request 1991 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 1992 mLooper.dispatchAll(); 1993 verifyRetransmissionStarted(); 1994 1995 // Validate outbound IKE INIT request 1996 verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture()); 1997 IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue(); 1998 1999 IkeHeader ikeHeader = ikeInitReqMessage.ikeHeader; 2000 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, ikeHeader.exchangeType); 2001 assertFalse(ikeHeader.isResponseMsg); 2002 assertTrue(ikeHeader.fromIkeInitiator); 2003 2004 List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList; 2005 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_SA)); 2006 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_KE)); 2007 assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_NONCE)); 2008 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED)); 2009 assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_SIGNATURE_HASH_ALGORITHMS)); 2010 2011 assertEquals( 2012 expectingNatDetection, 2013 isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP)); 2014 assertEquals( 2015 expectingNatDetection, 2016 isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP)); 2017 2018 if (expectingNatDetection) { 2019 verifyNatdSrcIpFromIkeInitReqMessage(ikeInitReqMessage, expectingFakedNatd); 2020 } 2021 } 2022 receiveAndGetIkeInitResp()2023 private ReceivedIkePacket receiveAndGetIkeInitResp() throws Exception { 2024 ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); 2025 mIkeSessionStateMachine.sendMessage( 2026 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 2027 mLooper.dispatchAll(); 2028 verifyIncrementLocaReqMsgId(); 2029 verifyIkeSaMetricsLogged( 2030 1, 2031 IkeMetrics.IKE_CALLER_UNKNOWN, 2032 IkeMetrics.IKE_SESSION_TYPE_IKE, 2033 IkeMetrics.IKE_STATE_IKE_CREATE_LOCAL_IKE_INIT, 2034 SaProposal.DH_GROUP_1024_BIT_MODP, 2035 IkeMetrics.ENCRYPTION_ALGORITHM_AES_CBC, 2036 IkeMetrics.KEY_LEN_AES_128, 2037 IkeMetrics.INTEGRITY_ALGORITHM_HMAC_SHA1_96, 2038 IkeMetrics.PSEUDORANDOM_FUNCTION_HMAC_SHA1, 2039 IkeMetrics.IKE_ERROR_NONE); 2040 return dummyReceivedIkePacket; 2041 } 2042 2043 @Test 2044 @SdkSuppress(minSdkVersion = 31, codeName = "S") testCreateIkeLocalIkeInitWithoutIpv6NatD()2045 public void testCreateIkeLocalIkeInitWithoutIpv6NatD() throws Exception { 2046 mIkeSessionStateMachine.quitNow(); 2047 resetMockConnectManager(); 2048 resetMockIkeMessageHelper(); 2049 2050 // Restart mIkeSessionStateMachine so it uses IPv6 addresses 2051 final Network v6OnlyNetwork = 2052 mockNewNetworkAndAddress(false /* isIpv4 */, LOCAL_ADDRESS_V6, REMOTE_ADDRESS_V6); 2053 final IkeSessionParams params = 2054 buildIkeSessionParamsCommon() 2055 .setAuthPsk(mPsk) 2056 .setNetwork(v6OnlyNetwork) 2057 .addIkeOption(IKE_OPTION_MOBIKE) 2058 .build(); 2059 mIkeSessionStateMachine = 2060 makeAndStartIkeSession( 2061 params, 2062 LOCAL_ADDRESS_V6, 2063 REMOTE_ADDRESS_V6); 2064 setupFirstIkeSa(); 2065 2066 triggerAndVerifyIkeInitReq(false /* expectingNatDetection */); 2067 receiveAndGetIkeInitResp(); 2068 2069 assertTrue(mSpyIkeConnectionCtrl.getIkeSocket() instanceof IkeUdp6Socket); 2070 assertEquals(NAT_TRAVERSAL_SUPPORT_NOT_CHECKED, mSpyIkeConnectionCtrl.getNatStatus()); 2071 } 2072 2073 @Ignore disableTestCreateIkeLocalIkeInit()2074 public void disableTestCreateIkeLocalIkeInit() throws Exception { 2075 setupFirstIkeSa(); 2076 2077 triggerAndVerifyIkeInitReq(true /* expectingNatDetection */); 2078 final ReceivedIkePacket dummyReceivedIkePacket = receiveAndGetIkeInitResp(); 2079 2080 verify(mMockCurrentIkeSocket) 2081 .registerIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi()), eq(mSpyIkeConnectionCtrl)); 2082 2083 verify(mMockIkeMessageHelper) 2084 .decode(0, dummyReceivedIkePacket.ikeHeader, dummyReceivedIkePacket.ikePacketBytes); 2085 assertTrue( 2086 mIkeSessionStateMachine.getCurrentState() 2087 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 2088 verifyRetransmissionStarted(); 2089 verifyIkeSaNegotiationResult(); 2090 } 2091 verifyIkeSaNegotiationResult()2092 private void verifyIkeSaNegotiationResult() throws Exception { 2093 // Validate negotiated SA proposal. 2094 IkeSaProposal negotiatedProposal = mIkeSessionStateMachine.mSaProposal; 2095 assertNotNull(negotiatedProposal); 2096 2097 assertEquals( 2098 new EncryptionTransform[] {mIkeEncryptionTransform}, 2099 negotiatedProposal.getEncryptionTransforms()); 2100 assertEquals( 2101 new IntegrityTransform[] {mIkeIntegrityTransform}, 2102 negotiatedProposal.getIntegrityTransforms()); 2103 assertEquals(new PrfTransform[] {mIkePrfTransform}, negotiatedProposal.getPrfTransforms()); 2104 2105 // Validate current IkeSaRecord. 2106 verify(mMockSaRecordHelper) 2107 .makeFirstIkeSaRecord( 2108 any(IkeMessage.class), 2109 any(IkeMessage.class), 2110 mIkeSaRecordConfigCaptor.capture()); 2111 2112 IkeSaRecordConfig ikeSaRecordConfig = mIkeSaRecordConfigCaptor.getValue(); 2113 assertEquals(KEY_LEN_IKE_PRF, ikeSaRecordConfig.prf.getKeyLength()); 2114 assertEquals(KEY_LEN_IKE_INTE, ikeSaRecordConfig.integrityKeyLength); 2115 assertEquals(KEY_LEN_IKE_ENCR, ikeSaRecordConfig.encryptionKeyLength); 2116 assertNotNull(ikeSaRecordConfig.saLifetimeAlarmScheduler); 2117 2118 // Validate NAT detection 2119 assertEquals(NAT_DETECTED, mSpyIkeConnectionCtrl.getNatStatus()); 2120 2121 // Validate vendor IDs 2122 List<byte[]> vendorIds = new ArrayList<>(); 2123 vendorIds.add(REMOTE_VENDOR_ID_ONE); 2124 assertByteArrayListEquals(vendorIds, mIkeSessionStateMachine.mRemoteVendorIds); 2125 2126 // Validate fragmentation support negotiation 2127 assertEquals( 2128 Arrays.asList(EXTENSION_TYPE_FRAGMENTATION), 2129 mIkeSessionStateMachine.mEnabledExtensions); 2130 2131 // Validate Signature Hash Algorithms received in IKE INIT response 2132 Set<Short> expectedHashAlgos = new HashSet<Short>(); 2133 for (short algo : IkeAuthDigitalSignPayload.ALL_SIGNATURE_ALGO_TYPES) { 2134 expectedHashAlgos.add(algo); 2135 } 2136 assertEquals( 2137 expectedHashAlgos, 2138 ((CreateIkeLocalIkeAuth) mIkeSessionStateMachine.mCreateIkeLocalIkeAuth) 2139 .mSetupData 2140 .peerSignatureHashAlgorithms); 2141 } 2142 setIkeInitResults()2143 private void setIkeInitResults() throws Exception { 2144 mIkeSessionStateMachine.mIkeCipher = mock(IkeCipher.class); 2145 mIkeSessionStateMachine.mIkeIntegrity = mock(IkeMacIntegrity.class); 2146 mIkeSessionStateMachine.mIkePrf = mock(IkeMacPrf.class); 2147 mIkeSessionStateMachine.mSaProposal = buildNegotiatedSaProposal(); 2148 mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyCurrentIkeSaRecord; 2149 mIkeSessionStateMachine.mRemoteVendorIds = 2150 Arrays.asList(REMOTE_VENDOR_ID_ONE, REMOTE_VENDOR_ID_TWO); 2151 mIkeSessionStateMachine.mEnabledExtensions.add(EXTENSION_TYPE_FRAGMENTATION); 2152 mIkeSessionStateMachine.addIkeSaRecord(mSpyCurrentIkeSaRecord); 2153 2154 mSpyIkeConnectionCtrl.handleNatDetectionResultInIkeInit( 2155 false /* isNatDetected */, mSpyCurrentIkeSaRecord.getLocalSpi()); 2156 mMockCurrentIkeSocket = mSpyIkeConnectionCtrl.getIkeSocket(); 2157 } 2158 2159 /** Initializes the mIkeSessionStateMachine in the IDLE state. */ setupIdleStateMachine()2160 private void setupIdleStateMachine() throws Exception { 2161 verify(mMockBusyWakelock).acquire(); 2162 2163 setIkeInitResults(); 2164 2165 mIkeSessionStateMachine.sendMessage( 2166 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 2167 mLooper.dispatchAll(); 2168 2169 mDummyChildSmCallback = 2170 createChildAndGetChildSessionSmCallback( 2171 mMockChildSessionStateMachine, CHILD_SPI_REMOTE, mMockChildSessionCallback); 2172 2173 assertTrue( 2174 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2175 2176 verify(mMockBusyWakelock).release(); 2177 2178 // For convenience to verify wakelocks in all other places. 2179 reset(mMockBusyWakelock); 2180 } 2181 2182 private abstract class IkeAuthTestPretestBase { 2183 protected IkeInitData mIkeInitData; 2184 IkeAuthTestPretestBase()2185 IkeAuthTestPretestBase() { 2186 this(new HashSet<>() /* peerSignatureHashAlgorithms */); 2187 } 2188 IkeAuthTestPretestBase(Set<Short> peerSignatureHashAlgorithms)2189 IkeAuthTestPretestBase(Set<Short> peerSignatureHashAlgorithms) { 2190 InitialSetupData initialSetupData = 2191 new InitialSetupData( 2192 mChildSessionParams, 2193 mMockChildSessionCallback, 2194 SaProposal.DH_GROUP_1024_BIT_MODP); 2195 2196 mIkeInitData = 2197 new IkeInitData( 2198 initialSetupData, 2199 new byte[0], 2200 new byte[0], 2201 new IkeNoncePayload(createMockRandomFactory()), 2202 new IkeNoncePayload(createMockRandomFactory()), 2203 peerSignatureHashAlgorithms); 2204 } 2205 mockIkeInitAndTransitionToIkeAuth()2206 public void mockIkeInitAndTransitionToIkeAuth() throws Exception { 2207 setIkeInitResults(); 2208 2209 // Need to create a real IkeMacPrf instance for authentication because we cannot inject 2210 // a method stub for IkeMacPrf#signBytes. IkeMacPrf#signBytes is inherited from a 2211 // package protected class IkePrf. We don't have the visibility to mock it. 2212 mIkeSessionStateMachine.mIkePrf = 2213 IkeMacPrf.create(new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)); 2214 2215 performStateTransition(); 2216 } 2217 performStateTransition()2218 abstract void performStateTransition() throws Exception; 2219 } 2220 2221 private final class IkeFirstAuthTestPretest extends IkeAuthTestPretestBase { IkeFirstAuthTestPretest()2222 IkeFirstAuthTestPretest() { 2223 super(); 2224 } 2225 IkeFirstAuthTestPretest(Set<Short> peerSignatureHashAlgorithms)2226 IkeFirstAuthTestPretest(Set<Short> peerSignatureHashAlgorithms) { 2227 super(peerSignatureHashAlgorithms); 2228 } 2229 2230 @Override performStateTransition()2231 void performStateTransition() throws Exception { 2232 mIkeSessionStateMachine.mCreateIkeLocalIkeAuth.setIkeSetupData(mIkeInitData); 2233 mIkeSessionStateMachine.sendMessage( 2234 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 2235 mIkeSessionStateMachine.mCreateIkeLocalIkeAuth); 2236 mLooper.dispatchAll(); 2237 } 2238 } 2239 2240 private abstract class IkeAuthEapTestPretestBase extends IkeAuthTestPretestBase { 2241 protected IkeAuthData mIkeAuthData; 2242 IkeAuthEapTestPretestBase(IkeIdPayload initIdPayload, IkeIdPayload respIdPayload)2243 IkeAuthEapTestPretestBase(IkeIdPayload initIdPayload, IkeIdPayload respIdPayload) 2244 throws Exception { 2245 super(); 2246 List<Integer> payloadTypeList = new ArrayList<>(); 2247 List<String> payloadHexStringList = new ArrayList<>(); 2248 2249 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA); 2250 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR); 2251 payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER); 2252 2253 payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING); 2254 payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING); 2255 payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING); 2256 2257 List<IkePayload> firstChildReqList = 2258 hexStrListToIkePayloadList( 2259 payloadTypeList, payloadHexStringList, false /*isResp*/); 2260 mIkeAuthData = 2261 new IkeAuthData(mIkeInitData, initIdPayload, respIdPayload, firstChildReqList); 2262 } 2263 } 2264 buildMockIkeIdPayload()2265 private static IkeIdPayload buildMockIkeIdPayload() { 2266 IkeIdPayload idPayload = mock(IkeIdPayload.class); 2267 doReturn(new byte[0]).when(idPayload).getEncodedPayloadBody(); 2268 return idPayload; 2269 } 2270 2271 private final class IkeAuthInEapTestPretest extends IkeAuthEapTestPretestBase { IkeAuthInEapTestPretest()2272 IkeAuthInEapTestPretest() throws Exception { 2273 super(buildMockIkeIdPayload(), buildMockIkeIdPayload()); 2274 } 2275 2276 @Override performStateTransition()2277 void performStateTransition() throws Exception { 2278 mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap.setIkeSetupData(mIkeAuthData); 2279 mIkeSessionStateMachine.sendMessage( 2280 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 2281 mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap); 2282 mLooper.dispatchAll(); 2283 } 2284 } 2285 2286 private final class IkeAuthPostEapTestPretest extends IkeAuthEapTestPretestBase { IkeAuthPostEapTestPretest(IkeIdPayload initIdPayload, IkeIdPayload respIdPayload)2287 IkeAuthPostEapTestPretest(IkeIdPayload initIdPayload, IkeIdPayload respIdPayload) 2288 throws Exception { 2289 super(initIdPayload, respIdPayload); 2290 } 2291 2292 @Override performStateTransition()2293 void performStateTransition() throws Exception { 2294 mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap.setIkeSetupData(mIkeAuthData); 2295 mIkeSessionStateMachine.sendMessage( 2296 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 2297 mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap); 2298 mLooper.dispatchAll(); 2299 } 2300 } 2301 2302 /** 2303 * Utility to register a new callback -> state machine mapping. 2304 * 2305 * <p>Must be used if IkeSessionStateMachine.openChildSession() is not called, but commands 2306 * injected instead. 2307 * 2308 * @param callback The callback to be used for the mapping 2309 * @param sm The ChildSessionStateMachine instance to be used. 2310 */ registerChildStateMachine( ChildSessionCallback callback, ChildSessionStateMachine sm)2311 private void registerChildStateMachine( 2312 ChildSessionCallback callback, ChildSessionStateMachine sm) { 2313 injectChildSessionInSpyDeps(mSpyDeps, sm, callback); 2314 mIkeSessionStateMachine.registerChildSessionCallback( 2315 mChildSessionParams, callback, false /*isFirstChild*/); 2316 } 2317 verifyMakeChildAndReturnChildSmCb( ChildSessionCallback expectedChildSessionCb)2318 private IChildSessionSmCallback verifyMakeChildAndReturnChildSmCb( 2319 ChildSessionCallback expectedChildSessionCb) { 2320 ArgumentCaptor<IkeContext> ikeContextCaptor = ArgumentCaptor.forClass(IkeContext.class); 2321 verify(mSpyDeps) 2322 .newChildSessionStateMachine( 2323 ikeContextCaptor.capture(), 2324 any(ChildSessionStateMachine.Config.class), 2325 eq(expectedChildSessionCb), 2326 mChildSessionSmCbCaptor.capture()); 2327 2328 IkeContext ikeContext = ikeContextCaptor.getValue(); 2329 assertEquals(mLooper.getLooper(), ikeContext.getLooper()); 2330 assertEquals(mSpyContext, ikeContext.getContext()); 2331 2332 return mChildSessionSmCbCaptor.getValue(); 2333 } 2334 2335 @Test testCreateAdditionalChild()2336 public void testCreateAdditionalChild() throws Exception { 2337 setupIdleStateMachine(); 2338 2339 ChildSessionCallback childCallback = mock(ChildSessionCallback.class); 2340 ChildSessionStateMachine childStateMachine = mock(ChildSessionStateMachine.class); 2341 registerChildStateMachine(childCallback, childStateMachine); 2342 2343 mIkeSessionStateMachine.sendMessage( 2344 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 2345 mLocalRequestFactory.getChildLocalRequest( 2346 IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_CHILD, 2347 childCallback, 2348 mChildSessionParams)); 2349 mLooper.dispatchAll(); 2350 2351 assertTrue( 2352 mIkeSessionStateMachine.getCurrentState() 2353 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2354 verify(childStateMachine) 2355 .createChildSession( 2356 eq(LOCAL_ADDRESS), 2357 eq(REMOTE_ADDRESS), 2358 any(), // udpEncapSocket 2359 eq(mIkeSessionStateMachine.mIkePrf), 2360 eq(mIkeSessionStateMachine.mSaProposal.getDhGroupTransforms()[0].id), 2361 any()); // sk_d 2362 2363 IChildSessionSmCallback cb = verifyMakeChildAndReturnChildSmCb(childCallback); 2364 2365 // Mocking sending request 2366 cb.onOutboundPayloadsReady( 2367 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 2368 false /*isResp*/, 2369 new ArrayList<>(), 2370 childStateMachine); 2371 mLooper.dispatchAll(); 2372 verifyRetransmissionStarted(); 2373 2374 IkeMessage createChildRequest = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 2375 2376 IkeHeader ikeHeader = createChildRequest.ikeHeader; 2377 assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); 2378 assertFalse(ikeHeader.isResponseMsg); 2379 assertTrue(ikeHeader.fromIkeInitiator); 2380 assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); 2381 assertTrue(createChildRequest.ikePayloadList.isEmpty()); 2382 2383 assertTrue( 2384 mIkeSessionStateMachine.getCurrentState() 2385 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2386 2387 // Mocking receiving response 2388 ReceivedIkePacket dummyCreateChildResp = makeCreateChildCreateMessage(true /*isResp*/); 2389 mIkeSessionStateMachine.sendMessage( 2390 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyCreateChildResp); 2391 mLooper.dispatchAll(); 2392 2393 verifyIncrementLocaReqMsgId(); 2394 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyCreateChildResp); 2395 2396 verify(childStateMachine) 2397 .receiveResponse( 2398 eq(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA), mPayloadListCaptor.capture()); 2399 2400 List<IkePayload> childRespList = mPayloadListCaptor.getValue(); 2401 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); 2402 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 2403 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 2404 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); 2405 2406 // Mock finishing procedure 2407 cb.onProcedureFinished(childStateMachine); 2408 mLooper.dispatchAll(); 2409 assertTrue( 2410 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2411 verifyRetransmissionStopped(); 2412 } 2413 2414 @Test testTriggerDeleteChildLocal()2415 public void testTriggerDeleteChildLocal() throws Exception { 2416 setupIdleStateMachine(); 2417 2418 mIkeSessionStateMachine.sendMessage( 2419 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 2420 mLocalRequestFactory.getChildLocalRequest( 2421 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, 2422 mMockChildSessionCallback, 2423 null /*childParams*/)); 2424 mLooper.dispatchAll(); 2425 2426 assertTrue( 2427 mIkeSessionStateMachine.getCurrentState() 2428 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2429 verify(mMockChildSessionStateMachine).deleteChildSession(); 2430 verify(mMockBusyWakelock).acquire(); 2431 } 2432 2433 @Test testHandleDeleteChildBeforeCreation()2434 public void testHandleDeleteChildBeforeCreation() throws Exception { 2435 setupIdleStateMachine(); 2436 2437 mIkeSessionStateMachine.sendMessage( 2438 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 2439 mLocalRequestFactory.getChildLocalRequest( 2440 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, 2441 mock(ChildSessionCallback.class), 2442 null /*childParams*/)); 2443 mLooper.dispatchAll(); 2444 2445 assertTrue( 2446 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2447 } 2448 2449 @Test testTriggerRekeyChildLocal()2450 public void testTriggerRekeyChildLocal() throws Exception { 2451 setupIdleStateMachine(); 2452 2453 mIkeSessionStateMachine.sendMessage( 2454 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 2455 mLocalRequestFactory.getChildLocalRequest( 2456 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, 2457 mMockChildSessionCallback, 2458 null /*childParams*/)); 2459 mLooper.dispatchAll(); 2460 2461 assertTrue( 2462 mIkeSessionStateMachine.getCurrentState() 2463 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2464 verify(mMockChildSessionStateMachine).rekeyChildSession(); 2465 verify(mMockBusyWakelock).acquire(); 2466 } 2467 createChildAndGetChildSessionSmCallback( ChildSessionStateMachine child, int remoteSpi)2468 private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( 2469 ChildSessionStateMachine child, int remoteSpi) throws Exception { 2470 return createChildAndGetChildSessionSmCallback( 2471 child, remoteSpi, mock(ChildSessionCallback.class)); 2472 } 2473 createChildAndGetChildSessionSmCallback( ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback)2474 private IChildSessionSmCallback createChildAndGetChildSessionSmCallback( 2475 ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback) 2476 throws Exception { 2477 registerChildStateMachine(childCallback, child); 2478 2479 IChildSessionSmCallback cb = mIkeSessionStateMachine.new ChildSessionSmCallback(); 2480 cb.onChildSaCreated(remoteSpi, child); 2481 mLooper.dispatchAll(); 2482 2483 return cb; 2484 } 2485 transitionToChildProcedureOngoing()2486 private void transitionToChildProcedureOngoing() { 2487 mIkeSessionStateMachine.sendMessage( 2488 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 2489 mIkeSessionStateMachine.mChildProcedureOngoing); 2490 mLooper.dispatchAll(); 2491 assertTrue( 2492 mIkeSessionStateMachine.getCurrentState() 2493 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2494 } 2495 verifyChildReceiveDeleteRequest( ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads)2496 private void verifyChildReceiveDeleteRequest( 2497 ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads) { 2498 verify(child) 2499 .receiveRequest( 2500 eq(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD), 2501 eq(EXCHANGE_TYPE_INFORMATIONAL), 2502 mPayloadListCaptor.capture()); 2503 List<IkePayload> reqPayloads = mPayloadListCaptor.getValue(); 2504 2505 int numExpectedDelPayloads = expectedDelPayloads.length; 2506 assertEquals(numExpectedDelPayloads, reqPayloads.size()); 2507 2508 for (int i = 0; i < numExpectedDelPayloads; i++) { 2509 assertEquals(expectedDelPayloads[i], (IkeDeletePayload) reqPayloads.get(i)); 2510 } 2511 } 2512 outboundDeleteChildPayloadsReady( IChildSessionSmCallback childSmCb, IkeDeletePayload delPayload, boolean isResp, ChildSessionStateMachine child)2513 private void outboundDeleteChildPayloadsReady( 2514 IChildSessionSmCallback childSmCb, 2515 IkeDeletePayload delPayload, 2516 boolean isResp, 2517 ChildSessionStateMachine child) { 2518 List<IkePayload> outPayloadList = new ArrayList<>(); 2519 outPayloadList.add(delPayload); 2520 childSmCb.onOutboundPayloadsReady( 2521 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, isResp, outPayloadList, child); 2522 mLooper.dispatchAll(); 2523 } 2524 verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp)2525 private List<IkePayload> verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp) { 2526 IkeMessage deleteChildMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 2527 2528 IkeHeader ikeHeader = deleteChildMessage.ikeHeader; 2529 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); 2530 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); 2531 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 2532 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 2533 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 2534 assertEquals(isResp, ikeHeader.isResponseMsg); 2535 2536 return deleteChildMessage.ikePayloadList; 2537 } 2538 2539 @Test testDeferChildRequestToChildProcedureOngoing()2540 public void testDeferChildRequestToChildProcedureOngoing() throws Exception { 2541 setupIdleStateMachine(); 2542 2543 IkeDeletePayload[] inboundDelPayloads = 2544 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 2545 mIkeSessionStateMachine.sendMessage( 2546 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2547 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2548 mLooper.dispatchAll(); 2549 2550 assertTrue( 2551 mIkeSessionStateMachine.getCurrentState() 2552 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2553 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 2554 } 2555 2556 @Test testRemoteDeleteOneChild()2557 public void testRemoteDeleteOneChild() throws Exception { 2558 setupIdleStateMachine(); 2559 transitionToChildProcedureOngoing(); 2560 2561 // Receive Delete Child Request 2562 IkeDeletePayload[] inboundDelPayloads = 2563 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 2564 mIkeSessionStateMachine.sendMessage( 2565 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2566 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2567 mLooper.dispatchAll(); 2568 2569 // Verify received payloads 2570 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 2571 2572 // Outbound payload list ready 2573 IkeDeletePayload outDelPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); 2574 outboundDeleteChildPayloadsReady( 2575 mDummyChildSmCallback, 2576 outDelPayload, 2577 true /*isResp*/, 2578 mMockChildSessionStateMachine); 2579 2580 // Verify outbound response 2581 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2582 assertEquals(1, payloadList.size()); 2583 assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); 2584 verify(mMockBusyWakelock).acquire(); 2585 } 2586 2587 @Test testRemoteDeleteMultipleChildSession()2588 public void testRemoteDeleteMultipleChildSession() throws Exception { 2589 ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); 2590 int childOneRemoteSpi = 11; 2591 int childOneLocalSpi = 12; 2592 2593 ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); 2594 int childTwoRemoteSpi = 21; 2595 int childTwoLocalSpi = 22; 2596 2597 setupIdleStateMachine(); 2598 IChildSessionSmCallback childSmCbOne = 2599 createChildAndGetChildSessionSmCallback(childOne, childOneRemoteSpi); 2600 IChildSessionSmCallback childSmCbTwo = 2601 createChildAndGetChildSessionSmCallback(childTwo, childTwoRemoteSpi); 2602 2603 transitionToChildProcedureOngoing(); 2604 2605 // Receive Delete Child Request 2606 IkeDeletePayload[] inboundDelPayloads = 2607 new IkeDeletePayload[] { 2608 new IkeDeletePayload(new int[] {childOneRemoteSpi, childTwoRemoteSpi}) 2609 }; 2610 mIkeSessionStateMachine.sendMessage( 2611 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2612 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2613 mLooper.dispatchAll(); 2614 2615 // Verify received payloads 2616 verifyChildReceiveDeleteRequest(childOne, inboundDelPayloads); 2617 verifyChildReceiveDeleteRequest(childTwo, inboundDelPayloads); 2618 2619 // childOne outbound payload list ready 2620 IkeDeletePayload outDelPayloadOne = new IkeDeletePayload(new int[] {childOneLocalSpi}); 2621 outboundDeleteChildPayloadsReady(childSmCbOne, outDelPayloadOne, true /*isResp*/, childOne); 2622 mLooper.dispatchAll(); 2623 2624 // Verify that no response is sent 2625 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 2626 2627 // childTwo outbound payload list ready 2628 IkeDeletePayload outDelPayloadTwo = new IkeDeletePayload(new int[] {childTwoLocalSpi}); 2629 outboundDeleteChildPayloadsReady(childSmCbTwo, outDelPayloadTwo, true /*isResp*/, childTwo); 2630 mLooper.dispatchAll(); 2631 2632 // Verify outbound response 2633 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2634 assertEquals(2, payloadList.size()); 2635 assertEquals(outDelPayloadOne, ((IkeDeletePayload) payloadList.get(0))); 2636 assertEquals(outDelPayloadTwo, ((IkeDeletePayload) payloadList.get(1))); 2637 } 2638 2639 @Test testRemoteDeleteMultipleChildSaInSameSession()2640 public void testRemoteDeleteMultipleChildSaInSameSession() throws Exception { 2641 int newChildRemoteSpi = 21; 2642 int newChildLocalSpi = 22; 2643 2644 setupIdleStateMachine(); 2645 mDummyChildSmCallback.onChildSaCreated(newChildRemoteSpi, mMockChildSessionStateMachine); 2646 2647 transitionToChildProcedureOngoing(); 2648 2649 // Receive Delete Child Request 2650 IkeDeletePayload[] inboundDelPayloads = 2651 new IkeDeletePayload[] { 2652 new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE}), 2653 new IkeDeletePayload(new int[] {newChildRemoteSpi}) 2654 }; 2655 mIkeSessionStateMachine.sendMessage( 2656 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2657 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2658 mLooper.dispatchAll(); 2659 2660 // Verify received payloads 2661 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 2662 2663 // child outbound payload list ready 2664 IkeDeletePayload outDelPayload = 2665 new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL, newChildLocalSpi}); 2666 outboundDeleteChildPayloadsReady( 2667 mDummyChildSmCallback, 2668 outDelPayload, 2669 true /*isResp*/, 2670 mMockChildSessionStateMachine); 2671 mLooper.dispatchAll(); 2672 2673 // Verify outbound response 2674 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2675 assertEquals(1, payloadList.size()); 2676 assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0))); 2677 } 2678 2679 @Test testIgnoreUnrecognizedChildSpi()2680 public void testIgnoreUnrecognizedChildSpi() throws Exception { 2681 int unrecognizedSpi = 2; 2682 2683 setupIdleStateMachine(); 2684 transitionToChildProcedureOngoing(); 2685 2686 // Receive Delete Child Request 2687 IkeDeletePayload[] inboundDelPayloads = 2688 new IkeDeletePayload[] { 2689 new IkeDeletePayload(new int[] {unrecognizedSpi, CHILD_SPI_REMOTE}) 2690 }; 2691 mIkeSessionStateMachine.sendMessage( 2692 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2693 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2694 mLooper.dispatchAll(); 2695 2696 // Verify received payloads 2697 verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads); 2698 2699 // child outbound payload list ready 2700 IkeDeletePayload outPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL}); 2701 outboundDeleteChildPayloadsReady( 2702 mDummyChildSmCallback, outPayload, true /*isResp*/, mMockChildSessionStateMachine); 2703 mLooper.dispatchAll(); 2704 2705 // Verify outbound response 2706 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2707 assertEquals(1, payloadList.size()); 2708 assertEquals(outPayload, ((IkeDeletePayload) payloadList.get(0))); 2709 } 2710 2711 @Test testRemoteDeleteChildHandlesReqWithNoRecognizedSpi()2712 public void testRemoteDeleteChildHandlesReqWithNoRecognizedSpi() throws Exception { 2713 int unrecognizedSpi = 2; 2714 2715 setupIdleStateMachine(); 2716 2717 // Receive Delete Child Request without any recognized SPI 2718 IkeDeletePayload[] inboundDelPayloads = 2719 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {unrecognizedSpi})}; 2720 mIkeSessionStateMachine.sendMessage( 2721 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2722 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2723 mLooper.dispatchAll(); 2724 2725 // Verify outbound empty response was sent 2726 List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2727 assertTrue(payloadList.isEmpty()); 2728 2729 // Verify IKE Session was back to Idle 2730 assertTrue( 2731 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2732 } 2733 2734 @Test testRemoteCreateChild()2735 public void testRemoteCreateChild() throws Exception { 2736 setupIdleStateMachine(); 2737 2738 mIkeSessionStateMachine.sendMessage( 2739 CMD_RECEIVE_IKE_PACKET, makeCreateChildCreateMessage(false /*isResp*/)); 2740 2741 mLooper.dispatchAll(); 2742 2743 assertTrue( 2744 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2745 2746 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2747 assertEquals(1, ikePayloadList.size()); 2748 assertEquals( 2749 ERROR_TYPE_NO_ADDITIONAL_SAS, 2750 ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 2751 } 2752 2753 @Test testRemoteRekeyChild()2754 public void testRemoteRekeyChild() throws Exception { 2755 setupIdleStateMachine(); 2756 2757 // Receive Rekey Create request 2758 mIkeSessionStateMachine.sendMessage( 2759 CMD_RECEIVE_IKE_PACKET, 2760 makeRekeyChildCreateMessage(false /*isResp*/, CHILD_SPI_REMOTE)); 2761 mLooper.dispatchAll(); 2762 2763 verify(mMockChildSessionStateMachine) 2764 .receiveRequest( 2765 eq(IKE_EXCHANGE_SUBTYPE_REKEY_CHILD), 2766 eq(EXCHANGE_TYPE_CREATE_CHILD_SA), 2767 any(List.class)); 2768 assertTrue( 2769 mIkeSessionStateMachine.getCurrentState() 2770 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 2771 2772 // Send Rekey Create response 2773 List<IkePayload> mockRekeyCreatePayloads = Arrays.asList(mock(IkePayload.class)); 2774 mDummyChildSmCallback.onOutboundPayloadsReady( 2775 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 2776 true /*isResp*/, 2777 mockRekeyCreatePayloads, 2778 mMockChildSessionStateMachine); 2779 mLooper.dispatchAll(); 2780 2781 IkeMessage rekeyCreateResp = 2782 verifyAndGetOutboundEncryptedResp(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 2783 assertEquals(mockRekeyCreatePayloads, rekeyCreateResp.ikePayloadList); 2784 2785 // Forget sending Rekey Create response 2786 resetMockIkeMessageHelper(); 2787 2788 // Receive Delete Child Request 2789 IkeDeletePayload[] inboundDelPayloads = 2790 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 2791 mIkeSessionStateMachine.sendMessage( 2792 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 2793 makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/)); 2794 mLooper.dispatchAll(); 2795 2796 verify(mMockChildSessionStateMachine) 2797 .receiveRequest( 2798 eq(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD), 2799 eq(EXCHANGE_TYPE_INFORMATIONAL), 2800 any(List.class)); 2801 2802 // Send Rekey Delete response 2803 List<IkePayload> mockRekeyDeletePayloads = Arrays.asList(mock(IkePayload.class)); 2804 mDummyChildSmCallback.onOutboundPayloadsReady( 2805 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 2806 true /*isResp*/, 2807 mockRekeyDeletePayloads, 2808 mMockChildSessionStateMachine); 2809 mLooper.dispatchAll(); 2810 2811 IkeMessage rekeyDeleteResp = 2812 verifyAndGetOutboundEncryptedResp(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 2813 assertEquals(mockRekeyDeletePayloads, rekeyDeleteResp.ikePayloadList); 2814 } 2815 2816 @Test testHandleRekeyChildReqWithUnrecognizedSpi()2817 public void testHandleRekeyChildReqWithUnrecognizedSpi() throws Exception { 2818 int unrecognizedSpi = 2; 2819 2820 setupIdleStateMachine(); 2821 2822 mIkeSessionStateMachine.sendMessage( 2823 CMD_RECEIVE_IKE_PACKET, 2824 makeRekeyChildCreateMessage(false /*isResp*/, unrecognizedSpi)); 2825 mLooper.dispatchAll(); 2826 2827 verify(mMockChildSessionStateMachine, never()).receiveRequest(anyInt(), anyInt(), any()); 2828 assertTrue( 2829 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2830 2831 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2832 assertEquals(1, ikePayloadList.size()); 2833 IkeNotifyPayload notifyPayload = (IkeNotifyPayload) ikePayloadList.get(0); 2834 assertEquals(ERROR_TYPE_CHILD_SA_NOT_FOUND, notifyPayload.notifyType); 2835 assertEquals(unrecognizedSpi, notifyPayload.spi); 2836 } 2837 verifyNotifyUserCloseSession(IState state)2838 private void verifyNotifyUserCloseSession(IState state) { 2839 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 2840 verify(mMockIkeSessionCallback).onClosed(); 2841 verifyIkeMetricsLogged(getStateCode(state), IkeMetrics.IKE_ERROR_NONE); 2842 } 2843 verifyNotifyUserCloseSessionWithException( IState state, Exception exception, boolean isErrorFromChild)2844 private void verifyNotifyUserCloseSessionWithException( 2845 IState state, Exception exception, boolean isErrorFromChild) { 2846 IkeException ikeException = 2847 exception instanceof IkeException 2848 ? (IkeException) exception 2849 : new IkeInternalException(exception); 2850 2851 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 2852 verify(mMockIkeSessionCallback) 2853 .onClosedWithException(argThat(e -> e.getCause() == ikeException.getCause())); 2854 2855 if (isErrorFromChild) { 2856 verify(mIkeMetrics, never()) 2857 .logSessionTerminated(anyInt(), anyInt(), anyInt(), anyInt()); 2858 } else { 2859 verifyIkeMetricsLogged(getStateCode(state), ikeException.getMetricsErrorCode()); 2860 } 2861 } 2862 2863 @Test testRcvRemoteDeleteIkeWhenChildProcedureOngoing()2864 public void testRcvRemoteDeleteIkeWhenChildProcedureOngoing() throws Exception { 2865 setupIdleStateMachine(); 2866 transitionToChildProcedureOngoing(); 2867 2868 mIkeSessionStateMachine.sendMessage( 2869 CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 2870 2871 mLooper.dispatchAll(); 2872 2873 verifyNotifyUserCloseSession(mIkeSessionStateMachine.mChildProcedureOngoing); 2874 2875 // Verify state machine quit properly 2876 assertNull(mIkeSessionStateMachine.getCurrentState()); 2877 2878 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2879 assertTrue(ikePayloadList.isEmpty()); 2880 } 2881 2882 @Test testRcvRemoteRekeyIkeWhenChildProcedureOngoing()2883 public void testRcvRemoteRekeyIkeWhenChildProcedureOngoing() throws Exception { 2884 setupIdleStateMachine(); 2885 transitionToChildProcedureOngoing(); 2886 2887 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest()); 2888 2889 mLooper.dispatchAll(); 2890 2891 // Since we have forced state machine to transition to ChildProcedureOngoing state without 2892 // really starting any Child procedure, it should transition to Idle at this time. 2893 assertTrue( 2894 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 2895 2896 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 2897 assertEquals(1, ikePayloadList.size()); 2898 assertEquals( 2899 ERROR_TYPE_TEMPORARY_FAILURE, 2900 ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 2901 } 2902 2903 @Test testKillChildSessions()2904 public void testKillChildSessions() throws Exception { 2905 setupIdleStateMachine(); 2906 2907 ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class); 2908 ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class); 2909 registerChildStateMachine(mock(ChildSessionCallback.class), childOne); 2910 registerChildStateMachine(mock(ChildSessionCallback.class), childTwo); 2911 2912 mIkeSessionStateMachine.mCurrentIkeSaRecord = null; 2913 2914 mIkeSessionStateMachine.quitNow(); 2915 2916 mLooper.dispatchAll(); 2917 2918 verify(childOne).killSession(); 2919 verify(childTwo).killSession(); 2920 } 2921 verifyAuthReqAndGetMsg()2922 private IkeMessage verifyAuthReqAndGetMsg() { 2923 IkeMessage ikeAuthReqMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 2924 2925 IkeHeader ikeHeader = ikeAuthReqMessage.ikeHeader; 2926 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); 2927 assertFalse(ikeHeader.isResponseMsg); 2928 assertTrue(ikeHeader.fromIkeInitiator); 2929 2930 return ikeAuthReqMessage; 2931 } 2932 verifyAuthReqWithChildPayloadsAndGetMsg()2933 private IkeMessage verifyAuthReqWithChildPayloadsAndGetMsg() { 2934 IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 2935 2936 assertNotNull( 2937 ikeAuthReqMessage.getPayloadForType( 2938 IkePayload.PAYLOAD_TYPE_ID_INITIATOR, IkeIdPayload.class)); 2939 assertNotNull( 2940 ikeAuthReqMessage.getPayloadForType( 2941 IkePayload.PAYLOAD_TYPE_ID_RESPONDER, IkeIdPayload.class)); 2942 assertNotNull( 2943 ikeAuthReqMessage.getPayloadForType( 2944 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); 2945 assertNotNull( 2946 ikeAuthReqMessage.getPayloadForType( 2947 IkePayload.PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class)); 2948 assertNotNull( 2949 ikeAuthReqMessage.getPayloadForType( 2950 IkePayload.PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class)); 2951 2952 IkeConfigPayload configPayload = 2953 ikeAuthReqMessage.getPayloadForType( 2954 IkePayload.PAYLOAD_TYPE_CP, IkeConfigPayload.class); 2955 assertNotNull(configPayload); 2956 2957 Map<Integer, Integer> expectedAttributes = 2958 Map.of( 2959 CONFIG_ATTR_IP4_PCSCF, 2960 1, 2961 CONFIG_ATTR_IP6_PCSCF, 2962 1, 2963 CONFIG_ATTR_INTERNAL_IP4_ADDRESS, 2964 1, 2965 CONFIG_ATTR_INTERNAL_IP6_ADDRESS, 2966 1, 2967 CONFIG_ATTR_APPLICATION_VERSION, 2968 1, 2969 CONFIG_ATTR_INTERNAL_IP4_NETMASK, 2970 1); 2971 Map<Integer, Integer> actualAttributes = 2972 buildAttributeMap(configPayload.recognizedAttributeList); 2973 assertEquals(expectedAttributes, actualAttributes); 2974 2975 IkeNoncePayload noncePayload = 2976 ikeAuthReqMessage.getPayloadForType( 2977 IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class); 2978 assertNull(noncePayload); 2979 2980 return ikeAuthReqMessage; 2981 } 2982 buildAttributeMap( List<IkeConfigPayload.ConfigAttribute> recognizedAttributeList)2983 private Map<Integer, Integer> buildAttributeMap( 2984 List<IkeConfigPayload.ConfigAttribute> recognizedAttributeList) { 2985 Map<Integer, Integer> attrCountMap = new HashMap<>(); 2986 for (IkeConfigPayload.ConfigAttribute attr : recognizedAttributeList) { 2987 attrCountMap.compute(attr.attributeType, (key, val) -> (val == null) ? 1 : val + 1); 2988 } 2989 2990 return attrCountMap; 2991 } 2992 verifyDigitalSignatureAuthentication( IkeAuthDigitalSignPayload spyAuthPayload, X509Certificate certificate, IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp)2993 private void verifyDigitalSignatureAuthentication( 2994 IkeAuthDigitalSignPayload spyAuthPayload, 2995 X509Certificate certificate, 2996 IkeIdPayload respIdPayload, 2997 List<IkePayload> authRelatedPayloads, 2998 boolean hasChildPayloads, 2999 boolean hasConfigPayloadInResp) 3000 throws Exception { 3001 IkeMessage ikeAuthReqMessage = 3002 verifyAuthenticationCommonAndGetIkeMessage( 3003 respIdPayload, 3004 authRelatedPayloads, 3005 hasChildPayloads, 3006 hasConfigPayloadInResp, 3007 false /* isMobikeEnabled */, 3008 true /* isIpv4 */, 3009 0 /* ike3gppCallbackInvocations */); 3010 3011 // Calling mSpyCurrentIkeSaRecord.getSkPr() inline will introduce a mockito compile error: 3012 // InvalidUseOfMatchersException 3013 byte[] expectedSkPr = mSpyCurrentIkeSaRecord.getSkPr(); 3014 verify(spyAuthPayload) 3015 .verifyInboundSignature( 3016 eq(certificate), 3017 any(), 3018 eq(mSpyCurrentIkeSaRecord.nonceInitiator), 3019 eq(respIdPayload.getEncodedPayloadBody()), 3020 eq(mIkeSessionStateMachine.mIkePrf), 3021 eq(expectedSkPr)); 3022 3023 assertNotNull( 3024 ikeAuthReqMessage.getPayloadForType( 3025 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthDigitalSignPayload.class)); 3026 } 3027 verifySharedKeyAuthentication( IkeAuthPskPayload spyAuthPayload, IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp)3028 private IkeMessage verifySharedKeyAuthentication( 3029 IkeAuthPskPayload spyAuthPayload, 3030 IkeIdPayload respIdPayload, 3031 List<IkePayload> authRelatedPayloads, 3032 boolean hasChildPayloads, 3033 boolean hasConfigPayloadInResp) 3034 throws Exception { 3035 return verifySharedKeyAuthentication( 3036 spyAuthPayload, 3037 respIdPayload, 3038 authRelatedPayloads, 3039 hasChildPayloads, 3040 hasConfigPayloadInResp, 3041 false /* isMobikeEnabled */, 3042 true /* isIpv4 */, 3043 0 /* ike3gppDataListenerInvocations */); 3044 } 3045 verifySharedKeyAuthentication( IkeAuthPskPayload spyAuthPayload, IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp, boolean isMobikeEnabled, boolean isIpv4, int ike3gppDataListenerInvocations)3046 private IkeMessage verifySharedKeyAuthentication( 3047 IkeAuthPskPayload spyAuthPayload, 3048 IkeIdPayload respIdPayload, 3049 List<IkePayload> authRelatedPayloads, 3050 boolean hasChildPayloads, 3051 boolean hasConfigPayloadInResp, 3052 boolean isMobikeEnabled, 3053 boolean isIpv4, 3054 int ike3gppDataListenerInvocations) 3055 throws Exception { 3056 IkeMessage ikeAuthReqMessage = 3057 verifyAuthenticationCommonAndGetIkeMessage( 3058 respIdPayload, 3059 authRelatedPayloads, 3060 hasChildPayloads, 3061 hasConfigPayloadInResp, 3062 isMobikeEnabled, 3063 isIpv4, 3064 ike3gppDataListenerInvocations); 3065 3066 // Calling mSpyCurrentIkeSaRecord.getSkPr() inline will introduce a mockito compile error: 3067 // InvalidUseOfMatchersException 3068 byte[] expectedSkPr = mSpyCurrentIkeSaRecord.getSkPr(); 3069 verify(spyAuthPayload) 3070 .verifyInboundSignature( 3071 eq(mPsk), 3072 any(), 3073 eq(mSpyCurrentIkeSaRecord.nonceInitiator), 3074 eq(respIdPayload.getEncodedPayloadBody()), 3075 eq(mIkeSessionStateMachine.mIkePrf), 3076 eq(expectedSkPr)); 3077 3078 assertNotNull( 3079 ikeAuthReqMessage.getPayloadForType( 3080 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPskPayload.class)); 3081 3082 return ikeAuthReqMessage; 3083 } 3084 verifyAuthenticationCommonAndGetIkeMessage( IkeIdPayload respIdPayload, List<IkePayload> authRelatedPayloads, boolean hasChildPayloads, boolean hasConfigPayloadInResp, boolean isMobikeEnabled, boolean isIpv4, int ike3gppDataListenerInvocations)3085 private IkeMessage verifyAuthenticationCommonAndGetIkeMessage( 3086 IkeIdPayload respIdPayload, 3087 List<IkePayload> authRelatedPayloads, 3088 boolean hasChildPayloads, 3089 boolean hasConfigPayloadInResp, 3090 boolean isMobikeEnabled, 3091 boolean isIpv4, 3092 int ike3gppDataListenerInvocations) 3093 throws Exception { 3094 // Send IKE AUTH response to IKE state machine 3095 ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads); 3096 mIkeSessionStateMachine.sendMessage( 3097 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp); 3098 mLooper.dispatchAll(); 3099 3100 // Validate outbound IKE AUTH request 3101 IkeMessage ikeAuthReqMessage; 3102 if (hasChildPayloads) { 3103 ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); 3104 } else { 3105 ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 3106 } 3107 3108 // Validate that there is no EAP only notify payload 3109 List<IkeNotifyPayload> notifyPayloads = 3110 ikeAuthReqMessage.getPayloadListForType( 3111 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 3112 assertFalse(hasExpectedNotifyPayload(notifyPayloads, NOTIFY_TYPE_EAP_ONLY_AUTHENTICATION)); 3113 3114 // Validate the N1 Mode Capability payload 3115 verifyN1ModeCapabilityPayload(notifyPayloads); 3116 3117 // Validate inbound IKE AUTH response 3118 verifyIncrementLocaReqMsgId(); 3119 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, authResp); 3120 3121 // Validate that user has been notified. Expect one invocation for 3122 // IkeSessionCallback#onOpened and 'ike3gppDataListenerInvocations' invocations for 3123 // Ike3gppDataListener#onIke3gppDataReceived 3124 verify(mSpyUserCbExecutor, times(1 + ike3gppDataListenerInvocations)) 3125 .execute(any(Runnable.class)); 3126 3127 // Verify IkeSessionConfiguration 3128 ArgumentCaptor<IkeSessionConfiguration> ikeSessionConfigurationArgumentCaptor = 3129 ArgumentCaptor.forClass(IkeSessionConfiguration.class); 3130 verify(mMockIkeSessionCallback).onOpened(ikeSessionConfigurationArgumentCaptor.capture()); 3131 3132 IkeSessionConfiguration sessionConfig = ikeSessionConfigurationArgumentCaptor.getValue(); 3133 assertNotNull(sessionConfig); 3134 if (hasConfigPayloadInResp) { 3135 List<InetAddress> pcscfAddressList = sessionConfig.getPcscfServers(); 3136 assertEquals(3, pcscfAddressList.size()); 3137 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS1))); 3138 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS2))); 3139 assertTrue(pcscfAddressList.contains(InetAddress.getByName(PCSCF_IPV6_ADDRESS3))); 3140 } else { 3141 assertTrue(sessionConfig.getPcscfServers().size() == 0); 3142 } 3143 3144 assertEquals( 3145 "" /*expected application version*/, sessionConfig.getRemoteApplicationVersion()); 3146 assertByteArrayListEquals( 3147 Arrays.asList(REMOTE_VENDOR_ID_ONE, REMOTE_VENDOR_ID_TWO), 3148 sessionConfig.getRemoteVendorIds()); 3149 assertTrue( 3150 sessionConfig.isIkeExtensionEnabled( 3151 IkeSessionConfiguration.EXTENSION_TYPE_FRAGMENTATION)); 3152 assertEquals( 3153 isMobikeEnabled, 3154 sessionConfig.isIkeExtensionEnabled(IkeSessionConfiguration.EXTENSION_TYPE_MOBIKE)); 3155 3156 IkeSessionConnectionInfo ikeConnInfo = sessionConfig.getIkeSessionConnectionInfo(); 3157 3158 InetAddress expectedLocalAddress = isIpv4 ? LOCAL_ADDRESS : LOCAL_ADDRESS_V6; 3159 InetAddress expectedRemoteAddress = isIpv4 ? REMOTE_ADDRESS : REMOTE_ADDRESS_V6; 3160 3161 assertEquals(expectedLocalAddress, ikeConnInfo.getLocalAddress()); 3162 assertEquals(expectedRemoteAddress, ikeConnInfo.getRemoteAddress()); 3163 assertEquals(mMockDefaultNetwork, ikeConnInfo.getNetwork()); 3164 3165 // Verify payload list pair for first Child negotiation 3166 ArgumentCaptor<List<IkePayload>> mReqPayloadListCaptor = 3167 ArgumentCaptor.forClass(List.class); 3168 ArgumentCaptor<List<IkePayload>> mRespPayloadListCaptor = 3169 ArgumentCaptor.forClass(List.class); 3170 verify(mMockChildSessionStateMachine) 3171 .handleFirstChildExchange( 3172 mReqPayloadListCaptor.capture(), 3173 mRespPayloadListCaptor.capture(), 3174 eq(expectedLocalAddress), 3175 eq(expectedRemoteAddress), 3176 any(), // udpEncapSocket 3177 eq(mIkeSessionStateMachine.mIkePrf), 3178 eq(mIkeSessionStateMachine.mSaProposal.getDhGroupTransforms()[0].id), 3179 any()); // sk_d 3180 List<IkePayload> childReqList = mReqPayloadListCaptor.getValue(); 3181 List<IkePayload> childRespList = mRespPayloadListCaptor.getValue(); 3182 3183 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_SA)); 3184 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 3185 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 3186 assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_NONCE)); 3187 IkeSaPayload reqSaPayload = 3188 IkePayload.getPayloadForTypeInProvidedList( 3189 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childReqList); 3190 assertFalse(reqSaPayload.isSaResponse); 3191 3192 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA)); 3193 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR)); 3194 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER)); 3195 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE)); 3196 if (hasConfigPayloadInResp) { 3197 assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_CP)); 3198 } else { 3199 assertFalse(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_CP)); 3200 } 3201 IkeSaPayload respSaPayload = 3202 IkePayload.getPayloadForTypeInProvidedList( 3203 IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childRespList); 3204 assertTrue(respSaPayload.isSaResponse); 3205 3206 // Mock finishing first Child SA negotiation. 3207 assertTrue( 3208 mIkeSessionStateMachine.getCurrentState() 3209 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 3210 3211 IChildSessionSmCallback cb = verifyMakeChildAndReturnChildSmCb(mMockChildSessionCallback); 3212 3213 cb.onProcedureFinished(mMockChildSessionStateMachine); 3214 mLooper.dispatchAll(); 3215 assertTrue( 3216 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3217 3218 return ikeAuthReqMessage; 3219 } 3220 verifyN1ModeCapabilityPayload(List<IkeNotifyPayload> notifyPayloads)3221 private void verifyN1ModeCapabilityPayload(List<IkeNotifyPayload> notifyPayloads) 3222 throws Exception { 3223 IkeNotifyPayload n1ModeCapabilityPayload = null; 3224 for (IkeNotifyPayload notifyPayload : notifyPayloads) { 3225 if (notifyPayload.notifyType == NOTIFY_TYPE_N1_MODE_CAPABILITY) { 3226 n1ModeCapabilityPayload = notifyPayload; 3227 } 3228 } 3229 3230 // Only expect a N1_MODE_CAPABILITY payload if an Ike3gppExtension and PDU Session ID 3231 // are specified. 3232 Ike3gppExtension ike3gppExtension = 3233 mIkeSessionStateMachine.mIkeSessionParams.getIke3gppExtension(); 3234 if (ike3gppExtension == null || !ike3gppExtension.getIke3gppParams().hasPduSessionId()) { 3235 assertNull(n1ModeCapabilityPayload); 3236 } else { 3237 byte[] expectedNotifyData = 3238 TestUtils.hexStringToByteArray(N1_MODE_CAPABILITY_PAYLOAD_DATA); 3239 assertArrayEquals(expectedNotifyData, n1ModeCapabilityPayload.notifyData); 3240 } 3241 } 3242 makeSpyRespPskPayload()3243 private IkeAuthPskPayload makeSpyRespPskPayload() throws Exception { 3244 IkeAuthPskPayload spyAuthPayload = 3245 spy( 3246 (IkeAuthPskPayload) 3247 IkeTestUtils.hexStringToIkePayload( 3248 IkePayload.PAYLOAD_TYPE_AUTH, 3249 true /*isResp*/, 3250 PSK_AUTH_RESP_PAYLOAD_HEX_STRING)); 3251 3252 doNothing() 3253 .when(spyAuthPayload) 3254 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 3255 return spyAuthPayload; 3256 } 3257 makeSpyDigitalSignAuthPayload()3258 private IkeAuthDigitalSignPayload makeSpyDigitalSignAuthPayload() throws Exception { 3259 IkeAuthDigitalSignPayload spyAuthPayload = 3260 spy( 3261 (IkeAuthDigitalSignPayload) 3262 IkeTestUtils.hexStringToIkePayload( 3263 IkePayload.PAYLOAD_TYPE_AUTH, 3264 true /*isResp*/, 3265 GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING)); 3266 doNothing() 3267 .when(spyAuthPayload) 3268 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 3269 return spyAuthPayload; 3270 } 3271 makeRespIdPayload()3272 private IkeIdPayload makeRespIdPayload() { 3273 return makeRespIdPayload(REMOTE_ID_FQDN); 3274 } 3275 makeDeviceIdentityPayloadFromNetwork()3276 private IkeNotifyPayload makeDeviceIdentityPayloadFromNetwork() { 3277 return new IkeNotifyPayload( 3278 NOTIFY_TYPE_DEVICE_IDENTITY, HexDump.hexStringToByteArray("01")); 3279 } 3280 makeRespIdPayload(IkeIdentification ikeId)3281 private IkeIdPayload makeRespIdPayload(IkeIdentification ikeId) { 3282 return new IkeIdPayload(false /* isInitiator */, ikeId); 3283 } 3284 verifyEmptyInformationalSent(int count, boolean expectedResp)3285 private void verifyEmptyInformationalSent(int count, boolean expectedResp) { 3286 verify(mMockIkeMessageHelper, times(count)) 3287 .encryptAndEncode( 3288 any(), 3289 any(), 3290 eq(mSpyCurrentIkeSaRecord), 3291 argThat( 3292 msg -> { 3293 return msg.ikePayloadList.isEmpty() 3294 && msg.ikeHeader.isResponseMsg == expectedResp 3295 && msg.ikeHeader.fromIkeInitiator 3296 && msg.ikeHeader.exchangeType 3297 == IkeHeader.EXCHANGE_TYPE_INFORMATIONAL; 3298 }), 3299 anyBoolean(), 3300 anyInt()); 3301 } 3302 3303 @Test testCreateIkeLocalIkeAuthDefersOtherMessages()3304 public void testCreateIkeLocalIkeAuthDefersOtherMessages() throws Exception { 3305 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3306 verifyRetransmissionStarted(); 3307 3308 // Build IKE AUTH response with Auth-PSK, ID-Responder and config payloads. 3309 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3310 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3311 authRelatedPayloads.add(spyAuthPayload); 3312 3313 ReceivedIkePacket req = 3314 makeDummyEncryptedReceivedIkePacket( 3315 mSpyCurrentIkeSaRecord, 3316 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 3317 false, 3318 Collections.emptyList(), 3319 Collections.emptyList()); 3320 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, req); 3321 3322 verifyEmptyInformationalSent(0, true /* expcetedResp*/); 3323 3324 // Send IKE AUTH response to IKE state machine to trigger moving to next state 3325 IkeIdPayload respIdPayload = makeRespIdPayload(); 3326 authRelatedPayloads.add(respIdPayload); 3327 authRelatedPayloads.add(makeConfigPayload()); 3328 3329 ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads); 3330 mIkeSessionStateMachine.sendMessage( 3331 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp); 3332 mLooper.dispatchAll(); 3333 3334 verifyEmptyInformationalSent(1, true /* expcetedResp*/); 3335 assertTrue( 3336 mIkeSessionStateMachine.getCurrentState() 3337 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 3338 } 3339 verifyCreateIkeLocalIkeAuthDigitalSignature(Set<Short> peerSignatureHashAlgorithms)3340 private void verifyCreateIkeLocalIkeAuthDigitalSignature(Set<Short> peerSignatureHashAlgorithms) 3341 throws Exception { 3342 // Quit and restart IKE Session with Digital Signature Auth params 3343 mIkeSessionStateMachine.quitNow(); 3344 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsDigitalSignature()); 3345 3346 new IkeFirstAuthTestPretest(peerSignatureHashAlgorithms) 3347 .mockIkeInitAndTransitionToIkeAuth(); 3348 3349 // Build IKE AUTH response with Digital Signature Auth, ID-Responder and config payloads. 3350 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3351 IkeAuthDigitalSignPayload spyAuthPayload = makeSpyDigitalSignAuthPayload(); 3352 authRelatedPayloads.add(spyAuthPayload); 3353 authRelatedPayloads.add(new IkeCertX509CertPayload(mServerEndCertificate)); 3354 3355 IkeIdPayload respIdPayload = makeRespIdPayload(); 3356 authRelatedPayloads.add(respIdPayload); 3357 authRelatedPayloads.add(makeConfigPayload()); 3358 3359 verifyDigitalSignatureAuthentication( 3360 spyAuthPayload, 3361 mServerEndCertificate, 3362 respIdPayload, 3363 authRelatedPayloads, 3364 true /*hasChildPayloads*/, 3365 true /*hasConfigPayloadInResp*/); 3366 verifyRetransmissionStopped(); 3367 } 3368 3369 @Test testCreateIkeLocalIkeAuthRsaDigitalSignature()3370 public void testCreateIkeLocalIkeAuthRsaDigitalSignature() throws Exception { 3371 verifyCreateIkeLocalIkeAuthDigitalSignature(new HashSet<>()); 3372 } 3373 3374 @Test testCreateIkeLocalIkeAuthGenericDigitalSignature()3375 public void testCreateIkeLocalIkeAuthGenericDigitalSignature() throws Exception { 3376 Set<Short> hashAlgos = new HashSet<Short>(); 3377 for (short algo : IkeAuthDigitalSignPayload.ALL_SIGNATURE_ALGO_TYPES) { 3378 hashAlgos.add(algo); 3379 } 3380 verifyCreateIkeLocalIkeAuthDigitalSignature(hashAlgos); 3381 } 3382 3383 @Test testCreateIkeLocalIkeAuthPsk()3384 public void testCreateIkeLocalIkeAuthPsk() throws Exception { 3385 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3386 verifyRetransmissionStarted(); 3387 3388 // Build IKE AUTH response with Auth-PSK, ID-Responder and config payloads. 3389 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3390 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3391 authRelatedPayloads.add(spyAuthPayload); 3392 3393 IkeIdPayload respIdPayload = makeRespIdPayload(); 3394 authRelatedPayloads.add(respIdPayload); 3395 authRelatedPayloads.add(makeConfigPayload()); 3396 3397 verifySharedKeyAuthentication( 3398 spyAuthPayload, 3399 respIdPayload, 3400 authRelatedPayloads, 3401 true /*hasChildPayloads*/, 3402 true /*hasConfigPayloadInResp*/); 3403 verifyRetransmissionStopped(); 3404 } 3405 3406 @Test testCreateIkeLocalIkeAuthDigitalSignatureIdMismatch()3407 public void testCreateIkeLocalIkeAuthDigitalSignatureIdMismatch() throws Exception { 3408 // Quit and restart IKE Session with Digital Signature Auth params 3409 mIkeSessionStateMachine.quitNow(); 3410 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsDigitalSignature()); 3411 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3412 resetMockIkeMessageHelper(); 3413 3414 // Build IKE AUTH response with Digital Signature Auth, ID-Responder and config payloads. 3415 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3416 IkeAuthDigitalSignPayload spyAuthPayload = makeSpyDigitalSignAuthPayload(); 3417 authRelatedPayloads.add(spyAuthPayload); 3418 authRelatedPayloads.add(new IkeCertX509CertPayload(mServerEndCertificate)); 3419 3420 authRelatedPayloads.add(makeRespIdPayload(REMOTE_ID_IPV4)); 3421 3422 sendAuthFailRespAndVerifyCloseIke( 3423 mIkeSessionStateMachine.mCreateIkeLocalIkeAuth, 3424 makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 3425 } 3426 3427 @Test testCreateIkeLocalIkeAuthPskVerifyFail()3428 public void testCreateIkeLocalIkeAuthPskVerifyFail() throws Exception { 3429 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3430 verifyRetransmissionStarted(); 3431 resetMockIkeMessageHelper(); 3432 3433 // Build IKE AUTH response with invalid Auth-PSK Payload and ID-Responder Payload. 3434 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3435 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3436 doThrow(new AuthenticationFailedException("DummyAuthFailException")) 3437 .when(spyAuthPayload) 3438 .verifyInboundSignature(any(), any(), any(), any(), any(), any()); 3439 authRelatedPayloads.add(spyAuthPayload); 3440 3441 IkeIdPayload respIdPayload = makeRespIdPayload(); 3442 authRelatedPayloads.add(respIdPayload); 3443 3444 sendAuthFailRespAndVerifyCloseIke( 3445 mIkeSessionStateMachine.mCreateIkeLocalIkeAuth, 3446 makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 3447 } 3448 sendAuthFailRespAndVerifyCloseIke(IState state, ReceivedIkePacket authFailResp)3449 private void sendAuthFailRespAndVerifyCloseIke(IState state, ReceivedIkePacket authFailResp) 3450 throws Exception { 3451 // Send response to IKE state machine 3452 mIkeSessionStateMachine.sendMessage( 3453 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authFailResp); 3454 mLooper.dispatchAll(); 3455 3456 // Verify Delete request was sent 3457 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3458 assertEquals(1, payloads.size()); 3459 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3460 3461 // Verify IKE Session was closed properly 3462 assertNull(mIkeSessionStateMachine.getCurrentState()); 3463 verify(mMockIkeSessionCallback) 3464 .onClosedWithException(any(AuthenticationFailedException.class)); 3465 3466 verifyIkeMetricsLogged( 3467 getStateCode(state), IkeMetrics.IKE_ERROR_PROTOCOL_AUTHENTICATION_FAILED); 3468 } 3469 3470 @Test testAuthHandlesIkeErrorNotify()3471 public void testAuthHandlesIkeErrorNotify() throws Exception { 3472 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3473 verifyRetransmissionStarted(); 3474 resetMockIkeMessageHelper(); 3475 3476 // Mock rejecting IKE AUTH with Authentication Failure notification 3477 ReceivedIkePacket mockAuthFailPacket = 3478 makeIkeAuthRespWithoutChildPayloads( 3479 Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED))); 3480 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); 3481 mLooper.dispatchAll(); 3482 3483 // Verify Delete request was never sent 3484 verifyEncryptAndEncodeNeverCalled(); 3485 3486 // Verify IKE Session is closed properly 3487 assertNull(mIkeSessionStateMachine.getCurrentState()); 3488 verify(mMockIkeSessionCallback) 3489 .onClosedWithException(any(AuthenticationFailedException.class)); 3490 } 3491 3492 @Test testAuthHandlesCreateChildErrorNotify()3493 public void testAuthHandlesCreateChildErrorNotify() throws Exception { 3494 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3495 verifyRetransmissionStarted(); 3496 resetMockIkeMessageHelper(); 3497 3498 // Mock rejecting IKE AUTH with a Create Child error notification 3499 ReceivedIkePacket mockAuthFailPacket = 3500 makeIkeAuthRespWithoutChildPayloads( 3501 Arrays.asList(new IkeNotifyPayload(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE))); 3502 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockAuthFailPacket); 3503 mLooper.dispatchAll(); 3504 3505 // Verify Delete request was sent 3506 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3507 assertEquals(1, payloads.size()); 3508 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3509 3510 // Verify IKE Session is closed properly 3511 assertNull(mIkeSessionStateMachine.getCurrentState()); 3512 3513 ArgumentCaptor<IkeProtocolException> captor = 3514 ArgumentCaptor.forClass(IkeProtocolException.class); 3515 verify(mMockIkeSessionCallback).onClosedWithException(captor.capture()); 3516 IkeProtocolException exception = captor.getValue(); 3517 assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, exception.getErrorType()); 3518 } 3519 3520 @Test testAuthPskHandleRespWithParsingError()3521 public void testAuthPskHandleRespWithParsingError() throws Exception { 3522 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3523 verifyRetransmissionStarted(); 3524 resetMockIkeMessageHelper(); 3525 3526 // Mock receiving packet with syntax error 3527 ReceivedIkePacket mockInvalidPacket = 3528 makeDummyReceivedIkePacketWithInvalidSyntax( 3529 mSpyCurrentIkeSaRecord, true /*isResp*/, IkeHeader.EXCHANGE_TYPE_IKE_AUTH); 3530 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 3531 mLooper.dispatchAll(); 3532 3533 // Verify Delete request was sent 3534 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 3535 assertEquals(1, payloads.size()); 3536 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 3537 3538 // Verify IKE Session is closed properly 3539 assertNull(mIkeSessionStateMachine.getCurrentState()); 3540 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 3541 } 3542 3543 @Test testAuthWithOptionAcceptAnyRemoteId()3544 public void testAuthWithOptionAcceptAnyRemoteId() throws Exception { 3545 mIkeSessionStateMachine.quitNow(); 3546 3547 IkeSessionParams ikeSessionParams = 3548 buildIkeSessionParamsWithIkeOptions( 3549 IkeSessionParams.IKE_OPTION_ACCEPT_ANY_REMOTE_ID); 3550 mIkeSessionStateMachine = makeAndStartIkeSession(ikeSessionParams); 3551 3552 // Mock IKE INIT 3553 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3554 verifyRetransmissionStarted(); 3555 3556 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload that is different 3557 // from configured ID-Responder. 3558 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3559 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3560 authRelatedPayloads.add(spyAuthPayload); 3561 3562 IkeIdPayload respIdPayload = makeRespIdPayload(REMOTE_ID_IPV4); 3563 authRelatedPayloads.add(respIdPayload); 3564 3565 // Send response to IKE state machine and verify authentication is done. 3566 verifySharedKeyAuthentication( 3567 spyAuthPayload, 3568 respIdPayload, 3569 authRelatedPayloads, 3570 true /*hasChildPayloads*/, 3571 false /*hasConfigPayloadInResp*/); 3572 verifyRetransmissionStopped(); 3573 } 3574 3575 @Test testAuthRejectOtherResponderId()3576 public void testAuthRejectOtherResponderId() throws Exception { 3577 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3578 verifyRetransmissionStarted(); 3579 3580 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload that is different 3581 // from configured ID-Responder. 3582 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3583 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3584 authRelatedPayloads.add(spyAuthPayload); 3585 3586 IkeIdPayload respIdPayload = makeRespIdPayload(REMOTE_ID_IPV4); 3587 authRelatedPayloads.add(respIdPayload); 3588 3589 // Send response to IKE state machine 3590 mIkeSessionStateMachine.sendMessage( 3591 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3592 makeIkeAuthRespWithChildPayloads(authRelatedPayloads)); 3593 mLooper.dispatchAll(); 3594 3595 // Verify IKE Session is closed properly 3596 assertNull(mIkeSessionStateMachine.getCurrentState()); 3597 verify(mMockIkeSessionCallback) 3598 .onClosedWithException(any(AuthenticationFailedException.class)); 3599 } 3600 3601 @Test testCreateIkeLocalIkeAuthPreEap()3602 public void testCreateIkeLocalIkeAuthPreEap() throws Exception { 3603 mIkeSessionStateMachine.quitNow(); 3604 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3605 3606 // Mock IKE INIT 3607 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3608 verifyRetransmissionStarted(); 3609 3610 // Build IKE AUTH response with EAP. Auth, ID-Resp and Cert payloads. 3611 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3612 3613 authRelatedPayloads.add(new IkeEapPayload(EAP_DUMMY_MSG)); 3614 authRelatedPayloads.add(makeSpyDigitalSignAuthPayload()); 3615 authRelatedPayloads.add(makeRespIdPayload()); 3616 3617 IkeCertX509CertPayload certPayload = new IkeCertX509CertPayload(mServerEndCertificate); 3618 authRelatedPayloads.add(certPayload); 3619 3620 // Send IKE AUTH response to IKE state machine 3621 mIkeSessionStateMachine.sendMessage( 3622 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3623 makeIkeAuthRespWithoutChildPayloads(authRelatedPayloads)); 3624 mLooper.dispatchAll(); 3625 3626 // Validate outbound IKE AUTH request 3627 IkeMessage ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg(); 3628 assertNull( 3629 ikeAuthReqMessage.getPayloadForType( 3630 IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPayload.class)); 3631 3632 assertTrue( 3633 mIkeSessionStateMachine.getCurrentState() 3634 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap); 3635 verifyRetransmissionStopped(); 3636 3637 IkeAuthData setupData = 3638 ((CreateIkeLocalIkeAuthInEap) mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap) 3639 .mSetupData; 3640 assertNotNull(setupData.initIdPayload); 3641 assertNotNull(setupData.respIdPayload); 3642 } 3643 verifyEapAuthenticatorCreatedAndGetCallback( EapSessionConfig eapSessionConfig)3644 private IEapCallback verifyEapAuthenticatorCreatedAndGetCallback( 3645 EapSessionConfig eapSessionConfig) { 3646 ArgumentCaptor<IkeContext> ikeContextCaptor = ArgumentCaptor.forClass(IkeContext.class); 3647 ArgumentCaptor<IEapCallback> eapCbCaptor = ArgumentCaptor.forClass(IEapCallback.class); 3648 3649 verify(mSpyDeps) 3650 .newEapAuthenticator( 3651 ikeContextCaptor.capture(), eapCbCaptor.capture(), eq(eapSessionConfig)); 3652 3653 IkeContext ikeContext = ikeContextCaptor.getValue(); 3654 assertEquals(mIkeSessionStateMachine.getHandler().getLooper(), ikeContext.getLooper()); 3655 assertEquals(mSpyContext, ikeContext.getContext()); 3656 3657 return eapCbCaptor.getValue(); 3658 } 3659 3660 @Test testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage()3661 public void testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage() 3662 throws Exception { 3663 mIkeSessionStateMachine.quitNow(); 3664 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3665 3666 // Setup state and go to IN_EAP state 3667 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3668 mLooper.dispatchAll(); 3669 3670 mIkeSessionStateMachine.sendMessage( 3671 IkeSessionStateMachine.CMD_EAP_START_EAP_AUTH, new IkeEapPayload(EAP_DUMMY_MSG)); 3672 mLooper.dispatchAll(); 3673 3674 verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3675 3676 verify(mMockEapAuthenticator).processEapMessage(eq(EAP_DUMMY_MSG)); 3677 } 3678 3679 @Test testInformationalResponseWithDeviceIdentity()3680 public void testInformationalResponseWithDeviceIdentity() throws Exception { 3681 mIkeSessionStateMachine.quitNow(); 3682 mIkeSessionStateMachine = 3683 makeAndStartIkeSession(buildIkeSessionParamsEapAkaWithDeviceIdentity()); 3684 setIkeInitResults(); 3685 3686 mIkeSessionStateMachine.sendMessage( 3687 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 3688 mLooper.dispatchAll(); 3689 3690 assertTrue( 3691 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 3692 verifyRcvDeviceIdentityCheckReqAndReply(); 3693 } 3694 3695 @Test testCreateIkeLocalIkeAuthInEapOutboundResponseIncludesDeviceIdentity()3696 public void testCreateIkeLocalIkeAuthInEapOutboundResponseIncludesDeviceIdentity() 3697 throws Exception { 3698 mIkeSessionStateMachine.quitNow(); 3699 mIkeSessionStateMachine = 3700 makeAndStartIkeSession(buildIkeSessionParamsEapAkaWithDeviceIdentity()); 3701 3702 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3703 verifyRetransmissionStarted(); 3704 3705 // Build IKE AUTH response with EAP. Auth, ID-Resp and device identity 3706 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3707 authRelatedPayloads.add(new IkeEapPayload(EAP_DUMMY_MSG)); 3708 authRelatedPayloads.add(makeRespIdPayload()); 3709 authRelatedPayloads.add(makeDeviceIdentityPayloadFromNetwork()); 3710 3711 // Send IKE AUTH response to IKE state machine 3712 mIkeSessionStateMachine.sendMessage( 3713 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3714 makeIkeAuthRespWithoutChildPayloads(authRelatedPayloads)); 3715 mLooper.dispatchAll(); 3716 3717 IEapCallback callback = 3718 verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfigEapAka); 3719 callback.onResponse( 3720 EAP_DUMMY_MSG, EAP_RESPONSE_FLAG_MASK_WITH_EAP_AKA_SERVER_AUTHENTICATED); 3721 mLooper.dispatchAll(); 3722 verifyRetransmissionStarted(); 3723 3724 verify(mMockIkeMessageHelper, times(2)) 3725 .encryptAndEncode( 3726 any(), 3727 any(), 3728 eq(mSpyCurrentIkeSaRecord), 3729 mIkeMessageCaptor.capture(), 3730 anyBoolean(), 3731 anyInt()); 3732 IkeMessage ikeAuthReqMessage = mIkeMessageCaptor.getValue(); 3733 3734 // Validate the DEVICE_IDENTITY payload and the content sent to the network 3735 List<IkeNotifyPayload> notifyPayloads = 3736 ikeAuthReqMessage.getPayloadListForType( 3737 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 3738 IkeNotifyPayload deviceIdentityPayload = null; 3739 for (IkeNotifyPayload notifyPayload : notifyPayloads) { 3740 if (notifyPayload.notifyType == NOTIFY_TYPE_DEVICE_IDENTITY) { 3741 deviceIdentityPayload = notifyPayload; 3742 } 3743 } 3744 assertArrayEquals(DEVICE_IDENTITY_PAYLOAD_IMEI, deviceIdentityPayload.notifyData); 3745 3746 assertTrue( 3747 mIkeSessionStateMachine.getCurrentState() 3748 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap); 3749 } 3750 3751 @Test testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse()3752 public void testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse() throws Exception { 3753 mIkeSessionStateMachine.quitNow(); 3754 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3755 3756 // Setup state and go to IN_EAP state 3757 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3758 mLooper.dispatchAll(); 3759 3760 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3761 callback.onResponse(EAP_DUMMY_MSG, EAP_RESPONSE_FLAGS_NOT_SET); 3762 mLooper.dispatchAll(); 3763 verifyRetransmissionStarted(); 3764 3765 // Verify EAP response 3766 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 3767 IkeHeader ikeHeader = resp.ikeHeader; 3768 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 3769 assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType); 3770 assertFalse(ikeHeader.isResponseMsg); 3771 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 3772 3773 assertEquals(1, resp.ikePayloadList.size()); 3774 assertArrayEquals(EAP_DUMMY_MSG, ((IkeEapPayload) resp.ikePayloadList.get(0)).eapMessage); 3775 } 3776 3777 @Test testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket()3778 public void testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket() throws Exception { 3779 mIkeSessionStateMachine.quitNow(); 3780 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3781 3782 // Setup state and go to IN_EAP state 3783 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3784 mLooper.dispatchAll(); 3785 3786 // Mock sending IKE_AUTH{EAP} request 3787 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3788 callback.onResponse(EAP_DUMMY_MSG, EAP_RESPONSE_FLAGS_NOT_SET); 3789 mLooper.dispatchAll(); 3790 verifyRetransmissionStarted(); 3791 3792 // Send IKE AUTH response with no EAP Payload to IKE state machine 3793 mIkeSessionStateMachine.sendMessage( 3794 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 3795 makeIkeAuthRespWithoutChildPayloads(new ArrayList<>())); 3796 mLooper.dispatchAll(); 3797 3798 // Verify state machine quit properly 3799 verify(mMockIkeSessionCallback) 3800 .onClosedWithException(any(AuthenticationFailedException.class)); 3801 assertNull(mIkeSessionStateMachine.getCurrentState()); 3802 } 3803 3804 @Test testCreateIkeLocalIkeAuthInEapHandlesSuccess()3805 public void testCreateIkeLocalIkeAuthInEapHandlesSuccess() throws Exception { 3806 mIkeSessionStateMachine.quitNow(); 3807 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3808 3809 // Setup state and go to IN_EAP state 3810 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3811 mLooper.dispatchAll(); 3812 3813 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3814 3815 EapAkaInfo eapInfo = 3816 new EapAkaInfo.Builder().setReauthId(REAUTH_ID_BYTES).build(); 3817 3818 callback.onSuccess(mPsk, new byte[0], eapInfo); // use mPsk as MSK, eMSK does not matter 3819 mLooper.dispatchAll(); 3820 3821 assertTrue( 3822 mIkeSessionStateMachine.getCurrentState() 3823 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthPostEap); 3824 assertEquals(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap.mEapInfo, eapInfo); 3825 } 3826 3827 @Test testCreateIkeLocalIkeAuthInEapHandlesError()3828 public void testCreateIkeLocalIkeAuthInEapHandlesError() throws Exception { 3829 mIkeSessionStateMachine.quitNow(); 3830 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3831 3832 // Setup state and go to IN_EAP state 3833 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3834 mLooper.dispatchAll(); 3835 3836 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3837 3838 Throwable error = new IllegalArgumentException(); 3839 callback.onError(error); 3840 mLooper.dispatchAll(); 3841 3842 // Fires user error callbacks 3843 verify(mMockIkeSessionCallback) 3844 .onClosedWithException(argThat(err -> err.getCause() == error)); 3845 3846 // Verify state machine quit properly 3847 verify(mSpyCurrentIkeSaRecord).close(); 3848 assertNull(mIkeSessionStateMachine.getCurrentState()); 3849 } 3850 3851 @Test testCreateIkeLocalIkeAuthInEapHandlesFailure()3852 public void testCreateIkeLocalIkeAuthInEapHandlesFailure() throws Exception { 3853 mIkeSessionStateMachine.quitNow(); 3854 mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionParamsEap()); 3855 3856 // Setup state and go to IN_EAP state 3857 new IkeAuthInEapTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3858 mLooper.dispatchAll(); 3859 3860 IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback(mEapSessionConfig); 3861 callback.onFail(); 3862 mLooper.dispatchAll(); 3863 3864 // Fires user error callbacks 3865 verify(mMockIkeSessionCallback) 3866 .onClosedWithException(any(AuthenticationFailedException.class)); 3867 3868 // Verify state machine quit properly 3869 verify(mSpyCurrentIkeSaRecord).close(); 3870 assertNull(mIkeSessionStateMachine.getCurrentState()); 3871 } 3872 3873 @Test testCreateIkeLocalIkeAuthPostEap()3874 public void testCreateIkeLocalIkeAuthPostEap() throws Exception { 3875 verifyCreateIkeLocalIkeAuthPostEap( 3876 buildIkeSessionParamsEap(), 3877 new ArrayList<>() /* authRelatedPayloads */, 3878 false /* isMobikeEnabled */); 3879 } 3880 verifyCreateIkeLocalIkeAuthPostEap( IkeSessionParams params, List<IkePayload> authRelatedPayloads, boolean isMobikeEnabled)3881 private void verifyCreateIkeLocalIkeAuthPostEap( 3882 IkeSessionParams params, List<IkePayload> authRelatedPayloads, boolean isMobikeEnabled) 3883 throws Exception { 3884 mIkeSessionStateMachine.quitNow(); 3885 mIkeSessionStateMachine = makeAndStartIkeSession(params); 3886 3887 // Setup state and go to IN_EAP state 3888 IkeIdPayload initIdPayload = mock(IkeIdPayload.class); 3889 doReturn(new byte[0]).when(initIdPayload).getEncodedPayloadBody(); 3890 IkeIdPayload respIdPayload = makeRespIdPayload(); 3891 new IkeAuthPostEapTestPretest(initIdPayload, respIdPayload) 3892 .mockIkeInitAndTransitionToIkeAuth(); 3893 3894 EapAkaInfo eapInfo = 3895 new EapAkaInfo.Builder().setReauthId(REAUTH_ID_BYTES).build(); 3896 mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap.setEapInfo(eapInfo); 3897 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_EAP_FINISH_EAP_AUTH, mPsk); 3898 mLooper.dispatchAll(); 3899 verifyRetransmissionStarted(); 3900 3901 // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. 3902 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3903 authRelatedPayloads.add(spyAuthPayload); 3904 3905 verifySharedKeyAuthentication( 3906 spyAuthPayload, 3907 respIdPayload, 3908 authRelatedPayloads, 3909 false /*hasChildPayloads*/, 3910 false /*hasConfigPayloadInResp*/, 3911 isMobikeEnabled, 3912 true /* isIpv4 */, 3913 0 /* ike3gppDataListenerInvocations */); 3914 verifyRetransmissionStopped(); 3915 3916 ArgumentCaptor<IkeSessionConfiguration> ikeSessionConfigurationArgumentCaptor = 3917 ArgumentCaptor.forClass(IkeSessionConfiguration.class); 3918 verify(mMockIkeSessionCallback).onOpened(ikeSessionConfigurationArgumentCaptor.capture()); 3919 3920 IkeSessionConfiguration sessionConfig = ikeSessionConfigurationArgumentCaptor.getValue(); 3921 assertNotNull(sessionConfig); 3922 assertArrayEquals(REAUTH_ID_BYTES, ((EapAkaInfo) sessionConfig.getEapInfo()).getReauthId()); 3923 } 3924 3925 @Test testCreateIkeLocalIkeAuthHandlesFirstFrag()3926 public void testCreateIkeLocalIkeAuthHandlesFirstFrag() throws Exception { 3927 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3928 verifyRetransmissionStarted(); 3929 3930 // Received IKE fragment 3931 byte[] unencryptedData = "testCreateIkeLocalIkeAuthHandlesFrag".getBytes(); 3932 int fragNum = 1; 3933 int totalFragments = 2; 3934 IkeSkfPayload skfPayload = 3935 IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); 3936 3937 ReceivedIkePacket packet = 3938 makeDummyReceivedIkeFragmentPacket( 3939 mSpyCurrentIkeSaRecord, 3940 true /*isResp*/, 3941 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 3942 skfPayload, 3943 PAYLOAD_TYPE_AUTH, 3944 null /* collectedFrags*/); 3945 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 3946 mLooper.dispatchAll(); 3947 3948 // Verify state doesn't change 3949 assertTrue( 3950 mIkeSessionStateMachine.getCurrentState() 3951 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 3952 3953 // Verify the IkeSaRecord has stored the fragment. 3954 DecodeResultPartial resultPartial = 3955 mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/); 3956 assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType); 3957 assertEquals(totalFragments, resultPartial.collectedFragsList.length); 3958 assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); 3959 assertFalse(resultPartial.isAllFragmentsReceived()); 3960 3961 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(false /*isResp*/)); 3962 } 3963 3964 @Test testCreateIkeLocalIkeAuthHandlesLastFragOk()3965 public void testCreateIkeLocalIkeAuthHandlesLastFragOk() throws Exception { 3966 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 3967 verifyRetransmissionStarted(); 3968 3969 // Set previously collected IKE fragments 3970 DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); 3971 mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); 3972 3973 // Build reassembled IKE AUTH response with Auth-PSK Payload and ID-Responder Payload. 3974 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 3975 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 3976 authRelatedPayloads.add(spyAuthPayload); 3977 3978 IkeIdPayload respIdPayload = makeRespIdPayload(); 3979 authRelatedPayloads.add(respIdPayload); 3980 3981 List<IkePayload> authPayloadList = 3982 getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads); 3983 3984 // Receive last auth response and do IKE_AUTH 3985 ReceivedIkePacket packet = 3986 makeDummyReceivedLastIkeFragmentPacketOk( 3987 mSpyCurrentIkeSaRecord, 3988 true /*isResp*/, 3989 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 3990 mockCollectedFrags, 3991 authPayloadList, 3992 "FirstFrag".getBytes()); 3993 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 3994 mLooper.dispatchAll(); 3995 3996 // Verify IKE AUTH is done 3997 assertTrue( 3998 mIkeSessionStateMachine.getCurrentState() 3999 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 4000 4001 // Verify collected response fragments are cleared. 4002 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); 4003 verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); 4004 } 4005 4006 @Test testCreateIkeLocalIkeAuthHandlesLastFragError()4007 public void testCreateIkeLocalIkeAuthHandlesLastFragError() throws Exception { 4008 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 4009 verifyRetransmissionStarted(); 4010 resetMockIkeMessageHelper(); 4011 4012 // Set previously collected IKE fragments 4013 DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class); 4014 mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/); 4015 4016 // Receive last auth response with syntax error 4017 ReceivedIkePacket packet = 4018 makeDummyReceivedLastIkeFragmentPacketError( 4019 mSpyCurrentIkeSaRecord, 4020 true /*isResp*/, 4021 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 4022 mockCollectedFrags, 4023 new InvalidSyntaxException("IkeStateMachineTest")); 4024 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 4025 mLooper.dispatchAll(); 4026 4027 // Verify Delete request is sent 4028 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 4029 assertEquals(1, payloads.size()); 4030 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 4031 4032 // Verify IKE Session is closed properly 4033 assertNull(mIkeSessionStateMachine.getCurrentState()); 4034 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 4035 4036 // Collected response fragments are cleared 4037 assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/)); 4038 verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/); 4039 } 4040 4041 @Test testRekeyIkeLocalCreateSendsRequest()4042 public void testRekeyIkeLocalCreateSendsRequest() throws Exception { 4043 setupIdleStateMachine(); 4044 4045 // Send Rekey-Create request 4046 mIkeSessionStateMachine.sendMessage( 4047 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4048 mLocalRequestFactory.getIkeLocalRequest( 4049 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4050 mLooper.dispatchAll(); 4051 assertTrue( 4052 mIkeSessionStateMachine.getCurrentState() 4053 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4054 verifyRetransmissionStarted(); 4055 4056 // Verify outbound message 4057 IkeMessage rekeyMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4058 4059 IkeHeader ikeHeader = rekeyMsg.ikeHeader; 4060 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4061 assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType); 4062 assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId); 4063 assertFalse(ikeHeader.isResponseMsg); 4064 assertTrue(ikeHeader.fromIkeInitiator); 4065 4066 // Verify SA payload & proposals 4067 IkeSaPayload saPayload = 4068 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class); 4069 assertFalse(saPayload.isSaResponse); 4070 assertEquals(1, saPayload.proposalList.size()); 4071 4072 IkeSaPayload.IkeProposal proposal = 4073 (IkeSaPayload.IkeProposal) saPayload.proposalList.get(0); 4074 assertEquals(1, proposal.number); // Must be 1-indexed 4075 assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId); 4076 assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize); 4077 assertEquals(mIkeSessionStateMachine.mSaProposal, proposal.saProposal); 4078 4079 // Verify Nonce and KE payloads exist. 4080 assertNotNull( 4081 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); 4082 4083 IkeKePayload kePayload = 4084 rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class); 4085 assertNotNull(kePayload); 4086 assertTrue(kePayload.isOutbound); 4087 } 4088 4089 @Test testRekeyIkeLocalCreateHandlesResponse()4090 public void testRekeyIkeLocalCreateHandlesResponse() throws Exception { 4091 setupIdleStateMachine(); 4092 4093 verifyRekeyIkeLocalCreateHandlesResponse(); 4094 } 4095 verifyRekeyIkeLocalCreateHandlesResponse()4096 private void verifyRekeyIkeLocalCreateHandlesResponse() throws Exception { 4097 // Send Rekey-Create request 4098 mIkeSessionStateMachine.sendMessage( 4099 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4100 mLocalRequestFactory.getIkeLocalRequest( 4101 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4102 mLooper.dispatchAll(); 4103 verifyRetransmissionStarted(); 4104 4105 // Prepare "rekeyed" SA 4106 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 4107 4108 // Receive Rekey response 4109 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 4110 mIkeSessionStateMachine.sendMessage( 4111 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 4112 mLooper.dispatchAll(); 4113 verifyIncrementLocaReqMsgId(); 4114 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); 4115 4116 // Verify in delete state, and new SA record was saved: 4117 assertTrue( 4118 mIkeSessionStateMachine.getCurrentState() 4119 instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); 4120 verifyRetransmissionStarted(); 4121 assertEquals(mSpyLocalInitIkeSaRecord, mIkeSessionStateMachine.mLocalInitNewIkeSaRecord); 4122 verify(mSpyIkeConnectionCtrl.getIkeSocket()) 4123 .registerIke(eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mSpyIkeConnectionCtrl)); 4124 verifyIkeSaMetricsLogged( 4125 1, 4126 IkeMetrics.IKE_CALLER_UNKNOWN, 4127 IkeMetrics.IKE_SESSION_TYPE_IKE, 4128 IkeMetrics.IKE_STATE_IKE_REKEY_LOCAL_CREATE, 4129 SaProposal.DH_GROUP_1024_BIT_MODP, 4130 IkeMetrics.ENCRYPTION_ALGORITHM_AES_CBC, 4131 IkeMetrics.KEY_LEN_AES_128, 4132 IkeMetrics.INTEGRITY_ALGORITHM_HMAC_SHA1_96, 4133 IkeMetrics.PSEUDORANDOM_FUNCTION_HMAC_SHA1, 4134 IkeMetrics.IKE_ERROR_NONE); 4135 } 4136 4137 @Test testRekeyIkeLocalCreateHandleRespWithParsingError()4138 public void testRekeyIkeLocalCreateHandleRespWithParsingError() throws Exception { 4139 setupIdleStateMachine(); 4140 4141 // Send Rekey-Create request 4142 mIkeSessionStateMachine.sendMessage( 4143 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4144 mLocalRequestFactory.getIkeLocalRequest( 4145 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4146 mLooper.dispatchAll(); 4147 verifyRetransmissionStarted(); 4148 resetMockIkeMessageHelper(); 4149 4150 // Mock receiving packet with syntax error 4151 ReceivedIkePacket mockInvalidPacket = 4152 makeDummyReceivedIkePacketWithInvalidSyntax( 4153 mSpyCurrentIkeSaRecord, 4154 true /*isResp*/, 4155 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 4156 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 4157 mLooper.dispatchAll(); 4158 4159 // Verify Delete request was sent 4160 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 4161 assertEquals(1, payloads.size()); 4162 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 4163 4164 // Verify IKE Session is closed properly 4165 assertNull(mIkeSessionStateMachine.getCurrentState()); 4166 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 4167 } 4168 4169 @Test testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify()4170 public void testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify() throws Exception { 4171 setupIdleStateMachine(); 4172 4173 // Send Rekey-Create request 4174 mIkeSessionStateMachine.sendMessage( 4175 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4176 mLocalRequestFactory.getIkeLocalRequest( 4177 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4178 mLooper.dispatchAll(); 4179 4180 // Mock receiving packet with NO_PROPOSAL_CHOSEN 4181 ReceivedIkePacket resp = 4182 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN)); 4183 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 4184 mLooper.dispatchAll(); 4185 4186 // Verify IKE Session goes back to Idle and retry is scheduled 4187 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 4188 assertTrue( 4189 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4190 } 4191 4192 @Test testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify()4193 public void testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify() throws Exception { 4194 setupIdleStateMachine(); 4195 4196 // Send Rekey-Create request 4197 mIkeSessionStateMachine.sendMessage( 4198 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4199 mLocalRequestFactory.getIkeLocalRequest( 4200 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4201 mLooper.dispatchAll(); 4202 resetMockIkeMessageHelper(); 4203 4204 // Mock receiving packet with NO_PROPOSAL_CHOSEN 4205 ReceivedIkePacket resp = 4206 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX)); 4207 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 4208 mLooper.dispatchAll(); 4209 4210 // Verify no message was sent because a fatal error notification was received 4211 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 4212 4213 // Verify IKE Session is closed properly 4214 assertNull(mIkeSessionStateMachine.getCurrentState()); 4215 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 4216 } 4217 4218 @Test testRekeyIkeLocalCreateSaCreationFail()4219 public void testRekeyIkeLocalCreateSaCreationFail() throws Exception { 4220 // Throw error when building new IKE SA 4221 throwExceptionWhenMakeRekeyIkeSa( 4222 new GeneralSecurityException("testRekeyIkeLocalCreateSaCreationFail")); 4223 4224 setupIdleStateMachine(); 4225 4226 // Send Rekey-Create request 4227 mIkeSessionStateMachine.sendMessage( 4228 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4229 mLocalRequestFactory.getIkeLocalRequest( 4230 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4231 mLooper.dispatchAll(); 4232 resetMockIkeMessageHelper(); 4233 4234 // Receive Rekey response 4235 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 4236 mIkeSessionStateMachine.sendMessage( 4237 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 4238 mLooper.dispatchAll(); 4239 4240 // Verify Delete request was sent 4241 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/); 4242 assertEquals(1, payloads.size()); 4243 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType); 4244 4245 // Verify IKE Session is closed properly 4246 assertNull(mIkeSessionStateMachine.getCurrentState()); 4247 verify(mMockIkeSessionCallback).onClosedWithException(any(IkeInternalException.class)); 4248 } 4249 4250 @Test testRekeyIkeLocalCreateHandleReqWithNonFatalError()4251 public void testRekeyIkeLocalCreateHandleReqWithNonFatalError() throws Exception { 4252 setupIdleStateMachine(); 4253 4254 // Send Rekey-Create request 4255 mIkeSessionStateMachine.sendMessage( 4256 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4257 mLocalRequestFactory.getIkeLocalRequest( 4258 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4259 mLooper.dispatchAll(); 4260 verifyRetransmissionStarted(); 4261 resetMockIkeMessageHelper(); 4262 4263 // Build protocol exception 4264 List<Integer> unsupportedPayloads = new ArrayList<>(); 4265 unsupportedPayloads.add(PAYLOAD_TYPE_UNSUPPORTED); 4266 UnsupportedCriticalPayloadException exception = 4267 new UnsupportedCriticalPayloadException(unsupportedPayloads); 4268 4269 // Mock receiving packet with unsupported critical payload 4270 ReceivedIkePacket mockInvalidPacket = 4271 makeDummyReceivedIkePacketWithDecodingError( 4272 mSpyCurrentIkeSaRecord, 4273 false /*isResp*/, 4274 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 4275 exception); 4276 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 4277 mLooper.dispatchAll(); 4278 4279 // Verify error notification was sent 4280 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 4281 assertEquals(1, payloads.size()); 4282 4283 IkePayload payload = payloads.get(0); 4284 assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); 4285 assertEquals( 4286 ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, ((IkeNotifyPayload) payload).notifyType); 4287 4288 // Verify IKE Session stays in the same state 4289 assertTrue( 4290 mIkeSessionStateMachine.getCurrentState() 4291 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4292 } 4293 mockRescheduleRekey(IkeSaRecord spySaRecord)4294 private void mockRescheduleRekey(IkeSaRecord spySaRecord) { 4295 IkeLocalRequest rekeyReq = 4296 mLocalRequestFactory.getIkeLocalRequest( 4297 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE); 4298 doAnswer( 4299 (invocation) -> { 4300 mIkeSessionStateMachine.sendMessageDelayed( 4301 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 4302 rekeyReq, 4303 RETRY_INTERVAL_MS); 4304 return null; 4305 }) 4306 .when(spySaRecord) 4307 .rescheduleRekey(eq(RETRY_INTERVAL_MS)); 4308 } 4309 4310 @Test testRekeyIkeLocalCreateHandleRespWithTempFailure()4311 public void testRekeyIkeLocalCreateHandleRespWithTempFailure() throws Exception { 4312 setupIdleStateMachine(); 4313 4314 // Send Rekey-Create request 4315 mIkeSessionStateMachine.sendMessage( 4316 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4317 mLocalRequestFactory.getIkeLocalRequest( 4318 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4319 mLooper.dispatchAll(); 4320 4321 // Mock sending TEMPORARY_FAILURE response 4322 mockRcvTempFail(); 4323 mLooper.dispatchAll(); 4324 4325 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 4326 assertTrue( 4327 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4328 } 4329 mockCreateAndTransitionToRekeyDeleteLocal()4330 private void mockCreateAndTransitionToRekeyDeleteLocal() { 4331 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 4332 mIkeSessionStateMachine.mLocalInitNewIkeSaRecord = mSpyLocalInitIkeSaRecord; 4333 mIkeSessionStateMachine.addIkeSaRecord(mSpyLocalInitIkeSaRecord); 4334 mIkeSessionStateMachine.sendMessage( 4335 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4336 mIkeSessionStateMachine.mRekeyIkeLocalDelete); 4337 mLooper.dispatchAll(); 4338 verifyRetransmissionStarted(); 4339 } 4340 4341 @Test testRekeyIkeLocalDeleteSendsRequest()4342 public void testRekeyIkeLocalDeleteSendsRequest() throws Exception { 4343 setupIdleStateMachine(); 4344 mockCreateAndTransitionToRekeyDeleteLocal(); 4345 4346 // Verify Rekey-Delete request 4347 assertTrue( 4348 mIkeSessionStateMachine.getCurrentState() 4349 instanceof IkeSessionStateMachine.RekeyIkeLocalDelete); 4350 verifyRetransmissionStarted(); 4351 4352 // Verify outbound message 4353 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4354 4355 IkeHeader ikeHeader = delMsg.ikeHeader; 4356 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi); 4357 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi); 4358 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 4359 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 4360 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 4361 assertFalse(ikeHeader.isResponseMsg); 4362 4363 List<IkeDeletePayload> deletePayloadList = 4364 delMsg.getPayloadListForType( 4365 IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); 4366 assertEquals(1, deletePayloadList.size()); 4367 4368 IkeDeletePayload deletePayload = deletePayloadList.get(0); 4369 assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); 4370 assertEquals(0, deletePayload.numSpi); 4371 assertEquals(0, deletePayload.spiSize); 4372 assertArrayEquals(new int[0], deletePayload.spisToDelete); 4373 } 4374 verifyRekeyReplaceSa(IkeSaRecord newSaRecord)4375 private void verifyRekeyReplaceSa(IkeSaRecord newSaRecord) { 4376 verify(mSpyCurrentIkeSaRecord).close(); 4377 verify(mMockCurrentIkeSocket).unregisterIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi())); 4378 verify(mMockCurrentIkeSocket, never()).unregisterIke(eq(newSaRecord.getLocalSpi())); 4379 4380 assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, newSaRecord); 4381 4382 verify(mMockChildSessionStateMachine).setSkD(newSaRecord.getSkD()); 4383 } 4384 4385 @Test testRekeyIkeLocalDeleteHandlesResponse()4386 public void testRekeyIkeLocalDeleteHandlesResponse() throws Exception { 4387 setupIdleStateMachine(); 4388 mockCreateAndTransitionToRekeyDeleteLocal(); 4389 4390 // Receive Delete response 4391 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 4392 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 4393 mIkeSessionStateMachine.sendMessage( 4394 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 4395 mLooper.dispatchAll(); 4396 verifyIncrementLocaReqMsgId(); 4397 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); 4398 4399 // Verify final state - Idle, with new SA, and old SA closed. 4400 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 4401 verify(mMockIkeSessionCallback, never()).onClosed(); 4402 assertTrue( 4403 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4404 verifyRetransmissionStopped(); 4405 } 4406 4407 @Ignore disableTestRekeyIkeLocalDeleteHandlesRespWithParsingError()4408 public void disableTestRekeyIkeLocalDeleteHandlesRespWithParsingError() throws Exception { 4409 setupIdleStateMachine(); 4410 mockCreateAndTransitionToRekeyDeleteLocal(); 4411 resetMockIkeMessageHelper(); 4412 4413 // Mock receiving packet with syntax error 4414 ReceivedIkePacket mockInvalidPacket = 4415 makeDummyReceivedIkePacketWithInvalidSyntax( 4416 mSpyCurrentIkeSaRecord, 4417 true /*isResp*/, 4418 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 4419 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 4420 mLooper.dispatchAll(); 4421 4422 // Verify no more request out 4423 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 4424 4425 // Verify final state - Idle, with new SA, and old SA closed. 4426 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 4427 assertTrue( 4428 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4429 verifyRetransmissionStopped(); 4430 } 4431 4432 @Test testRekeyIkeLocalDeleteWithRequestOnNewSa()4433 public void testRekeyIkeLocalDeleteWithRequestOnNewSa() throws Exception { 4434 setupIdleStateMachine(); 4435 mockCreateAndTransitionToRekeyDeleteLocal(); 4436 4437 // Receive an empty (DPD) request on the new IKE SA 4438 mIkeSessionStateMachine.sendMessage( 4439 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 4440 makeDpdIkeRequest(mSpyLocalInitIkeSaRecord)); 4441 mLooper.dispatchAll(); 4442 4443 // Verify final state - Idle, with new SA, and old SA closed. 4444 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 4445 assertTrue( 4446 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4447 verifyRetransmissionStopped(); 4448 } 4449 4450 @Test testRekeyIkeLocalDeleteWithRequestFragOnNewSa()4451 public void testRekeyIkeLocalDeleteWithRequestFragOnNewSa() throws Exception { 4452 setupIdleStateMachine(); 4453 mockCreateAndTransitionToRekeyDeleteLocal(); 4454 4455 // Received IKE fragment 4456 byte[] unencryptedData = "testRekeyIkeLocalDeleteWithRequestFragOnNewSa".getBytes(); 4457 int fragNum = 1; 4458 int totalFragments = 2; 4459 IkeSkfPayload skfPayload = 4460 IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments); 4461 4462 ReceivedIkePacket packet = 4463 makeDummyReceivedIkeFragmentPacket( 4464 mSpyLocalInitIkeSaRecord, 4465 false /*isResp*/, 4466 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 4467 skfPayload, 4468 PAYLOAD_TYPE_SA, 4469 null /* collectedFrags*/); 4470 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 4471 mLooper.dispatchAll(); 4472 4473 // Verify rekey is done. 4474 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 4475 verifyRetransmissionStopped(); 4476 4477 // Verify the IkeSaRecord has stored the new fragment. 4478 DecodeResultPartial resultPartial = 4479 mSpyLocalInitIkeSaRecord.getCollectedFragments(false /*isResp*/); 4480 assertEquals(PAYLOAD_TYPE_SA, resultPartial.firstPayloadType); 4481 assertEquals(totalFragments, resultPartial.collectedFragsList.length); 4482 assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]); 4483 assertFalse(resultPartial.isAllFragmentsReceived()); 4484 } 4485 4486 @Test testRekeyIkeRemoteDeleteWithRequestOnNewSa()4487 public void testRekeyIkeRemoteDeleteWithRequestOnNewSa() throws Exception { 4488 setupIdleStateMachine(); 4489 4490 // Seed fake rekey data and force transition to RekeyIkeRemoteDelete 4491 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 4492 mIkeSessionStateMachine.addIkeSaRecord(mSpyRemoteInitIkeSaRecord); 4493 mIkeSessionStateMachine.sendMessage( 4494 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4495 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4496 mLooper.dispatchAll(); 4497 4498 // Receive an empty (DPD) request on the new IKE SA 4499 mIkeSessionStateMachine.sendMessage( 4500 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 4501 makeDpdIkeRequest(mSpyRemoteInitIkeSaRecord)); 4502 mLooper.dispatchAll(); 4503 4504 // Verify final state - Idle, with new SA, and old SA closed. 4505 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 4506 assertTrue( 4507 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4508 } 4509 4510 @Test testRekeyIkeRemoteCreate()4511 public void testRekeyIkeRemoteCreate() throws Exception { 4512 setupIdleStateMachine(); 4513 4514 setupRekeyedIkeSa(mSpyRemoteInitIkeSaRecord); 4515 4516 // Receive Rekey request 4517 ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); 4518 mIkeSessionStateMachine.sendMessage( 4519 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); 4520 mLooper.dispatchAll(); 4521 verifyIncrementRemoteReqMsgId(); 4522 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); 4523 4524 // Verify SA created with correct parameters 4525 ArgumentCaptor<SaRecord.IkeSaRecordConfig> recordConfigCaptor = 4526 ArgumentCaptor.forClass(SaRecord.IkeSaRecordConfig.class); 4527 verify(mMockSaRecordHelper) 4528 .makeRekeyedIkeSaRecord(any(), any(), any(), any(), recordConfigCaptor.capture()); 4529 assertEquals(IKE_REKEY_SA_INITIATOR_SPI, recordConfigCaptor.getValue().initSpi.getSpi()); 4530 4531 // Verify outbound CREATE_CHILD_SA message 4532 IkeMessage rekeyCreateResp = 4533 verifyAndGetOutboundEncryptedResp(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 4534 assertNotNull( 4535 rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class)); 4536 assertNotNull( 4537 rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class)); 4538 assertNotNull( 4539 rekeyCreateResp.getPayloadForType( 4540 IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)); 4541 4542 // Verify SA, StateMachine state 4543 assertEquals(mSpyCurrentIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordAwaitingRemoteDel); 4544 assertEquals(mSpyRemoteInitIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordSurviving); 4545 assertTrue( 4546 mIkeSessionStateMachine.getCurrentState() 4547 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 4548 verify(mMockCurrentIkeSocket) 4549 .registerIke( 4550 eq(mSpyRemoteInitIkeSaRecord.getLocalSpi()), eq(mSpyIkeConnectionCtrl)); 4551 4552 // IKE_STATE_IKE_RECEIVING for remote rekey 4553 verifyIkeSaMetricsLogged( 4554 1, 4555 IkeMetrics.IKE_CALLER_UNKNOWN, 4556 IkeMetrics.IKE_SESSION_TYPE_IKE, 4557 IkeMetrics.IKE_STATE_IKE_RECEIVING, 4558 SaProposal.DH_GROUP_1024_BIT_MODP, 4559 IkeMetrics.ENCRYPTION_ALGORITHM_AES_CBC, 4560 IkeMetrics.KEY_LEN_AES_128, 4561 IkeMetrics.INTEGRITY_ALGORITHM_HMAC_SHA1_96, 4562 IkeMetrics.PSEUDORANDOM_FUNCTION_HMAC_SHA1, 4563 IkeMetrics.IKE_ERROR_NONE); 4564 } 4565 4566 @Ignore disableTestRekeyIkeRemoteCreateHandlesInvalidReq()4567 public void disableTestRekeyIkeRemoteCreateHandlesInvalidReq() throws Exception { 4568 setupIdleStateMachine(); 4569 4570 // Receive Rekey request 4571 ReceivedIkePacket request = makeRekeyIkeRequestWithUnacceptableProposal(); 4572 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4573 mLooper.dispatchAll(); 4574 4575 verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); 4576 } 4577 4578 @Ignore disableTestRekeyIkeRemoteCreateSaCreationFailure()4579 public void disableTestRekeyIkeRemoteCreateSaCreationFailure() throws Exception { 4580 // Throw error when building new IKE SA 4581 throwExceptionWhenMakeRekeyIkeSa( 4582 new GeneralSecurityException("testRekeyIkeRemoteCreateSaCreationFailure")); 4583 setupIdleStateMachine(); 4584 4585 // Receive Rekey request 4586 ReceivedIkePacket request = makeRekeyIkeRequest(); 4587 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4588 mLooper.dispatchAll(); 4589 4590 verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); 4591 } 4592 4593 @Test testRekeyIkeRemoteCreateHandlesInvalidKePayload()4594 public void testRekeyIkeRemoteCreateHandlesInvalidKePayload() throws Exception { 4595 setupIdleStateMachine(); 4596 4597 // Build Rekey request 4598 // SA Payload: ENCR_AES_CBC(128)|AUTH_HMAC_SHA1_96|DH_1024_BIT_MODP|PRF_HMAC_SHA1 4599 IkePayload saPayload = 4600 IkeTestUtils.hexStringToIkePayload( 4601 IkePayload.PAYLOAD_TYPE_SA, 4602 false /*isResp*/, 4603 IKE_REKEY_SA_PAYLOAD_HEX_STRING); 4604 4605 // Unrecognized DH Group: 0x0fff 4606 String unrecognizedKePayload = 4607 "280000880fff0000b4a2faf4bb54878ae21d638512ece55d9236fc50" 4608 + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa" 4609 + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd" 4610 + "92f46bef84f0be7db860351843858f8acf87056e272377f7" 4611 + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2" 4612 + "6bbeb08214c7071376079587"; 4613 IkePayload kePayload = 4614 IkeTestUtils.hexStringToIkePayload( 4615 IkePayload.PAYLOAD_TYPE_KE, false /*isResp*/, unrecognizedKePayload); 4616 4617 IkePayload noncePayload = 4618 IkeTestUtils.hexStringToIkePayload( 4619 IkePayload.PAYLOAD_TYPE_NONCE, 4620 false /*isResp*/, 4621 NONCE_INIT_PAYLOAD_HEX_STRING); 4622 4623 ReceivedIkePacket request = 4624 makeDummyEncryptedReceivedIkePacketWithPayloadList( 4625 mSpyCurrentIkeSaRecord, 4626 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 4627 false /*isResp*/, 4628 Arrays.asList(saPayload, kePayload, noncePayload)); 4629 4630 // Receive Rekey request 4631 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4632 mLooper.dispatchAll(); 4633 4634 verifyProcessRekeyReqFailure(ERROR_TYPE_INVALID_KE_PAYLOAD); 4635 } 4636 4637 @Test testRejectRemoteRekeyWithoutDhGroupInProposal()4638 public void testRejectRemoteRekeyWithoutDhGroupInProposal() throws Exception { 4639 setupIdleStateMachine(); 4640 4641 // Build a Rekey request that does not propose DH groups. 4642 String rekeySaPayloadWithoutDhGroup = 4643 "22000038000000340101080400000000000000FF0300000c0100000c800e0080030" 4644 + "000080300000203000008020000020000000802000002"; 4645 IkePayload saPayload = 4646 IkeTestUtils.hexStringToIkePayload( 4647 IkePayload.PAYLOAD_TYPE_SA, false /*isResp*/, rekeySaPayloadWithoutDhGroup); 4648 IkePayload kePayload = 4649 IkeTestUtils.hexStringToIkePayload( 4650 IkePayload.PAYLOAD_TYPE_KE, false /*isResp*/, KE_PAYLOAD_HEX_STRING); 4651 IkePayload noncePayload = 4652 IkeTestUtils.hexStringToIkePayload( 4653 IkePayload.PAYLOAD_TYPE_NONCE, 4654 false /*isResp*/, 4655 NONCE_INIT_PAYLOAD_HEX_STRING); 4656 ReceivedIkePacket request = 4657 makeRekeyIkeRequestWithPayloads(Arrays.asList(saPayload, kePayload, noncePayload)); 4658 4659 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4660 mLooper.dispatchAll(); 4661 4662 verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN); 4663 } 4664 4665 @Test testRejectRemoteRekeyWithoutKePayload()4666 public void testRejectRemoteRekeyWithoutKePayload() throws Exception { 4667 setupIdleStateMachine(); 4668 4669 // Build a Rekey request that proposes DH groups but does not include a KE payload 4670 IkePayload saPayload = 4671 IkeTestUtils.hexStringToIkePayload( 4672 IkePayload.PAYLOAD_TYPE_SA, 4673 false /*isResp*/, 4674 IKE_REKEY_SA_PAYLOAD_HEX_STRING); 4675 IkePayload noncePayload = 4676 IkeTestUtils.hexStringToIkePayload( 4677 IkePayload.PAYLOAD_TYPE_NONCE, 4678 false /*isResp*/, 4679 NONCE_INIT_PAYLOAD_HEX_STRING); 4680 ReceivedIkePacket request = 4681 makeRekeyIkeRequestWithPayloads(Arrays.asList(saPayload, noncePayload)); 4682 4683 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 4684 mLooper.dispatchAll(); 4685 4686 verifyProcessRekeyReqFailure(ERROR_TYPE_INVALID_SYNTAX); 4687 } 4688 verifyProcessRekeyReqFailure(int expectedErrorCode)4689 private void verifyProcessRekeyReqFailure(int expectedErrorCode) { 4690 // Verify IKE Session is back to Idle 4691 assertTrue( 4692 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4693 4694 // Verify error notification was sent 4695 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 4696 assertEquals(1, payloads.size()); 4697 IkeNotifyPayload notify = (IkeNotifyPayload) payloads.get(0); 4698 assertEquals(expectedErrorCode, notify.notifyType); 4699 } 4700 4701 @Test testRekeyIkeRemoteDelete()4702 public void testRekeyIkeRemoteDelete() throws Exception { 4703 setupIdleStateMachine(); 4704 4705 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 4706 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 4707 mIkeSessionStateMachine.sendMessage( 4708 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4709 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4710 mLooper.dispatchAll(); 4711 4712 // Rekey Delete request 4713 ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket = 4714 makeDeleteIkeRequest(mSpyCurrentIkeSaRecord); 4715 mIkeSessionStateMachine.sendMessage( 4716 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket); 4717 mLooper.dispatchAll(); 4718 verifyIncrementRemoteReqMsgId(); 4719 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); 4720 4721 // Verify outbound DELETE_IKE_SA message 4722 IkeMessage rekeyDeleteResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 4723 IkeHeader rekeyDeleteRespHeader = rekeyDeleteResp.ikeHeader; 4724 assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyDeleteRespHeader.nextPayloadType); 4725 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, rekeyDeleteRespHeader.exchangeType); 4726 assertTrue(rekeyDeleteRespHeader.isResponseMsg); 4727 assertTrue(rekeyDeleteRespHeader.fromIkeInitiator); 4728 assertTrue(rekeyDeleteResp.ikePayloadList.isEmpty()); 4729 4730 // Verify final state - Idle, with new SA, and old SA closed. 4731 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 4732 4733 verify(mMockIkeSessionCallback, never()).onClosed(); 4734 4735 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket); 4736 assertTrue( 4737 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4738 } 4739 4740 @Test testRekeyIkeRemoteDeleteExitAndRenter()4741 public void testRekeyIkeRemoteDeleteExitAndRenter() throws Exception { 4742 setupIdleStateMachine(); 4743 4744 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 4745 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 4746 mIkeSessionStateMachine.sendMessage( 4747 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4748 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4749 mLooper.dispatchAll(); 4750 4751 // Trigger a timeout, and immediately re-enter remote-delete 4752 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); 4753 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE); 4754 mIkeSessionStateMachine.sendMessage( 4755 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4756 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4757 mLooper.dispatchAll(); 4758 4759 // Shift time forward, and assert the previous timeout was NOT fired. 4760 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1); 4761 mLooper.dispatchAll(); 4762 4763 // Verify no request received, or response sent. 4764 verify(mMockIkeMessageHelper, never()).decode(anyInt(), any(), any()); 4765 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 4766 4767 // Verify final state has not changed - signal was not sent. 4768 assertTrue( 4769 mIkeSessionStateMachine.getCurrentState() 4770 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 4771 } 4772 4773 @Test testRekeyIkeRemoteDeleteTimedOut()4774 public void testRekeyIkeRemoteDeleteTimedOut() throws Exception { 4775 setupIdleStateMachine(); 4776 4777 // Seed fake rekey data and force transition to RekeyIkeLocalDelete 4778 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 4779 mIkeSessionStateMachine.sendMessage( 4780 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 4781 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 4782 mLooper.dispatchAll(); 4783 4784 mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS); 4785 mLooper.dispatchAll(); 4786 4787 // Verify no request received, or response sent. 4788 verify(mMockIkeMessageHelper, never()).decode(anyInt(), any(), any()); 4789 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 4790 4791 // Verify final state - Idle, with new SA, and old SA closed. 4792 verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord); 4793 4794 assertTrue( 4795 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4796 } 4797 4798 @Ignore disableTestSimulRekey()4799 public void disableTestSimulRekey() throws Exception { 4800 setupIdleStateMachine(); 4801 4802 // Prepare "rekeyed" SA 4803 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 4804 doReturn(1).when(mSpyLocalInitIkeSaRecord).compareTo(mSpyRemoteInitIkeSaRecord); 4805 4806 // Send Rekey request on mSpyCurrentIkeSaRecord 4807 mIkeSessionStateMachine.sendMessage( 4808 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4809 mLocalRequestFactory.getIkeLocalRequest( 4810 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4811 4812 // Receive Rekey request on mSpyCurrentIkeSaRecord 4813 ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest(); 4814 mIkeSessionStateMachine.sendMessage( 4815 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket); 4816 mLooper.dispatchAll(); 4817 verifyIncrementRemoteReqMsgId(); 4818 4819 // Receive Rekey response on mSpyCurrentIkeSaRecord 4820 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 4821 mIkeSessionStateMachine.sendMessage( 4822 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 4823 mLooper.dispatchAll(); 4824 verifyIncrementLocaReqMsgId(); 4825 verify(mMockCurrentIkeSocket) 4826 .registerIke(eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mSpyIkeConnectionCtrl)); 4827 4828 // Receive Delete response on mSpyCurrentIkeSaRecord 4829 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 4830 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 4831 mIkeSessionStateMachine.sendMessage( 4832 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 4833 mLooper.dispatchAll(); 4834 verifyIncrementLocaReqMsgId(); 4835 4836 // Verify 4837 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket); 4838 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket); 4839 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket); 4840 assertTrue( 4841 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 4842 4843 verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord); 4844 verify(mMockIkeSessionCallback, never()).onClosed(); 4845 } 4846 4847 @Test testOpenIkeSession()4848 public void testOpenIkeSession() throws Exception { 4849 assertTrue( 4850 mIkeSessionStateMachine.getCurrentState() 4851 instanceof IkeSessionStateMachine.Initial); 4852 4853 mIkeSessionStateMachine.openSession(); 4854 mLooper.dispatchAll(); 4855 4856 assertTrue( 4857 mIkeSessionStateMachine.getCurrentState() 4858 instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit); 4859 } 4860 4861 @Test testIkeInitSchedulesRekey()4862 public void testIkeInitSchedulesRekey() throws Exception { 4863 setupFirstIkeSa(); 4864 4865 // Send IKE INIT request 4866 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 4867 4868 // Receive IKE INIT response 4869 ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse(); 4870 mIkeSessionStateMachine.sendMessage( 4871 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket); 4872 4873 // Mock IKE AUTH and transition to Idle 4874 mIkeSessionStateMachine.sendMessage( 4875 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 4876 mLooper.dispatchAll(); 4877 mIkeSessionStateMachine.mSaProposal = buildSaProposal(); 4878 4879 // Move time forward to trigger rekey 4880 mLooper.moveTimeForward( 4881 mIkeSessionStateMachine.mIkeSessionParams.getSoftLifetimeMsInternal()); 4882 mLooper.dispatchAll(); 4883 4884 assertTrue( 4885 mIkeSessionStateMachine.getCurrentState() 4886 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4887 } 4888 4889 @Test testRekeyCreateIkeSchedulesRekey()4890 public void testRekeyCreateIkeSchedulesRekey() throws Exception { 4891 setupIdleStateMachine(); 4892 4893 // Send Rekey-Create request 4894 mIkeSessionStateMachine.sendMessage( 4895 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 4896 mLocalRequestFactory.getIkeLocalRequest( 4897 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 4898 mLooper.dispatchAll(); 4899 4900 // Prepare "rekeyed" SA 4901 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 4902 4903 // Receive Rekey response 4904 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 4905 mIkeSessionStateMachine.sendMessage( 4906 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 4907 mLooper.dispatchAll(); 4908 4909 // Mock rekey delete and transition to Idle 4910 mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyLocalInitIkeSaRecord; 4911 mIkeSessionStateMachine.sendMessage( 4912 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 4913 mLooper.dispatchAll(); 4914 4915 // Move time forward to trigger rekey 4916 mLooper.moveTimeForward( 4917 mIkeSessionStateMachine.mIkeSessionParams.getSoftLifetimeMsInternal()); 4918 mLooper.dispatchAll(); 4919 4920 assertTrue( 4921 mIkeSessionStateMachine.getCurrentState() 4922 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 4923 } 4924 4925 @Test testBuildEncryptedInformationalMessage()4926 public void testBuildEncryptedInformationalMessage() throws Exception { 4927 IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX, new byte[0]); 4928 4929 boolean isResp = false; 4930 IkeMessage generated = 4931 mIkeSessionStateMachine.buildEncryptedInformationalMessage( 4932 mSpyCurrentIkeSaRecord, new IkeInformationalPayload[] {payload}, isResp, 0); 4933 4934 assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), generated.ikeHeader.ikeInitiatorSpi); 4935 assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), generated.ikeHeader.ikeResponderSpi); 4936 assertEquals( 4937 mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), generated.ikeHeader.messageId); 4938 assertEquals(isResp, generated.ikeHeader.isResponseMsg); 4939 assertEquals(IkePayload.PAYLOAD_TYPE_SK, generated.ikeHeader.nextPayloadType); 4940 4941 List<IkeNotifyPayload> generatedPayloads = 4942 generated.getPayloadListForType( 4943 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 4944 assertEquals(1, generatedPayloads.size()); 4945 4946 IkeNotifyPayload generatedPayload = generatedPayloads.get(0); 4947 assertArrayEquals(new byte[0], generatedPayload.notifyData); 4948 assertEquals(ERROR_TYPE_INVALID_SYNTAX, generatedPayload.notifyType); 4949 } 4950 verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord)4951 private void verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord) { 4952 if (expectedPackets == null) { 4953 assertNull(saRecord.getLastSentRespAllPackets()); 4954 return; 4955 } 4956 4957 assertEquals(expectedPackets.length, saRecord.getLastSentRespAllPackets().size()); 4958 for (int i = 0; i < expectedPackets.length; i++) { 4959 assertArrayEquals(expectedPackets[i], saRecord.getLastSentRespAllPackets().get(i)); 4960 } 4961 } 4962 4963 @Test testEncryptedRetransmitterImmediatelySendsRequest()4964 public void testEncryptedRetransmitterImmediatelySendsRequest() throws Exception { 4965 setupIdleStateMachine(); 4966 byte[][] dummyLastRespBytes = 4967 new byte[][] {"testRetransmitterSendsRequestLastResp".getBytes()}; 4968 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets( 4969 Arrays.asList(dummyLastRespBytes), 4970 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1); 4971 4972 IkeMessage spyIkeReqMessage = 4973 spy( 4974 new IkeMessage( 4975 new IkeHeader( 4976 mSpyCurrentIkeSaRecord.getInitiatorSpi(), 4977 mSpyCurrentIkeSaRecord.getResponderSpi(), 4978 IkePayload.PAYLOAD_TYPE_SK, 4979 EXCHANGE_TYPE_INFORMATIONAL, 4980 false /*isResp*/, 4981 mSpyCurrentIkeSaRecord.isLocalInit, 4982 mSpyCurrentIkeSaRecord.getLocalRequestMessageId()), 4983 new ArrayList<>())); 4984 4985 // Use something unique as a sentinel value 4986 byte[][] dummyReqBytesList = 4987 new byte[][] { 4988 "testRetransmitterSendsReqFrag1".getBytes(), 4989 "testRetransmitterSendsReqFrag2".getBytes() 4990 }; 4991 4992 doReturn(dummyReqBytesList) 4993 .when(spyIkeReqMessage) 4994 .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); 4995 4996 IkeSessionStateMachine.EncryptedRetransmitter retransmitter = 4997 mIkeSessionStateMachine.new EncryptedRetransmitter(spyIkeReqMessage); 4998 4999 // Verify message is sent out, and that request does not change cached retransmit-response 5000 // mLastSentIkeResp. 5001 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS)); 5002 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyReqBytesList[1]), eq(REMOTE_ADDRESS)); 5003 verifyLastSentRespAllPackets(dummyLastRespBytes, mSpyCurrentIkeSaRecord); 5004 } 5005 5006 @Test testRetransmittedPacketsAreIdentical()5007 public void testRetransmittedPacketsAreIdentical() throws Exception { 5008 setupIdleStateMachine(); 5009 5010 IkeMessage mockIkeReqMsg = mock(IkeMessage.class); 5011 byte[][] dummyReqBytesList = 5012 new byte[][] {"testRetransmittedPacketsAreIdentical".getBytes()}; 5013 doReturn(dummyReqBytesList) 5014 .when(mockIkeReqMsg) 5015 .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); 5016 5017 IkeSessionStateMachine.EncryptedRetransmitter retransmitter = 5018 mIkeSessionStateMachine.new EncryptedRetransmitter(mockIkeReqMsg); 5019 5020 // Packet is immediately sent out 5021 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS)); 5022 verify(mockIkeReqMsg) 5023 .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); 5024 5025 // Retransmit packet 5026 retransmitter.retransmit(); 5027 verify(mMockCurrentIkeSocket, times(2)) 5028 .sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS)); 5029 verify(mockIkeReqMsg) 5030 .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt()); 5031 } 5032 5033 // TODO: b/141275871 Test retransmisstions are fired for correct times within certain time. 5034 5035 @Test testCacheLastRequestAndResponse()5036 public void testCacheLastRequestAndResponse() throws Exception { 5037 setupIdleStateMachine(); 5038 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(null /*reqPacket*/); 5039 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets( 5040 null /*respPacketList*/, mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1); 5041 5042 byte[] dummyIkeReqFirstPacket = "testLastSentRequest".getBytes(); 5043 byte[][] dummyIkeResp = 5044 new byte[][] { 5045 "testLastSentRespFrag1".getBytes(), "testLastSentRespFrag2".getBytes() 5046 }; 5047 5048 doReturn(dummyIkeResp) 5049 .when(mMockIkeMessageHelper) 5050 .encryptAndEncode( 5051 any(), 5052 any(), 5053 eq(mSpyCurrentIkeSaRecord), 5054 any(IkeMessage.class), 5055 anyBoolean(), 5056 anyInt()); 5057 5058 // Receive a DPD request, expect to send dummyIkeResp 5059 ReceivedIkePacket dummyDpdRequest = 5060 makeDpdIkeRequest( 5061 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId(), dummyIkeReqFirstPacket); 5062 mIkeSessionStateMachine.sendMessage( 5063 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 5064 mLooper.dispatchAll(); 5065 5066 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); 5067 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[1]), eq(REMOTE_ADDRESS)); 5068 5069 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 5070 assertTrue(mSpyCurrentIkeSaRecord.isRetransmittedRequest(dummyIkeReqFirstPacket)); 5071 5072 assertTrue( 5073 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5074 } 5075 5076 @Test testReplyRetransmittedRequest()5077 public void testReplyRetransmittedRequest() throws Exception { 5078 setupIdleStateMachine(); 5079 5080 // Mock last sent request and response 5081 byte[] dummyIkeReqFirstPacket = "testRcvRetransmittedRequestReq".getBytes(); 5082 byte[][] dummyIkeResp = new byte[][] {"testRcvRetransmittedRequestResp".getBytes()}; 5083 5084 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); 5085 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets( 5086 Arrays.asList(dummyIkeResp), 5087 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1); 5088 5089 // Build request with last validated message ID 5090 ReceivedIkePacket request = 5091 makeDpdIkeRequest( 5092 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, 5093 dummyIkeReqFirstPacket); 5094 5095 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 5096 5097 mLooper.dispatchAll(); 5098 5099 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 5100 verify(mMockCurrentIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS)); 5101 5102 assertTrue( 5103 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5104 } 5105 5106 @Test testDiscardFakeRetransmittedRequest()5107 public void testDiscardFakeRetransmittedRequest() throws Exception { 5108 setupIdleStateMachine(); 5109 5110 // Mock last sent request and response 5111 byte[] dummyIkeReqFirstPacket = "testDiscardFakeRetransmittedRequestReq".getBytes(); 5112 byte[][] dummyIkeResp = new byte[][] {"testDiscardFakeRetransmittedRequestResp".getBytes()}; 5113 mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket); 5114 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets( 5115 Arrays.asList(dummyIkeResp), 5116 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1); 5117 5118 // Build request with last validated message ID but different bytes 5119 ReceivedIkePacket request = 5120 makeDpdIkeRequest( 5121 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, new byte[0]); 5122 5123 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 5124 5125 mLooper.dispatchAll(); 5126 5127 verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord); 5128 verify(mMockCurrentIkeSocket, never()).sendIkePacket(any(), any()); 5129 5130 assertTrue( 5131 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5132 } 5133 5134 @Test testRcvRetransmittedRequestBeforeReplyOriginalRequest()5135 public void testRcvRetransmittedRequestBeforeReplyOriginalRequest() throws Exception { 5136 setupIdleStateMachine(); 5137 5138 // Mock last sent response 5139 byte[][] dummyIkeResp = new byte[][] {"testLastSentResponse".getBytes()}; 5140 mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets( 5141 Arrays.asList(dummyIkeResp), 5142 mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1); 5143 5144 // Send request with next message ID 5145 IkeDeletePayload[] inboundDelPayloads = 5146 new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})}; 5147 ReceivedIkePacket request = makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/); 5148 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 5149 mLooper.dispatchAll(); 5150 5151 // Verify that no response has been sent out since we didn't configure Child Session to 5152 // respond 5153 verify(mMockCurrentIkeSocket, never()).sendIkePacket(any(), any()); 5154 assertTrue( 5155 mIkeSessionStateMachine.getCurrentState() 5156 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 5157 5158 // Retransmit the request 5159 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 5160 mLooper.dispatchAll(); 5161 5162 // Verify that no response has been sent out and state machine is still in 5163 // ChildProcedureOngoing 5164 verify(mMockCurrentIkeSocket, never()).sendIkePacket(any(), any()); 5165 assertTrue( 5166 mIkeSessionStateMachine.getCurrentState() 5167 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 5168 } 5169 5170 @Test testDiscardRetransmittedResponse()5171 public void testDiscardRetransmittedResponse() throws Exception { 5172 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 5173 verifyRetransmissionStarted(); 5174 5175 // Build and send fake response with last validated message ID to IKE state machine 5176 ReceivedIkePacket resp = 5177 makeDummyEncryptedReceivedIkePacketWithPayloadList( 5178 mSpyCurrentIkeSaRecord, 5179 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 5180 true /*isResp*/, 5181 mSpyCurrentIkeSaRecord.getLocalRequestMessageId() - 1, 5182 new ArrayList<>(), 5183 new byte[0]); 5184 5185 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 5186 mLooper.dispatchAll(); 5187 5188 // Verify current state does not change 5189 verifyRetransmissionStarted(); 5190 assertTrue( 5191 mIkeSessionStateMachine.getCurrentState() 5192 instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth); 5193 } 5194 5195 @Test testDeleteIkeLocalDeleteRequest()5196 public void testDeleteIkeLocalDeleteRequest() throws Exception { 5197 setupIdleStateMachine(); 5198 5199 mIkeSessionStateMachine.sendMessage( 5200 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5201 mLocalRequestFactory.getIkeLocalRequest( 5202 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 5203 mLooper.dispatchAll(); 5204 verifyRetransmissionStarted(); 5205 5206 // Verify outbound message 5207 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5208 5209 IkeHeader ikeHeader = delMsg.ikeHeader; 5210 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 5211 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 5212 assertFalse(ikeHeader.isResponseMsg); 5213 assertTrue(ikeHeader.fromIkeInitiator); 5214 5215 List<IkeDeletePayload> deletePayloadList = 5216 delMsg.getPayloadListForType( 5217 IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class); 5218 assertEquals(1, deletePayloadList.size()); 5219 5220 IkeDeletePayload deletePayload = deletePayloadList.get(0); 5221 assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId); 5222 assertEquals(0, deletePayload.numSpi); 5223 assertEquals(0, deletePayload.spiSize); 5224 assertArrayEquals(new int[0], deletePayload.spisToDelete); 5225 } 5226 5227 @Test testDeleteIkeLocalDeleteResponse()5228 public void testDeleteIkeLocalDeleteResponse() throws Exception { 5229 setupIdleStateMachine(); 5230 5231 mIkeSessionStateMachine.sendMessage( 5232 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5233 mLocalRequestFactory.getIkeLocalRequest( 5234 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 5235 mLooper.dispatchAll(); 5236 verifyRetransmissionStarted(); 5237 5238 ReceivedIkePacket received = makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 5239 mIkeSessionStateMachine.sendMessage( 5240 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); 5241 mLooper.dispatchAll(); 5242 verifyIncrementLocaReqMsgId(); 5243 5244 verifyNotifyUserCloseSession(mIkeSessionStateMachine.mDeleteIkeLocalDelete); 5245 5246 // Verify state machine quit properly 5247 assertNull(mIkeSessionStateMachine.getCurrentState()); 5248 } 5249 5250 @Test testDeleteIkeLocalDeleteResponseWithParsingError()5251 public void testDeleteIkeLocalDeleteResponseWithParsingError() throws Exception { 5252 setupIdleStateMachine(); 5253 5254 mIkeSessionStateMachine.sendMessage( 5255 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5256 mLocalRequestFactory.getIkeLocalRequest( 5257 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 5258 mLooper.dispatchAll(); 5259 verifyRetransmissionStarted(); 5260 resetMockIkeMessageHelper(); 5261 5262 // Mock receiving response with syntax error 5263 ReceivedIkePacket mockInvalidPacket = 5264 makeDummyReceivedIkePacketWithInvalidSyntax( 5265 mSpyCurrentIkeSaRecord, 5266 true /*isResp*/, 5267 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 5268 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 5269 mLooper.dispatchAll(); 5270 5271 // Verify no more request out 5272 verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord); 5273 5274 // Verify state machine quit properly 5275 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 5276 assertNull(mIkeSessionStateMachine.getCurrentState()); 5277 } 5278 5279 @Test testDeleteIkeLocalDeleteHandlesInvalidResp()5280 public void testDeleteIkeLocalDeleteHandlesInvalidResp() throws Exception { 5281 setupIdleStateMachine(); 5282 5283 // Send delete request 5284 mIkeSessionStateMachine.sendMessage( 5285 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5286 mLocalRequestFactory.getIkeLocalRequest( 5287 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 5288 mLooper.dispatchAll(); 5289 5290 // Receive response with wrong exchange type 5291 ReceivedIkePacket resp = 5292 makeDummyReceivedIkePacketWithInvalidSyntax( 5293 mSpyCurrentIkeSaRecord, 5294 true /*isResp*/, 5295 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 5296 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp); 5297 mLooper.dispatchAll(); 5298 5299 // Verify state machine quit properly 5300 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 5301 assertNull(mIkeSessionStateMachine.getCurrentState()); 5302 } 5303 5304 @Test testDeleteIkeLocalDeleteReceivedNonDeleteRequest()5305 public void testDeleteIkeLocalDeleteReceivedNonDeleteRequest() throws Exception { 5306 setupIdleStateMachine(); 5307 5308 mIkeSessionStateMachine.sendMessage( 5309 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5310 mLocalRequestFactory.getIkeLocalRequest( 5311 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE)); 5312 mLooper.dispatchAll(); 5313 verifyRetransmissionStarted(); 5314 5315 // Verify delete sent out. 5316 verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5317 5318 resetMockIkeMessageHelper(); // Discard value. 5319 5320 ReceivedIkePacket received = makeRekeyIkeRequest(); 5321 mIkeSessionStateMachine.sendMessage( 5322 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received); 5323 5324 mLooper.dispatchAll(); 5325 verifyRetransmissionStarted(); 5326 verifyIncrementRemoteReqMsgId(); 5327 5328 verifySendTempFailResponse(); 5329 } 5330 verifySendTempFailResponse()5331 private void verifySendTempFailResponse() { 5332 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5333 5334 IkeHeader ikeHeader = resp.ikeHeader; 5335 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 5336 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 5337 assertTrue(ikeHeader.isResponseMsg); 5338 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 5339 5340 List<IkeNotifyPayload> notificationPayloadList = 5341 resp.getPayloadListForType(IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 5342 assertEquals(1, notificationPayloadList.size()); 5343 5344 IkeNotifyPayload notifyPayload = notificationPayloadList.get(0); 5345 assertEquals(IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType); 5346 } 5347 5348 @Test testDeleteIkeRemoteDelete()5349 public void testDeleteIkeRemoteDelete() throws Exception { 5350 setupIdleStateMachine(); 5351 5352 verifyIkeDeleteRequestHandled(mIkeSessionStateMachine.mReceiving); 5353 } 5354 verifyIkeDeleteRequestHandled(IState expectedState)5355 private void verifyIkeDeleteRequestHandled(IState expectedState) throws Exception { 5356 mIkeSessionStateMachine.sendMessage( 5357 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, 5358 makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 5359 5360 mLooper.dispatchAll(); 5361 verifyIncrementRemoteReqMsgId(); 5362 5363 // Verify outbound message 5364 IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5365 5366 IkeHeader ikeHeader = delMsg.ikeHeader; 5367 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 5368 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 5369 assertTrue(ikeHeader.isResponseMsg); 5370 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 5371 5372 assertTrue(delMsg.ikePayloadList.isEmpty()); 5373 5374 verifyNotifyUserCloseSession(expectedState); 5375 5376 // Verify state machine quit properly 5377 assertNull(mIkeSessionStateMachine.getCurrentState()); 5378 } 5379 verifySessionKilled(IState state, boolean hasDeleteRequestSent)5380 private void verifySessionKilled(IState state, boolean hasDeleteRequestSent) { 5381 verifySessionKilledWithException( 5382 state, hasDeleteRequestSent, null, false /* isErrorFromChild */); 5383 } 5384 verifySessionKilledWithException( IState state, boolean hasDeleteRequestSent, Exception exception, boolean isErrorFromChild)5385 private void verifySessionKilledWithException( 5386 IState state, 5387 boolean hasDeleteRequestSent, 5388 Exception exception, 5389 boolean isErrorFromChild) { 5390 verify(mSpyCurrentIkeSaRecord).close(); 5391 verify(mMockCurrentIkeSocket).unregisterIke(mSpyCurrentIkeSaRecord.getInitiatorSpi()); 5392 5393 if (exception != null) { 5394 verifyNotifyUserCloseSessionWithException(state, exception, isErrorFromChild); 5395 } else { 5396 verifyNotifyUserCloseSession(state); 5397 } 5398 5399 if (hasDeleteRequestSent) { 5400 // Verify outbound request 5401 IkeMessage req = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5402 IkeHeader ikeHeader = req.ikeHeader; 5403 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 5404 assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType); 5405 assertFalse(ikeHeader.isResponseMsg); 5406 assertEquals(1, req.ikePayloadList.size()); 5407 assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, req.ikePayloadList.get(0).payloadType); 5408 } else { 5409 // Verify no outbound request 5410 verifyEncryptAndEncodeNeverCalled(); 5411 } 5412 5413 // Verify state machine quit properly 5414 assertNull(mIkeSessionStateMachine.getCurrentState()); 5415 verify(mMockBusyWakelock).release(); 5416 } 5417 5418 @Test testKillSessionDeleteIkeRequestSent()5419 public void testKillSessionDeleteIkeRequestSent() throws Exception { 5420 setupIdleStateMachine(); 5421 5422 mIkeSessionStateMachine.killSession(); 5423 mLooper.dispatchAll(); 5424 5425 verifySessionKilled(mIkeSessionStateMachine.mIdle, true /* hasDeleteRequestSent */); 5426 } 5427 5428 @Test testKillSessionNoDeleteIkeRequestSent()5429 public void testKillSessionNoDeleteIkeRequestSent() throws Exception { 5430 setupIdleStateMachine(); 5431 5432 // Transition to state that does not send IKE delete requests 5433 InitialSetupData initialSetupData = 5434 new InitialSetupData( 5435 mChildSessionParams, 5436 mMockChildSessionCallback, 5437 SaProposal.DH_GROUP_1024_BIT_MODP); 5438 mIkeSessionStateMachine.mCreateIkeLocalIkeInit.setIkeSetupData(initialSetupData); 5439 mIkeSessionStateMachine.sendMessage( 5440 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 5441 mIkeSessionStateMachine.mCreateIkeLocalIkeInit); 5442 mLooper.dispatchAll(); 5443 5444 mIkeSessionStateMachine.killSession(); 5445 mLooper.dispatchAll(); 5446 5447 verifySessionKilled( 5448 mIkeSessionStateMachine.mCreateIkeLocalIkeInit, false /* hasDeleteRequestSent */); 5449 } 5450 5451 @Test testOnFatalIkeSessionErrorFromChild()5452 public void testOnFatalIkeSessionErrorFromChild() throws Exception { 5453 setupIdleStateMachine(); 5454 5455 transitionToChildProcedureOngoing(); 5456 5457 Exception exception = new IkeInternalException("IkeStateMachineTest"); 5458 mDummyChildSmCallback.onFatalIkeSessionError(exception); 5459 mLooper.dispatchAll(); 5460 5461 verifySessionKilledWithException( 5462 mIkeSessionStateMachine.mChildProcedureOngoing, 5463 false /* hasDeleteRequestSent */, 5464 exception, 5465 true /* isErrorFromChild */); 5466 } 5467 5468 @Test testScheduleDpd()5469 public void testScheduleDpd() throws Exception { 5470 setupIdleStateMachine(); 5471 5472 ArgumentCaptor<IkeAlarmConfig> captor = ArgumentCaptor.forClass(IkeAlarmConfig.class); 5473 verify(mSpyDeps).newExactAndAllowWhileIdleAlarm(captor.capture()); 5474 assertEquals( 5475 TimeUnit.SECONDS.toMillis( 5476 mIkeSessionStateMachine.mIkeSessionParams.getDpdDelaySeconds()), 5477 captor.getValue().delayMs); 5478 } 5479 5480 @Test testDisableDpd()5481 public void testDisableDpd() throws Exception { 5482 mIkeSessionStateMachine.quitNow(); 5483 mLooper.dispatchAll(); 5484 5485 // Clear the wakelock call in quitNow() for setupIdleStateMachine() to pass 5486 reset(mMockBusyWakelock); 5487 5488 // Restart IKE Session with DPD disabled 5489 IkeSessionParams ikeSessionParams = 5490 buildIkeSessionParamsCommon() 5491 .setAuthPsk(mPsk) 5492 .setDpdDelaySeconds(Integer.MAX_VALUE) 5493 .build(); 5494 mIkeSessionStateMachine = makeAndStartIkeSession(ikeSessionParams); 5495 setupIdleStateMachine(); 5496 5497 verify(mSpyDeps, never()).newExactAndAllowWhileIdleAlarm(any()); 5498 } 5499 verifyAndGetOutboundEncryptedResp(int exchangeType)5500 private IkeMessage verifyAndGetOutboundEncryptedResp(int exchangeType) { 5501 IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5502 IkeHeader ikeHeader = resp.ikeHeader; 5503 assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType); 5504 assertEquals(exchangeType, ikeHeader.exchangeType); 5505 assertTrue(ikeHeader.isResponseMsg); 5506 assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator); 5507 return resp; 5508 } 5509 verifyAndGetOutboundInformationalResp()5510 private IkeMessage verifyAndGetOutboundInformationalResp() { 5511 return verifyAndGetOutboundEncryptedResp(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL); 5512 } 5513 5514 @Test testReceiveDpd()5515 public void testReceiveDpd() throws Exception { 5516 setupIdleStateMachine(); 5517 5518 // Receive a DPD request, expect to stay in IDLE state 5519 ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); 5520 mIkeSessionStateMachine.sendMessage( 5521 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 5522 mLooper.dispatchAll(); 5523 assertTrue( 5524 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5525 5526 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); 5527 5528 // Verify outbound response 5529 IkeMessage resp = verifyAndGetOutboundInformationalResp(); 5530 assertTrue(resp.ikePayloadList.isEmpty()); 5531 } 5532 5533 @Test testReceiveDpdNonIdle()5534 public void testReceiveDpdNonIdle() throws Exception { 5535 setupIdleStateMachine(); 5536 5537 // Move to a non-idle state. Use RekeyIkeRemoteDelete, as it doesn't send out any requests. 5538 mIkeSessionStateMachine.sendMessage( 5539 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 5540 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 5541 mLooper.dispatchAll(); 5542 5543 // In a rekey state, receiving (and handling) a DPD should not result in a change of states 5544 ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord); 5545 mIkeSessionStateMachine.sendMessage( 5546 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest); 5547 mLooper.dispatchAll(); 5548 assertTrue( 5549 mIkeSessionStateMachine.getCurrentState() 5550 instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete); 5551 5552 verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest); 5553 5554 // Verify outbound response 5555 IkeMessage resp = verifyAndGetOutboundInformationalResp(); 5556 assertTrue(resp.ikePayloadList.isEmpty()); 5557 } 5558 executeAndVerifySendLocalDPD()5559 private void executeAndVerifySendLocalDPD() throws Exception { 5560 setupIdleStateMachine(); 5561 5562 mIkeSessionStateMachine.sendMessage( 5563 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mDpdIkeLocalInfo); 5564 mLooper.dispatchAll(); 5565 5566 verifyEmptyInformationalSent(1, false /* expectedResp*/); 5567 resetMockIkeMessageHelper(); 5568 } 5569 5570 @Test testDpdIkeLocalInfoRcvDpdReq()5571 public void testDpdIkeLocalInfoRcvDpdReq() throws Exception { 5572 executeAndVerifySendLocalDPD(); 5573 mIkeSessionStateMachine.sendMessage( 5574 CMD_RECEIVE_IKE_PACKET, makeDpdIkeRequest(mSpyCurrentIkeSaRecord)); 5575 mLooper.dispatchAll(); 5576 5577 verifyEmptyInformationalSent(1, true /* expectedResp*/); 5578 assertTrue( 5579 mIkeSessionStateMachine.getCurrentState() 5580 instanceof IkeSessionStateMachine.DpdIkeLocalInfo); 5581 } 5582 5583 @Test testDpdIkeLocalInfoRcvDeleteIkeReq()5584 public void testDpdIkeLocalInfoRcvDeleteIkeReq() throws Exception { 5585 executeAndVerifySendLocalDPD(); 5586 mIkeSessionStateMachine.sendMessage( 5587 CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord)); 5588 mLooper.dispatchAll(); 5589 5590 verifyEmptyInformationalSent(1, true /* expectedResp*/); 5591 assertNull(mIkeSessionStateMachine.getCurrentState()); 5592 } 5593 5594 @Test testDpdIkeLocalInfoRcvRekeyIkeReq()5595 public void testDpdIkeLocalInfoRcvRekeyIkeReq() throws Exception { 5596 executeAndVerifySendLocalDPD(); 5597 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest()); 5598 mLooper.dispatchAll(); 5599 5600 verifySendTempFailResponse(); 5601 assertTrue( 5602 mIkeSessionStateMachine.getCurrentState() 5603 instanceof IkeSessionStateMachine.DpdIkeLocalInfo); 5604 } 5605 5606 @Test testIdleTriggersNewRequests()5607 public void testIdleTriggersNewRequests() throws Exception { 5608 setupIdleStateMachine(); 5609 5610 mIkeSessionStateMachine.sendMessage( 5611 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5612 mLocalRequestFactory.getIkeLocalRequest( 5613 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 5614 mLooper.dispatchAll(); 5615 5616 // Verify that the command is executed, and the state machine transitions to the right state 5617 assertTrue( 5618 mIkeSessionStateMachine.getCurrentState() 5619 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 5620 verifyRetransmissionStarted(); 5621 } 5622 5623 @Test testNonIdleStateDoesNotTriggerNewRequests()5624 public void testNonIdleStateDoesNotTriggerNewRequests() throws Exception { 5625 setupIdleStateMachine(); 5626 5627 // Force ourselves into a non-idle state 5628 mIkeSessionStateMachine.sendMessage( 5629 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving); 5630 mLooper.dispatchAll(); 5631 verifyEncryptAndEncodeNeverCalled(); 5632 5633 // Queue a local request, and expect that it is not run (yet) 5634 mIkeSessionStateMachine.sendMessage( 5635 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE, 5636 mLocalRequestFactory.getIkeLocalRequest( 5637 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 5638 mLooper.dispatchAll(); 5639 5640 // Verify that the state machine is still in the Receiving state 5641 verifyEncryptAndEncodeNeverCalled(); 5642 assertTrue( 5643 mIkeSessionStateMachine.getCurrentState() 5644 instanceof IkeSessionStateMachine.Receiving); 5645 5646 // Go back to Idle, and expect to immediately transition to RekeyIkeLocalCreate from the 5647 // queued request 5648 mIkeSessionStateMachine.sendMessage( 5649 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 5650 mLooper.dispatchAll(); 5651 assertTrue( 5652 mIkeSessionStateMachine.getCurrentState() 5653 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 5654 verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord); 5655 } 5656 5657 @Test testOpenChildSessionValidatesArgs()5658 public void testOpenChildSessionValidatesArgs() throws Exception { 5659 setupIdleStateMachine(); 5660 5661 // Expect failure - no callbacks provided 5662 try { 5663 mIkeSessionStateMachine.openChildSession(mChildSessionParams, null); 5664 fail("Expected to fail due to missing ChildSessionCallback"); 5665 } catch (IllegalArgumentException expected) { 5666 } 5667 5668 // Expect failure - callbacks already registered 5669 try { 5670 mIkeSessionStateMachine.openChildSession( 5671 mChildSessionParams, mMockChildSessionCallback); 5672 fail("Expected to fail due to invalid ChildSessionCallback"); 5673 } catch (IllegalArgumentException expected) { 5674 } 5675 } 5676 5677 @Test testOpenChildSession()5678 public void testOpenChildSession() throws Exception { 5679 setupIdleStateMachine(); 5680 5681 ChildSessionCallback cb = mock(ChildSessionCallback.class); 5682 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 5683 5684 // Test that inserting the same cb returns an error, even before the state 5685 // machine has a chance to process it. 5686 try { 5687 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 5688 fail("Expected to fail due to invalid ChildSessionCallback"); 5689 } catch (IllegalArgumentException expected) { 5690 } 5691 5692 verifyMakeChildAndReturnChildSmCb(cb); 5693 5694 // Verify state in IkeSessionStateMachine 5695 mLooper.dispatchAll(); 5696 assertTrue( 5697 mIkeSessionStateMachine.getCurrentState() 5698 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 5699 5700 synchronized (mIkeSessionStateMachine.mChildCbToSessions) { 5701 assertTrue(mIkeSessionStateMachine.mChildCbToSessions.containsKey(cb)); 5702 } 5703 } 5704 5705 @Test(expected = IllegalArgumentException.class) 5706 @SdkSuppress(minSdkVersion = 31, codeName = "S") testOpenChildSessionWithMobikeAndTransport()5707 public void testOpenChildSessionWithMobikeAndTransport() throws Exception { 5708 mIkeSessionStateMachine = restartStateMachineWithRfcMobikeConfigured(); 5709 5710 mIkeSessionStateMachine.openChildSession( 5711 mock(TransportModeChildSessionParams.class), mock(ChildSessionCallback.class)); 5712 } 5713 5714 @Test testCloseChildSessionValidatesArgs()5715 public void testCloseChildSessionValidatesArgs() throws Exception { 5716 setupIdleStateMachine(); 5717 5718 // Expect failure - callbacks not registered 5719 try { 5720 mIkeSessionStateMachine.closeChildSession(mock(ChildSessionCallback.class)); 5721 fail("Expected to fail since callback is not registered"); 5722 } catch (IllegalArgumentException expected) { 5723 } 5724 } 5725 5726 @Test testCloseChildSession()5727 public void testCloseChildSession() throws Exception { 5728 setupIdleStateMachine(); 5729 5730 mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); 5731 mLooper.dispatchAll(); 5732 5733 assertTrue( 5734 mIkeSessionStateMachine.getCurrentState() 5735 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 5736 } 5737 5738 @Test testCloseImmediatelyAfterOpenChildSession()5739 public void testCloseImmediatelyAfterOpenChildSession() throws Exception { 5740 setupIdleStateMachine(); 5741 5742 ChildSessionCallback cb = mock(ChildSessionCallback.class); 5743 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 5744 5745 // Verify that closing the session immediately still picks up the child callback 5746 // even before the looper has a chance to run. 5747 mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback); 5748 } 5749 5750 @Test testOnChildSessionClosed()5751 public void testOnChildSessionClosed() throws Exception { 5752 setupIdleStateMachine(); 5753 5754 mDummyChildSmCallback.onChildSessionClosed(mMockChildSessionCallback); 5755 5756 synchronized (mIkeSessionStateMachine.mChildCbToSessions) { 5757 assertFalse( 5758 mIkeSessionStateMachine.mChildCbToSessions.containsKey( 5759 mMockChildSessionCallback)); 5760 } 5761 } 5762 5763 @Test testHandleUnexpectedExceptionInEnterState()5764 public void testHandleUnexpectedExceptionInEnterState() throws Exception { 5765 Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); 5766 IkeManager.setIkeLog(spyIkeLog); 5767 5768 IkeSessionParams mockSessionParams = mock(IkeSessionParams.class); 5769 when(mockSessionParams.getServerHostname()).thenReturn(REMOTE_HOSTNAME); 5770 5771 RuntimeException cause = new RuntimeException(); 5772 when(mockSessionParams.getSaProposalsInternal()).thenThrow(cause); 5773 5774 DhGroupTransform dhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_2048_BIT_MODP); 5775 IkeSaProposal mockSaProposal = mock(IkeSaProposal.class); 5776 when(mockSaProposal.getDhGroupTransforms()) 5777 .thenReturn(new DhGroupTransform[] {dhGroupTransform}); 5778 when(mockSessionParams.getSaProposals()).thenReturn(Arrays.asList(mockSaProposal)); 5779 5780 mIkeSessionStateMachine.quitNow(); 5781 mIkeSessionStateMachine = makeAndStartIkeSession(mockSessionParams); 5782 5783 // Send IKE INIT request 5784 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 5785 mLooper.dispatchAll(); 5786 5787 assertNull(mIkeSessionStateMachine.getCurrentState()); 5788 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 5789 verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); 5790 5791 ArgumentCaptor<IkeInternalException> internalExceptionCaptor = 5792 ArgumentCaptor.forClass(IkeInternalException.class); 5793 verify(mMockIkeSessionCallback).onClosedWithException(internalExceptionCaptor.capture()); 5794 IkeInternalException internalException = internalExceptionCaptor.getValue(); 5795 5796 // Verify that the Exception which caused the IkeSessionStateMachine to close is the same 5797 // one mocked for IkeSessionParams#getSaProposalsInternal 5798 assertSame(cause, internalException.getCause()); 5799 } 5800 5801 @Test testHandleUnexpectedExceptionInProcessStateMsg()5802 public void testHandleUnexpectedExceptionInProcessStateMsg() throws Exception { 5803 Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG); 5804 IkeManager.setIkeLog(spyIkeLog); 5805 5806 setupIdleStateMachine(); 5807 mIkeSessionStateMachine.sendMessage( 5808 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, null /*receivedIkePacket*/); 5809 mLooper.dispatchAll(); 5810 5811 assertNull(mIkeSessionStateMachine.getCurrentState()); 5812 verify(mSpyUserCbExecutor).execute(any(Runnable.class)); 5813 verify(mMockIkeSessionCallback).onClosedWithException(any(IkeInternalException.class)); 5814 verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class)); 5815 } 5816 5817 @Test testCreateIkeLocalIkeInitRcvErrorNotify()5818 public void testCreateIkeLocalIkeInitRcvErrorNotify() throws Exception { 5819 // Send IKE INIT request 5820 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 5821 mLooper.dispatchAll(); 5822 verifyRetransmissionStarted(); 5823 5824 // Receive IKE INIT response with erro notification. 5825 List<IkePayload> payloads = new ArrayList<>(); 5826 payloads.add(new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN)); 5827 ReceivedIkePacket resp = 5828 makeDummyUnencryptedReceivedIkePacket( 5829 1L /*initiator SPI*/, 5830 2L /*respodner SPI*/, 5831 IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, 5832 true /*isResp*/, 5833 false /*fromIkeInit*/, 5834 payloads); 5835 5836 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 5837 mLooper.dispatchAll(); 5838 5839 // Fires user error callbacks 5840 verify(mMockIkeSessionCallback) 5841 .onClosedWithException( 5842 argThat(err -> err instanceof NoValidProposalChosenException)); 5843 // Verify state machine quit properly 5844 assertNull(mIkeSessionStateMachine.getCurrentState()); 5845 } 5846 mockSendRekeyChildReq(boolean withMobike)5847 private void mockSendRekeyChildReq(boolean withMobike) throws Exception { 5848 if (withMobike) { 5849 setupIdleStateMachineWithMobike(); 5850 } else { 5851 setupIdleStateMachine(); 5852 } 5853 5854 ChildLocalRequest childLocalRequest = 5855 mLocalRequestFactory.getChildLocalRequest( 5856 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD, 5857 mMockChildSessionCallback, 5858 null /*childParams*/); 5859 5860 mIkeSessionStateMachine.sendMessage( 5861 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, childLocalRequest); 5862 mLooper.dispatchAll(); 5863 5864 assertTrue( 5865 mIkeSessionStateMachine.getCurrentState() 5866 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 5867 verify(mMockChildSessionStateMachine).rekeyChildSession(); 5868 5869 // Mocking sending request 5870 mDummyChildSmCallback.onOutboundPayloadsReady( 5871 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, 5872 false /*isResp*/, 5873 new ArrayList<>(), 5874 mMockChildSessionStateMachine); 5875 mLooper.dispatchAll(); 5876 } 5877 mockRcvTempFail()5878 private void mockRcvTempFail() throws Exception { 5879 ReceivedIkePacket resp = 5880 makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_TEMPORARY_FAILURE)); 5881 5882 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp); 5883 mIkeSessionStateMachine.sendMessage( 5884 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 5885 mLooper.dispatchAll(); 5886 } 5887 5888 @Ignore disableTestTempFailureHandlerTimeout()5889 public void disableTestTempFailureHandlerTimeout() throws Exception { 5890 long currentTime = 0; 5891 int retryCnt = 0; 5892 5893 mockSendRekeyChildReq(false); 5894 5895 while (currentTime + RETRY_INTERVAL_MS < TEMP_FAILURE_RETRY_TIMEOUT_MS) { 5896 mockRcvTempFail(); 5897 5898 mLooper.moveTimeForward(RETRY_INTERVAL_MS); 5899 currentTime += RETRY_INTERVAL_MS; 5900 mLooper.dispatchAll(); 5901 5902 retryCnt++; 5903 verify(mMockChildSessionStateMachine, times(1 + retryCnt)).rekeyChildSession(); 5904 } 5905 5906 mLooper.moveTimeForward(RETRY_INTERVAL_MS); 5907 mLooper.dispatchAll(); 5908 5909 assertNull(mIkeSessionStateMachine.getCurrentState()); 5910 verify(mMockIkeSessionCallback).onClosedWithException(any(IkeInternalException.class)); 5911 } 5912 5913 @Test testTempFailureHandlerCancelTimer()5914 public void testTempFailureHandlerCancelTimer() throws Exception { 5915 mockRescheduleRekey(mSpyCurrentIkeSaRecord); 5916 setupIdleStateMachine(); 5917 5918 // Send Rekey-Create request 5919 mIkeSessionStateMachine.sendMessage( 5920 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 5921 mLocalRequestFactory.getIkeLocalRequest( 5922 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 5923 mLooper.dispatchAll(); 5924 verifyRetransmissionStarted(); 5925 5926 // Mock sending TEMPORARY_FAILURE response 5927 mockRcvTempFail(); 5928 mLooper.dispatchAll(); 5929 verify(mSpyCurrentIkeSaRecord).rescheduleRekey(eq(RETRY_INTERVAL_MS)); 5930 assertTrue( 5931 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5932 5933 // Move time forward to trigger retry 5934 mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS); 5935 mLooper.dispatchAll(); 5936 assertTrue( 5937 mIkeSessionStateMachine.getCurrentState() 5938 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 5939 5940 // Prepare "rekeyed" SA 5941 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 5942 5943 // Receive valid Rekey-Create response 5944 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 5945 mIkeSessionStateMachine.sendMessage( 5946 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 5947 mLooper.dispatchAll(); 5948 5949 // Receive Delete response 5950 ReceivedIkePacket dummyDeleteIkeRespReceivedPacket = 5951 makeDeleteIkeResponse(mSpyCurrentIkeSaRecord); 5952 mIkeSessionStateMachine.sendMessage( 5953 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket); 5954 mLooper.dispatchAll(); 5955 assertTrue( 5956 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5957 5958 // Move time forward 5959 mLooper.moveTimeForward(IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS); 5960 mLooper.dispatchAll(); 5961 5962 // Validate IKE Session is not closed 5963 assertTrue( 5964 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 5965 } 5966 5967 @Ignore disableTestIdleReceiveRequestWithFatalError()5968 public void disableTestIdleReceiveRequestWithFatalError() throws Exception { 5969 setupIdleStateMachine(); 5970 5971 // Mock receiving packet with syntax error 5972 ReceivedIkePacket mockInvalidPacket = 5973 makeDummyReceivedIkePacketWithInvalidSyntax( 5974 mSpyCurrentIkeSaRecord, 5975 false /*isResp*/, 5976 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA); 5977 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket); 5978 mLooper.dispatchAll(); 5979 5980 // Verify Delete request was sent 5981 List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 5982 assertEquals(1, payloads.size()); 5983 5984 IkePayload payload = payloads.get(0); 5985 assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType); 5986 assertEquals(ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) payload).notifyType); 5987 5988 // Verify IKE Session is closed properly 5989 assertNull(mIkeSessionStateMachine.getCurrentState()); 5990 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 5991 } 5992 5993 @Test testHandlesInvalidRequest()5994 public void testHandlesInvalidRequest() throws Exception { 5995 setupIdleStateMachine(); 5996 5997 mIkeSessionStateMachine.sendMessage( 5998 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 5999 mIkeSessionStateMachine.mChildProcedureOngoing); 6000 6001 // Receive an IKE AUTH request 6002 ReceivedIkePacket request = 6003 makeDummyEncryptedReceivedIkePacketWithPayloadList( 6004 mSpyCurrentIkeSaRecord, 6005 IkeHeader.EXCHANGE_TYPE_IKE_AUTH, 6006 false /*isResp*/, 6007 new ArrayList<IkePayload>()); 6008 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request); 6009 mLooper.dispatchAll(); 6010 6011 // Verify error notification was sent 6012 List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/); 6013 assertEquals(1, ikePayloadList.size()); 6014 assertEquals( 6015 ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType); 6016 6017 // Verify IKE Session has quit 6018 assertNull(mIkeSessionStateMachine.getCurrentState()); 6019 verify(mMockIkeSessionCallback).onClosedWithException(any(InvalidSyntaxException.class)); 6020 } 6021 6022 @Test testIdleHandlesDecryptPacketFailed()6023 public void testIdleHandlesDecryptPacketFailed() throws Exception { 6024 setupIdleStateMachine(); 6025 6026 ReceivedIkePacket packet = 6027 makeDummyReceivedIkePacketWithUnprotectedError( 6028 mSpyCurrentIkeSaRecord, 6029 false /*isResp*/, 6030 EXCHANGE_TYPE_INFORMATIONAL, 6031 mock(IkeException.class)); 6032 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 6033 mLooper.dispatchAll(); 6034 6035 assertTrue( 6036 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 6037 } 6038 6039 @Test testHandlesUnencryptedPacket()6040 public void testHandlesUnencryptedPacket() throws Exception { 6041 setupIdleStateMachine(); 6042 IkeMessage.setIkeMessageHelper(new IkeMessageHelper()); 6043 6044 ReceivedIkePacket packet = 6045 makeDummyUnencryptedReceivedIkePacket( 6046 mSpyCurrentIkeSaRecord.getLocalSpi(), 6047 mSpyCurrentIkeSaRecord.getRemoteSpi(), 6048 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 6049 false /*isResp*/, 6050 false /*fromIkeInit*/, 6051 new ArrayList<>()); 6052 6053 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet); 6054 mLooper.dispatchAll(); 6055 6056 assertTrue( 6057 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 6058 6059 // Reset the IkeMessageHelper to be a mock. This is needed for #killSession (called in 6060 // #tearDown), which attempts to notify the remote about the IKE session dying in the Idle 6061 // state. 6062 IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper); 6063 resetMockIkeMessageHelper(); 6064 } 6065 6066 @Test testEapOnlyOption()6067 public void testEapOnlyOption() throws Exception { 6068 mIkeSessionStateMachine.quitNow(); 6069 IkeSessionParams ikeSessionParams = 6070 buildIkeSessionParamsCommon() 6071 .setAuthEap(mRootCertificate, mEapSessionConfig) 6072 .addIkeOption(IKE_OPTION_EAP_ONLY_AUTH) 6073 .build(); 6074 6075 verifyIkeAuthWithNotifyPayload(ikeSessionParams, NOTIFY_TYPE_EAP_ONLY_AUTHENTICATION); 6076 } 6077 6078 @Test testInitialContact()6079 public void testInitialContact() throws Exception { 6080 mIkeSessionStateMachine.quitNow(); 6081 IkeSessionParams ikeSessionParams = 6082 buildIkeSessionParamsWithIkeOptions(IkeSessionParams.IKE_OPTION_INITIAL_CONTACT); 6083 6084 verifyIkeAuthWithNotifyPayload(ikeSessionParams, NOTIFY_TYPE_INITIAL_CONTACT); 6085 } 6086 verifyIkeAuthWithNotifyPayload( IkeSessionParams ikeSessionParams, int expectedNotifyType)6087 private void verifyIkeAuthWithNotifyPayload( 6088 IkeSessionParams ikeSessionParams, int expectedNotifyType) throws Exception { 6089 mIkeSessionStateMachine.quitNow(); 6090 mIkeSessionStateMachine = makeAndStartIkeSession(ikeSessionParams); 6091 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 6092 6093 IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg(); 6094 List<IkeNotifyPayload> notifyPayloads = 6095 ikeAuthReqMessage.getPayloadListForType( 6096 IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 6097 assertTrue(hasExpectedNotifyPayload(notifyPayloads, expectedNotifyType)); 6098 } 6099 makeConfigPayload()6100 private IkeConfigPayload makeConfigPayload() throws Exception { 6101 return (IkeConfigPayload) 6102 IkeTestUtils.hexStringToIkePayload( 6103 IkePayload.PAYLOAD_TYPE_CP, true /*isResp*/, CP_PAYLOAD_HEX_STRING); 6104 } 6105 hasExpectedNotifyPayload( List<IkeNotifyPayload> notifyPayloads, int expectedNotifyType)6106 private boolean hasExpectedNotifyPayload( 6107 List<IkeNotifyPayload> notifyPayloads, int expectedNotifyType) { 6108 for (IkeNotifyPayload payload : notifyPayloads) { 6109 if (payload.notifyType == expectedNotifyType) { 6110 return true; 6111 } 6112 } 6113 6114 return false; 6115 } 6116 6117 @Test testAcquireAndReleaseLocalReqWakeLock()6118 public void testAcquireAndReleaseLocalReqWakeLock() throws Exception { 6119 setupIdleStateMachine(); 6120 6121 ChildSessionCallback cb = mock(ChildSessionCallback.class); 6122 mIkeSessionStateMachine.openChildSession(mChildSessionParams, cb); 6123 6124 mLooper.dispatchAll(); 6125 assertTrue( 6126 mIkeSessionStateMachine.getCurrentState() 6127 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 6128 verify(mMockLocalRequestWakelock).acquire(); 6129 verify(mMockLocalRequestWakelock).release(); 6130 } 6131 6132 @Test testQuitClearAllLocalReqWakeLocks()6133 public void testQuitClearAllLocalReqWakeLocks() throws Exception { 6134 final int localReqCnt = 3; 6135 setupIdleStateMachine(); 6136 6137 // Leave a Idle state so that the LocalRequest won't be executed 6138 mIkeSessionStateMachine.sendMessage( 6139 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving); 6140 mLooper.dispatchAll(); 6141 6142 // Only in test that all local requests will get the same WakeLock instance but in function 6143 // code each local request will have a separate WakeLock. 6144 for (int i = 0; i < localReqCnt; i++) { 6145 mIkeSessionStateMachine.openChildSession( 6146 mChildSessionParams, mock(ChildSessionCallback.class)); 6147 } 6148 mLooper.dispatchAll(); 6149 verify(mMockLocalRequestWakelock, times(localReqCnt)).acquire(); 6150 6151 mIkeSessionStateMachine.killSession(); 6152 mLooper.dispatchAll(); 6153 verify(mMockLocalRequestWakelock, times(localReqCnt)).release(); 6154 } 6155 6156 @Test testIkeAuthWithN1Mode()6157 public void testIkeAuthWithN1Mode() throws Exception { 6158 verifyIkeAuthWith3gppEnabled( 6159 makeN1ModeInformationPayload(), 1 /* ike3gppDataListenerInvocations */); 6160 6161 verifyN1ModeReceived(); 6162 } 6163 verifyIkeAuthWith3gppEnabled( IkePayload ike3gppPayload, int ike3gppDataListenerInvocations)6164 private void verifyIkeAuthWith3gppEnabled( 6165 IkePayload ike3gppPayload, int ike3gppDataListenerInvocations) throws Exception { 6166 // Quit and restart IKE Session with N1 Mode Capability params 6167 mIkeSessionStateMachine.quitNow(); 6168 mIkeSessionStateMachine = 6169 makeAndStartIkeSession(buildIkeSessionParamsIke3gppExtension(PDU_SESSION_ID)); 6170 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 6171 6172 // Build IKE AUTH response with Auth-PSK, ID-Responder and config payloads. 6173 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 6174 authRelatedPayloads.add(ike3gppPayload); 6175 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 6176 authRelatedPayloads.add(spyAuthPayload); 6177 6178 IkeIdPayload respIdPayload = makeRespIdPayload(); 6179 authRelatedPayloads.add(respIdPayload); 6180 authRelatedPayloads.add(makeConfigPayload()); 6181 6182 verifySharedKeyAuthentication( 6183 spyAuthPayload, 6184 respIdPayload, 6185 authRelatedPayloads, 6186 true /*hasChildPayloads*/, 6187 true /*hasConfigPayloadInResp*/, 6188 false /* isMobikeEnabled */, 6189 true /* isIpv4 */, 6190 ike3gppDataListenerInvocations); 6191 verifyRetransmissionStopped(); 6192 } 6193 makeN1ModeInformationPayload()6194 private IkeNotifyPayload makeN1ModeInformationPayload() { 6195 ByteBuffer n1ModeInformationBuffer = ByteBuffer.allocate(SNSSAI.length + 1); 6196 n1ModeInformationBuffer.put((byte) SNSSAI.length); 6197 n1ModeInformationBuffer.put(SNSSAI); 6198 return new IkeNotifyPayload( 6199 NOTIFY_TYPE_N1_MODE_INFORMATION, n1ModeInformationBuffer.array()); 6200 } 6201 verifyN1ModeReceived()6202 private void verifyN1ModeReceived() { 6203 ArgumentCaptor<List<Ike3gppData>> ike3gppDataCaptor = ArgumentCaptor.forClass(List.class); 6204 verify(mMockIke3gppDataListener).onIke3gppDataReceived(ike3gppDataCaptor.capture()); 6205 6206 Ike3gppN1ModeInformation n1ModeInformation = null; 6207 for (Ike3gppData payload : ike3gppDataCaptor.getValue()) { 6208 if (payload.getDataType() == Ike3gppData.DATA_TYPE_NOTIFY_N1_MODE_INFORMATION) { 6209 n1ModeInformation = (Ike3gppN1ModeInformation) payload; 6210 } 6211 } 6212 6213 assertNotNull(n1ModeInformation); 6214 assertArrayEquals(SNSSAI, n1ModeInformation.getSnssai()); 6215 } 6216 6217 @Test testIkeAuthWithBackoffTimerNetworkError()6218 public void testIkeAuthWithBackoffTimerNetworkError() throws Exception { 6219 verifyIkeAuthWithBackoffTimer( 6220 ERROR_TYPE_NETWORK_FAILURE, UnrecognizedIkeProtocolException.class); 6221 } 6222 6223 @Test testIkeAuthWithBackoffTimerNoApnSubscription()6224 public void testIkeAuthWithBackoffTimerNoApnSubscription() throws Exception { 6225 verifyIkeAuthWithBackoffTimer( 6226 ERROR_TYPE_NO_APN_SUBSCRIPTION, UnrecognizedIkeProtocolException.class); 6227 } 6228 6229 @Test testIkeAuthWithBackoffTimerAuthenticationFailed()6230 public void testIkeAuthWithBackoffTimerAuthenticationFailed() throws Exception { 6231 verifyIkeAuthWithBackoffTimer( 6232 ERROR_TYPE_AUTHENTICATION_FAILED, AuthenticationFailedException.class); 6233 } 6234 verifyIkeAuthWithBackoffTimer( int expectedNotifyErrorCause, Class<? extends IkeProtocolException> exceptionType)6235 private void verifyIkeAuthWithBackoffTimer( 6236 int expectedNotifyErrorCause, Class<? extends IkeProtocolException> exceptionType) 6237 throws Exception { 6238 // Quit and restart IKE Session with N1 Mode Capability params 6239 mIkeSessionStateMachine.quitNow(); 6240 mIkeSessionStateMachine = 6241 makeAndStartIkeSession(buildIkeSessionParamsIke3gppExtension(PDU_SESSION_ID)); 6242 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 6243 6244 // Build IKE AUTH response with BackoffTimer and Error-Notify 6245 IkeNotifyPayload backoffTimerPayload = 6246 new IkeNotifyPayload(NOTIFY_TYPE_BACKOFF_TIMER, BACKOFF_TIMER_DATA); 6247 IkeNotifyPayload errorNotify = new IkeNotifyPayload(expectedNotifyErrorCause); 6248 6249 ReceivedIkePacket mockBackoffTimerResponsePacket = 6250 makeIkeAuthRespWithoutChildPayloads( 6251 Arrays.asList(backoffTimerPayload, errorNotify)); 6252 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockBackoffTimerResponsePacket); 6253 mLooper.dispatchAll(); 6254 6255 // Verify IKE Session is closed properly 6256 assertNull(mIkeSessionStateMachine.getCurrentState()); 6257 6258 // This exception is mapped to metrics error code: 6259 int expectedError = expectedNotifyErrorCause; 6260 if (expectedError == ERROR_TYPE_AUTHENTICATION_FAILED) { 6261 expectedError = IkeMetrics.IKE_ERROR_PROTOCOL_AUTHENTICATION_FAILED; 6262 } 6263 6264 verify(mMockIkeSessionCallback).onClosedWithException(any(exceptionType)); 6265 6266 verifyIkeMetricsLogged( 6267 getStateCode(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth), expectedError); 6268 6269 verifyBackoffTimer(expectedNotifyErrorCause); 6270 } 6271 verifyBackoffTimer(int expectedNotifyErrorCause)6272 private void verifyBackoffTimer(int expectedNotifyErrorCause) { 6273 ArgumentCaptor<List<Ike3gppData>> ike3gppDataCaptor = ArgumentCaptor.forClass(List.class); 6274 verify(mMockIke3gppDataListener).onIke3gppDataReceived(ike3gppDataCaptor.capture()); 6275 6276 Ike3gppBackoffTimer backoffTimer = null; 6277 for (Ike3gppData payload : ike3gppDataCaptor.getValue()) { 6278 if (payload.getDataType() == Ike3gppData.DATA_TYPE_NOTIFY_BACKOFF_TIMER) { 6279 backoffTimer = (Ike3gppBackoffTimer) payload; 6280 } 6281 } 6282 6283 assertNotNull(backoffTimer); 6284 assertEquals(BACKOFF_TIMER, backoffTimer.getBackoffTimer()); 6285 assertEquals(expectedNotifyErrorCause, backoffTimer.getBackoffCause()); 6286 } 6287 6288 @Test testIkeAuthWithBackoffTimerWithoutError()6289 public void testIkeAuthWithBackoffTimerWithoutError() throws Exception { 6290 verifyIkeAuthWith3gppEnabled( 6291 new IkeNotifyPayload(NOTIFY_TYPE_BACKOFF_TIMER, BACKOFF_TIMER_DATA), 6292 0 /* ike3gppDataListenerInvocations */); 6293 6294 // BackoffTimer should be ignored 6295 verify(mMockIke3gppDataListener, never()).onIke3gppDataReceived(any()); 6296 } 6297 6298 @Test(expected = IllegalArgumentException.class) testIke3gppReuseCallback()6299 public void testIke3gppReuseCallback() throws Exception { 6300 mIkeSessionStateMachine = 6301 makeAndStartIkeSession(buildIkeSessionParamsIke3gppExtension(PDU_SESSION_ID)); 6302 makeAndStartIkeSession(buildIkeSessionParamsIke3gppExtension(PDU_SESSION_ID)); 6303 } 6304 6305 @Test 6306 @SdkSuppress(minSdkVersion = 31, codeName = "S") testOnlyRfcMobikeEnabled()6307 public void testOnlyRfcMobikeEnabled() throws Exception { 6308 verifyRfcMobikeEnabled(true /* doesPeerSupportMobike */); 6309 6310 killSessionAndVerifyNetworkCallback(); 6311 } 6312 6313 @Test 6314 @SdkSuppress(minSdkVersion = 31, codeName = "S") testOnlyRfcMobikeEnabledPeerUnsupported()6315 public void testOnlyRfcMobikeEnabledPeerUnsupported() throws Exception { 6316 verifyRfcMobikeEnabled(false /* doesPeerSupportMobike */); 6317 6318 killSessionAndVerifyNetworkCallback(); 6319 } 6320 6321 @Test 6322 @SdkSuppress(minSdkVersion = 31, codeName = "S") testOnlyRekeyMobilityEnabled()6323 public void testOnlyRekeyMobilityEnabled() throws Exception { 6324 verifyOnlyRekeyMobilityEnabled(); 6325 6326 killSessionAndVerifyNetworkCallback(); 6327 } 6328 6329 @Test 6330 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeRekeyMobilityEnabled()6331 public void testMobikeRekeyMobilityEnabled() throws Exception { 6332 verifyMobikeRekeyMobilityEnabled(true /* doesPeerSupportMobike */); 6333 6334 killSessionAndVerifyNetworkCallback(); 6335 } 6336 6337 @Test 6338 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeRekeyMobilityEnabledPeerUnsupported()6339 public void testMobikeRekeyMobilityEnabledPeerUnsupported() throws Exception { 6340 verifyMobikeRekeyMobilityEnabled(false /* doesPeerSupportMobike */); 6341 6342 killSessionAndVerifyNetworkCallback(); 6343 } 6344 6345 @Test 6346 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeEnabledWithEap()6347 public void testMobikeEnabledWithEap() throws Exception { 6348 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 6349 authRelatedPayloads.add(new IkeNotifyPayload(NOTIFY_TYPE_MOBIKE_SUPPORTED)); 6350 6351 verifyCreateIkeLocalIkeAuthPostEap( 6352 buildIkeSessionParamsWithIkeOptions(IKE_OPTION_MOBIKE), 6353 authRelatedPayloads, 6354 true /* isMobikeEnabled */); 6355 assertTrue(mIkeSessionStateMachine.mEnabledExtensions.contains(EXTENSION_TYPE_MOBIKE)); 6356 } 6357 6358 @Test 6359 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeEnabledNattSupportedIpv4()6360 public void testMobikeEnabledNattSupportedIpv4() throws Exception { 6361 verifyMobikeEnabled(true /* doesPeerSupportNatt */, true /* isIpv4 */); 6362 6363 killSessionAndVerifyNetworkCallback(); 6364 } 6365 6366 @Test 6367 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeEnabledNattUnsupportedIpv4()6368 public void testMobikeEnabledNattUnsupportedIpv4() throws Exception { 6369 verifyMobikeEnabled(false /* doesPeerSupportNatt */, true /* isIpv4 */); 6370 6371 killSessionAndVerifyNetworkCallback(); 6372 } 6373 6374 @Test 6375 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeEnabledNattUnsupportedIpv6()6376 public void testMobikeEnabledNattUnsupportedIpv6() throws Exception { 6377 verifyMobikeEnabled(false /* doesPeerSupportNatt */, false /* isIpv4 */); 6378 6379 killSessionAndVerifyNetworkCallback(); 6380 } 6381 6382 /** 6383 * Restarts the IkeSessionStateMachine with MOBIKE enabled. If doesPeerSupportMobike, MOBIKE 6384 * will be active for the Session. 6385 * 6386 * @return the registered IkeDefaultNetworkCallack is returned if MOBIKE is active, else null 6387 */ 6388 @Nullable verifyRfcMobikeEnabled(boolean doesPeerSupportMobike)6389 private IkeDefaultNetworkCallback verifyRfcMobikeEnabled(boolean doesPeerSupportMobike) 6390 throws Exception { 6391 // Can cast to IkeDefaultNetworkCallback because no Network is specified 6392 return (IkeDefaultNetworkCallback) 6393 verifyMobikeEnabled(doesPeerSupportMobike, null /* configuredNetwork */); 6394 } 6395 6396 @Nullable verifyMobikeRekeyMobilityEnabled( boolean doesPeerSupportMobike)6397 private IkeDefaultNetworkCallback verifyMobikeRekeyMobilityEnabled( 6398 boolean doesPeerSupportMobike) throws Exception { 6399 // Can cast to IkeDefaultNetworkCallback because no Network is specified 6400 return (IkeDefaultNetworkCallback) 6401 verifyMobikeEnabled( 6402 doesPeerSupportMobike, 6403 true /* doesPeerSupportNatt */, 6404 true /* isIpv4 */, 6405 false /* isEnforcePort4500*/, 6406 null /* configuredNetwork */, 6407 true /* mobikeEnabled */, 6408 true /* rekeyMobilityEnabled */); 6409 } 6410 6411 @Nullable verifyOnlyRekeyMobilityEnabled()6412 private IkeDefaultNetworkCallback verifyOnlyRekeyMobilityEnabled() throws Exception { 6413 // Can cast to IkeDefaultNetworkCallback because no Network is specified 6414 return (IkeDefaultNetworkCallback) 6415 verifyMobikeEnabled( 6416 false /* doesPeerSupportMobike */, 6417 true /* doesPeerSupportNatt */, 6418 true /* isIpv4 */, 6419 false /* isEnforcePort4500*/, 6420 null /* configuredNetwork */, 6421 false /* mobikeEnabled */, 6422 true /* rekeyMobilityEnabled */); 6423 } 6424 6425 @Nullable verifyMobikeEnabled( boolean doesPeerSupportMobike, Network configuredNetwork)6426 private IkeNetworkCallbackBase verifyMobikeEnabled( 6427 boolean doesPeerSupportMobike, Network configuredNetwork) throws Exception { 6428 return verifyMobikeEnabled( 6429 doesPeerSupportMobike, 6430 true /* doesPeerSupportNatt */, 6431 true /* isIpv4 */, 6432 false /* isEnforcePort4500*/, 6433 configuredNetwork, 6434 true /* mobikeEnabled */, 6435 false /* rekeyMobilityEnabled */); 6436 } 6437 6438 @Nullable verifyMobikeEnabled( boolean doesPeerSupportNatt, boolean isIpv4)6439 private IkeDefaultNetworkCallback verifyMobikeEnabled( 6440 boolean doesPeerSupportNatt, boolean isIpv4) throws Exception { 6441 // Can cast to IkeDefaultNetworkCallback because no Network is specified 6442 return (IkeDefaultNetworkCallback) 6443 verifyMobikeEnabled( 6444 true /* doesPeerSupportMobike */, 6445 doesPeerSupportNatt, 6446 isIpv4, 6447 false /* isEnforcePort4500*/, 6448 null /* configuredNetwork */, 6449 true /* mobikeEnabled */, 6450 false /* rekeyMobilityEnabled */); 6451 } 6452 6453 /** Returns the expected IkeSocket type when MOBIKE is supported by both sides */ getExpectedSocketType( boolean doesPeerSupportNatt, boolean isEnforcePort4500, boolean isIpv4)6454 private Class<? extends IkeSocket> getExpectedSocketType( 6455 boolean doesPeerSupportNatt, boolean isEnforcePort4500, boolean isIpv4) { 6456 if (doesPeerSupportNatt || isEnforcePort4500) { 6457 if (isIpv4) { 6458 return IkeUdpEncapSocket.class; 6459 } else { 6460 return IkeUdp6WithEncapPortSocket.class; 6461 } 6462 } else { 6463 if (isIpv4) { 6464 return IkeUdp4Socket.class; 6465 } else { 6466 return IkeUdp6Socket.class; 6467 } 6468 } 6469 } 6470 6471 @Nullable verifyMobikeEnabled( boolean doesPeerSupportMobike, boolean doesPeerSupportNatt, boolean isIpv4, boolean isEnforcePort4500, Network configuredNetwork, boolean mobikeEnabled, boolean rekeyMobilityEnabled)6472 private IkeNetworkCallbackBase verifyMobikeEnabled( 6473 boolean doesPeerSupportMobike, 6474 boolean doesPeerSupportNatt, 6475 boolean isIpv4, 6476 boolean isEnforcePort4500, 6477 Network configuredNetwork, 6478 boolean mobikeEnabled, 6479 boolean rekeyMobilityEnabled) 6480 throws Exception { 6481 mIkeSessionStateMachine = 6482 restartStateMachineWithMobikeConfigured( 6483 configuredNetwork, 6484 isEnforcePort4500, 6485 isIpv4, 6486 mobikeEnabled, 6487 rekeyMobilityEnabled); 6488 new IkeFirstAuthTestPretest().mockIkeInitAndTransitionToIkeAuth(); 6489 6490 // Enable force_udp_encap under IPv4 network because the kernel cannot process both 6491 // UDP-encap and non-UDP-encap ESP packets for a single SA 6492 boolean doesEnableForceUdpEncap = isIpv4; 6493 6494 if (isIpv4) { 6495 if (doesPeerSupportNatt || doesEnableForceUdpEncap) { 6496 // Either NAT detected or not detected won't affect the test since both cases 6497 // indicate the server support NAT-T 6498 mSpyIkeConnectionCtrl.handleNatDetectionResultInIkeInit( 6499 true /* isNatDetected */, mSpyCurrentIkeSaRecord.getLocalSpi()); 6500 } else { 6501 mSpyIkeConnectionCtrl.markSeverNattUnsupported(); 6502 } 6503 } else { 6504 // IKE client does not support IPv6 NAT-T and will not check if the server supports 6505 // NAT-T when using IPv6 for IKE Session setup. 6506 mSpyIkeConnectionCtrl.resetSeverNattSupport(); 6507 } 6508 6509 // Build IKE AUTH response. Include MOBIKE_SUPPORTED if doesPeerSupportMobike is true 6510 List<IkePayload> authRelatedPayloads = new ArrayList<>(); 6511 IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload(); 6512 authRelatedPayloads.add(spyAuthPayload); 6513 6514 IkeIdPayload respIdPayload = makeRespIdPayload(); 6515 authRelatedPayloads.add(respIdPayload); 6516 authRelatedPayloads.add(makeConfigPayload()); 6517 6518 if (doesPeerSupportMobike) { 6519 authRelatedPayloads.add(new IkeNotifyPayload(NOTIFY_TYPE_MOBIKE_SUPPORTED)); 6520 } 6521 6522 IkeMessage ikeAuthReqMessage = 6523 verifySharedKeyAuthentication( 6524 spyAuthPayload, 6525 respIdPayload, 6526 authRelatedPayloads, 6527 true /* hasChildPayloads */, 6528 true /* hasConfigPayloadInResp */, 6529 doesPeerSupportMobike, 6530 isIpv4, 6531 0 /* ike3gppDataListenerInvocations */); 6532 verifyRetransmissionStopped(); 6533 6534 boolean isMobikeSupportIndicated = false; 6535 List<IkeNotifyPayload> reqNotifyPayloads = 6536 ikeAuthReqMessage.getPayloadListForType( 6537 PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 6538 for (IkeNotifyPayload notifyPayload : reqNotifyPayloads) { 6539 if (notifyPayload.notifyType == NOTIFY_TYPE_MOBIKE_SUPPORTED) { 6540 isMobikeSupportIndicated = true; 6541 break; 6542 } 6543 } 6544 6545 assertEquals(mobikeEnabled, isMobikeSupportIndicated); 6546 6547 assertEquals( 6548 doesPeerSupportMobike, 6549 mIkeSessionStateMachine.mEnabledExtensions.contains(EXTENSION_TYPE_MOBIKE)); 6550 6551 if (rekeyMobilityEnabled || doesPeerSupportMobike) { 6552 assertTrue(mSpyIkeConnectionCtrl.isMobilityEnabled()); 6553 assertTrue( 6554 getExpectedSocketType( 6555 doesPeerSupportNatt || doesEnableForceUdpEncap, 6556 isEnforcePort4500, 6557 isIpv4) 6558 .isInstance(mSpyIkeConnectionCtrl.getIkeSocket())); 6559 } else { 6560 assertFalse(mSpyIkeConnectionCtrl.isMobilityEnabled()); 6561 } 6562 6563 ArgumentCaptor<IkeNetworkCallbackBase> networkCallbackCaptor = 6564 ArgumentCaptor.forClass(IkeNetworkCallbackBase.class); 6565 // Expect different NetworkCallback registrations if there is a caller-configured 6566 // Network 6567 if (configuredNetwork == null) { 6568 verify(mMockConnectManager) 6569 .registerDefaultNetworkCallback(networkCallbackCaptor.capture(), any()); 6570 } else { 6571 verify(mMockConnectManager) 6572 .registerNetworkCallback(any(), networkCallbackCaptor.capture(), any()); 6573 } 6574 6575 IkeNetworkCallbackBase networkCallback = networkCallbackCaptor.getValue(); 6576 Class<? extends IkeNetworkCallbackBase> expectedCallbackType = 6577 configuredNetwork == null 6578 ? IkeDefaultNetworkCallback.class 6579 : IkeSpecificNetworkCallback.class; 6580 assertTrue(expectedCallbackType.isInstance(networkCallback)); 6581 return networkCallback; 6582 } 6583 killSessionAndVerifyNetworkCallback()6584 private void killSessionAndVerifyNetworkCallback() { 6585 mIkeSessionStateMachine.killSession(); 6586 mLooper.dispatchAll(); 6587 6588 verify(mMockConnectManager).unregisterNetworkCallback(any(IkeDefaultNetworkCallback.class)); 6589 } 6590 6591 /** Restarts the IkeSessionStateMachine with MOBIKE configured in the IkeSessionParams. */ restartStateMachineWithRfcMobikeConfigured()6592 private IkeSessionStateMachine restartStateMachineWithRfcMobikeConfigured() throws Exception { 6593 return restartStateMachineWithMobikeConfigured( 6594 null /* network */, 6595 false /* isEnforcePort4500*/, 6596 true /* isIpv4 */, 6597 true /* mobikeEnabled */, 6598 false /* rekeyMobilityEnabled */); 6599 } 6600 restartStateMachineWithMobikeConfigured( @ullable Network configuredNetwork, boolean isEnforcePort4500, boolean isIpv4, boolean mobikeEnabled, boolean rekeyMobilityEnabled)6601 private IkeSessionStateMachine restartStateMachineWithMobikeConfigured( 6602 @Nullable Network configuredNetwork, 6603 boolean isEnforcePort4500, 6604 boolean isIpv4, 6605 boolean mobikeEnabled, 6606 boolean rekeyMobilityEnabled) 6607 throws Exception { 6608 mIkeSessionStateMachine.quitNow(); 6609 mLooper.dispatchAll(); 6610 6611 // Clear ConnectivityManager#getActiveNetwork (#makeAndStartIkeSession() expects no use of 6612 // ConnectivityManager#getActiveNetwork when there is a configured Network) and the network 6613 // callback registration call in #setUp(). 6614 resetMockConnectManager(); 6615 6616 // Set local and remote address 6617 Network network = configuredNetwork == null ? mMockDefaultNetwork : configuredNetwork; 6618 InetAddress localAddress = isIpv4 ? LOCAL_ADDRESS : LOCAL_ADDRESS_V6; 6619 InetAddress remoteAddress = isIpv4 ? REMOTE_ADDRESS : REMOTE_ADDRESS_V6; 6620 setupLocalAddressForNetwork(network, localAddress); 6621 setupRemoteAddressForNetwork(network, remoteAddress); 6622 6623 IkeSessionParams.Builder ikeSessionParamsBuilder = 6624 buildIkeSessionParamsCommon().setAuthPsk(mPsk); 6625 6626 if (mobikeEnabled) { 6627 ikeSessionParamsBuilder.addIkeOption(IKE_OPTION_MOBIKE); 6628 } 6629 6630 if (rekeyMobilityEnabled) { 6631 ikeSessionParamsBuilder.addIkeOptionInternal(IKE_OPTION_REKEY_MOBILITY); 6632 } else { 6633 // IKE_OPTION_REKEY_MOBILITY will be automatically added with IKE_OPTION_MOBIKE. So 6634 // explicitly remove it here 6635 ikeSessionParamsBuilder.removeIkeOption(IKE_OPTION_REKEY_MOBILITY); 6636 } 6637 6638 if (isEnforcePort4500) { 6639 ikeSessionParamsBuilder.addIkeOption(IKE_OPTION_FORCE_PORT_4500); 6640 } 6641 if (configuredNetwork != null) { 6642 ikeSessionParamsBuilder.setNetwork(configuredNetwork); 6643 } 6644 return makeAndStartIkeSession(ikeSessionParamsBuilder.build(), localAddress, remoteAddress); 6645 } 6646 verifyHandleNetworkChange()6647 private void verifyHandleNetworkChange() throws Exception { 6648 if (SdkLevel.isAtLeastT()) { 6649 verify(mMockIkeSessionCallback).onClosedWithException(any(IkeException.class)); 6650 assertNull(mIkeSessionStateMachine.getCurrentState()); 6651 } else { 6652 verify(mMockIkeSessionCallback).onError(any(IkeException.class)); 6653 assertNotNull(mIkeSessionStateMachine.getCurrentState()); 6654 } 6655 } 6656 6657 @Test 6658 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobilityDisabledNetworkDies()6659 public void testMobilityDisabledNetworkDies() throws Exception { 6660 IkeDefaultNetworkCallback callback = 6661 verifyRfcMobikeEnabled(false /* doesPeerSupportMobike */); 6662 callback.onLost(mMockDefaultNetwork); 6663 mLooper.dispatchAll(); 6664 6665 verifyHandleNetworkChange(); 6666 } 6667 6668 @Test 6669 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobilityDisabledNetworkUpdates()6670 public void testMobilityDisabledNetworkUpdates() throws Exception { 6671 IkeDefaultNetworkCallback callback = 6672 verifyRfcMobikeEnabled(false /* doesPeerSupportMobike */); 6673 Network newNetwork = mock(Network.class); 6674 callback.onAvailable(newNetwork); 6675 callback.onCapabilitiesChanged(newNetwork, mock(NetworkCapabilities.class)); 6676 callback.onLinkPropertiesChanged(newNetwork, mock(LinkProperties.class)); 6677 6678 mLooper.dispatchAll(); 6679 6680 verifyHandleNetworkChange(); 6681 } 6682 6683 @Test 6684 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeEnabledNetworkDies()6685 public void testMobikeEnabledNetworkDies() throws Exception { 6686 IkeDefaultNetworkCallback callback = 6687 verifyRfcMobikeEnabled(true /* doesPeerSupportMobike */); 6688 callback.onLost(mMockDefaultNetwork); 6689 6690 ArgumentCaptor<IkeException> exceptionCaptor = ArgumentCaptor.forClass(IkeException.class); 6691 verify(mMockIkeSessionCallback).onError(exceptionCaptor.capture()); 6692 IkeNetworkLostException cause = (IkeNetworkLostException) exceptionCaptor.getValue(); 6693 assertEquals(mMockDefaultNetwork, cause.getNetwork()); 6694 } 6695 verifyMobikeActiveMobilityEvent(boolean isEnforcePort4500)6696 private void verifyMobikeActiveMobilityEvent(boolean isEnforcePort4500) throws Exception { 6697 IkeDefaultNetworkCallback callback = 6698 (IkeDefaultNetworkCallback) 6699 verifyMobikeEnabled( 6700 true /* doesPeerSupportMobike */, 6701 false /* doesPeerSupportNatt */, 6702 true /* isIpv4 */, 6703 isEnforcePort4500, 6704 null /* configuredNetwork */, 6705 true /* mobikeEnabled */, 6706 false /* rekeyMobilityEnabled */); 6707 6708 Network newNetwork = mockNewNetworkAndAddress(true /* isIpv4 */); 6709 6710 callback.onAvailable(newNetwork); 6711 callback.onCapabilitiesChanged(newNetwork, mock(NetworkCapabilities.class)); 6712 callback.onLinkPropertiesChanged( 6713 newNetwork, mMockConnectManager.getLinkProperties(newNetwork)); 6714 mLooper.dispatchAll(); 6715 6716 verifyNetworkAndLocalAddressUpdated( 6717 newNetwork, UPDATED_LOCAL_ADDRESS, REMOTE_ADDRESS, callback); 6718 verify(mMockIkeLocalAddressGenerator) 6719 .generateLocalAddress( 6720 eq(newNetwork), eq(true /* isIpv4 */), eq(REMOTE_ADDRESS), anyInt()); 6721 } 6722 6723 @Test 6724 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeActiveMobilityEvent()6725 public void testMobikeActiveMobilityEvent() throws Exception { 6726 verifyMobikeActiveMobilityEvent(false /* isEnforcePort4500 */); 6727 assertTrue(mSpyIkeConnectionCtrl.getIkeSocket() instanceof IkeUdpEncapSocket); 6728 } 6729 6730 @Test 6731 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeActiveMobilityEventWithEnforcePort4500()6732 public void testMobikeActiveMobilityEventWithEnforcePort4500() throws Exception { 6733 verifyMobikeActiveMobilityEvent(true /* isEnforcePort4500 */); 6734 assertTrue(mSpyIkeConnectionCtrl.getIkeSocket() instanceof IkeUdpEncapSocket); 6735 } 6736 mockNewNetworkAndAddress(boolean isIpv4)6737 private Network mockNewNetworkAndAddress(boolean isIpv4) throws Exception { 6738 InetAddress expectedRemoteAddress; 6739 InetAddress injectedLocalAddress; 6740 if (isIpv4) { 6741 expectedRemoteAddress = REMOTE_ADDRESS; 6742 injectedLocalAddress = UPDATED_LOCAL_ADDRESS; 6743 } else { 6744 expectedRemoteAddress = REMOTE_ADDRESS_V6; 6745 injectedLocalAddress = UPDATED_LOCAL_ADDRESS_V6; 6746 } 6747 6748 return mockNewNetworkAndAddress(isIpv4, injectedLocalAddress, expectedRemoteAddress); 6749 } 6750 mockNewNetworkAndAddress( boolean isIpv4, InetAddress localAddress, InetAddress remoteAddress)6751 private Network mockNewNetworkAndAddress( 6752 boolean isIpv4, InetAddress localAddress, InetAddress remoteAddress) throws Exception { 6753 return mockNewNetworkAndAddress(isIpv4, localAddress, remoteAddress, 1 /* dnsLookups */); 6754 } 6755 mockNewNetworkAndAddress( boolean isIpv4, InetAddress localAddress, InetAddress remoteAddress, int dnsLookups)6756 private Network mockNewNetworkAndAddress( 6757 boolean isIpv4, InetAddress localAddress, InetAddress remoteAddress, int dnsLookups) 6758 throws Exception { 6759 Network newNetwork = mock(Network.class); 6760 6761 LinkAddress linkAddress = mock(LinkAddress.class); 6762 when(linkAddress.getAddress()).thenReturn(localAddress); 6763 6764 LinkProperties linkProperties = new LinkProperties(); 6765 linkProperties.addLinkAddress(linkAddress); 6766 when(mMockConnectManager.getLinkProperties(eq(newNetwork))).thenReturn(linkProperties); 6767 6768 if (!isIpv4) { 6769 when(linkAddress.isGlobalPreferred()).thenReturn(true); 6770 } 6771 6772 setupDnsResolutionForNetwork(newNetwork, dnsLookups, remoteAddress); 6773 setupLocalAddressForNetwork(newNetwork, localAddress); 6774 6775 return newNetwork; 6776 } 6777 verifyNetworkAndLocalAddressUpdated( Network underlyingNetwork, InetAddress localAddress, InetAddress remoteAddress, IkeNetworkCallbackBase networkCallback)6778 private void verifyNetworkAndLocalAddressUpdated( 6779 Network underlyingNetwork, 6780 InetAddress localAddress, 6781 InetAddress remoteAddress, 6782 IkeNetworkCallbackBase networkCallback) 6783 throws Exception { 6784 assertEquals(underlyingNetwork, mSpyIkeConnectionCtrl.getNetwork()); 6785 assertEquals(underlyingNetwork, mSpyIkeConnectionCtrl.getNetwork()); 6786 assertEquals(localAddress, mSpyIkeConnectionCtrl.getLocalAddress()); 6787 assertEquals(remoteAddress, mSpyIkeConnectionCtrl.getRemoteAddress()); 6788 6789 verifyIkeSaAddresses( 6790 mIkeSessionStateMachine.mCurrentIkeSaRecord, localAddress, remoteAddress); 6791 6792 verify(underlyingNetwork, atLeastOnce()).getAllByName(REMOTE_HOSTNAME); 6793 6794 assertEquals(underlyingNetwork, networkCallback.getNetwork()); 6795 assertEquals(localAddress, networkCallback.getAddress()); 6796 } 6797 verifyIkeSaAddresses( IkeSaRecord saRecord, InetAddress localAddress, InetAddress remoteAddress)6798 private void verifyIkeSaAddresses( 6799 IkeSaRecord saRecord, InetAddress localAddress, InetAddress remoteAddress) { 6800 assertEquals( 6801 localAddress, saRecord.getInitiatorIkeSecurityParameterIndex().getSourceAddress()); 6802 assertEquals( 6803 remoteAddress, saRecord.getResponderIkeSecurityParameterIndex().getSourceAddress()); 6804 } 6805 6806 // TODO : this should be NullPointerException 6807 @Test(expected = IllegalArgumentException.class) testSetNetworkNull()6808 public void testSetNetworkNull() throws Exception { 6809 mIkeSessionStateMachine.setNetwork(null, 6810 IkeSessionParams.ESP_IP_VERSION_AUTO, 6811 IkeSessionParams.ESP_ENCAP_TYPE_AUTO, 6812 IkeSessionParams.NATT_KEEPALIVE_INTERVAL_AUTO); 6813 } 6814 6815 @Test(expected = IllegalStateException.class) testSetNetworkMobikeNotActive()6816 public void testSetNetworkMobikeNotActive() throws Exception { 6817 Network newNetwork = mock(Network.class); 6818 6819 mIkeSessionStateMachine.setNetwork(newNetwork, 6820 IkeSessionParams.ESP_IP_VERSION_AUTO, 6821 IkeSessionParams.ESP_ENCAP_TYPE_AUTO, 6822 IkeSessionParams.NATT_KEEPALIVE_INTERVAL_AUTO); 6823 } 6824 6825 @Test(expected = IllegalStateException.class) 6826 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkMobikeActiveNetworkNotSpecified()6827 public void testSetNetworkMobikeActiveNetworkNotSpecified() throws Exception { 6828 Network newNetwork = mock(Network.class); 6829 6830 verifyRfcMobikeEnabled(true /* doesPeerSupportMobike */); 6831 6832 mIkeSessionStateMachine.setNetwork(newNetwork, 6833 IkeSessionParams.ESP_IP_VERSION_AUTO, 6834 IkeSessionParams.ESP_ENCAP_TYPE_AUTO, 6835 IkeSessionParams.NATT_KEEPALIVE_INTERVAL_AUTO); 6836 } 6837 verifySetNetwork( IkeNetworkCallbackBase callback, IkeSaRecord rekeySaRecord, State expectedState)6838 private void verifySetNetwork( 6839 IkeNetworkCallbackBase callback, IkeSaRecord rekeySaRecord, State expectedState) 6840 throws Exception { 6841 verifySetNetwork(callback, rekeySaRecord, expectedState, true /* isIpv4 */); 6842 } 6843 verifySetNetwork( IkeNetworkCallbackBase callback, IkeSaRecord rekeySaRecord, State expectedState, boolean isIpv4)6844 private void verifySetNetwork( 6845 IkeNetworkCallbackBase callback, 6846 IkeSaRecord rekeySaRecord, 6847 State expectedState, 6848 boolean isIpv4) 6849 throws Exception { 6850 Network newNetwork = mockNewNetworkAndAddress(isIpv4); 6851 6852 mIkeSessionStateMachine.setNetwork(newNetwork, 6853 IkeSessionParams.ESP_IP_VERSION_AUTO, 6854 IkeSessionParams.ESP_ENCAP_TYPE_AUTO, 6855 IkeSessionParams.NATT_KEEPALIVE_INTERVAL_AUTO); 6856 mLooper.dispatchAll(); 6857 6858 InetAddress expectedUpdatedLocalAddress = 6859 isIpv4 ? UPDATED_LOCAL_ADDRESS : UPDATED_LOCAL_ADDRESS_V6; 6860 InetAddress expectedRemoteAddress = isIpv4 ? REMOTE_ADDRESS : REMOTE_ADDRESS_V6; 6861 6862 verifyNetworkAndLocalAddressUpdated( 6863 newNetwork, expectedUpdatedLocalAddress, expectedRemoteAddress, callback); 6864 verify(mMockIkeLocalAddressGenerator) 6865 .generateLocalAddress( 6866 eq(newNetwork), eq(isIpv4), eq(expectedRemoteAddress), anyInt()); 6867 6868 verify(mSpyIkeConnectionCtrl.getIkeSocket()) 6869 .registerIke( 6870 mIkeSessionStateMachine.mCurrentIkeSaRecord.getLocalSpi(), 6871 mSpyIkeConnectionCtrl); 6872 6873 if (rekeySaRecord != null) { 6874 verifyIkeSaAddresses(rekeySaRecord, expectedUpdatedLocalAddress, expectedRemoteAddress); 6875 verify(mSpyIkeConnectionCtrl.getIkeSocket()) 6876 .registerIke(rekeySaRecord.getLocalSpi(), mSpyIkeConnectionCtrl); 6877 } 6878 6879 assertEquals(expectedState, mIkeSessionStateMachine.getCurrentState()); 6880 } 6881 setupIdleStateMachineWithMobike()6882 private IkeNetworkCallbackBase setupIdleStateMachineWithMobike() throws Exception { 6883 return setupIdleStateMachineWithMobike(true /* doesPeerSupportNatt */, true /* isIpv4 */); 6884 } 6885 setupIdleStateMachineWithMobike( boolean doesPeerSupportNatt, boolean isIpv4)6886 private IkeNetworkCallbackBase setupIdleStateMachineWithMobike( 6887 boolean doesPeerSupportNatt, boolean isIpv4) throws Exception { 6888 IkeNetworkCallbackBase callback = 6889 verifyMobikeEnabled( 6890 true /* doesPeerSupportMobike */, 6891 doesPeerSupportNatt, 6892 isIpv4, 6893 false /* isEnforcePort4500*/, 6894 mMockDefaultNetwork, 6895 true /* mobikeEnabled */, 6896 false /* rekeyMobilityEnabled */); 6897 6898 // reset IkeMessageHelper to make verifying outbound req easier 6899 resetMockIkeMessageHelper(); 6900 6901 mDummyChildSmCallback = 6902 createChildAndGetChildSessionSmCallback( 6903 mMockChildSessionStateMachine, CHILD_SPI_REMOTE, mMockChildSessionCallback); 6904 6905 mIkeSessionStateMachine.sendMessage( 6906 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 6907 mLooper.dispatchAll(); 6908 6909 return callback; 6910 } 6911 verifySetNetworkInIdleState( boolean doesPeerSupportNatt, boolean isIpv4BeforeNetworkChange, boolean isIpv4AfterNetworkChange)6912 private void verifySetNetworkInIdleState( 6913 boolean doesPeerSupportNatt, 6914 boolean isIpv4BeforeNetworkChange, 6915 boolean isIpv4AfterNetworkChange) 6916 throws Exception { 6917 IkeNetworkCallbackBase callback = 6918 setupIdleStateMachineWithMobike(doesPeerSupportNatt, isIpv4BeforeNetworkChange); 6919 6920 verifySetNetwork( 6921 callback, 6922 null /* rekeySaRecord */, 6923 mIkeSessionStateMachine.mMobikeLocalInfo, 6924 isIpv4AfterNetworkChange); 6925 assertTrue( 6926 getExpectedSocketType( 6927 doesPeerSupportNatt 6928 || isIpv4AfterNetworkChange /* force UDP-encap */, 6929 false /* isEnforcePort4500*/, 6930 isIpv4AfterNetworkChange) 6931 .isInstance(mSpyIkeConnectionCtrl.getIkeSocket())); 6932 } 6933 6934 @Test 6935 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkInIdleStateNattSupportedIpv4ToIpv6()6936 public void testSetNetworkInIdleStateNattSupportedIpv4ToIpv6() throws Exception { 6937 verifySetNetworkInIdleState( 6938 true /* doesPeerSupportNatt */, 6939 true /* isIpv4BeforeNetworkChange */, 6940 false /* isIpv4AfterNetworkChange */); 6941 } 6942 6943 @Test 6944 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkInIdleStateNattSupportedIpv6ToIpv4()6945 public void testSetNetworkInIdleStateNattSupportedIpv6ToIpv4() throws Exception { 6946 verifySetNetworkInIdleState( 6947 true /* doesPeerSupportNatt */, 6948 true /* isIpv4BeforeNetworkChange */, 6949 false /* isIpv4AfterNetworkChange */); 6950 } 6951 6952 @Test 6953 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkInIdleStateNattSupportedIpv4ToIpv4()6954 public void testSetNetworkInIdleStateNattSupportedIpv4ToIpv4() throws Exception { 6955 verifySetNetworkInIdleState( 6956 true /* doesPeerSupportNatt */, 6957 true /* isIpv4BeforeNetworkChange */, 6958 true /* isIpv4AfterNetworkChange */); 6959 } 6960 6961 @Test 6962 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkInIdleStateNattUnsupportedIpv4ToIpv4()6963 public void testSetNetworkInIdleStateNattUnsupportedIpv4ToIpv4() throws Exception { 6964 verifySetNetworkInIdleState( 6965 false /* doesPeerSupportNatt */, 6966 true /* isIpv4BeforeNetworkChange */, 6967 true /* isIpv4AfterNetworkChange */); 6968 } 6969 6970 @Test 6971 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkInIdleStateNattUnsupportedIpv6ToIpv6()6972 public void testSetNetworkInIdleStateNattUnsupportedIpv6ToIpv6() throws Exception { 6973 verifySetNetworkInIdleState( 6974 false /* doesPeerSupportNatt */, 6975 false /* isIpv4BeforeNetworkChange */, 6976 false /* isIpv4AfterNetworkChange */); 6977 } 6978 6979 @Test 6980 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkLocalRekeyState()6981 public void testSetNetworkLocalRekeyState() throws Exception { 6982 // Start IKE Session + transition to Idle 6983 IkeNetworkCallbackBase callback = 6984 verifyMobikeEnabled(true /* doesPeerSupportMobike */, mMockDefaultNetwork); 6985 mIkeSessionStateMachine.sendMessage( 6986 IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle); 6987 6988 verifyRekeyIkeLocalCreateHandlesResponse(); 6989 6990 verifySetNetwork( 6991 callback, 6992 mIkeSessionStateMachine.mLocalInitNewIkeSaRecord, 6993 mIkeSessionStateMachine.mRekeyIkeLocalDelete); 6994 } 6995 6996 @Test 6997 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSetNetworkRemoteRekeyState()6998 public void testSetNetworkRemoteRekeyState() throws Exception { 6999 // Start IKE Session + transition to remote rekey 7000 IkeNetworkCallbackBase callback = 7001 verifyMobikeEnabled(true /* doesPeerSupportMobike */, mMockDefaultNetwork); 7002 7003 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord; 7004 mIkeSessionStateMachine.addIkeSaRecord(mSpyRemoteInitIkeSaRecord); 7005 mIkeSessionStateMachine.sendMessage( 7006 IkeSessionStateMachine.CMD_FORCE_TRANSITION, 7007 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 7008 mLooper.dispatchAll(); 7009 7010 verifySetNetwork( 7011 callback, 7012 mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord, 7013 mIkeSessionStateMachine.mRekeyIkeRemoteDelete); 7014 } 7015 verifyRcvDeviceIdentityCheckReqAndReply()7016 private void verifyRcvDeviceIdentityCheckReqAndReply() throws Exception { 7017 // Receive a Information req with DEVICE_IDENTITY payload 7018 ReceivedIkePacket dummyRequest = makeDeviceIdentityIkeRequest(); 7019 mIkeSessionStateMachine.sendMessage( 7020 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRequest); 7021 mLooper.dispatchAll(); 7022 7023 IkeMessage resp = verifyAndGetOutboundInformationalResp(); 7024 7025 List<IkeNotifyPayload> notifyPayloads = 7026 resp.getPayloadListForType(PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 7027 assertEquals(1, notifyPayloads.size()); 7028 IkeNotifyPayload deviceIdentity = notifyPayloads.get(0); 7029 assertEquals(NOTIFY_TYPE_DEVICE_IDENTITY, deviceIdentity.notifyType); 7030 assertArrayEquals(DEVICE_IDENTITY_PAYLOAD_IMEI, deviceIdentity.notifyData); 7031 } 7032 verifyRcvRoutabilityCheckReqAndReply()7033 private void verifyRcvRoutabilityCheckReqAndReply() throws Exception { 7034 // Receive a routability check request 7035 ReceivedIkePacket dummyRequest = makeRoutabilityCheckIkeRequest(); 7036 mIkeSessionStateMachine.sendMessage( 7037 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRequest); 7038 mLooper.dispatchAll(); 7039 7040 IkeMessage resp = verifyAndGetOutboundInformationalResp(); 7041 7042 List<IkeNotifyPayload> notifyPayloads = 7043 resp.getPayloadListForType(PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class); 7044 assertEquals(1, notifyPayloads.size()); 7045 IkeNotifyPayload cookie2 = notifyPayloads.get(0); 7046 assertEquals(NOTIFY_TYPE_COOKIE2, cookie2.notifyType); 7047 assertArrayEquals(COOKIE2_DATA, cookie2.notifyData); 7048 } 7049 7050 @Test testRcvRoutabilityCheckReqInIdle()7051 public void testRcvRoutabilityCheckReqInIdle() throws Exception { 7052 setupIdleStateMachine(); 7053 7054 verifyRcvRoutabilityCheckReqAndReply(); 7055 assertTrue( 7056 mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle); 7057 } 7058 7059 @Test testRcvRoutabilityCheckReqInDpd()7060 public void testRcvRoutabilityCheckReqInDpd() throws Exception { 7061 executeAndVerifySendLocalDPD(); 7062 verifyRcvRoutabilityCheckReqAndReply(); 7063 assertTrue( 7064 mIkeSessionStateMachine.getCurrentState() 7065 instanceof IkeSessionStateMachine.DpdIkeLocalInfo); 7066 } 7067 7068 @Test testRcvRoutabilityCheckReqInChildProcedureOngoing()7069 public void testRcvRoutabilityCheckReqInChildProcedureOngoing() throws Exception { 7070 setupIdleStateMachine(); 7071 7072 mIkeSessionStateMachine.sendMessage( 7073 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 7074 mLocalRequestFactory.getChildLocalRequest( 7075 IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD, 7076 mMockChildSessionCallback, 7077 null /*childParams*/)); 7078 mLooper.dispatchAll(); 7079 7080 // For conveniency to verify outbound routability check response, reset IkeMessageHelper to 7081 // forget sending Delete Child request 7082 resetMockIkeMessageHelper(); 7083 7084 verifyRcvRoutabilityCheckReqAndReply(); 7085 assertTrue( 7086 mIkeSessionStateMachine.getCurrentState() 7087 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 7088 } 7089 7090 @Test testRcvRoutabilityCheckReqInLocalRekeyIkeCreate()7091 public void testRcvRoutabilityCheckReqInLocalRekeyIkeCreate() throws Exception { 7092 setupIdleStateMachine(); 7093 7094 // Send Rekey-Create request 7095 mIkeSessionStateMachine.sendMessage( 7096 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 7097 mLocalRequestFactory.getIkeLocalRequest( 7098 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 7099 mLooper.dispatchAll(); 7100 7101 // For conveniency to verify outbound routability check response, reset IkeMessageHelper to 7102 // forget sending Rekey Create request 7103 resetMockIkeMessageHelper(); 7104 7105 verifyRcvRoutabilityCheckReqAndReply(); 7106 assertTrue( 7107 mIkeSessionStateMachine.getCurrentState() 7108 instanceof IkeSessionStateMachine.RekeyIkeLocalCreate); 7109 } 7110 verifyMobikeLocalInfoSendsRequest( boolean migrateToIpv4, boolean natSupported, boolean natDetected, boolean expectNatDetection)7111 private void verifyMobikeLocalInfoSendsRequest( 7112 boolean migrateToIpv4, 7113 boolean natSupported, 7114 boolean natDetected, 7115 boolean expectNatDetection) 7116 throws Exception { 7117 // IKE Session is set up with IPv4 address and with NAT detected 7118 setupIdleStateMachineWithMobike(); 7119 7120 if (natSupported) { 7121 mSpyIkeConnectionCtrl.setNatDetected(natDetected); 7122 } else { 7123 mSpyIkeConnectionCtrl.markSeverNattUnsupported(); 7124 } 7125 7126 if (!migrateToIpv4) { 7127 mSpyIkeConnectionCtrl.setLocalAddress(LOCAL_ADDRESS_V6); 7128 mSpyIkeConnectionCtrl.setRemoteAddress(REMOTE_ADDRESS_V6); 7129 } 7130 7131 mIkeSessionStateMachine.sendMessage( 7132 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7133 mLooper.dispatchAll(); 7134 7135 verifyUpdateSaAddressesReq(expectNatDetection); 7136 } 7137 7138 @Test 7139 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNatDetectedIpv4()7140 public void testMobikeLocalInfoSendsRequestNatDetectedIpv4() throws Exception { 7141 verifyMobikeLocalInfoSendsRequest( 7142 true /* migrateToIpv4 */, 7143 true /* natSupported */, 7144 true /* natDetected */, 7145 true /* expectNatDetection */); 7146 } 7147 7148 @Test 7149 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNatNotDetectedIpv4()7150 public void testMobikeLocalInfoSendsRequestNatNotDetectedIpv4() throws Exception { 7151 verifyMobikeLocalInfoSendsRequest( 7152 true /* migrateToIpv4 */, 7153 true /* natSupported */, 7154 false /* natDetected */, 7155 true /* expectNatDetection */); 7156 } 7157 7158 @Test 7159 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNattUnsupportedIpv4()7160 public void testMobikeLocalInfoSendsRequestNattUnsupportedIpv4() throws Exception { 7161 verifyMobikeLocalInfoSendsRequest( 7162 true /* migrateToIpv4 */, 7163 false /* natSupported */, 7164 false /* natDetected */, 7165 false /* expectNatDetection */); 7166 } 7167 7168 @Test 7169 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNatDetectedIpv6()7170 public void testMobikeLocalInfoSendsRequestNatDetectedIpv6() throws Exception { 7171 verifyMobikeLocalInfoSendsRequest( 7172 false /* migrateToIpv4 */, 7173 true /* natSupported */, 7174 true /* natDetected */, 7175 true /* expectNatDetection */); 7176 } 7177 7178 @Test 7179 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNatNotDetectedIpv6()7180 public void testMobikeLocalInfoSendsRequestNatNotDetectedIpv6() throws Exception { 7181 verifyMobikeLocalInfoSendsRequest( 7182 false /* migrateToIpv4 */, 7183 true /* natSupported */, 7184 false /* natDetected */, 7185 false /* expectNatDetection */); 7186 } 7187 7188 @Test 7189 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoSendsRequestNattUnsupportedIpv6()7190 public void testMobikeLocalInfoSendsRequestNattUnsupportedIpv6() throws Exception { 7191 verifyMobikeLocalInfoSendsRequest( 7192 false /* migrateToIpv4 */, 7193 false /* natSupported */, 7194 false /* natDetected */, 7195 false /* expectNatDetection */); 7196 } 7197 7198 @Test 7199 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoHandlesResponseWithNatDetection()7200 public void testMobikeLocalInfoHandlesResponseWithNatDetection() throws Exception { 7201 setupIdleStateMachineWithMobike(); 7202 7203 mIkeSessionStateMachine.sendMessage( 7204 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7205 mLooper.dispatchAll(); 7206 7207 verifyUpdateSaAddressesResp( 7208 true /* expectNatDetected */, 7209 mSpyIkeConnectionCtrl.getNetwork(), 7210 mSpyIkeConnectionCtrl.getLocalAddress(), 7211 mSpyIkeConnectionCtrl.getRemoteAddress()); 7212 } 7213 7214 @Test 7215 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoHandlesResponseWithoutNatDetection()7216 public void testMobikeLocalInfoHandlesResponseWithoutNatDetection() throws Exception { 7217 setupIdleStateMachineWithMobike(); 7218 mSpyIkeConnectionCtrl.markSeverNattUnsupported(); 7219 7220 mIkeSessionStateMachine.sendMessage( 7221 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7222 mLooper.dispatchAll(); 7223 7224 verifyUpdateSaAddressesResp( 7225 false /* expectNatDetected */, 7226 mSpyIkeConnectionCtrl.getNetwork(), 7227 mSpyIkeConnectionCtrl.getLocalAddress(), 7228 mSpyIkeConnectionCtrl.getRemoteAddress()); 7229 } 7230 7231 @Test 7232 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoHandlesResponseWithNatDetectedIpv6()7233 public void testMobikeLocalInfoHandlesResponseWithNatDetectedIpv6() throws Exception { 7234 setupIdleStateMachineWithMobike(); 7235 7236 // Migrate to Ipv6 7237 mSpyIkeConnectionCtrl.setLocalAddress(LOCAL_ADDRESS_V6); 7238 mSpyIkeConnectionCtrl.setRemoteAddress(REMOTE_ADDRESS_V6); 7239 7240 mIkeSessionStateMachine.sendMessage( 7241 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7242 mLooper.dispatchAll(); 7243 7244 // Send response with NAT_DETECTION payloads 7245 List<Integer> respPayloadTypeList = new ArrayList<>(); 7246 List<String> respPayloadHexStringList = new ArrayList<>(); 7247 respPayloadTypeList.add(PAYLOAD_TYPE_NOTIFY); 7248 respPayloadTypeList.add(PAYLOAD_TYPE_NOTIFY); 7249 respPayloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING); 7250 respPayloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING); 7251 7252 ReceivedIkePacket respIkePacket = 7253 makeDummyEncryptedReceivedIkePacket( 7254 mSpyCurrentIkeSaRecord, 7255 EXCHANGE_TYPE_INFORMATIONAL, 7256 true /* isResp */, 7257 respPayloadTypeList, 7258 respPayloadHexStringList); 7259 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, respIkePacket); 7260 mLooper.dispatchAll(); 7261 7262 // Verify IKE Session was closed properly 7263 assertNull(mIkeSessionStateMachine.getCurrentState()); 7264 verify(mMockIkeSessionCallback).onClosedWithException(any(IkeInternalException.class)); 7265 } 7266 verifyUpdateSaAddressesReq(boolean expectNatDetection)7267 private void verifyUpdateSaAddressesReq(boolean expectNatDetection) throws Exception { 7268 List<IkePayload> reqPayloadList = verifyOutInfoMsgHeaderAndGetPayloads(false /* isResp */); 7269 int expectedPayloads = expectNatDetection ? 3 : 1; 7270 assertEquals(expectedPayloads, reqPayloadList.size()); 7271 assertTrue(isNotifyExist(reqPayloadList, NOTIFY_TYPE_UPDATE_SA_ADDRESSES)); 7272 7273 if (expectNatDetection) { 7274 assertTrue(isNotifyExist(reqPayloadList, NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP)); 7275 assertTrue(isNotifyExist(reqPayloadList, NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP)); 7276 } 7277 } 7278 verifyUpdateSaAddressesResp( boolean expectNatDetected, Network expectedNetwork, InetAddress expectedLocalAddr, InetAddress expectedRemoteAddr)7279 private void verifyUpdateSaAddressesResp( 7280 boolean expectNatDetected, 7281 Network expectedNetwork, 7282 InetAddress expectedLocalAddr, 7283 InetAddress expectedRemoteAddr) 7284 throws Exception { 7285 List<Integer> respPayloadTypeList = new ArrayList<>(); 7286 List<String> respPayloadHexStringList = new ArrayList<>(); 7287 7288 // For simplicity, if the test tries to verify a case when there is not NAT detected, just 7289 // do not include NAT Detection payload in the response 7290 if (!expectNatDetected) { 7291 respPayloadTypeList.add(PAYLOAD_TYPE_NOTIFY); 7292 respPayloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING); 7293 7294 respPayloadTypeList.add(PAYLOAD_TYPE_NOTIFY); 7295 respPayloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING); 7296 } 7297 7298 ReceivedIkePacket respIkePacket = 7299 makeDummyEncryptedReceivedIkePacket( 7300 mSpyCurrentIkeSaRecord, 7301 EXCHANGE_TYPE_INFORMATIONAL, 7302 true /* isResp */, 7303 respPayloadTypeList, 7304 respPayloadHexStringList); 7305 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, respIkePacket); 7306 mLooper.dispatchAll(); 7307 7308 int expectedNatStatus = expectNatDetected ? NAT_DETECTED : NAT_TRAVERSAL_UNSUPPORTED; 7309 assertEquals(expectedNatStatus, mSpyIkeConnectionCtrl.getNatStatus()); 7310 7311 ArgumentCaptor<IkeSessionConnectionInfo> connectionInfoCaptor = 7312 ArgumentCaptor.forClass(IkeSessionConnectionInfo.class); 7313 verify(mMockIkeSessionCallback) 7314 .onIkeSessionConnectionInfoChanged(connectionInfoCaptor.capture()); 7315 7316 IkeSessionConnectionInfo newConnectionInfo = connectionInfoCaptor.getValue(); 7317 assertEquals(expectedNetwork, newConnectionInfo.getNetwork()); 7318 assertEquals(expectedLocalAddr, newConnectionInfo.getLocalAddress()); 7319 assertEquals(expectedRemoteAddr, newConnectionInfo.getRemoteAddress()); 7320 7321 // TODO(b/172015298): verify IPsec SAs migrated instead of rekey when kernel supports it 7322 7323 // Verify that Child Rekey (MOBIKE) initiated after successful UPDATE_SA_ADDRESSES resp 7324 assertTrue( 7325 mIkeSessionStateMachine.getCurrentState() 7326 instanceof IkeSessionStateMachine.ChildProcedureOngoing); 7327 verify(mMockChildSessionStateMachine) 7328 .performMigration(eq(expectedLocalAddr), eq(expectedRemoteAddr), any()); 7329 } 7330 7331 @Test 7332 @SdkSuppress(minSdkVersion = 31, codeName = "S") testNattKeepaliveStoppedDuringMobilityEvent()7333 public void testNattKeepaliveStoppedDuringMobilityEvent() throws Exception { 7334 // IKE Session established with IPv4 address and a NAT detected 7335 IkeNetworkCallbackBase callback = setupIdleStateMachineWithMobike(); 7336 7337 verifySetNetwork( 7338 callback, 7339 null /* rekeySaRecord */, 7340 mIkeSessionStateMachine.mMobikeLocalInfo, 7341 false /* isIpv4 */); 7342 7343 // Keepalive for the old UDP encap socket stopped 7344 verify(mMockIkeNattKeepalive).stop(); 7345 7346 // Keepalive is no longer needed since IKE Session switches to IPv6 7347 assertNull(mSpyIkeConnectionCtrl.getIkeNattKeepalive()); 7348 } 7349 7350 @Test 7351 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoHandlesDeleteRequest()7352 public void testMobikeLocalInfoHandlesDeleteRequest() throws Exception { 7353 setupIdleStateMachineWithMobike(); 7354 7355 mIkeSessionStateMachine.sendMessage( 7356 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7357 mLooper.dispatchAll(); 7358 7359 // Reset to ignore UPDATE_SA_ADDRESSES req sent when entering MobikeLocalInfo 7360 resetMockIkeMessageHelper(); 7361 7362 // Reset to ignore IkeSessionCallback#onOpened from setting up the state machine 7363 resetSpyUserCbExecutor(); 7364 7365 verifyIkeDeleteRequestHandled(mIkeSessionStateMachine.mMobikeLocalInfo); 7366 } 7367 7368 @Test 7369 @SdkSuppress(minSdkVersion = 31, codeName = "S") testMobikeLocalInfoHandlesNonDeleteRequest()7370 public void testMobikeLocalInfoHandlesNonDeleteRequest() throws Exception { 7371 setupIdleStateMachineWithMobike(); 7372 7373 mIkeSessionStateMachine.sendMessage( 7374 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mMobikeLocalInfo); 7375 mLooper.dispatchAll(); 7376 7377 // Reset to ignore UPDATE_SA_ADDRESSES req sent when entering MobikeLocalInfo 7378 resetMockIkeMessageHelper(); 7379 7380 mIkeSessionStateMachine.sendMessage( 7381 CMD_RECEIVE_IKE_PACKET, makeRoutabilityCheckIkeRequest()); 7382 mLooper.dispatchAll(); 7383 7384 verifyIncrementRemoteReqMsgId(); 7385 7386 List<IkePayload> respPayloads = verifyOutInfoMsgHeaderAndGetPayloads(true /* isResp */); 7387 assertEquals(1, respPayloads.size()); 7388 IkeNotifyPayload notifyPayload = (IkeNotifyPayload) respPayloads.get(0); 7389 assertEquals(ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType); 7390 7391 assertEquals( 7392 mIkeSessionStateMachine.mMobikeLocalInfo, 7393 mIkeSessionStateMachine.getCurrentState()); 7394 } 7395 setupAndVerifyDnsLookupsOnSetNetwork( int dnsLookupsForSuccess, int expectedDnsLookups, boolean expectSessionClosed)7396 private void setupAndVerifyDnsLookupsOnSetNetwork( 7397 int dnsLookupsForSuccess, int expectedDnsLookups, boolean expectSessionClosed) 7398 throws Exception { 7399 final IkeNetworkCallbackBase callback = setupIdleStateMachineWithMobike(); 7400 7401 final Network newNetwork = 7402 mockNewNetworkAndAddress( 7403 false /* isIpv4 */, 7404 UPDATED_LOCAL_ADDRESS_V6, 7405 REMOTE_ADDRESS_V6, 7406 dnsLookupsForSuccess); 7407 7408 mIkeSessionStateMachine.setNetwork(newNetwork, 7409 IkeSessionParams.ESP_IP_VERSION_AUTO, 7410 IkeSessionParams.ESP_ENCAP_TYPE_AUTO, 7411 IkeSessionParams.NATT_KEEPALIVE_INTERVAL_AUTO); 7412 mLooper.dispatchAll(); 7413 7414 verify(newNetwork, times(expectedDnsLookups)).getAllByName(REMOTE_HOSTNAME); 7415 if (expectSessionClosed) { 7416 assertNull(mIkeSessionStateMachine.getCurrentState()); 7417 verifyFireCallbackOnDnsFailure(mMockIkeSessionCallback, mIkeSessionStateMachine.mIdle); 7418 } else { 7419 assertTrue(mSpyIkeConnectionCtrl.getAllRemoteIpv4Addresses().isEmpty()); 7420 assertEquals( 7421 Arrays.asList(REMOTE_ADDRESS_V6), 7422 mSpyIkeConnectionCtrl.getAllRemoteIpv6Addresses()); 7423 verifyNetworkAndLocalAddressUpdated( 7424 newNetwork, UPDATED_LOCAL_ADDRESS_V6, REMOTE_ADDRESS_V6, callback); 7425 } 7426 } 7427 verifyRetransmitSuspendedAndResumedOnNewNetwork( Class<?> expectedStateOfSuspended, Class<?> expectedStateOfResumed)7428 private void verifyRetransmitSuspendedAndResumedOnNewNetwork( 7429 Class<?> expectedStateOfSuspended, Class<?> expectedStateOfResumed) { 7430 // Make sure the retransmit flag is set to suspended. 7431 assertTrue(mIkeSessionStateMachine.mIsRetransmitSuspended); 7432 7433 // Make sure if there is no future retransmission. 7434 verifyRetransmissionStopped(); 7435 7436 // Make sure the state machine is still alive. 7437 assertTrue(expectedStateOfSuspended.isInstance(mIkeSessionStateMachine.getCurrentState())); 7438 7439 // Elapse all retransmission timeouts. 7440 int[] timeouts = 7441 mIkeSessionStateMachine.mIkeSessionParams.getRetransmissionTimeoutsMillis(); 7442 for (long delay : timeouts) { 7443 mLooper.dispatchAll(); 7444 mLooper.moveTimeForward(delay); 7445 } 7446 mLooper.dispatchAll(); 7447 7448 // Connect to a new underlying network. 7449 // DPD packet should be sent by resuming retransmission. 7450 mIkeSessionStateMachine.onUnderlyingNetworkUpdated(); 7451 mLooper.dispatchAll(); 7452 7453 // Make sure the retransmit flag is set to unsuspended. 7454 assertFalse(mIkeSessionStateMachine.mIsRetransmitSuspended); 7455 7456 // Make sure if there is future retransmission. 7457 verifyRetransmissionStarted(); 7458 7459 // Make sure the state machine is still alive. 7460 assertTrue(expectedStateOfResumed.isInstance(mIkeSessionStateMachine.getCurrentState())); 7461 } 7462 verifyRetransmitContinuesAndSessionTerminatedByTimeout(Class<?> expectedState)7463 private void verifyRetransmitContinuesAndSessionTerminatedByTimeout(Class<?> expectedState) { 7464 // Make sure the retransmit flag is not set to suspended. 7465 assertFalse(mIkeSessionStateMachine.mIsRetransmitSuspended); 7466 7467 // Make sure the state machine is still alive. 7468 assertTrue(expectedState.isInstance(mIkeSessionStateMachine.getCurrentState())); 7469 7470 // Elapse all retransmission timeouts. 7471 int[] timeouts = 7472 mIkeSessionStateMachine.mIkeSessionParams.getRetransmissionTimeoutsMillis(); 7473 for (long delay : timeouts) { 7474 mLooper.dispatchAll(); 7475 mLooper.moveTimeForward(delay); 7476 } 7477 mLooper.dispatchAll(); 7478 7479 assertNull(mIkeSessionStateMachine.getCurrentState()); 7480 if (SdkLevel.isAtLeastT()) { 7481 verify(mMockIkeSessionCallback) 7482 .onClosedWithException( 7483 argThat( 7484 e -> 7485 e instanceof IkeIOException 7486 && e.getCause() 7487 instanceof IkeTimeoutException)); 7488 } else { 7489 verify(mMockIkeSessionCallback) 7490 .onClosedWithException( 7491 argThat( 7492 e -> 7493 e instanceof IkeInternalException 7494 && e.getCause() instanceof IOException)); 7495 } 7496 } 7497 7498 @Test 7499 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSuspendRetransmission_inDpd()7500 public void testSuspendRetransmission_inDpd() throws Exception { 7501 setupIdleStateMachineWithMobike(); 7502 7503 // Start DPD task. 7504 mIkeSessionStateMachine.sendMessage( 7505 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mDpdIkeLocalInfo); 7506 mLooper.dispatchAll(); 7507 7508 // Verify that retransmission has started. 7509 verifyRetransmissionStarted(); 7510 verifyEmptyInformationalSent(1, false /* expectedResp*/); 7511 7512 // Disconnect from the underlying network. 7513 mIkeSessionStateMachine.onUnderlyingNetworkDied(mMockDefaultNetwork); 7514 mLooper.dispatchAll(); 7515 7516 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.VANILLA_ICE_CREAM) { 7517 verifyRetransmitContinuesAndSessionTerminatedByTimeout( 7518 IkeSessionStateMachine.DpdIkeLocalInfo.class); 7519 } else { 7520 verifyRetransmitSuspendedAndResumedOnNewNetwork( 7521 IkeSessionStateMachine.DpdIkeLocalInfo.class, 7522 IkeSessionStateMachine.DpdIkeLocalInfo.class); 7523 } 7524 } 7525 7526 @Test 7527 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSuspendRetransmission_beforeEnteringDpd()7528 public void testSuspendRetransmission_beforeEnteringDpd() throws Exception { 7529 setupIdleStateMachineWithMobike(); 7530 7531 // Disconnect from the underlying network. 7532 mIkeSessionStateMachine.onUnderlyingNetworkDied(mMockDefaultNetwork); 7533 7534 // Start DPD task. 7535 mIkeSessionStateMachine.sendMessage( 7536 CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mDpdIkeLocalInfo); 7537 mLooper.dispatchAll(); 7538 7539 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.VANILLA_ICE_CREAM) { 7540 verifyRetransmitContinuesAndSessionTerminatedByTimeout( 7541 IkeSessionStateMachine.DpdIkeLocalInfo.class); 7542 } else { 7543 verifyRetransmitSuspendedAndResumedOnNewNetwork( 7544 IkeSessionStateMachine.DpdIkeLocalInfo.class, 7545 IkeSessionStateMachine.DpdIkeLocalInfo.class); 7546 verifyEmptyInformationalSent(1, false /* expectedResp*/); 7547 } 7548 } 7549 7550 @Test 7551 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSuspendRetransmission_inIdle()7552 public void testSuspendRetransmission_inIdle() throws Exception { 7553 setupIdleStateMachineWithMobike(); 7554 7555 // Disconnect from the underlying network. 7556 mIkeSessionStateMachine.onUnderlyingNetworkDied(mMockDefaultNetwork); 7557 mLooper.dispatchAll(); 7558 7559 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.VANILLA_ICE_CREAM) { 7560 // Make sure the retransmit flag is not set to suspended. 7561 assertFalse(mIkeSessionStateMachine.mIsRetransmitSuspended); 7562 } else { 7563 verifyRetransmitSuspendedAndResumedOnNewNetwork( 7564 IkeSessionStateMachine.Idle.class, 7565 IkeSessionStateMachine.MobikeLocalInfo.class); 7566 } 7567 } 7568 7569 @Test 7570 @SdkSuppress(minSdkVersion = 31, codeName = "S") testSuspendRetransmission_inRekeyChild()7571 public void testSuspendRetransmission_inRekeyChild() throws Exception { 7572 // Step 1. Init with the mobike and verify sending RekeyChildCreate request 7573 // Send the RekeyChildCreate 7574 mockSendRekeyChildReq(true); 7575 // Verify that message is EXCHANGE_TYPE_CREATE_CHILD_SA. 7576 verify(mMockIkeMessageHelper, times(1)) 7577 .encryptAndEncode( 7578 any(), 7579 any(), 7580 eq(mSpyCurrentIkeSaRecord), 7581 mIkeMessageCaptor.capture(), 7582 anyBoolean(), 7583 anyInt()); 7584 IkeMessage createChildMessage = mIkeMessageCaptor.getValue(); 7585 assertEquals( 7586 IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, createChildMessage.ikeHeader.exchangeType); 7587 7588 // Verify that retransmission has started. 7589 verifyRetransmissionStarted(); 7590 7591 // Step 2. Underlying network died, verify retransmission is suspended 7592 // Disconnect from the underlying network. 7593 mIkeSessionStateMachine.onUnderlyingNetworkDied(mMockDefaultNetwork); 7594 mLooper.dispatchAll(); 7595 7596 if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.VANILLA_ICE_CREAM) { 7597 // Make sure the retransmit flag is not set to suspended. 7598 assertFalse(mIkeSessionStateMachine.mIsRetransmitSuspended); 7599 // Verify that retransmission has started. 7600 verifyRetransmissionStarted(); 7601 // Stop testing 7602 return; 7603 } else { 7604 // Make sure the retransmit flag is set to suspended. 7605 assertTrue(mIkeSessionStateMachine.mIsRetransmitSuspended); 7606 // Make sure if there is no future retransmission. 7607 verifyRetransmissionStopped(); 7608 } 7609 7610 // Step 3. Receive a response with the last packet before the network dies, verify child 7611 // notifies to send the RekeyChildDelete request but should not be sent. 7612 // Mocking receiving response 7613 ReceivedIkePacket dummyCreateChildResp = makeCreateChildCreateMessage(true /*isResp*/); 7614 mIkeSessionStateMachine.sendMessage( 7615 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyCreateChildResp); 7616 mLooper.dispatchAll(); 7617 // Make sure it is received. 7618 verify(mMockChildSessionStateMachine) 7619 .receiveResponse(eq(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA), any()); 7620 // Send the DeleteRekeyChildRequest 7621 List<IkePayload> mockRekeyDeletePayloads = Arrays.asList(mock(IkePayload.class)); 7622 mDummyChildSmCallback.onOutboundPayloadsReady( 7623 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, 7624 false /*isResp*/, 7625 mockRekeyDeletePayloads, 7626 mMockChildSessionStateMachine); 7627 mLooper.dispatchAll(); 7628 // Verify that message is EXCHANGE_TYPE_INFORMATIONAL. 7629 verify(mMockIkeMessageHelper, times(2)) 7630 .encryptAndEncode( 7631 any(), 7632 any(), 7633 eq(mSpyCurrentIkeSaRecord), 7634 mIkeMessageCaptor.capture(), 7635 anyBoolean(), 7636 anyInt()); 7637 IkeMessage deleteChildMessage = mIkeMessageCaptor.getValue(); 7638 assertEquals( 7639 IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, deleteChildMessage.ikeHeader.exchangeType); 7640 7641 // Step 4. Network updated, verify the RekeyChildDelete request is sent 7642 verifyRetransmitSuspendedAndResumedOnNewNetwork( 7643 IkeSessionStateMachine.ChildProcedureOngoing.class, 7644 IkeSessionStateMachine.ChildProcedureOngoing.class); 7645 } 7646 7647 @Test 7648 @SdkSuppress(minSdkVersion = 31, codeName = "S") testDnsLookupOnSetNetwork()7649 public void testDnsLookupOnSetNetwork() throws Exception { 7650 setupAndVerifyDnsLookupsOnSetNetwork( 7651 1 /* dnsLookupsForSuccess */, 7652 1 /* expectedDnsLookups */, 7653 false /* expectSessionClosed */); 7654 } 7655 7656 @Test 7657 @SdkSuppress(minSdkVersion = 31, codeName = "S") testDnsLookupOnSetNetworkWithDnsRetries()7658 public void testDnsLookupOnSetNetworkWithDnsRetries() throws Exception { 7659 setupAndVerifyDnsLookupsOnSetNetwork( 7660 2 /* dnsLookupsForSuccess */, 7661 2 /* expectedDnsLookups */, 7662 false /* expectSessionClosed */); 7663 } 7664 7665 @Test 7666 @SdkSuppress(minSdkVersion = 31, codeName = "S") testDnsLookupOnSetNetworkWithDnsFailure()7667 public void testDnsLookupOnSetNetworkWithDnsFailure() throws Exception { 7668 // Require more lookups for successful DNS than IKE allows to force failure 7669 setupAndVerifyDnsLookupsOnSetNetwork( 7670 4 /* dnsLookupsForSuccess */, 7671 3 /* expectedDnsLookups */, 7672 true /* expectSessionClosed */); 7673 } 7674 7675 @Test testNattKeepaliveStarts()7676 public void testNattKeepaliveStarts() throws Exception { 7677 IkeSessionParams sessionParams = 7678 buildIkeSessionParamsCommon() 7679 .setAuthPsk(mPsk) 7680 .build(); 7681 7682 // Restart IkeSessionStateMachine with NATT Keepalive delay configured 7683 setupFirstIkeSa(); 7684 mIkeSessionStateMachine.quitNow(); 7685 7686 mIkeSessionStateMachine = makeAndStartIkeSession(sessionParams); 7687 mIkeSessionStateMachine.openSession(); 7688 mLooper.dispatchAll(); 7689 7690 mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeIkeInitResponse()); 7691 mLooper.dispatchAll(); 7692 7693 verify(mMockIkeNattKeepalive).start(); 7694 } 7695 7696 @Test testHandleRetransmissionTimeout()7697 public void testHandleRetransmissionTimeout() throws Exception { 7698 mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE); 7699 7700 for (long delay : 7701 mIkeSessionStateMachine.mIkeSessionParams.getRetransmissionTimeoutsMillis()) { 7702 mLooper.dispatchAll(); 7703 mLooper.moveTimeForward(delay); 7704 } 7705 7706 mLooper.dispatchAll(); 7707 assertNull(mIkeSessionStateMachine.getCurrentState()); 7708 7709 if (SdkLevel.isAtLeastT()) { 7710 verify(mMockIkeSessionCallback).onClosedWithException( 7711 argThat(e -> e instanceof IkeIOException 7712 && e.getCause() instanceof IkeTimeoutException)); 7713 } else { 7714 verify(mMockIkeSessionCallback).onClosedWithException( 7715 argThat(e -> e instanceof IkeInternalException 7716 && e.getCause() instanceof IOException)); 7717 } 7718 } 7719 verifyLivenessStatusCallback( @keSessionCallback.LivenessStatus int expectedStatus)7720 private void verifyLivenessStatusCallback( 7721 @IkeSessionCallback.LivenessStatus int expectedStatus) { 7722 verify(mMockIkeSessionCallback).onLivenessStatusChanged(eq(expectedStatus)); 7723 } 7724 executeAndVerifyRequestLivenessCheck()7725 private void executeAndVerifyRequestLivenessCheck() throws Exception { 7726 setupIdleStateMachine(); 7727 7728 mIkeSessionStateMachine.requestLivenessCheck(); 7729 mLooper.dispatchAll(); 7730 7731 verifyEmptyInformationalSent(1, false /* expectedResp*/); 7732 verifyLivenessStatusCallback(IkeSessionCallback.LIVENESS_STATUS_ON_DEMAND_STARTED); 7733 resetMockIkeMessageHelper(); 7734 } 7735 7736 @Test testDpdOnDemandIkeLocalInfoRcvDpdReq()7737 public void testDpdOnDemandIkeLocalInfoRcvDpdReq() throws Exception { 7738 executeAndVerifyRequestLivenessCheck(); 7739 mIkeSessionStateMachine.sendMessage( 7740 CMD_RECEIVE_IKE_PACKET, makeDpdIkeRequest(mSpyCurrentIkeSaRecord)); 7741 mLooper.dispatchAll(); 7742 7743 verifyEmptyInformationalSent(1, true /* expectedResp*/); 7744 verifyLivenessStatusCallback(IkeSessionCallback.LIVENESS_STATUS_SUCCESS); 7745 assertTrue( 7746 mIkeSessionStateMachine.getCurrentState() 7747 instanceof IkeSessionStateMachine.DpdOnDemandIkeLocalInfo); 7748 } 7749 7750 @Test testDpdOnDemandIkeLocalInfoLivenessRetransmissionTimeout()7751 public void testDpdOnDemandIkeLocalInfoLivenessRetransmissionTimeout() throws Exception { 7752 executeAndVerifyRequestLivenessCheck(); 7753 7754 int[] timeouts = 7755 mIkeSessionStateMachine.mIkeSessionParams.getLivenessRetransmissionTimeoutsMillis(); 7756 for (long delay : timeouts) { 7757 mLooper.dispatchAll(); 7758 mLooper.moveTimeForward(delay); 7759 } 7760 mLooper.dispatchAll(); 7761 7762 verifyLivenessStatusCallback(IkeSessionCallback.LIVENESS_STATUS_FAILURE); 7763 if (SdkLevel.isAtLeastT()) { 7764 verify(mMockIkeSessionCallback) 7765 .onClosedWithException( 7766 argThat( 7767 e -> 7768 e instanceof IkeIOException 7769 && e.getCause() 7770 instanceof IkeTimeoutException)); 7771 } else { 7772 verify(mMockIkeSessionCallback) 7773 .onClosedWithException( 7774 argThat( 7775 e -> 7776 e instanceof IkeInternalException 7777 && e.getCause() instanceof IOException)); 7778 } 7779 } 7780 7781 @Test testLivenessCheckWithIncomingPacketsInBusyState()7782 public void testLivenessCheckWithIncomingPacketsInBusyState() throws Exception { 7783 setupIdleStateMachine(); 7784 7785 // Send Rekey-Create request 7786 mIkeSessionStateMachine.sendMessage( 7787 IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, 7788 mLocalRequestFactory.getIkeLocalRequest( 7789 IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE)); 7790 mLooper.dispatchAll(); 7791 verifyRetransmissionStarted(); 7792 7793 // Request to check liveness during local rekey status 7794 mIkeSessionStateMachine.requestLivenessCheck(); 7795 mLooper.dispatchAll(); 7796 7797 verifyLivenessStatusCallback(IkeSessionCallback.LIVENESS_STATUS_BACKGROUND_STARTED); 7798 7799 // Prepare "rekeyed" SA 7800 setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord); 7801 7802 // Receive Rekey response 7803 ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse(); 7804 mIkeSessionStateMachine.sendMessage( 7805 IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket); 7806 mLooper.dispatchAll(); 7807 7808 verifyLivenessStatusCallback(IkeSessionCallback.LIVENESS_STATUS_SUCCESS); 7809 } 7810 } 7811