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