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