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 android.net.ipsec.ike; 18 19 import static android.system.OsConstants.AF_INET; 20 import static android.system.OsConstants.AF_INET6; 21 22 import static com.android.internal.net.ipsec.ike.utils.IkeCertUtils.certificateFromByteArray; 23 import static com.android.internal.net.ipsec.ike.utils.IkeCertUtils.privateKeyFromByteArray; 24 25 import android.annotation.FlaggedApi; 26 import android.annotation.IntDef; 27 import android.annotation.IntRange; 28 import android.annotation.NonNull; 29 import android.annotation.Nullable; 30 import android.annotation.SuppressLint; 31 import android.annotation.SystemApi; 32 import android.content.Context; 33 import android.net.ConnectivityManager; 34 import android.net.Network; 35 import android.net.eap.EapSessionConfig; 36 import android.net.ipsec.ike.ike3gpp.Ike3gppExtension; 37 import android.os.PersistableBundle; 38 import android.util.SparseArray; 39 40 import com.android.internal.annotations.VisibleForTesting; 41 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute; 42 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Pcscf; 43 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Pcscf; 44 import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.IkeConfigAttribute; 45 import com.android.internal.net.ipsec.ike.message.IkePayload; 46 import com.android.modules.utils.build.SdkLevel; 47 import com.android.server.vcn.util.PersistableBundleUtils; 48 49 import java.io.PrintWriter; 50 import java.lang.annotation.Retention; 51 import java.lang.annotation.RetentionPolicy; 52 import java.net.Inet4Address; 53 import java.net.Inet6Address; 54 import java.net.InetAddress; 55 import java.security.PrivateKey; 56 import java.security.cert.CertificateEncodingException; 57 import java.security.cert.TrustAnchor; 58 import java.security.cert.X509Certificate; 59 import java.security.interfaces.RSAKey; 60 import java.util.ArrayList; 61 import java.util.Arrays; 62 import java.util.Collections; 63 import java.util.HashSet; 64 import java.util.LinkedList; 65 import java.util.List; 66 import java.util.Objects; 67 import java.util.Set; 68 import java.util.concurrent.TimeUnit; 69 70 /** 71 * IkeSessionParams contains all user provided configurations for negotiating an {@link IkeSession}. 72 * 73 * <p>Note that all negotiated configurations will be reused during rekey including SA Proposal and 74 * lifetime. 75 */ 76 public final class IkeSessionParams { 77 /** @hide */ 78 @Retention(RetentionPolicy.SOURCE) 79 @IntDef({IKE_AUTH_METHOD_PSK, IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, IKE_AUTH_METHOD_EAP}) 80 public @interface IkeAuthMethod {} 81 82 // Constants to describe user configured authentication methods. 83 /** @hide */ 84 public static final int IKE_AUTH_METHOD_PSK = 1; 85 /** @hide */ 86 public static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2; 87 /** @hide */ 88 public static final int IKE_AUTH_METHOD_EAP = 3; 89 90 /** @hide */ 91 @Retention(RetentionPolicy.SOURCE) 92 @IntDef({AUTH_DIRECTION_LOCAL, AUTH_DIRECTION_REMOTE, AUTH_DIRECTION_BOTH}) 93 public @interface AuthDirection {} 94 95 // Constants to describe which side (local and/or remote) the authentication configuration will 96 // be used. 97 /** @hide */ 98 public static final int AUTH_DIRECTION_LOCAL = 1; 99 /** @hide */ 100 public static final int AUTH_DIRECTION_REMOTE = 2; 101 /** @hide */ 102 public static final int AUTH_DIRECTION_BOTH = 3; 103 104 /** @hide */ 105 @Retention(RetentionPolicy.SOURCE) 106 @IntDef({ 107 IKE_OPTION_ACCEPT_ANY_REMOTE_ID, 108 IKE_OPTION_EAP_ONLY_AUTH, 109 IKE_OPTION_MOBIKE, 110 IKE_OPTION_FORCE_PORT_4500, 111 IKE_OPTION_INITIAL_CONTACT, 112 IKE_OPTION_REKEY_MOBILITY, 113 IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION, 114 IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES, 115 IKE_OPTION_AUTOMATIC_KEEPALIVE_ON_OFF, 116 IKE_OPTION_FORCE_DNS_RESOLUTION 117 }) 118 public @interface IkeOption {} 119 120 /** 121 * If set, the IKE library will accept any remote (server) identity, even if it does not match 122 * the configured remote identity 123 * 124 * <p>See {@link Builder#setRemoteIdentification(IkeIdentification)} 125 */ 126 public static final int IKE_OPTION_ACCEPT_ANY_REMOTE_ID = 0; 127 /** 128 * If set, and EAP has been configured as the authentication method, the IKE library will 129 * request that the remote (also) use an EAP-only authentication flow. 130 * 131 * <p>@see {@link Builder#setAuthEap(X509Certificate, EapSessionConfig)} 132 */ 133 public static final int IKE_OPTION_EAP_ONLY_AUTH = 1; 134 135 /** 136 * If set, the IKE Session will attempt to handle IP address changes using RFC4555 MOBIKE. 137 * 138 * <p>Upon IP address changes (including Network changes), the IKE session will initiate an RFC 139 * 4555 MOBIKE procedure, migrating both this IKE Session and associated IPsec Transforms to the 140 * new local and remote address pair. 141 * 142 * <p>The IKE library will first attempt to enable MOBIKE to handle the changes of underlying 143 * network and addresses. For callers targeting SDK {@link android.os.Build.VERSION_CODES#S_V2} 144 * and earlier, this option will implicitly enable the support for rekey-based mobility, and 145 * thus if the server does not support MOBIKE, the IKE Session will try migration by rekeying 146 * all associated IPsec SAs. This rekey-based mobility feature is not best-practice and has 147 * technical issues; accordingly, it will no longer be enabled for callers targeting SDK {@link 148 * android.os.Build.VERSION_CODES#TIRAMISU} and above. 149 * 150 * <p>Checking whether or not MOBIKE is supported by both the IKE library and the server in an 151 * IKE Session is done via {@link IkeSessionConfiguration#isIkeExtensionEnabled(int)}. 152 * 153 * <p>It is recommended that IKE_OPTION_MOBIKE be enabled unless precluded for compatibility 154 * reasons. 155 * 156 * <p>If this option is set for an IKE Session, Transport-mode SAs will not be allowed in that 157 * Session. 158 * 159 * <p>Callers that need to perform migration of IPsec transforms and tunnels MUST implement 160 * migration specific methods in {@link IkeSessionCallback} and {@link ChildSessionCallback}. 161 */ 162 public static final int IKE_OPTION_MOBIKE = 2; 163 164 /** 165 * Configures the IKE session to always send to port 4500. 166 * 167 * <p>If set, the IKE Session will be initiated and maintained exclusively using 168 * destination port 4500, regardless of the presence of NAT. Otherwise, the IKE Session will 169 * be initiated on destination port 500; then, if either a NAT is detected or both MOBIKE 170 * and NAT-T are supported by the peer, it will proceed on port 4500. 171 */ 172 public static final int IKE_OPTION_FORCE_PORT_4500 = 3; 173 174 /** 175 * If set, the IKE library will send INITIAL_CONTACT notification to the peers. 176 * 177 * <p>If this option is set, the INITIAL_CONTACT notification payload is sent in IKE_AUTH. The 178 * client can use this option to assert to the peer that this IKE SA is the only IKE SA 179 * currently active between the authenticated identities. 180 * 181 * <p>@see "https://tools.ietf.org/html/rfc7296#section-2.4" RFC 7296, Internet Key Exchange 182 * Protocol Version 2 (IKEv2) 183 * 184 * <p>@see {@link Builder#addIkeOption(int)} 185 */ 186 public static final int IKE_OPTION_INITIAL_CONTACT = 4; 187 188 /** 189 * If set, the IKE Session will attempt to handle IP address changes by rekeying with new 190 * addresses. 191 * 192 * <p>Upon IP address changes (including Network changes), the IKE session will initiate a 193 * standard rekey Child procedure using the new local address to replace the existing associated 194 * IPsec transforms with new transforms tied to the new addresses. At the same time the IKE 195 * library will notify the remote of the address change and implicitly migrate itself to the new 196 * address. 197 * 198 * <p>This capability is NOT negotiated; it is the responsibility of the caller to ensure that 199 * the remote supports rekey-based mobility. Failure to do so may lead to increased disruption 200 * during mobility events. 201 * 202 * <p>This option may be set together with {@link #IKE_OPTION_MOBIKE} as a fallback. If both 203 * {@link #IKE_OPTION_MOBIKE} and {@link #IKE_OPTION_REKEY_MOBILITY} are set: 204 * 205 * <ul> 206 * <li>If the server has indicated MOBIKE support, MOBIKE will be used for mobility 207 * <li>Otherwise, Rekey will be used for mobility 208 * </ul> 209 * 210 * <p>For callers targeting SDK {@link android.os.Build.VERSION_CODES#S_V2} or earlier, setting 211 * {@link #IKE_OPTION_MOBIKE} will implicitly set {@link #IKE_OPTION_REKEY_MOBILITY}. 212 * 213 * <p>If this option is set for an IKE Session, Transport-mode SAs will not be allowed in that 214 * Session. 215 * 216 * <p>Callers that need to perform migration of IPsec transforms and tunnels MUST implement 217 * migration specific methods in {@link IkeSessionCallback} and {@link ChildSessionCallback}. 218 * 219 * @see {@link IKE_OPTION_MOBIKE} 220 * @see {@link IkeSession#setNetwork(Network)} 221 * @hide 222 */ 223 @SystemApi public static final int IKE_OPTION_REKEY_MOBILITY = 5; 224 225 /** 226 * If set, IKE Session will automatically select address families. 227 * 228 * <p>IP address families often have different performance characteristics on any given network. 229 * For example, IPv6 ESP may not be hardware-accelerated by middleboxes, or completely 230 * black-holed. This option allows the IKE session to automatically select based on the IP 231 * address family it perceives as the most likely to work well. 232 * 233 * @hide 234 */ 235 public static final int IKE_OPTION_AUTOMATIC_ADDRESS_FAMILY_SELECTION = 6; 236 237 /** 238 * If set, the IKE session will select the NATT keepalive timers automatically. 239 * 240 * <p>NATT keepalive timers will be selected and adjusted based on the underlying network 241 * configurations, and updated as underlying network configurations change. 242 * 243 * @hide 244 */ 245 public static final int IKE_OPTION_AUTOMATIC_NATT_KEEPALIVES = 7; 246 247 /** 248 * If set, the IKE session will start the NATT keepalive with a power optimization flag. 249 * 250 * <p>IKE session will start the keepalive with {@link SocketKeepalive#FLAG_AUTOMATIC_ON_OFF}. 251 * The system will automatically disable keepalives when no TCP connections are open on the 252 * network that is associated with the IKE session. 253 * 254 * <p>For callers relying on long-lived UDP port mappings through the IPsec layer, this flag 255 * should never be used since the keepalive may be stopped unexpectedly. 256 * 257 * <p>This option applies to only hardware keepalive. When keepalive switches to software 258 * keepalive because of errors on hardware keepalive, this option may be ignored. 259 * 260 * @hide 261 */ 262 // TODO(b/269200616): Move software keepalive mechanism to other place with the required 263 // permission to get TCP socket status via netlink commands to also get benefit from this 264 // option. 265 @SystemApi 266 public static final int IKE_OPTION_AUTOMATIC_KEEPALIVE_ON_OFF = 8; 267 268 /** 269 * Force DNS lookups when performing mobility update 270 * 271 * <p>Note: Forcing DNS lookups may introduce delays or even failures in network migration. 272 * 273 * @see IkeSession#setNetwork(Network) 274 * @hide 275 */ 276 // TODO: b/340950997 Expose this option 277 public static final int IKE_OPTION_FORCE_DNS_RESOLUTION = 9; 278 279 private static final int MIN_IKE_OPTION = IKE_OPTION_ACCEPT_ANY_REMOTE_ID; 280 private static final int MAX_IKE_OPTION = IKE_OPTION_FORCE_DNS_RESOLUTION; 281 282 /** 283 * Automatically choose the IP version for ESP packets. 284 * @hide 285 */ 286 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 287 public static final int ESP_IP_VERSION_AUTO = 0; 288 289 /** 290 * Use IPv4 for ESP packets. 291 * @hide 292 */ 293 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 294 public static final int ESP_IP_VERSION_IPV4 = 4; 295 296 /** 297 * Use IPv6 for ESP packets. 298 * @hide 299 */ 300 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 301 public static final int ESP_IP_VERSION_IPV6 = 6; 302 303 // IP version to store in mEspIpVersion. 304 /** @hide */ 305 @Retention(RetentionPolicy.SOURCE) 306 @IntDef({ 307 ESP_IP_VERSION_AUTO, 308 ESP_IP_VERSION_IPV4, 309 ESP_IP_VERSION_IPV6, 310 }) 311 public @interface EspIpVersion {} 312 313 /** 314 * Automatically choose the encapsulation type for ESP packets. 315 * @hide 316 */ 317 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 318 public static final int ESP_ENCAP_TYPE_AUTO = 0; 319 320 /** 321 * Do not encapsulate ESP packets in transport layer protocol. 322 * 323 * Under this encapsulation type, the IKE Session will send NAT detection only when it is 324 * performing mobility update from an environment with a NAT, as an attempt to stop using 325 * UDP encapsulation for the ESP packets. If IKE Session still detects a NAT in this case, 326 * the IKE Session will be terminated. 327 * 328 * @hide 329 */ 330 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 331 public static final int ESP_ENCAP_TYPE_NONE = -1; 332 333 /** 334 * Encapsulate ESP packets in UDP. 335 * 336 * Under this encapsulation type, the IKE Session will send NAT detection and fake a local 337 * NAT. In this case the IKE Session will always encapsulate ESP packets in UDP as long as 338 * the server also supports NAT traversal. 339 * 340 * @hide 341 */ 342 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 343 public static final int ESP_ENCAP_TYPE_UDP = 17; 344 345 // Encap type to store in mEspEncapType. 346 /** @hide */ 347 @Retention(RetentionPolicy.SOURCE) 348 @IntDef({ 349 ESP_ENCAP_TYPE_AUTO, 350 ESP_ENCAP_TYPE_NONE, 351 ESP_ENCAP_TYPE_UDP, 352 }) 353 public @interface EspEncapType {} 354 355 /** 356 * Automatically choose the keepalive interval. 357 * 358 * This constant can be passed to 359 * {@link com.android.internal.net.ipsec.ike.IkeSessionStateMachine#setNetwork} to signify 360 * that the keepalive delay should be deduced automatically from the underlying network. 361 * 362 * @see #getNattKeepAliveDelaySeconds 363 * @hide 364 */ 365 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 366 public static final int NATT_KEEPALIVE_INTERVAL_AUTO = -1; 367 368 /** 369 * Setting timer to this value will disable the Dead Peer Detection(DPD). 370 * 371 * <p>@see {@link Builder#setDpdDelaySeconds} 372 */ 373 @FlaggedApi("com.android.ipsec.flags.dpd_disable_api") 374 public static final int IKE_DPD_DELAY_SEC_DISABLED = Integer.MAX_VALUE; 375 376 /** @hide */ 377 public static final SparseArray<String> IP_VERSION_TO_STR; 378 379 static { 380 IP_VERSION_TO_STR = new SparseArray<>(); IP_VERSION_TO_STR.put(ESP_IP_VERSION_AUTO, "AUTO")381 IP_VERSION_TO_STR.put(ESP_IP_VERSION_AUTO, "AUTO"); IP_VERSION_TO_STR.put(ESP_IP_VERSION_IPV4, "IPV4")382 IP_VERSION_TO_STR.put(ESP_IP_VERSION_IPV4, "IPV4"); IP_VERSION_TO_STR.put(ESP_IP_VERSION_IPV6, "IPV6")383 IP_VERSION_TO_STR.put(ESP_IP_VERSION_IPV6, "IPV6"); 384 } 385 386 /** @hide */ 387 public static final SparseArray<String> ENCAP_TYPE_TO_STR; 388 389 static { 390 ENCAP_TYPE_TO_STR = new SparseArray<>(); ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_NONE, "NONE")391 ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_NONE, "NONE"); ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_AUTO, "AUTO")392 ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_AUTO, "AUTO"); ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_UDP, "UDP")393 ENCAP_TYPE_TO_STR.put(ESP_ENCAP_TYPE_UDP, "UDP"); 394 } 395 396 /** @hide */ 397 @VisibleForTesting static final int IKE_HARD_LIFETIME_SEC_MINIMUM = 300; // 5 minutes 398 /** @hide */ 399 @VisibleForTesting static final int IKE_HARD_LIFETIME_SEC_MAXIMUM = 86400; // 24 hours 400 /** @hide */ 401 @VisibleForTesting static final int IKE_HARD_LIFETIME_SEC_DEFAULT = 14400; // 4 hours 402 403 /** @hide */ 404 @VisibleForTesting static final int IKE_SOFT_LIFETIME_SEC_MINIMUM = 120; // 2 minutes 405 /** @hide */ 406 @VisibleForTesting static final int IKE_SOFT_LIFETIME_SEC_DEFAULT = 7200; // 2 hours 407 408 /** @hide */ 409 @VisibleForTesting 410 static final int IKE_LIFETIME_MARGIN_SEC_MINIMUM = (int) TimeUnit.MINUTES.toSeconds(1L); 411 412 /** @hide */ 413 @VisibleForTesting static final int IKE_DPD_DELAY_SEC_MIN = 20; 414 /** @hide */ 415 @VisibleForTesting static final int IKE_DPD_DELAY_SEC_MAX = 1800; // 30 minutes 416 /** @hide */ 417 @VisibleForTesting static final int IKE_DPD_DELAY_SEC_DEFAULT = 120; // 2 minutes 418 419 /** @hide */ 420 @VisibleForTesting public static final int IKE_NATT_KEEPALIVE_DELAY_SEC_MIN = 10; 421 /** @hide */ 422 @VisibleForTesting public static final int IKE_NATT_KEEPALIVE_DELAY_SEC_MAX = 3600; 423 /** @hide */ 424 @VisibleForTesting static final int IKE_NATT_KEEPALIVE_DELAY_SEC_DEFAULT = 10; 425 426 /** @hide */ 427 @VisibleForTesting static final int DSCP_MIN = 0; 428 /** @hide */ 429 @VisibleForTesting static final int DSCP_MAX = 63; 430 /** @hide */ 431 @VisibleForTesting static final int DSCP_DEFAULT = 0; 432 433 /** @hide */ 434 @VisibleForTesting static final int IKE_RETRANS_TIMEOUT_MS_MIN = 500; 435 /** @hide */ 436 @VisibleForTesting 437 static final int IKE_RETRANS_TIMEOUT_MS_MAX = (int) TimeUnit.MINUTES.toMillis(30L); 438 /** @hide */ 439 @VisibleForTesting static final int IKE_RETRANS_MAX_ATTEMPTS_MAX = 10; 440 /** @hide */ 441 @VisibleForTesting 442 static final int[] IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT = 443 new int[] {500, 1000, 2000, 4000, 8000}; 444 445 /** @hide */ 446 @VisibleForTesting static final int LIVENESS_RETRANS_TIMEOUT_MS_MIN = 500; 447 /** @hide */ 448 @VisibleForTesting static final int LIVENESS_RETRANS_TIMEOUT_MS_MAX = 30000; 449 /** @hide */ 450 @VisibleForTesting static final int LIVENESS_RETRANS_TIMEOUT_MS_TOTAL = 30000; 451 /** @hide */ 452 @VisibleForTesting static final int LIVENESS_RETRANS_MAX_ATTEMPTS_MAX = 10; 453 /** @hide */ 454 @VisibleForTesting 455 static final int[] LIVENESS_RETRANS_TIMEOUT_MS_LIST_DEFAULT = 456 new int[] {500, 1000, 2000, 4000, 8000}; 457 458 private static final String SERVER_HOST_NAME_KEY = "mServerHostname"; 459 private static final String SA_PROPOSALS_KEY = "mSaProposals"; 460 private static final String LOCAL_ID_KEY = "mLocalIdentification"; 461 private static final String REMOTE_ID_KEY = "mRemoteIdentification"; 462 private static final String LOCAL_AUTH_KEY = "mLocalAuthConfig"; 463 private static final String REMOTE_AUTH_KEY = "mRemoteAuthConfig"; 464 private static final String CONFIG_ATTRIBUTES_KEY = "mConfigRequests"; 465 private static final String RETRANS_TIMEOUTS_KEY = "mRetransTimeoutMsList"; 466 private static final String LIVENESS_RETRANS_TIMEOUTS_KEY = "mLivenessRetransTimeoutMsList"; 467 private static final String IKE_OPTIONS_KEY = "mIkeOptions"; 468 private static final String HARD_LIFETIME_SEC_KEY = "mHardLifetimeSec"; 469 private static final String SOFT_LIFETIME_SEC_KEY = "mSoftLifetimeSec"; 470 private static final String DPD_DELAY_SEC_KEY = "mDpdDelaySec"; 471 private static final String NATT_KEEPALIVE_DELAY_SEC_KEY = "mNattKeepaliveDelaySec"; 472 private static final String DSCP_KEY = "mDscp"; 473 private static final String IS_IKE_FRAGMENT_SUPPORTED_KEY = "mIsIkeFragmentationSupported"; 474 private static final String IP_VERSION_KEY = "mIpVersion"; 475 private static final String ENCAP_TYPE_KEY = "mEncapType"; 476 477 @NonNull private final String mServerHostname; 478 479 // @see #getNetwork for reasons of changing the annotation from @NonNull to @Nullable in SDK S. 480 // Do not include mDefaultOrConfiguredNetwork in #hashCode or #equal because when it represents 481 // configured network, it always has the same value as mCallerConfiguredNetwork. When it 482 // represents a default network it can only reflects the device status at the IkeSessionParams 483 // creation time. Since the actually default network may change after IkeSessionParams is 484 // constructed, depending on mDefaultOrConfiguredNetwork in #hashCode and #equal to decide 485 // if this object equals to another object does not make sense. 486 @Nullable private final Network mDefaultOrConfiguredNetwork; 487 488 @Nullable private final Network mCallerConfiguredNetwork; 489 490 @NonNull private final IkeSaProposal[] mSaProposals; 491 492 @NonNull private final IkeIdentification mLocalIdentification; 493 @NonNull private final IkeIdentification mRemoteIdentification; 494 495 @NonNull private final IkeAuthConfig mLocalAuthConfig; 496 @NonNull private final IkeAuthConfig mRemoteAuthConfig; 497 498 @NonNull private final IkeConfigAttribute[] mConfigRequests; 499 500 @NonNull private final int[] mRetransTimeoutMsList; 501 @NonNull private final int[] mLivenessRetransTimeoutMsList; 502 503 @Nullable private final Ike3gppExtension mIke3gppExtension; 504 505 private final long mIkeOptions; 506 507 private final int mHardLifetimeSec; 508 private final int mSoftLifetimeSec; 509 510 private final int mDpdDelaySec; 511 private final int mNattKeepaliveDelaySec; 512 private final int mDscp; 513 @EspIpVersion private final int mIpVersion; 514 @EspEncapType private final int mEncapType; 515 516 private final boolean mIsIkeFragmentationSupported; 517 IkeSessionParams( @onNull String serverHostname, @NonNull Network defaultOrConfiguredNetwork, @NonNull Network callerConfiguredNetwork, @NonNull IkeSaProposal[] proposals, @NonNull IkeIdentification localIdentification, @NonNull IkeIdentification remoteIdentification, @NonNull IkeAuthConfig localAuthConfig, @NonNull IkeAuthConfig remoteAuthConfig, @NonNull IkeConfigAttribute[] configRequests, @NonNull int[] retransTimeoutMsList, @NonNull int[] livenessRetransTimeoutMsList, @Nullable Ike3gppExtension ike3gppExtension, long ikeOptions, int hardLifetimeSec, int softLifetimeSec, int dpdDelaySec, int nattKeepaliveDelaySec, int dscp, @EspIpVersion int espIpVersion, @EspEncapType int espEncapType, boolean isIkeFragmentationSupported)518 private IkeSessionParams( 519 @NonNull String serverHostname, 520 @NonNull Network defaultOrConfiguredNetwork, 521 @NonNull Network callerConfiguredNetwork, 522 @NonNull IkeSaProposal[] proposals, 523 @NonNull IkeIdentification localIdentification, 524 @NonNull IkeIdentification remoteIdentification, 525 @NonNull IkeAuthConfig localAuthConfig, 526 @NonNull IkeAuthConfig remoteAuthConfig, 527 @NonNull IkeConfigAttribute[] configRequests, 528 @NonNull int[] retransTimeoutMsList, 529 @NonNull int[] livenessRetransTimeoutMsList, 530 @Nullable Ike3gppExtension ike3gppExtension, 531 long ikeOptions, 532 int hardLifetimeSec, 533 int softLifetimeSec, 534 int dpdDelaySec, 535 int nattKeepaliveDelaySec, 536 int dscp, 537 @EspIpVersion int espIpVersion, 538 @EspEncapType int espEncapType, 539 boolean isIkeFragmentationSupported) { 540 mServerHostname = serverHostname; 541 mDefaultOrConfiguredNetwork = defaultOrConfiguredNetwork; 542 mCallerConfiguredNetwork = callerConfiguredNetwork; 543 544 mSaProposals = proposals; 545 546 mLocalIdentification = localIdentification; 547 mRemoteIdentification = remoteIdentification; 548 549 mLocalAuthConfig = localAuthConfig; 550 mRemoteAuthConfig = remoteAuthConfig; 551 552 mConfigRequests = configRequests; 553 554 mRetransTimeoutMsList = retransTimeoutMsList; 555 mLivenessRetransTimeoutMsList = livenessRetransTimeoutMsList; 556 557 mIke3gppExtension = ike3gppExtension; 558 559 mIkeOptions = ikeOptions; 560 561 mHardLifetimeSec = hardLifetimeSec; 562 mSoftLifetimeSec = softLifetimeSec; 563 564 mDpdDelaySec = dpdDelaySec; 565 mNattKeepaliveDelaySec = nattKeepaliveDelaySec; 566 mDscp = dscp; 567 568 mIpVersion = espIpVersion; 569 mEncapType = espEncapType; 570 571 mIsIkeFragmentationSupported = isIkeFragmentationSupported; 572 } 573 validateIkeOptionOrThrow(@keOption int ikeOption)574 private static void validateIkeOptionOrThrow(@IkeOption int ikeOption) { 575 if (ikeOption < MIN_IKE_OPTION || ikeOption > MAX_IKE_OPTION) { 576 throw new IllegalArgumentException("Invalid IKE Option: " + ikeOption); 577 } 578 } 579 getOptionBitValue(int ikeOption)580 private static long getOptionBitValue(int ikeOption) { 581 return 1 << ikeOption; 582 } 583 584 /** 585 * Constructs this object by deserializing a PersistableBundle 586 * 587 * <p>Constructed IkeSessionParams is guaranteed to be valid, as checked by the 588 * IkeSessionParams.Builder 589 * 590 * @hide 591 */ 592 @NonNull fromPersistableBundle(@onNull PersistableBundle in)593 public static IkeSessionParams fromPersistableBundle(@NonNull PersistableBundle in) { 594 Objects.requireNonNull(in, "PersistableBundle is null"); 595 596 IkeSessionParams.Builder builder = new IkeSessionParams.Builder(); 597 598 builder.setServerHostname(in.getString(SERVER_HOST_NAME_KEY)); 599 600 PersistableBundle proposalBundle = in.getPersistableBundle(SA_PROPOSALS_KEY); 601 Objects.requireNonNull(in, "SA Proposals is null"); 602 List<IkeSaProposal> saProposals = 603 PersistableBundleUtils.toList(proposalBundle, IkeSaProposal::fromPersistableBundle); 604 for (IkeSaProposal proposal : saProposals) { 605 builder.addSaProposal(proposal); 606 } 607 608 builder.setLocalIdentification( 609 IkeIdentification.fromPersistableBundle(in.getPersistableBundle(LOCAL_ID_KEY))); 610 builder.setRemoteIdentification( 611 IkeIdentification.fromPersistableBundle(in.getPersistableBundle(REMOTE_ID_KEY))); 612 builder.setAuth( 613 IkeAuthConfig.fromPersistableBundle(in.getPersistableBundle(LOCAL_AUTH_KEY)), 614 IkeAuthConfig.fromPersistableBundle(in.getPersistableBundle(REMOTE_AUTH_KEY))); 615 616 PersistableBundle configBundle = in.getPersistableBundle(CONFIG_ATTRIBUTES_KEY); 617 Objects.requireNonNull(configBundle, "configBundle is null"); 618 List<ConfigAttribute> configList = 619 PersistableBundleUtils.toList(configBundle, ConfigAttribute::fromPersistableBundle); 620 for (ConfigAttribute configAttribute : configList) { 621 builder.addConfigRequest((IkeConfigAttribute) configAttribute); 622 } 623 624 builder.setRetransmissionTimeoutsMillis(in.getIntArray(RETRANS_TIMEOUTS_KEY)); 625 builder.setLivenessRetransmissionTimeoutsMillis( 626 in.getIntArray(LIVENESS_RETRANS_TIMEOUTS_KEY)); 627 628 long ikeOptions = in.getLong(IKE_OPTIONS_KEY); 629 for (int option = MIN_IKE_OPTION; option <= MAX_IKE_OPTION; option++) { 630 if (hasIkeOption(ikeOptions, option)) { 631 builder.addIkeOptionInternal(option); 632 } else { 633 builder.removeIkeOption(option); 634 } 635 } 636 637 builder.setLifetimeSeconds( 638 in.getInt(HARD_LIFETIME_SEC_KEY), in.getInt(SOFT_LIFETIME_SEC_KEY)); 639 builder.setDpdDelaySeconds(in.getInt(DPD_DELAY_SEC_KEY)); 640 builder.setNattKeepAliveDelaySeconds(in.getInt(NATT_KEEPALIVE_DELAY_SEC_KEY)); 641 642 builder.setIpVersion(in.getInt(IP_VERSION_KEY)); 643 builder.setEncapType(in.getInt(ENCAP_TYPE_KEY)); 644 645 // Fragmentation policy is not configurable. IkeSessionParams will always be constructed to 646 // support fragmentation. 647 if (!in.getBoolean(IS_IKE_FRAGMENT_SUPPORTED_KEY)) { 648 throw new IllegalArgumentException("Invalid fragmentation policy"); 649 } 650 651 return builder.build(); 652 } 653 /** 654 * Serializes this object to a PersistableBundle 655 * 656 * @hide 657 */ 658 @NonNull toPersistableBundle()659 public PersistableBundle toPersistableBundle() { 660 if (mCallerConfiguredNetwork != null || mIke3gppExtension != null) { 661 throw new IllegalStateException( 662 "Cannot convert a IkeSessionParams with a caller configured network or with" 663 + " 3GPP extension enabled"); 664 } 665 final PersistableBundle result = new PersistableBundle(); 666 667 result.putString(SERVER_HOST_NAME_KEY, mServerHostname); 668 669 PersistableBundle saProposalBundle = 670 PersistableBundleUtils.fromList( 671 Arrays.asList(mSaProposals), IkeSaProposal::toPersistableBundle); 672 result.putPersistableBundle(SA_PROPOSALS_KEY, saProposalBundle); 673 674 result.putPersistableBundle(LOCAL_ID_KEY, mLocalIdentification.toPersistableBundle()); 675 result.putPersistableBundle(REMOTE_ID_KEY, mRemoteIdentification.toPersistableBundle()); 676 result.putPersistableBundle(LOCAL_AUTH_KEY, mLocalAuthConfig.toPersistableBundle()); 677 result.putPersistableBundle(REMOTE_AUTH_KEY, mRemoteAuthConfig.toPersistableBundle()); 678 679 PersistableBundle configAttributeBundle = 680 PersistableBundleUtils.fromList( 681 Arrays.asList(mConfigRequests), ConfigAttribute::toPersistableBundle); 682 result.putPersistableBundle(CONFIG_ATTRIBUTES_KEY, configAttributeBundle); 683 684 result.putIntArray(RETRANS_TIMEOUTS_KEY, mRetransTimeoutMsList); 685 result.putIntArray(LIVENESS_RETRANS_TIMEOUTS_KEY, mLivenessRetransTimeoutMsList); 686 result.putLong(IKE_OPTIONS_KEY, mIkeOptions); 687 result.putInt(HARD_LIFETIME_SEC_KEY, mHardLifetimeSec); 688 result.putInt(SOFT_LIFETIME_SEC_KEY, mSoftLifetimeSec); 689 result.putInt(DPD_DELAY_SEC_KEY, mDpdDelaySec); 690 result.putInt(NATT_KEEPALIVE_DELAY_SEC_KEY, mNattKeepaliveDelaySec); 691 result.putInt(DSCP_KEY, mDscp); 692 result.putBoolean(IS_IKE_FRAGMENT_SUPPORTED_KEY, mIsIkeFragmentationSupported); 693 result.putInt(IP_VERSION_KEY, mIpVersion); 694 result.putInt(ENCAP_TYPE_KEY, mEncapType); 695 696 return result; 697 } 698 699 /** 700 * Retrieves the configured server hostname 701 * 702 * <p>The configured server hostname will be resolved during IKE Session creation. 703 */ 704 @NonNull getServerHostname()705 public String getServerHostname() { 706 return mServerHostname; 707 } 708 709 /** 710 * Retrieves the configured {@link Network}, or null if was not set 711 * 712 * <p>This getter is for internal use. Not matter {@link Builder#Builder(Context)} or {@link 713 * Builder#Builder()} is used, this method will always return null if no Network was set by the 714 * caller. 715 * 716 * @hide 717 */ 718 @Nullable getConfiguredNetwork()719 public Network getConfiguredNetwork() { 720 return mCallerConfiguredNetwork; 721 } 722 723 // This method was first released as a @NonNull System APi and has been changed to @Nullable 724 // since Android S. This method needs to be @Nullable because a new Builder constructor {@link 725 // Builder#Builder() was added in Android S, and by using the new constructor the return value 726 // of this method will be null if no network was set. 727 // For apps that are using a null-safe language, making this method @Nullable will break 728 // compilation, and apps need to update their code. For apps that are not using null-safe 729 // language, making this change will not break the backwards compatibility because for any app 730 // that uses the deprecated constructor {@link Builder#Builder(Context)}, the return value of 731 // this method is still guaranteed to be non-null. 732 /** 733 * Retrieves the configured {@link Network}, or null if was not set. 734 * 735 * <p>@see {@link Builder#setNetwork(Network)} 736 */ 737 @Nullable getNetwork()738 public Network getNetwork() { 739 return mDefaultOrConfiguredNetwork; 740 } 741 742 /** 743 * Retrieves all IkeSaProposals configured 744 * 745 * @deprecated Callers should use {@link #getIkeSaProposals()}. This method is deprecated 746 * because its name does not match the return type. 747 * @hide 748 */ 749 @Deprecated 750 @SystemApi 751 @NonNull getSaProposals()752 public List<IkeSaProposal> getSaProposals() { 753 return getIkeSaProposals(); 754 } 755 756 /** Retrieves all IkeSaProposals configured */ 757 @NonNull getIkeSaProposals()758 public List<IkeSaProposal> getIkeSaProposals() { 759 return Arrays.asList(mSaProposals); 760 } 761 762 /** @hide */ getSaProposalsInternal()763 public IkeSaProposal[] getSaProposalsInternal() { 764 return mSaProposals; 765 } 766 767 /** Retrieves the local (client) identity */ 768 @NonNull getLocalIdentification()769 public IkeIdentification getLocalIdentification() { 770 return mLocalIdentification; 771 } 772 773 /** Retrieves the required remote (server) identity */ 774 @NonNull getRemoteIdentification()775 public IkeIdentification getRemoteIdentification() { 776 return mRemoteIdentification; 777 } 778 779 /** Retrieves the local (client) authentication configuration */ 780 @NonNull getLocalAuthConfig()781 public IkeAuthConfig getLocalAuthConfig() { 782 return mLocalAuthConfig; 783 } 784 785 /** Retrieves the remote (server) authentication configuration */ 786 @NonNull getRemoteAuthConfig()787 public IkeAuthConfig getRemoteAuthConfig() { 788 return mRemoteAuthConfig; 789 } 790 791 /** Retrieves hard lifetime in seconds */ 792 // Use "second" because smaller unit won't make sense to describe a rekey interval. 793 @SuppressLint("MethodNameUnits") 794 @IntRange(from = IKE_HARD_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) getHardLifetimeSeconds()795 public int getHardLifetimeSeconds() { 796 return mHardLifetimeSec; 797 } 798 799 /** Retrieves soft lifetime in seconds */ 800 // Use "second" because smaller unit does not make sense to a rekey interval. 801 @SuppressLint("MethodNameUnits") 802 @IntRange(from = IKE_SOFT_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) getSoftLifetimeSeconds()803 public int getSoftLifetimeSeconds() { 804 return mSoftLifetimeSec; 805 } 806 807 /** Retrieves the Dead Peer Detection(DPD) delay in seconds */ 808 // Use "second" because smaller unit does not make sense to a DPD delay. 809 @SuppressLint("MethodNameUnits") 810 @IntRange(from = IKE_DPD_DELAY_SEC_MIN) getDpdDelaySeconds()811 public int getDpdDelaySeconds() { 812 return mDpdDelaySec; 813 } 814 815 /** Retrieves the Network Address Translation Traversal (NATT) keepalive delay in seconds */ 816 // Use "second" because smaller unit does not make sense for a NATT Keepalive delay. 817 @SuppressLint("MethodNameUnits") 818 @IntRange(from = IKE_NATT_KEEPALIVE_DELAY_SEC_MIN, to = IKE_NATT_KEEPALIVE_DELAY_SEC_MAX) getNattKeepAliveDelaySeconds()819 public int getNattKeepAliveDelaySeconds() { 820 return mNattKeepaliveDelaySec; 821 } 822 823 /** 824 * Retrieves the DSCP field of IKE packets. 825 * 826 * @hide 827 */ 828 @SystemApi 829 @IntRange(from = DSCP_MIN, to = DSCP_MAX) getDscp()830 public int getDscp() { 831 return mDscp; 832 } 833 834 /** 835 * Retrieves the IP version. 836 * @hide 837 */ 838 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) getIpVersion()839 @EspIpVersion public int getIpVersion() { 840 return mIpVersion; 841 } 842 843 /** 844 * Retrieves the encap type. 845 * @hide 846 */ 847 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) getEncapType()848 @EspEncapType public int getEncapType() { 849 return mEncapType; 850 } 851 852 /** 853 * Retrieves the relative retransmission timeout list in milliseconds 854 * 855 * <p>@see {@link Builder#setRetransmissionTimeoutsMillis(int[])} 856 */ 857 @NonNull getRetransmissionTimeoutsMillis()858 public int[] getRetransmissionTimeoutsMillis() { 859 return mRetransTimeoutMsList; 860 } 861 862 /** 863 * Retrieves the relative retransmission timeout list for configuring on-demand liveness checks 864 * in milliseconds. 865 * 866 * <p>The on-demand liveness check uses the returned list of liveness retransmission timeouts 867 * set from {@link Builder#setLivenessRetransmissionTimeoutsMillis} or uses the default value of 868 * {0.5s, 1s, 2s, 4s, 8s} if no override is defined. 869 * 870 * <p>@see {@link Builder#setLivenessRetransmissionTimeoutsMillis} for more information about 871 * how the list is structured. 872 * 873 * @hide 874 */ 875 @SystemApi 876 @FlaggedApi("com.android.ipsec.flags.liveness_check_api") 877 @NonNull getLivenessRetransmissionTimeoutsMillis()878 public int[] getLivenessRetransmissionTimeoutsMillis() { 879 return mLivenessRetransTimeoutMsList; 880 } 881 882 /** 883 * Retrieves the configured Ike3gppExtension, or null if it was not set. 884 * 885 * @hide 886 */ 887 @SystemApi 888 @Nullable getIke3gppExtension()889 public Ike3gppExtension getIke3gppExtension() { 890 return mIke3gppExtension; 891 } 892 hasIkeOption(long ikeOptionsRecord, @IkeOption int ikeOption)893 private static boolean hasIkeOption(long ikeOptionsRecord, @IkeOption int ikeOption) { 894 validateIkeOptionOrThrow(ikeOption); 895 return (ikeOptionsRecord & getOptionBitValue(ikeOption)) != 0; 896 } 897 898 /** 899 * Checks if the given IKE Session negotiation option is set 900 * 901 * @param ikeOption the option to check. 902 * @throws IllegalArgumentException if the provided option is invalid. 903 */ hasIkeOption(@keOption int ikeOption)904 public boolean hasIkeOption(@IkeOption int ikeOption) { 905 return hasIkeOption(mIkeOptions, ikeOption); 906 } 907 908 /** 909 * Return all the enabled IKE Options 910 * 911 * @return A Set of enabled IKE options that have been added using {@link 912 * Builder#addIkeOption(int)} 913 */ 914 @FlaggedApi("com.android.ipsec.flags.enabled_ike_options_api") 915 @NonNull 916 @IkeOption getIkeOptions()917 public Set<Integer> getIkeOptions() { 918 final Set<Integer> result = new HashSet<>(); 919 920 long ikeOptionBits = mIkeOptions; 921 int optionValue = 0; 922 while (ikeOptionBits > 0) { 923 if ((ikeOptionBits & 1) == 1) { 924 result.add(optionValue); 925 } 926 ikeOptionBits >>>= 1; 927 optionValue++; 928 } 929 930 return result; 931 } 932 933 /** @hide */ getHardLifetimeMsInternal()934 public long getHardLifetimeMsInternal() { 935 return TimeUnit.SECONDS.toMillis((long) mHardLifetimeSec); 936 } 937 938 /** @hide */ getSoftLifetimeMsInternal()939 public long getSoftLifetimeMsInternal() { 940 return TimeUnit.SECONDS.toMillis((long) mSoftLifetimeSec); 941 } 942 943 /** @hide */ isIkeFragmentationSupported()944 public boolean isIkeFragmentationSupported() { 945 return mIsIkeFragmentationSupported; 946 } 947 948 /** @hide */ getConfigurationAttributesInternal()949 public IkeConfigAttribute[] getConfigurationAttributesInternal() { 950 return mConfigRequests; 951 } 952 953 /** 954 * Retrieves the list of Configuration Requests 955 * 956 * @hide 957 */ 958 @SystemApi 959 @NonNull getConfigurationRequests()960 public List<IkeConfigRequest> getConfigurationRequests() { 961 return Collections.unmodifiableList(Arrays.asList(mConfigRequests)); 962 } 963 964 /** @hide */ 965 @Override hashCode()966 public int hashCode() { 967 return Objects.hash( 968 mServerHostname, 969 mCallerConfiguredNetwork, 970 Arrays.hashCode(mSaProposals), 971 mLocalIdentification, 972 mRemoteIdentification, 973 mLocalAuthConfig, 974 mRemoteAuthConfig, 975 mIke3gppExtension, 976 Arrays.hashCode(mConfigRequests), 977 Arrays.hashCode(mRetransTimeoutMsList), 978 Arrays.hashCode(mLivenessRetransTimeoutMsList), 979 mIkeOptions, 980 mHardLifetimeSec, 981 mSoftLifetimeSec, 982 mDpdDelaySec, 983 mNattKeepaliveDelaySec, 984 mDscp, 985 mIsIkeFragmentationSupported, 986 mIpVersion, 987 mEncapType); 988 } 989 990 /** @hide */ 991 @Override equals(Object o)992 public boolean equals(Object o) { 993 if (!(o instanceof IkeSessionParams)) { 994 return false; 995 } 996 997 IkeSessionParams other = (IkeSessionParams) o; 998 999 return mServerHostname.equals(other.mServerHostname) 1000 && Objects.equals(mCallerConfiguredNetwork, other.mCallerConfiguredNetwork) 1001 && Arrays.equals(mSaProposals, other.mSaProposals) 1002 && mLocalIdentification.equals(other.mLocalIdentification) 1003 && mRemoteIdentification.equals(other.mRemoteIdentification) 1004 && mLocalAuthConfig.equals(other.mLocalAuthConfig) 1005 && mRemoteAuthConfig.equals(other.mRemoteAuthConfig) 1006 && Objects.equals(mIke3gppExtension, other.mIke3gppExtension) 1007 && Arrays.equals(mConfigRequests, other.mConfigRequests) 1008 && Arrays.equals(mRetransTimeoutMsList, other.mRetransTimeoutMsList) 1009 && Arrays.equals(mLivenessRetransTimeoutMsList, other.mLivenessRetransTimeoutMsList) 1010 && mIkeOptions == other.mIkeOptions 1011 && mHardLifetimeSec == other.mHardLifetimeSec 1012 && mSoftLifetimeSec == other.mSoftLifetimeSec 1013 && mDpdDelaySec == other.mDpdDelaySec 1014 && mNattKeepaliveDelaySec == other.mNattKeepaliveDelaySec 1015 && mDscp == other.mDscp 1016 && mIsIkeFragmentationSupported == other.mIsIkeFragmentationSupported 1017 && mIpVersion == other.mIpVersion 1018 && mEncapType == other.mEncapType; 1019 } 1020 1021 /** 1022 * Represents an IKE session configuration request type 1023 * 1024 * @hide 1025 */ 1026 @SystemApi 1027 public interface IkeConfigRequest {} 1028 1029 /** 1030 * Represents an IPv4 P_CSCF request 1031 * 1032 * @hide 1033 */ 1034 @SystemApi 1035 public interface ConfigRequestIpv4PcscfServer extends IkeConfigRequest { 1036 /** 1037 * Retrieves the requested IPv4 P_CSCF server address 1038 * 1039 * @return The requested P_CSCF server address, or null if no specific P_CSCF server was 1040 * requested 1041 */ 1042 @Nullable getAddress()1043 Inet4Address getAddress(); 1044 } 1045 1046 /** 1047 * Represents an IPv6 P_CSCF request 1048 * 1049 * @hide 1050 */ 1051 @SystemApi 1052 public interface ConfigRequestIpv6PcscfServer extends IkeConfigRequest { 1053 /** 1054 * Retrieves the requested IPv6 P_CSCF server address 1055 * 1056 * @return The requested P_CSCF server address, or null if no specific P_CSCF server was 1057 * requested 1058 */ 1059 @Nullable getAddress()1060 Inet6Address getAddress(); 1061 } 1062 1063 /** This class contains common information of an IKEv2 authentication configuration. */ 1064 public abstract static class IkeAuthConfig { 1065 private static final String AUTH_METHOD_KEY = "mAuthMethod"; 1066 private static final String AUTH_DIRECTION_KEY = "mAuthDirection"; 1067 /** @hide */ 1068 @IkeAuthMethod public final int mAuthMethod; 1069 /** @hide */ 1070 @AuthDirection public final int mAuthDirection; 1071 1072 /** @hide */ IkeAuthConfig(@keAuthMethod int authMethod, @AuthDirection int authDirection)1073 IkeAuthConfig(@IkeAuthMethod int authMethod, @AuthDirection int authDirection) { 1074 mAuthMethod = authMethod; 1075 mAuthDirection = authDirection; 1076 } 1077 1078 /** 1079 * Constructs this object by deserializing a PersistableBundle 1080 * 1081 * @hide 1082 */ 1083 @NonNull fromPersistableBundle(PersistableBundle in)1084 public static IkeAuthConfig fromPersistableBundle(PersistableBundle in) { 1085 Objects.requireNonNull(in, "PersistableBundle is null"); 1086 1087 int authMethod = in.getInt(AUTH_METHOD_KEY); 1088 switch (authMethod) { 1089 case IKE_AUTH_METHOD_PSK: 1090 return IkeAuthPskConfig.fromPersistableBundle(in); 1091 case IKE_AUTH_METHOD_PUB_KEY_SIGNATURE: 1092 switch (in.getInt(AUTH_DIRECTION_KEY)) { 1093 case AUTH_DIRECTION_LOCAL: 1094 return IkeAuthDigitalSignLocalConfig.fromPersistableBundle(in); 1095 case AUTH_DIRECTION_REMOTE: 1096 return IkeAuthDigitalSignRemoteConfig.fromPersistableBundle(in); 1097 default: 1098 throw new IllegalArgumentException( 1099 "Digital-signature-based auth configuration with invalid" 1100 + " direction: " 1101 + in.getInt(AUTH_DIRECTION_KEY)); 1102 } 1103 case IKE_AUTH_METHOD_EAP: 1104 return IkeAuthEapConfig.fromPersistableBundle(in); 1105 default: 1106 throw new IllegalArgumentException("Invalid Auth Method: " + authMethod); 1107 } 1108 } 1109 1110 /** 1111 * Serializes this object to a PersistableBundle 1112 * 1113 * @hide 1114 */ 1115 @NonNull toPersistableBundle()1116 protected PersistableBundle toPersistableBundle() { 1117 final PersistableBundle result = new PersistableBundle(); 1118 1119 result.putInt(AUTH_METHOD_KEY, mAuthMethod); 1120 result.putInt(AUTH_DIRECTION_KEY, mAuthDirection); 1121 return result; 1122 } 1123 1124 @Override hashCode()1125 public int hashCode() { 1126 return Objects.hash(mAuthMethod, mAuthDirection); 1127 } 1128 1129 @Override equals(Object o)1130 public boolean equals(Object o) { 1131 if (!(o instanceof IkeAuthConfig)) { 1132 return false; 1133 } 1134 1135 IkeAuthConfig other = (IkeAuthConfig) o; 1136 1137 return mAuthMethod == other.mAuthMethod && mAuthDirection == other.mAuthDirection; 1138 } 1139 } 1140 1141 /** 1142 * This class represents the configuration to support IKEv2 pre-shared-key-based authentication 1143 * of local or remote side. 1144 */ 1145 public static class IkeAuthPskConfig extends IkeAuthConfig { 1146 private static final String PSK_KEY = "mPsk"; 1147 /** @hide */ 1148 @NonNull public final byte[] mPsk; 1149 1150 /** @hide */ 1151 @VisibleForTesting IkeAuthPskConfig(byte[] psk)1152 IkeAuthPskConfig(byte[] psk) { 1153 super(IKE_AUTH_METHOD_PSK, AUTH_DIRECTION_BOTH); 1154 mPsk = psk; 1155 } 1156 1157 /** 1158 * Constructs this object by deserializing a PersistableBundle 1159 * 1160 * @hide 1161 */ 1162 @NonNull fromPersistableBundle(@onNull PersistableBundle in)1163 public static IkeAuthPskConfig fromPersistableBundle(@NonNull PersistableBundle in) { 1164 Objects.requireNonNull(in, "PersistableBundle is null"); 1165 1166 PersistableBundle pskBundle = in.getPersistableBundle(PSK_KEY); 1167 Objects.requireNonNull(in, "PSK bundle is null"); 1168 1169 return new IkeAuthPskConfig(PersistableBundleUtils.toByteArray(pskBundle)); 1170 } 1171 1172 /** 1173 * Serializes this object to a PersistableBundle 1174 * 1175 * @hide 1176 */ 1177 @Override 1178 @NonNull toPersistableBundle()1179 public PersistableBundle toPersistableBundle() { 1180 final PersistableBundle result = super.toPersistableBundle(); 1181 1182 result.putPersistableBundle(PSK_KEY, PersistableBundleUtils.fromByteArray(mPsk)); 1183 return result; 1184 } 1185 1186 /** Retrieves the pre-shared key */ 1187 @NonNull getPsk()1188 public byte[] getPsk() { 1189 return Arrays.copyOf(mPsk, mPsk.length); 1190 } 1191 1192 @Override hashCode()1193 public int hashCode() { 1194 return Objects.hash(super.hashCode(), Arrays.hashCode(mPsk)); 1195 } 1196 1197 @Override equals(Object o)1198 public boolean equals(Object o) { 1199 if (!super.equals(o) || !(o instanceof IkeAuthPskConfig)) { 1200 return false; 1201 } 1202 1203 return Arrays.equals(mPsk, ((IkeAuthPskConfig) o).mPsk); 1204 } 1205 } 1206 1207 /** 1208 * This class represents the configuration to support IKEv2 public-key-signature-based 1209 * authentication of the remote side. 1210 */ 1211 public static class IkeAuthDigitalSignRemoteConfig extends IkeAuthConfig { 1212 private static final String TRUST_CERT_KEY = "TRUST_CERT_KEY"; 1213 /** @hide */ 1214 @Nullable public final TrustAnchor mTrustAnchor; 1215 1216 /** 1217 * If a certificate is provided, it MUST be the root CA used by the remote (server), or 1218 * authentication will fail. If no certificate is provided, any root CA in the system's 1219 * truststore is considered acceptable. 1220 * 1221 * @hide 1222 */ 1223 @VisibleForTesting IkeAuthDigitalSignRemoteConfig(@ullable X509Certificate caCert)1224 IkeAuthDigitalSignRemoteConfig(@Nullable X509Certificate caCert) { 1225 super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, AUTH_DIRECTION_REMOTE); 1226 if (caCert == null) { 1227 mTrustAnchor = null; 1228 } else { 1229 // The name constraints extension, defined in RFC 5280, indicates a name space 1230 // within which all subject names in subsequent certificates in a certification path 1231 // MUST be located. 1232 mTrustAnchor = new TrustAnchor(caCert, null /*nameConstraints*/); 1233 1234 // TODO: Investigate if we need to support the name constraints extension. 1235 } 1236 } 1237 1238 /** 1239 * Constructs this object by deserializing a PersistableBundle 1240 * 1241 * @hide 1242 */ 1243 @NonNull fromPersistableBundle( @onNull PersistableBundle in)1244 public static IkeAuthDigitalSignRemoteConfig fromPersistableBundle( 1245 @NonNull PersistableBundle in) { 1246 Objects.requireNonNull(in, "PersistableBundle is null"); 1247 1248 PersistableBundle trustCertBundle = in.getPersistableBundle(TRUST_CERT_KEY); 1249 1250 X509Certificate caCert = null; 1251 if (trustCertBundle != null) { 1252 byte[] encodedCert = PersistableBundleUtils.toByteArray(trustCertBundle); 1253 caCert = certificateFromByteArray(encodedCert); 1254 } 1255 1256 return new IkeAuthDigitalSignRemoteConfig(caCert); 1257 } 1258 1259 /** 1260 * Serializes this object to a PersistableBundle 1261 * 1262 * @hide 1263 */ 1264 @Override 1265 @NonNull toPersistableBundle()1266 public PersistableBundle toPersistableBundle() { 1267 final PersistableBundle result = super.toPersistableBundle(); 1268 1269 try { 1270 if (mTrustAnchor != null) { 1271 result.putPersistableBundle( 1272 TRUST_CERT_KEY, 1273 PersistableBundleUtils.fromByteArray( 1274 mTrustAnchor.getTrustedCert().getEncoded())); 1275 } 1276 1277 } catch (CertificateEncodingException e) { 1278 throw new IllegalArgumentException("Fail to encode the certificate"); 1279 } 1280 1281 return result; 1282 } 1283 1284 /** Retrieves the provided CA certificate for validating the remote certificate(s) */ 1285 @Nullable getRemoteCaCert()1286 public X509Certificate getRemoteCaCert() { 1287 if (mTrustAnchor == null) return null; 1288 return mTrustAnchor.getTrustedCert(); 1289 } 1290 1291 @Override hashCode()1292 public int hashCode() { 1293 // Use #getTrustedCert() because TrustAnchor does not override #hashCode() 1294 return Objects.hash( 1295 super.hashCode(), 1296 (mTrustAnchor == null) ? null : mTrustAnchor.getTrustedCert()); 1297 } 1298 1299 @Override equals(Object o)1300 public boolean equals(Object o) { 1301 if (!super.equals(o) || !(o instanceof IkeAuthDigitalSignRemoteConfig)) { 1302 return false; 1303 } 1304 1305 IkeAuthDigitalSignRemoteConfig other = (IkeAuthDigitalSignRemoteConfig) o; 1306 1307 if (mTrustAnchor == null && other.mTrustAnchor == null) { 1308 return true; 1309 } 1310 1311 // Compare #getTrustedCert() because TrustAnchor does not override #equals(Object) 1312 return mTrustAnchor != null 1313 && other.mTrustAnchor != null 1314 && Objects.equals( 1315 mTrustAnchor.getTrustedCert(), other.mTrustAnchor.getTrustedCert()); 1316 } 1317 } 1318 1319 /** 1320 * This class represents the configuration to support IKEv2 public-key-signature-based 1321 * authentication of the local side. 1322 */ 1323 public static class IkeAuthDigitalSignLocalConfig extends IkeAuthConfig { 1324 private static final String END_CERT_KEY = "mEndCert"; 1325 private static final String INTERMEDIATE_CERTS_KEY = "mIntermediateCerts"; 1326 private static final String PRIVATE_KEY_KEY = "mPrivateKey"; 1327 /** @hide */ 1328 @NonNull public final X509Certificate mEndCert; 1329 1330 /** @hide */ 1331 @NonNull public final List<X509Certificate> mIntermediateCerts; 1332 1333 /** @hide */ 1334 @NonNull public final PrivateKey mPrivateKey; 1335 1336 /** @hide */ 1337 @VisibleForTesting IkeAuthDigitalSignLocalConfig( @onNull X509Certificate clientEndCert, @NonNull List<X509Certificate> clientIntermediateCerts, @NonNull PrivateKey privateKey)1338 IkeAuthDigitalSignLocalConfig( 1339 @NonNull X509Certificate clientEndCert, 1340 @NonNull List<X509Certificate> clientIntermediateCerts, 1341 @NonNull PrivateKey privateKey) { 1342 super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, AUTH_DIRECTION_LOCAL); 1343 mEndCert = clientEndCert; 1344 mIntermediateCerts = clientIntermediateCerts; 1345 mPrivateKey = privateKey; 1346 } 1347 1348 /** 1349 * Constructs this object by deserializing a PersistableBundle 1350 * 1351 * @hide 1352 */ 1353 @NonNull fromPersistableBundle( @onNull PersistableBundle in)1354 public static IkeAuthDigitalSignLocalConfig fromPersistableBundle( 1355 @NonNull PersistableBundle in) { 1356 Objects.requireNonNull(in, "PersistableBundle is null"); 1357 1358 PersistableBundle endCertBundle = in.getPersistableBundle(END_CERT_KEY); 1359 Objects.requireNonNull(endCertBundle, "End cert not provided"); 1360 byte[] encodedCert = PersistableBundleUtils.toByteArray(endCertBundle); 1361 X509Certificate endCert = certificateFromByteArray(encodedCert); 1362 1363 PersistableBundle certsBundle = in.getPersistableBundle(INTERMEDIATE_CERTS_KEY); 1364 Objects.requireNonNull(certsBundle, "Intermediate certs not provided"); 1365 List<byte[]> encodedCertList = 1366 PersistableBundleUtils.toList(certsBundle, PersistableBundleUtils::toByteArray); 1367 List<X509Certificate> certList = new ArrayList<>(encodedCertList.size()); 1368 for (byte[] encoded : encodedCertList) { 1369 certList.add(certificateFromByteArray(encoded)); 1370 } 1371 1372 PersistableBundle privateKeyBundle = in.getPersistableBundle(PRIVATE_KEY_KEY); 1373 Objects.requireNonNull(privateKeyBundle, "PrivateKey bundle is null"); 1374 PrivateKey privateKey = 1375 privateKeyFromByteArray(PersistableBundleUtils.toByteArray(privateKeyBundle)); 1376 Objects.requireNonNull(privateKeyBundle, "PrivateKey is null"); 1377 1378 return new IkeAuthDigitalSignLocalConfig(endCert, certList, privateKey); 1379 } 1380 1381 /** 1382 * Serializes this object to a PersistableBundle 1383 * 1384 * @hide 1385 */ 1386 @Override 1387 @NonNull toPersistableBundle()1388 public PersistableBundle toPersistableBundle() { 1389 final PersistableBundle result = super.toPersistableBundle(); 1390 1391 try { 1392 result.putPersistableBundle( 1393 END_CERT_KEY, PersistableBundleUtils.fromByteArray(mEndCert.getEncoded())); 1394 1395 List<byte[]> encodedCertList = new ArrayList<>(mIntermediateCerts.size()); 1396 for (X509Certificate cert : mIntermediateCerts) { 1397 encodedCertList.add(cert.getEncoded()); 1398 } 1399 PersistableBundle certsBundle = 1400 PersistableBundleUtils.fromList( 1401 encodedCertList, PersistableBundleUtils::fromByteArray); 1402 result.putPersistableBundle(INTERMEDIATE_CERTS_KEY, certsBundle); 1403 } catch (CertificateEncodingException e) { 1404 throw new IllegalArgumentException("Fail to encode certificate"); 1405 } 1406 1407 // TODO: b/170670506 Consider putting PrivateKey in Android KeyStore 1408 result.putPersistableBundle( 1409 PRIVATE_KEY_KEY, 1410 PersistableBundleUtils.fromByteArray(mPrivateKey.getEncoded())); 1411 1412 return result; 1413 } 1414 1415 /** Retrieves the client end certificate */ 1416 @NonNull getClientEndCertificate()1417 public X509Certificate getClientEndCertificate() { 1418 return mEndCert; 1419 } 1420 1421 /** Retrieves the intermediate certificates */ 1422 @NonNull getIntermediateCertificates()1423 public List<X509Certificate> getIntermediateCertificates() { 1424 return mIntermediateCerts; 1425 } 1426 1427 /** Retrieves the private key */ 1428 @NonNull getPrivateKey()1429 public PrivateKey getPrivateKey() { 1430 return mPrivateKey; 1431 } 1432 1433 @Override hashCode()1434 public int hashCode() { 1435 return Objects.hash(super.hashCode(), mEndCert, mIntermediateCerts, mPrivateKey); 1436 } 1437 1438 @Override equals(Object o)1439 public boolean equals(Object o) { 1440 if (!super.equals(o) || !(o instanceof IkeAuthDigitalSignLocalConfig)) { 1441 return false; 1442 } 1443 1444 IkeAuthDigitalSignLocalConfig other = (IkeAuthDigitalSignLocalConfig) o; 1445 1446 return mEndCert.equals(other.mEndCert) 1447 && mIntermediateCerts.equals(other.mIntermediateCerts) 1448 && mPrivateKey.equals(other.mPrivateKey); 1449 } 1450 } 1451 1452 /** 1453 * This class represents the configuration to support EAP authentication of the local side. 1454 * 1455 * <p>@see {@link IkeSessionParams.Builder#setAuthEap(X509Certificate, EapSessionConfig)} 1456 */ 1457 public static class IkeAuthEapConfig extends IkeAuthConfig { 1458 private static final String EAP_CONFIG_KEY = "mEapConfig"; 1459 1460 /** @hide */ 1461 @NonNull public final EapSessionConfig mEapConfig; 1462 1463 /** @hide */ 1464 @VisibleForTesting IkeAuthEapConfig(EapSessionConfig eapConfig)1465 IkeAuthEapConfig(EapSessionConfig eapConfig) { 1466 super(IKE_AUTH_METHOD_EAP, AUTH_DIRECTION_LOCAL); 1467 1468 mEapConfig = eapConfig; 1469 } 1470 1471 /** 1472 * Constructs this object by deserializing a PersistableBundle 1473 * 1474 * @hide 1475 */ 1476 @NonNull fromPersistableBundle(@onNull PersistableBundle in)1477 public static IkeAuthEapConfig fromPersistableBundle(@NonNull PersistableBundle in) { 1478 Objects.requireNonNull(in, "PersistableBundle null"); 1479 1480 PersistableBundle eapBundle = in.getPersistableBundle(EAP_CONFIG_KEY); 1481 Objects.requireNonNull(in, "EAP Config bundle is null"); 1482 1483 EapSessionConfig eapConfig = EapSessionConfig.fromPersistableBundle(eapBundle); 1484 Objects.requireNonNull(eapConfig, "EAP Config is null"); 1485 1486 return new IkeAuthEapConfig(eapConfig); 1487 } 1488 1489 /** 1490 * Serializes this object to a PersistableBundle 1491 * 1492 * @hide 1493 */ 1494 @Override 1495 @NonNull toPersistableBundle()1496 public PersistableBundle toPersistableBundle() { 1497 final PersistableBundle result = super.toPersistableBundle(); 1498 result.putPersistableBundle(EAP_CONFIG_KEY, mEapConfig.toPersistableBundle()); 1499 return result; 1500 } 1501 1502 /** Retrieves EAP configuration */ 1503 @NonNull getEapConfig()1504 public EapSessionConfig getEapConfig() { 1505 return mEapConfig; 1506 } 1507 1508 @Override hashCode()1509 public int hashCode() { 1510 return Objects.hash(super.hashCode(), mEapConfig); 1511 } 1512 1513 @Override equals(Object o)1514 public boolean equals(Object o) { 1515 if (!super.equals(o) || !(o instanceof IkeAuthEapConfig)) { 1516 return false; 1517 } 1518 1519 return mEapConfig.equals(((IkeAuthEapConfig) o).mEapConfig); 1520 } 1521 } 1522 1523 /** This class can be used to incrementally construct a {@link IkeSessionParams}. */ 1524 public static final class Builder { 1525 // This field has changed from @NonNull to @Nullable since Android S. It has to be @Nullable 1526 // because the new constructor #Builder() will not need and will not able to get a 1527 // ConnectivityManager instance anymore. Making it @Nullable does not break the backwards 1528 // compatibility because if apps use the old constructor #Builder(Context), the Builder and 1529 // the IkeSessionParams built from it will still work in the old way. @see #Builder(Context) 1530 @Nullable private ConnectivityManager mConnectivityManager; 1531 1532 @NonNull private final List<IkeSaProposal> mSaProposalList = new LinkedList<>(); 1533 @NonNull private final List<IkeConfigAttribute> mConfigRequestList = new ArrayList<>(); 1534 1535 @NonNull 1536 private int[] mRetransTimeoutMsList = 1537 Arrays.copyOf( 1538 IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT, 1539 IKE_RETRANS_TIMEOUT_MS_LIST_DEFAULT.length); 1540 1541 @NonNull 1542 private int[] mLivenessRetransTimeoutMsList = 1543 Arrays.copyOf( 1544 LIVENESS_RETRANS_TIMEOUT_MS_LIST_DEFAULT, 1545 LIVENESS_RETRANS_TIMEOUT_MS_LIST_DEFAULT.length); 1546 1547 @NonNull private String mServerHostname; 1548 @Nullable private Network mCallerConfiguredNetwork; 1549 1550 @Nullable private IkeIdentification mLocalIdentification; 1551 @Nullable private IkeIdentification mRemoteIdentification; 1552 1553 @Nullable private IkeAuthConfig mLocalAuthConfig; 1554 @Nullable private IkeAuthConfig mRemoteAuthConfig; 1555 1556 @Nullable private Ike3gppExtension mIke3gppExtension; 1557 1558 private long mIkeOptions = 0; 1559 1560 private int mHardLifetimeSec = IKE_HARD_LIFETIME_SEC_DEFAULT; 1561 private int mSoftLifetimeSec = IKE_SOFT_LIFETIME_SEC_DEFAULT; 1562 1563 private int mDpdDelaySec = IKE_DPD_DELAY_SEC_DEFAULT; 1564 private int mNattKeepaliveDelaySec = IKE_NATT_KEEPALIVE_DELAY_SEC_DEFAULT; 1565 private int mDscp = DSCP_DEFAULT; 1566 private final boolean mIsIkeFragmentationSupported = true; 1567 1568 @EspIpVersion private int mIpVersion = ESP_IP_VERSION_AUTO; 1569 @EspEncapType private int mEncapType = ESP_ENCAP_TYPE_AUTO; 1570 1571 /** 1572 * Construct Builder 1573 * 1574 * <p>This constructor is deprecated since Android S. Apps that use this constructor can 1575 * still expect {@link #build()} to throw if no configured or default network was found. But 1576 * apps that use {@link #Builder()} MUST NOT expect that behavior anymore. 1577 * 1578 * <p>For a caller that used this constructor and did not set any Network, {@link 1579 * IkeSessionParams#getNetwork()} will return the default Network resolved in {@link 1580 * IkeSessionParams.Builder#build()}. This return value is only informational because if 1581 * MOBIKE is enabled, IKE Session may switch to a different default Network. 1582 * 1583 * @param context a valid {@link Context} instance. 1584 * @deprecated Callers should use {@link #Builder()}.This method is deprecated because it is 1585 * unnecessary to try resolving a default network or to validate network is connected 1586 * before {@link IkeSession} starts the setup process. 1587 * @hide 1588 */ 1589 @Deprecated 1590 @SystemApi Builder(@onNull Context context)1591 public Builder(@NonNull Context context) { 1592 this((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE)); 1593 } 1594 1595 /** 1596 * Construct Builder 1597 */ Builder()1598 public Builder() {} 1599 1600 /** @hide */ 1601 // TODO: b/178389011 This constructor should be removed when #Builder(Context) can be safely 1602 // removed. See #Builder(Context) for reasons. 1603 @VisibleForTesting Builder(ConnectivityManager connectManager)1604 public Builder(ConnectivityManager connectManager) { 1605 mConnectivityManager = connectManager; 1606 } 1607 1608 /** 1609 * Construct Builder from the {@link IkeSessionParams} object. 1610 * 1611 * @param ikeSessionParams the object this Builder will be constructed with. 1612 */ Builder(@onNull IkeSessionParams ikeSessionParams)1613 public Builder(@NonNull IkeSessionParams ikeSessionParams) { 1614 mSaProposalList.addAll(ikeSessionParams.getSaProposals()); 1615 mConfigRequestList.addAll(Arrays.asList(ikeSessionParams.mConfigRequests)); 1616 1617 int[] retransmissionTimeouts = ikeSessionParams.getRetransmissionTimeoutsMillis(); 1618 mRetransTimeoutMsList = 1619 Arrays.copyOf(retransmissionTimeouts, retransmissionTimeouts.length); 1620 1621 int[] livenessretransmissionTimeouts = ikeSessionParams.mLivenessRetransTimeoutMsList; 1622 if (livenessretransmissionTimeouts != null) { 1623 mLivenessRetransTimeoutMsList = 1624 Arrays.copyOf( 1625 livenessretransmissionTimeouts, 1626 livenessretransmissionTimeouts.length); 1627 } 1628 1629 mServerHostname = ikeSessionParams.getServerHostname(); 1630 mCallerConfiguredNetwork = ikeSessionParams.getConfiguredNetwork(); 1631 mLocalIdentification = ikeSessionParams.getLocalIdentification(); 1632 mRemoteIdentification = ikeSessionParams.getRemoteIdentification(); 1633 mLocalAuthConfig = ikeSessionParams.getLocalAuthConfig(); 1634 mRemoteAuthConfig = ikeSessionParams.getRemoteAuthConfig(); 1635 1636 mIke3gppExtension = ikeSessionParams.getIke3gppExtension(); 1637 1638 mHardLifetimeSec = ikeSessionParams.getHardLifetimeSeconds(); 1639 mSoftLifetimeSec = ikeSessionParams.getSoftLifetimeSeconds(); 1640 mDpdDelaySec = ikeSessionParams.getDpdDelaySeconds(); 1641 mNattKeepaliveDelaySec = ikeSessionParams.getNattKeepAliveDelaySeconds(); 1642 mDscp = ikeSessionParams.getDscp(); 1643 mIpVersion = ikeSessionParams.getIpVersion(); 1644 mEncapType = ikeSessionParams.getEncapType(); 1645 1646 mIkeOptions = ikeSessionParams.mIkeOptions; 1647 1648 if (!ikeSessionParams.mIsIkeFragmentationSupported) { 1649 throw new IllegalStateException( 1650 "mIsIkeFragmentationSupported should never be false"); 1651 } 1652 } 1653 1654 /** 1655 * Sets the server hostname for the {@link IkeSessionParams} being built. 1656 * 1657 * @param serverHostname the hostname of the IKE server, such as "ike.android.com". 1658 * @return Builder this, to facilitate chaining. 1659 */ 1660 @NonNull setServerHostname(@onNull String serverHostname)1661 public Builder setServerHostname(@NonNull String serverHostname) { 1662 Objects.requireNonNull(serverHostname, "Required argument not provided"); 1663 1664 mServerHostname = serverHostname; 1665 return this; 1666 } 1667 1668 /** 1669 * Sets the {@link Network} for the {@link IkeSessionParams} being built. 1670 * 1671 * <p>If no {@link Network} is provided, the default Network (as per {@link 1672 * ConnectivityManager#getActiveNetwork()}) will be used when constructing an {@link 1673 * IkeSession}. 1674 * 1675 * @param network the {@link Network} that IKE Session will use, or {@code null} to clear 1676 * the previously set {@link Network} 1677 * @return Builder this, to facilitate chaining. 1678 */ 1679 @NonNull setNetwork(@ullable Network network)1680 public Builder setNetwork(@Nullable Network network) { 1681 mCallerConfiguredNetwork = network; 1682 return this; 1683 } 1684 1685 /** 1686 * Sets local IKE identification for the {@link IkeSessionParams} being built. 1687 * 1688 * <p>It is not allowed to use KEY ID together with digital-signature-based authentication 1689 * as per RFC 7296. 1690 * 1691 * @param identification the local IKE identification. 1692 * @return Builder this, to facilitate chaining. 1693 */ 1694 @NonNull setLocalIdentification(@onNull IkeIdentification identification)1695 public Builder setLocalIdentification(@NonNull IkeIdentification identification) { 1696 if (identification == null) { 1697 throw new NullPointerException("Required argument not provided"); 1698 } 1699 1700 mLocalIdentification = identification; 1701 return this; 1702 } 1703 1704 /** 1705 * Sets remote IKE identification for the {@link IkeSessionParams} being built. 1706 * 1707 * @param identification the remote IKE identification. 1708 * @return Builder this, to facilitate chaining. 1709 */ 1710 @NonNull setRemoteIdentification(@onNull IkeIdentification identification)1711 public Builder setRemoteIdentification(@NonNull IkeIdentification identification) { 1712 if (identification == null) { 1713 throw new NullPointerException("Required argument not provided"); 1714 } 1715 1716 mRemoteIdentification = identification; 1717 return this; 1718 } 1719 1720 /** 1721 * Adds an IKE SA proposal to the {@link IkeSessionParams} being built. 1722 * 1723 * @param proposal IKE SA proposal. 1724 * @return Builder this, to facilitate chaining. 1725 * @deprecated Callers should use {@link #addIkeSaProposal(IkeSaProposal)}. This method is 1726 * deprecated because its name does not match the input type. 1727 * @hide 1728 */ 1729 @Deprecated 1730 @SystemApi 1731 @NonNull addSaProposal(@onNull IkeSaProposal proposal)1732 public Builder addSaProposal(@NonNull IkeSaProposal proposal) { 1733 return addIkeSaProposal(proposal); 1734 } 1735 1736 /** 1737 * Adds an IKE SA proposal to the {@link IkeSessionParams} being built. 1738 * 1739 * @param proposal IKE SA proposal. 1740 * @return Builder this, to facilitate chaining. 1741 */ 1742 @NonNull addIkeSaProposal(@onNull IkeSaProposal proposal)1743 public Builder addIkeSaProposal(@NonNull IkeSaProposal proposal) { 1744 if (proposal == null) { 1745 throw new NullPointerException("Required argument not provided"); 1746 } 1747 1748 if (proposal.getProtocolId() != IkePayload.PROTOCOL_ID_IKE) { 1749 throw new IllegalArgumentException( 1750 "Expected IKE SA Proposal but received Child SA proposal"); 1751 } 1752 mSaProposalList.add(proposal); 1753 return this; 1754 } 1755 1756 /** 1757 * Configures authentication for IKE Session. Internal use only. 1758 * 1759 * @hide 1760 */ 1761 @NonNull setAuth(IkeAuthConfig local, IkeAuthConfig remote)1762 private Builder setAuth(IkeAuthConfig local, IkeAuthConfig remote) { 1763 mLocalAuthConfig = local; 1764 mRemoteAuthConfig = remote; 1765 return this; 1766 } 1767 1768 /** 1769 * Configures the {@link IkeSession} to use pre-shared-key-based authentication. 1770 * 1771 * <p>Both client and server MUST be authenticated using the provided shared key. IKE 1772 * authentication will fail if the remote peer tries to use other authentication methods. 1773 * 1774 * <p>Callers MUST declare only one authentication method. Calling this function will 1775 * override the previously set authentication configuration. 1776 * 1777 * <p>Callers SHOULD NOT use this if any other authentication methods can be used; PSK-based 1778 * authentication is generally considered insecure. 1779 * 1780 * @param sharedKey the shared key. 1781 * @return Builder this, to facilitate chaining. 1782 */ 1783 // #getLocalAuthConfig and #getRemoveAuthConfig are defined to retrieve 1784 // authentication configurations 1785 @SuppressLint("MissingGetterMatchingBuilder") 1786 @NonNull setAuthPsk(@onNull byte[] sharedKey)1787 public Builder setAuthPsk(@NonNull byte[] sharedKey) { 1788 if (sharedKey == null) { 1789 throw new NullPointerException("Required argument not provided"); 1790 } 1791 1792 return setAuth(new IkeAuthPskConfig(sharedKey), new IkeAuthPskConfig(sharedKey)); 1793 } 1794 1795 /** 1796 * Configures the {@link IkeSession} to use EAP authentication. 1797 * 1798 * <p>Not all EAP methods provide mutual authentication. As such EAP MUST be used in 1799 * conjunction with a public-key-signature-based authentication of the remote server, unless 1800 * EAP-Only authentication is enabled. 1801 * 1802 * <p>Callers may enable EAP-Only authentication by setting {@link 1803 * #IKE_OPTION_EAP_ONLY_AUTH}, which will make IKE library request the remote to use 1804 * EAP-Only authentication. The remote may opt to reject the request, at which point the 1805 * received certificates and authentication payload WILL be validated with the provided root 1806 * CA or system's truststore as usual. Only safe EAP methods as listed in RFC 5998 will be 1807 * accepted for EAP-Only authentication. 1808 * 1809 * <p>If {@link #IKE_OPTION_EAP_ONLY_AUTH} is set, callers MUST configure EAP as the 1810 * authentication method and all EAP methods set in EAP Session configuration MUST be safe 1811 * methods that are accepted for EAP-Only authentication. Otherwise callers will get an 1812 * exception when building the {@link IkeSessionParams} 1813 * 1814 * <p>Callers MUST declare only one authentication method. Calling this function will 1815 * override the previously set authentication configuration. 1816 * 1817 * @see <a href="https://tools.ietf.org/html/rfc5280">RFC 5280, Internet X.509 Public Key 1818 * Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a> 1819 * @see <a href="https://tools.ietf.org/html/rfc5998">RFC 5998, An Extension for EAP-Only 1820 * Authentication in IKEv2</a> 1821 * @param serverCaCert the CA certificate for validating the received server certificate(s). 1822 * If a certificate is provided, it MUST be the root CA used by the server, or 1823 * authentication will fail. If no certificate is provided, any root CA in the system's 1824 * truststore is considered acceptable. 1825 * @return Builder this, to facilitate chaining. 1826 */ 1827 // TODO(b/151667921): Consider also supporting configuring EAP method that is not accepted 1828 // by EAP-Only when {@link #IKE_OPTION_EAP_ONLY_AUTH} is set 1829 // MissingGetterMatchingBuilder: #getLocalAuthConfig and #getRemoveAuthConfig are defined to 1830 // retrieve authentication configurations 1831 @SuppressLint("MissingGetterMatchingBuilder") 1832 @NonNull setAuthEap( @ullable X509Certificate serverCaCert, @NonNull EapSessionConfig eapConfig)1833 public Builder setAuthEap( 1834 @Nullable X509Certificate serverCaCert, @NonNull EapSessionConfig eapConfig) { 1835 if (eapConfig == null) { 1836 throw new NullPointerException("Required argument not provided"); 1837 } 1838 1839 return setAuth( 1840 new IkeAuthEapConfig(eapConfig), 1841 new IkeAuthDigitalSignRemoteConfig(serverCaCert)); 1842 } 1843 1844 /** 1845 * Configures the {@link IkeSession} to use public-key-signature-based authentication. 1846 * 1847 * <p>The public key included by the client end certificate and the private key used for 1848 * signing MUST be a matching key pair. 1849 * 1850 * <p>The IKE library will use the strongest signature algorithm supported by both sides. 1851 * 1852 * <p>Currenly only RSA digital signature is supported. 1853 * 1854 * @param serverCaCert the CA certificate for validating the received server certificate(s). 1855 * If a certificate is provided, it MUST be the root CA used by the server, or 1856 * authentication will fail. If no certificate is provided, any root CA in the system's 1857 * truststore is considered acceptable. 1858 * @param clientEndCert the end certificate for remote server to verify the locally 1859 * generated signature. 1860 * @param clientPrivateKey private key to generate outbound digital signature. The {@link 1861 * PrivateKey} MUST be an instance of {@link RSAKey}. 1862 * @return Builder this, to facilitate chaining. 1863 */ 1864 // #getLocalAuthConfig and #getRemoveAuthConfig are defined to retrieve 1865 // authentication configurations 1866 @SuppressLint("MissingGetterMatchingBuilder") 1867 @NonNull setAuthDigitalSignature( @ullable X509Certificate serverCaCert, @NonNull X509Certificate clientEndCert, @NonNull PrivateKey clientPrivateKey)1868 public Builder setAuthDigitalSignature( 1869 @Nullable X509Certificate serverCaCert, 1870 @NonNull X509Certificate clientEndCert, 1871 @NonNull PrivateKey clientPrivateKey) { 1872 return setAuthDigitalSignature( 1873 serverCaCert, 1874 clientEndCert, 1875 new LinkedList<X509Certificate>(), 1876 clientPrivateKey); 1877 } 1878 1879 /** 1880 * Configures the {@link IkeSession} to use public-key-signature-based authentication. 1881 * 1882 * <p>The public key included by the client end certificate and the private key used for 1883 * signing MUST be a matching key pair. 1884 * 1885 * <p>The IKE library will use the strongest signature algorithm supported by both sides. 1886 * 1887 * <p>Currenly only RSA digital signature is supported. 1888 * 1889 * @param serverCaCert the CA certificate for validating the received server certificate(s). 1890 * If a null value is provided, IKE library will try all default CA certificates stored 1891 * in Android system to do the validation. Otherwise, it will only use the provided CA 1892 * certificate. 1893 * @param clientEndCert the end certificate for remote server to verify locally generated 1894 * signature. 1895 * @param clientIntermediateCerts intermediate certificates for the remote server to 1896 * validate the end certificate. 1897 * @param clientPrivateKey private key to generate outbound digital signature. The {@link 1898 * PrivateKey} MUST be an instance of {@link RSAKey}. 1899 * @return Builder this, to facilitate chaining. 1900 */ 1901 // #getLocalAuthConfig and #getRemoveAuthConfig are defined to retrieve 1902 // authentication configurations 1903 @SuppressLint("MissingGetterMatchingBuilder") 1904 @NonNull setAuthDigitalSignature( @ullable X509Certificate serverCaCert, @NonNull X509Certificate clientEndCert, @NonNull List<X509Certificate> clientIntermediateCerts, @NonNull PrivateKey clientPrivateKey)1905 public Builder setAuthDigitalSignature( 1906 @Nullable X509Certificate serverCaCert, 1907 @NonNull X509Certificate clientEndCert, 1908 @NonNull List<X509Certificate> clientIntermediateCerts, 1909 @NonNull PrivateKey clientPrivateKey) { 1910 if (clientEndCert == null 1911 || clientIntermediateCerts == null 1912 || clientPrivateKey == null) { 1913 throw new NullPointerException("Required argument not provided"); 1914 } 1915 1916 if (!(clientPrivateKey instanceof RSAKey)) { 1917 throw new IllegalArgumentException("Unsupported private key type"); 1918 } 1919 1920 IkeAuthConfig localConfig = 1921 new IkeAuthDigitalSignLocalConfig( 1922 clientEndCert, clientIntermediateCerts, clientPrivateKey); 1923 IkeAuthConfig remoteConfig = new IkeAuthDigitalSignRemoteConfig(serverCaCert); 1924 1925 return setAuth(localConfig, remoteConfig); 1926 } 1927 1928 /** 1929 * Adds a configuration request. Internal use only. 1930 * 1931 * @hide 1932 */ 1933 @NonNull addConfigRequest(IkeConfigAttribute configReq)1934 private Builder addConfigRequest(IkeConfigAttribute configReq) { 1935 mConfigRequestList.add(configReq); 1936 return this; 1937 } 1938 1939 /** 1940 * Adds a specific internal P_CSCF server request to the {@link IkeSessionParams} being 1941 * built. 1942 * 1943 * @param address the requested P_CSCF address. 1944 * @return Builder this, to facilitate chaining. 1945 * @hide 1946 */ 1947 // #getConfigurationRequests is defined to retrieve PCSCF server requests 1948 @SuppressLint("MissingGetterMatchingBuilder") 1949 @SystemApi 1950 @NonNull addPcscfServerRequest(@onNull InetAddress address)1951 public Builder addPcscfServerRequest(@NonNull InetAddress address) { 1952 if (address == null) { 1953 throw new NullPointerException("Required argument not provided"); 1954 } 1955 1956 if (address instanceof Inet4Address) { 1957 return addConfigRequest(new ConfigAttributeIpv4Pcscf((Inet4Address) address)); 1958 } else if (address instanceof Inet6Address) { 1959 return addConfigRequest(new ConfigAttributeIpv6Pcscf((Inet6Address) address)); 1960 } else { 1961 throw new IllegalArgumentException("Invalid address family"); 1962 } 1963 } 1964 1965 /** 1966 * Adds a internal P_CSCF server request to the {@link IkeSessionParams} being built. 1967 * 1968 * @param addressFamily the address family. Only {@code AF_INET} and {@code AF_INET6} are 1969 * allowed. 1970 * @return Builder this, to facilitate chaining. 1971 * @hide 1972 */ 1973 // #getConfigurationRequests is defined to retrieve PCSCF server requests 1974 @SuppressLint("MissingGetterMatchingBuilder") 1975 @SystemApi 1976 @NonNull addPcscfServerRequest(int addressFamily)1977 public Builder addPcscfServerRequest(int addressFamily) { 1978 if (addressFamily == AF_INET) { 1979 return addConfigRequest(new ConfigAttributeIpv4Pcscf()); 1980 } else if (addressFamily == AF_INET6) { 1981 return addConfigRequest(new ConfigAttributeIpv6Pcscf()); 1982 } else { 1983 throw new IllegalArgumentException("Invalid address family: " + addressFamily); 1984 } 1985 } 1986 1987 /** 1988 * Sets hard and soft lifetimes. 1989 * 1990 * <p>Lifetimes will not be negotiated with the remote IKE server. 1991 * 1992 * @param hardLifetimeSeconds number of seconds after which IKE SA will expire. Defaults to 1993 * 14400 seconds (4 hours). MUST be a value from 300 seconds (5 minutes) to 86400 1994 * seconds (24 hours), inclusive. 1995 * @param softLifetimeSeconds number of seconds after which IKE SA will request rekey. 1996 * Defaults to 7200 seconds (2 hours). MUST be at least 120 seconds (2 minutes), and at 1997 * least 60 seconds (1 minute) shorter than the hard lifetime. 1998 * @return Builder this, to facilitate chaining. 1999 */ 2000 // #getHardLifetimeSeconds and #getSoftLifetimeSeconds are defined for callers to retrieve 2001 // the lifetimes 2002 @SuppressLint("MissingGetterMatchingBuilder") 2003 @NonNull setLifetimeSeconds( @ntRangefrom = IKE_HARD_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) int hardLifetimeSeconds, @IntRange(from = IKE_SOFT_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) int softLifetimeSeconds)2004 public Builder setLifetimeSeconds( 2005 @IntRange(from = IKE_HARD_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) 2006 int hardLifetimeSeconds, 2007 @IntRange(from = IKE_SOFT_LIFETIME_SEC_MINIMUM, to = IKE_HARD_LIFETIME_SEC_MAXIMUM) 2008 int softLifetimeSeconds) { 2009 if (hardLifetimeSeconds < IKE_HARD_LIFETIME_SEC_MINIMUM 2010 || hardLifetimeSeconds > IKE_HARD_LIFETIME_SEC_MAXIMUM 2011 || softLifetimeSeconds < IKE_SOFT_LIFETIME_SEC_MINIMUM 2012 || hardLifetimeSeconds - softLifetimeSeconds 2013 < IKE_LIFETIME_MARGIN_SEC_MINIMUM) { 2014 throw new IllegalArgumentException("Invalid lifetime value"); 2015 } 2016 2017 mHardLifetimeSec = hardLifetimeSeconds; 2018 mSoftLifetimeSec = softLifetimeSeconds; 2019 return this; 2020 } 2021 2022 /** 2023 * Sets the Dead Peer Detection(DPD) delay in seconds. 2024 * 2025 * @param dpdDelaySeconds number of seconds after which IKE SA will initiate DPD if no 2026 * inbound cryptographically protected IKE message was received. Defaults to 120 2027 * seconds. MUST be a value greater than or equal to than 20 seconds. Setting the value 2028 * to {@link IkeSessionParams#IKE_DPD_DELAY_SEC_DISABLED} will disable DPD. 2029 * @return Builder this, to facilitate chaining. 2030 */ 2031 @NonNull setDpdDelaySeconds( @ntRangefrom = IKE_DPD_DELAY_SEC_MIN) int dpdDelaySeconds)2032 public Builder setDpdDelaySeconds( 2033 @IntRange(from = IKE_DPD_DELAY_SEC_MIN) int dpdDelaySeconds) { 2034 if (dpdDelaySeconds < IKE_DPD_DELAY_SEC_MIN) { 2035 throw new IllegalArgumentException("Invalid DPD delay value"); 2036 } 2037 mDpdDelaySec = dpdDelaySeconds; 2038 return this; 2039 } 2040 2041 /** 2042 * Sets the Network Address Translation Traversal (NATT) keepalive delay in seconds. 2043 * 2044 * @param nattKeepaliveDelaySeconds number of seconds between keepalive packet 2045 * transmissions. Defaults to 10 seconds. MUST be a value from 10 seconds to 3600 2046 * seconds, inclusive. 2047 * @return Builder this, to facilitate chaining. 2048 */ 2049 @NonNull setNattKeepAliveDelaySeconds( @ntRange from = IKE_NATT_KEEPALIVE_DELAY_SEC_MIN, to = IKE_NATT_KEEPALIVE_DELAY_SEC_MAX) int nattKeepaliveDelaySeconds)2050 public Builder setNattKeepAliveDelaySeconds( 2051 @IntRange( 2052 from = IKE_NATT_KEEPALIVE_DELAY_SEC_MIN, 2053 to = IKE_NATT_KEEPALIVE_DELAY_SEC_MAX) 2054 int nattKeepaliveDelaySeconds) { 2055 if (nattKeepaliveDelaySeconds < IKE_NATT_KEEPALIVE_DELAY_SEC_MIN 2056 || nattKeepaliveDelaySeconds > IKE_NATT_KEEPALIVE_DELAY_SEC_MAX) { 2057 throw new IllegalArgumentException("Invalid NATT keepalive delay value"); 2058 } 2059 mNattKeepaliveDelaySec = nattKeepaliveDelaySeconds; 2060 return this; 2061 } 2062 2063 /** 2064 * Sets the DSCP field of the IKE packets. 2065 * 2066 * <p>Differentiated services code point (DSCP) is a 6-bit field in the IP header that is 2067 * used for packet classification and prioritization. The DSCP field is encoded in the 6 2068 * higher order bits of the Type of Service (ToS) in IPv4 header, or the traffic class (TC) 2069 * field in IPv6 header. 2070 * 2071 * <p>Any 6-bit values (0 to 63) are acceptable, whether IANA-defined, or 2072 * implementation-specific values. 2073 * 2074 * @see <a href="https://tools.ietf.org/html/rfc2474">RFC 2474, Definition of the 2075 * Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers</a> 2076 * @see <a href="https://www.iana.org/assignments/dscp-registry/dscp-registry.xhtml"> 2077 * Differentiated Services Field Codepoints (DSCP)</a> 2078 * @param dscp the dscp value. Defaults to 0. 2079 * @return Builder this, to facilitate chaining. 2080 * @hide 2081 */ 2082 @SystemApi 2083 @NonNull setDscp(@ntRangefrom = DSCP_MIN, to = DSCP_MAX) int dscp)2084 public Builder setDscp(@IntRange(from = DSCP_MIN, to = DSCP_MAX) int dscp) { 2085 if (dscp < DSCP_MIN || dscp > DSCP_MAX) { 2086 throw new IllegalArgumentException("Invalid DSCP value"); 2087 } 2088 mDscp = dscp; 2089 return this; 2090 } 2091 2092 /** 2093 * Sets the IP version to use for ESP packets. 2094 * 2095 * @param ipVersion the IP version to use. 2096 * @return the {@code Builder} to facilitate chaining. 2097 * @hide 2098 */ 2099 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 2100 @NonNull setIpVersion(@spIpVersion int ipVersion)2101 public Builder setIpVersion(@EspIpVersion int ipVersion) { 2102 if (ESP_IP_VERSION_AUTO != ipVersion 2103 && ESP_IP_VERSION_IPV4 != ipVersion 2104 && ESP_IP_VERSION_IPV6 != ipVersion) { 2105 throw new IllegalArgumentException("Invalid IP version : " + ipVersion); 2106 } 2107 mIpVersion = ipVersion; 2108 return this; 2109 } 2110 2111 /** 2112 * Sets the encapsulation type to use for ESP packets. 2113 * 2114 * @param encapType the IP version to use. 2115 * @return the {@code Builder} to facilitate chaining. 2116 * @hide 2117 */ 2118 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 2119 @NonNull setEncapType(@spEncapType int encapType)2120 public Builder setEncapType(@EspEncapType int encapType) { 2121 if (ESP_ENCAP_TYPE_AUTO != encapType 2122 && ESP_ENCAP_TYPE_NONE != encapType 2123 && ESP_ENCAP_TYPE_UDP != encapType) { 2124 throw new IllegalArgumentException("Invalid encap type : " + encapType); 2125 } 2126 mEncapType = encapType; 2127 return this; 2128 } 2129 2130 /** 2131 * Sets the retransmission timeout list in milliseconds. 2132 * 2133 * <p>Configures the retransmission by providing an array of relative retransmission 2134 * timeouts in milliseconds. After sending out a request and before receiving the response, 2135 * the IKE Session will iterate through the array and wait for the relative timeout before 2136 * the next retry. If the last timeout is exceeded, the IKE Session will be terminated. 2137 * 2138 * <p>Each element in the array MUST be a value from 500 ms to 1800000 ms (30 minutes). The 2139 * length of the array MUST NOT exceed 10. This retransmission timeout list defaults to 2140 * {0.5s, 1s, 2s, 4s, 8s} 2141 * 2142 * @param retransTimeoutMillisList the array of relative retransmission timeout in 2143 * milliseconds. 2144 * @return Builder this, to facilitate chaining. 2145 */ 2146 @NonNull setRetransmissionTimeoutsMillis(@onNull int[] retransTimeoutMillisList)2147 public Builder setRetransmissionTimeoutsMillis(@NonNull int[] retransTimeoutMillisList) { 2148 boolean isValid = true; 2149 if (retransTimeoutMillisList == null 2150 || retransTimeoutMillisList.length == 0 2151 || retransTimeoutMillisList.length > IKE_RETRANS_MAX_ATTEMPTS_MAX) { 2152 isValid = false; 2153 } 2154 for (int t : retransTimeoutMillisList) { 2155 if (t < IKE_RETRANS_TIMEOUT_MS_MIN || t > IKE_RETRANS_TIMEOUT_MS_MAX) { 2156 isValid = false; 2157 } 2158 } 2159 if (!isValid) throw new IllegalArgumentException("Invalid retransmission timeout list"); 2160 2161 mRetransTimeoutMsList = retransTimeoutMillisList; 2162 return this; 2163 } 2164 2165 /** 2166 * Sets a list of retransmission timeouts in milliseconds for performing on-demand liveness 2167 * checks. 2168 * 2169 * <p>Provides the user the ability to set an array of relative retransmission timeouts for 2170 * on-demand liveness checks in milliseconds. After sending out a request and before 2171 * receiving the response, the IKE Session will iterate through the array and wait for the 2172 * relative timeout before the next retry. If the last timeout is exceeded, the IKE Session 2173 * will be terminated. 2174 * 2175 * <p>Each element in the array MUST be a value from 500 ms to 30000 ms. The length of the 2176 * array MUST NOT exceed 10. The total retransmission timeouts MUST NOT exceed 30000 ms. 2177 * This retransmission timeout list defaults to {0.5s, 1s, 2s, 4s, 8s}. 2178 * 2179 * @param retransTimeoutMillisList the array of relative retransmission timeout in 2180 * milliseconds for checking peer's liveness. 2181 * @return Builder this, to facilitate chaining. 2182 * @hide 2183 */ 2184 @SystemApi 2185 @FlaggedApi("com.android.ipsec.flags.liveness_check_api") 2186 @NonNull setLivenessRetransmissionTimeoutsMillis( @onNull int[] retransTimeoutMillisList)2187 public Builder setLivenessRetransmissionTimeoutsMillis( 2188 @NonNull int[] retransTimeoutMillisList) { 2189 boolean isValid = true; 2190 int totalTimeoutMs = 0; 2191 if (retransTimeoutMillisList == null 2192 || retransTimeoutMillisList.length == 0 2193 || retransTimeoutMillisList.length > LIVENESS_RETRANS_MAX_ATTEMPTS_MAX) { 2194 isValid = false; 2195 } 2196 for (int t : retransTimeoutMillisList) { 2197 totalTimeoutMs += t; 2198 if (t < LIVENESS_RETRANS_TIMEOUT_MS_MIN || t > LIVENESS_RETRANS_TIMEOUT_MS_MAX) { 2199 isValid = false; 2200 } 2201 } 2202 if (totalTimeoutMs > LIVENESS_RETRANS_TIMEOUT_MS_TOTAL) { 2203 isValid = false; 2204 } 2205 2206 if (!isValid) { 2207 throw new IllegalArgumentException("Invalid liveness retransmission timeout list."); 2208 } 2209 mLivenessRetransTimeoutMsList = retransTimeoutMillisList; 2210 return this; 2211 } 2212 2213 /** 2214 * Sets the parameters to be used for 3GPP-specific behavior during the IKE Session. 2215 * 2216 * <p>Setting the Ike3gppExtension also enables support for non-configurable payloads, such 2217 * as the Notify - BACKOFF_TIMER payload. 2218 * 2219 * @see 3GPP ETSI TS 24.302: Access to the 3GPP Evolved Packet Core (EPC) via non-3GPP 2220 * access networks 2221 * @param ike3gppExtension the Ike3gppExtension to use for this IKE Session. 2222 * @return Builder this, to facilitate chaining. 2223 * @hide 2224 */ 2225 @SystemApi 2226 @NonNull setIke3gppExtension(@onNull Ike3gppExtension ike3gppExtension)2227 public Builder setIke3gppExtension(@NonNull Ike3gppExtension ike3gppExtension) { 2228 Objects.requireNonNull(ike3gppExtension, "ike3gppExtension must not be null"); 2229 2230 mIke3gppExtension = ike3gppExtension; 2231 return this; 2232 } 2233 2234 /** 2235 * Sets the specified IKE Option as enabled. 2236 * 2237 * @param ikeOption the option to be enabled. 2238 * @return Builder this, to facilitate chaining. 2239 * @throws IllegalArgumentException if the provided option is invalid. 2240 */ 2241 @NonNull addIkeOption(@keOption int ikeOption)2242 public Builder addIkeOption(@IkeOption int ikeOption) { 2243 return addIkeOptionInternal(ikeOption); 2244 } 2245 2246 /** @hide */ 2247 @NonNull addIkeOptionInternal(@keOption int ikeOption)2248 public Builder addIkeOptionInternal(@IkeOption int ikeOption) { 2249 validateIkeOptionOrThrow(ikeOption); 2250 if (ikeOption == IKE_OPTION_MOBIKE || ikeOption == IKE_OPTION_REKEY_MOBILITY) { 2251 if (!SdkLevel.isAtLeastS()) { 2252 throw new UnsupportedOperationException("Mobility only supported for S/S+"); 2253 } else if (!SdkLevel.isAtLeastT() && ikeOption == IKE_OPTION_MOBIKE) { 2254 // Automatically enable IKE_OPTION_REKEY_MOBILITY if S <= SDK < T for 2255 // compatibility 2256 mIkeOptions |= getOptionBitValue(IKE_OPTION_REKEY_MOBILITY); 2257 } 2258 } 2259 2260 mIkeOptions |= getOptionBitValue(ikeOption); 2261 return this; 2262 } 2263 2264 /** 2265 * Resets (disables) the specified IKE Option. 2266 * 2267 * @param ikeOption the option to be disabled. 2268 * @return Builder this, to facilitate chaining. 2269 * @throws IllegalArgumentException if the provided option is invalid. 2270 */ 2271 // Use #removeIkeOption instead of #clearIkeOption because "clear" sounds indicating 2272 // clearing all enabled IKE options 2273 @SuppressLint("BuilderSetStyle") 2274 @NonNull removeIkeOption(@keOption int ikeOption)2275 public Builder removeIkeOption(@IkeOption int ikeOption) { 2276 validateIkeOptionOrThrow(ikeOption); 2277 mIkeOptions &= ~getOptionBitValue(ikeOption); 2278 return this; 2279 } 2280 2281 /** 2282 * Validates and builds the {@link IkeSessionParams}. 2283 * 2284 * @return IkeSessionParams the validated IkeSessionParams. 2285 */ 2286 @NonNull build()2287 public IkeSessionParams build() { 2288 if (mSaProposalList.isEmpty()) { 2289 throw new IllegalArgumentException("IKE SA proposal not found"); 2290 } 2291 2292 // TODO: b/178389011 This code block should be removed when 2293 // IkeSessionParams#getNetwork() and #Builder(Context) can be safely removed. This block 2294 // makes sure if the Builder is constructed with the deprecated constructor 2295 // #Builder(Context), #build() still works in the same way and will throw exception when 2296 // there is no configured or default network. 2297 Network defaultOrConfiguredNetwork = mCallerConfiguredNetwork; 2298 if (mConnectivityManager != null && defaultOrConfiguredNetwork == null) { 2299 defaultOrConfiguredNetwork = mConnectivityManager.getActiveNetwork(); 2300 if (defaultOrConfiguredNetwork == null) { 2301 throw new IllegalArgumentException("Network not found"); 2302 } 2303 } 2304 2305 if (mServerHostname == null 2306 || mLocalIdentification == null 2307 || mRemoteIdentification == null 2308 || mLocalAuthConfig == null 2309 || mRemoteAuthConfig == null) { 2310 throw new IllegalArgumentException("Necessary parameter missing."); 2311 } 2312 2313 if ((mIkeOptions & getOptionBitValue(IKE_OPTION_EAP_ONLY_AUTH)) != 0) { 2314 if (!(mLocalAuthConfig instanceof IkeAuthEapConfig)) { 2315 throw new IllegalArgumentException( 2316 "If IKE_OPTION_EAP_ONLY_AUTH is set," 2317 + " eap authentication needs to be configured."); 2318 } 2319 2320 IkeAuthEapConfig ikeAuthEapConfig = (IkeAuthEapConfig) mLocalAuthConfig; 2321 if (!ikeAuthEapConfig.getEapConfig().areAllMethodsEapOnlySafe()) { 2322 throw new IllegalArgumentException( 2323 "Only EAP-only safe method allowed" + " when using EAP-only option."); 2324 } 2325 } 2326 2327 // as of today, the device_identity feature is only implemented for EAP-AKA 2328 if ((mIke3gppExtension != null 2329 && mIke3gppExtension.getIke3gppParams().getMobileDeviceIdentity() != null)) { 2330 if (!(mLocalAuthConfig instanceof IkeAuthEapConfig) 2331 || ((IkeAuthEapConfig) mLocalAuthConfig).getEapConfig().getEapAkaConfig() 2332 == null) { 2333 throw new IllegalArgumentException( 2334 "If device identity is set in Ike3gppParams, then EAP-KA MUST be" 2335 + " configured as an acceptable authentication method"); 2336 } 2337 } 2338 2339 if (mLocalAuthConfig.mAuthMethod == IKE_AUTH_METHOD_PUB_KEY_SIGNATURE 2340 && mLocalIdentification.idType == IkeIdentification.ID_TYPE_KEY_ID) { 2341 throw new IllegalArgumentException( 2342 "It is not allowed to use KEY_ID as local ID when local authentication" 2343 + " method is digital-signature-based"); 2344 } 2345 2346 if ((mIpVersion == ESP_IP_VERSION_IPV4 && mEncapType == ESP_ENCAP_TYPE_NONE) 2347 || (mIpVersion == ESP_IP_VERSION_IPV6 && mEncapType == ESP_ENCAP_TYPE_UDP)) { 2348 throw new UnsupportedOperationException("Sending packets with IPv4 ESP or IPv6 UDP" 2349 + " are not supported"); 2350 } 2351 2352 return new IkeSessionParams( 2353 mServerHostname, 2354 defaultOrConfiguredNetwork, 2355 mCallerConfiguredNetwork, 2356 mSaProposalList.toArray(new IkeSaProposal[0]), 2357 mLocalIdentification, 2358 mRemoteIdentification, 2359 mLocalAuthConfig, 2360 mRemoteAuthConfig, 2361 mConfigRequestList.toArray(new IkeConfigAttribute[0]), 2362 mRetransTimeoutMsList, 2363 mLivenessRetransTimeoutMsList, 2364 mIke3gppExtension, 2365 mIkeOptions, 2366 mHardLifetimeSec, 2367 mSoftLifetimeSec, 2368 mDpdDelaySec, 2369 mNattKeepaliveDelaySec, 2370 mDscp, 2371 mIpVersion, 2372 mEncapType, 2373 mIsIkeFragmentationSupported); 2374 } 2375 2376 // TODO: add methods for supporting IKE fragmentation. 2377 } 2378 2379 /** 2380 * Dumps the state of {@link IkeSessionParams} 2381 * 2382 * @param pw {@link PrintWriter} to write the state of the object. 2383 * @param prefix prefix for indentation 2384 * @hide 2385 */ dump(PrintWriter pw, String prefix)2386 public void dump(PrintWriter pw, String prefix) { 2387 // Please make sure that the dump is thread-safe 2388 // so the client won't get a crash or exception when adding codes to the dump. 2389 2390 pw.println("------------------------------"); 2391 pw.println("IkeSessionParams:"); 2392 pw.println(prefix + "Caller configured network: " + mCallerConfiguredNetwork); 2393 pw.println(prefix + "Dpd Delay timer in secs: " + mDpdDelaySec); 2394 pw.println(prefix + "Dscp: " + mDscp); 2395 pw.println(prefix + "Esp ip version: " + IP_VERSION_TO_STR.get(mIpVersion)); 2396 pw.println(prefix + "Esp encap type: " + ENCAP_TYPE_TO_STR.get(mEncapType)); 2397 pw.println(prefix + "Force port4500 status: " + hasIkeOption(IKE_OPTION_FORCE_PORT_4500)); 2398 pw.println(prefix + "Hard life time in secs: " + mHardLifetimeSec); 2399 pw.println( 2400 prefix 2401 + "Liveness retransmission timer in millis : " 2402 + Arrays.toString(mLivenessRetransTimeoutMsList)); 2403 pw.println(prefix + "Nat keep alive delay in secs: " + mNattKeepaliveDelaySec); 2404 pw.println(prefix + "Soft life time in secs: " + mSoftLifetimeSec); 2405 pw.println(prefix + "Remote host name: " + mServerHostname); 2406 pw.println( 2407 prefix 2408 + "Retransmission timer in millis : " 2409 + Arrays.toString(mRetransTimeoutMsList)); 2410 for (IkeSaProposal saProposal : getIkeSaProposals()) { 2411 pw.println(); 2412 pw.println(prefix + "IkeSaProposal:"); 2413 pw.println( 2414 prefix 2415 + "Encryption algorithm: " 2416 + saProposal.getEncryptionAlgorithms().toString()); 2417 pw.println( 2418 prefix 2419 + "Integrity algorithm: " 2420 + saProposal.getIntegrityAlgorithms().toString()); 2421 pw.println(prefix + "Dh Group algorithm: " + saProposal.getDhGroups().toString()); 2422 pw.println( 2423 prefix + "Prf algorithm: " + saProposal.getPseudorandomFunctions().toString()); 2424 } 2425 pw.println("------------------------------"); 2426 pw.println(); 2427 } 2428 } 2429