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