/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.net;

import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_PSK;
import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_RSA;
import static android.net.PlatformVpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;

import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.util.Preconditions.checkStringNotEmpty;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Process;
import android.security.Credentials;
import android.security.KeyStore;
import android.security.keystore.AndroidKeyStoreProvider;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.VpnProfile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * The Ikev2VpnProfile is a configuration for the platform setup of IKEv2/IPsec VPNs.
 *
 * <p>Together with VpnManager, this allows apps to provision IKEv2/IPsec VPNs that do not require
 * the VPN app to constantly run in the background.
 *
 * @see VpnManager
 * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296 - Internet Key
 *     Exchange, Version 2 (IKEv2)</a>
 */
public final class Ikev2VpnProfile extends PlatformVpnProfile {
    /** Prefix for when a Private Key is an alias to look for in KeyStore @hide */
    public static final String PREFIX_KEYSTORE_ALIAS = "KEYSTORE_ALIAS:";
    /** Prefix for when a Private Key is stored directly in the profile @hide */
    public static final String PREFIX_INLINE = "INLINE:";

    private static final String MISSING_PARAM_MSG_TMPL = "Required parameter was not provided: %s";
    private static final String EMPTY_CERT = "";

    /** @hide */
    public static final List<String> DEFAULT_ALGORITHMS =
            Collections.unmodifiableList(Arrays.asList(
                    IpSecAlgorithm.CRYPT_AES_CBC,
                    IpSecAlgorithm.AUTH_HMAC_SHA256,
                    IpSecAlgorithm.AUTH_HMAC_SHA384,
                    IpSecAlgorithm.AUTH_HMAC_SHA512,
                    IpSecAlgorithm.AUTH_CRYPT_AES_GCM));

    @NonNull private final String mServerAddr;
    @NonNull private final String mUserIdentity;

    // PSK authentication
    @Nullable private final byte[] mPresharedKey;

    // Username/Password, RSA authentication
    @Nullable private final X509Certificate mServerRootCaCert;

    // Username/Password authentication
    @Nullable private final String mUsername;
    @Nullable private final String mPassword;

    // RSA Certificate authentication
    @Nullable private final PrivateKey mRsaPrivateKey;
    @Nullable private final X509Certificate mUserCert;

    @Nullable private final ProxyInfo mProxyInfo;
    @NonNull private final List<String> mAllowedAlgorithms;
    private final boolean mIsBypassable; // Defaults in builder
    private final boolean mIsMetered; // Defaults in builder
    private final int mMaxMtu; // Defaults in builder

    private Ikev2VpnProfile(
            int type,
            @NonNull String serverAddr,
            @NonNull String userIdentity,
            @Nullable byte[] presharedKey,
            @Nullable X509Certificate serverRootCaCert,
            @Nullable String username,
            @Nullable String password,
            @Nullable PrivateKey rsaPrivateKey,
            @Nullable X509Certificate userCert,
            @Nullable ProxyInfo proxyInfo,
            @NonNull List<String> allowedAlgorithms,
            boolean isBypassable,
            boolean isMetered,
            int maxMtu) {
        super(type);

        checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "Server address");
        checkNotNull(userIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");
        checkNotNull(allowedAlgorithms, MISSING_PARAM_MSG_TMPL, "Allowed Algorithms");

        mServerAddr = serverAddr;
        mUserIdentity = userIdentity;
        mPresharedKey =
                presharedKey == null ? null : Arrays.copyOf(presharedKey, presharedKey.length);
        mServerRootCaCert = serverRootCaCert;
        mUsername = username;
        mPassword = password;
        mRsaPrivateKey = rsaPrivateKey;
        mUserCert = userCert;
        mProxyInfo = new ProxyInfo(proxyInfo);

        // UnmodifiableList doesn't make a defensive copy by default.
        mAllowedAlgorithms = Collections.unmodifiableList(new ArrayList<>(allowedAlgorithms));

        mIsBypassable = isBypassable;
        mIsMetered = isMetered;
        mMaxMtu = maxMtu;

        validate();
    }

    private void validate() {
        // Server Address not validated except to check an address was provided. This allows for
        // dual-stack servers and hostname based addresses.
        checkStringNotEmpty(mServerAddr, MISSING_PARAM_MSG_TMPL, "Server Address");
        checkStringNotEmpty(mUserIdentity, MISSING_PARAM_MSG_TMPL, "User Identity");

        // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6
        // networks, the VPN must provide a link fulfilling the stricter of the two conditions
        // (at least that of the IPv6 MTU).
        if (mMaxMtu < LinkProperties.MIN_MTU_V6) {
            throw new IllegalArgumentException(
                    "Max MTU must be at least" + LinkProperties.MIN_MTU_V6);
        }

        switch (mType) {
            case TYPE_IKEV2_IPSEC_USER_PASS:
                checkNotNull(mUsername, MISSING_PARAM_MSG_TMPL, "Username");
                checkNotNull(mPassword, MISSING_PARAM_MSG_TMPL, "Password");

                if (mServerRootCaCert != null) checkCert(mServerRootCaCert);

                break;
            case TYPE_IKEV2_IPSEC_PSK:
                checkNotNull(mPresharedKey, MISSING_PARAM_MSG_TMPL, "Preshared Key");
                break;
            case TYPE_IKEV2_IPSEC_RSA:
                checkNotNull(mUserCert, MISSING_PARAM_MSG_TMPL, "User cert");
                checkNotNull(mRsaPrivateKey, MISSING_PARAM_MSG_TMPL, "RSA Private key");

                checkCert(mUserCert);
                if (mServerRootCaCert != null) checkCert(mServerRootCaCert);

                break;
            default:
                throw new IllegalArgumentException("Invalid auth method set");
        }

        validateAllowedAlgorithms(mAllowedAlgorithms);
    }

    /**
     * Validates that the allowed algorithms are a valid set for IPsec purposes
     *
     * <p>In order for the algorithm list to be a valid set, it must contain at least one algorithm
     * that provides Authentication, and one that provides Encryption. Authenticated Encryption with
     * Associated Data (AEAD) algorithms are counted as providing Authentication and Encryption.
     *
     * @param allowedAlgorithms The list to be validated
     */
    private static void validateAllowedAlgorithms(@NonNull List<String> algorithmNames) {
        VpnProfile.validateAllowedAlgorithms(algorithmNames);

        // First, make sure no insecure algorithms were proposed.
        if (algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_MD5)
                || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA1)) {
            throw new IllegalArgumentException("Algorithm not supported for IKEv2 VPN profiles");
        }

        // Validate that some valid combination (AEAD or AUTH + CRYPT) is present
        if (hasAeadAlgorithms(algorithmNames) || hasNormalModeAlgorithms(algorithmNames)) {
            return;
        }

        throw new IllegalArgumentException("Algorithm set missing support for Auth, Crypt or both");
    }

    /**
     * Checks if the provided list has AEAD algorithms
     *
     * @hide
     */
    public static boolean hasAeadAlgorithms(@NonNull List<String> algorithmNames) {
        return algorithmNames.contains(IpSecAlgorithm.AUTH_CRYPT_AES_GCM);
    }

    /**
     * Checks the provided list has acceptable (non-AEAD) authentication and encryption algorithms
     *
     * @hide
     */
    public static boolean hasNormalModeAlgorithms(@NonNull List<String> algorithmNames) {
        final boolean hasCrypt = algorithmNames.contains(IpSecAlgorithm.CRYPT_AES_CBC);
        final boolean hasAuth = algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA256)
                || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA384)
                || algorithmNames.contains(IpSecAlgorithm.AUTH_HMAC_SHA512);

        return hasCrypt && hasAuth;
    }

    /** Retrieves the server address string. */
    @NonNull
    public String getServerAddr() {
        return mServerAddr;
    }

    /** Retrieves the user identity. */
    @NonNull
    public String getUserIdentity() {
        return mUserIdentity;
    }

    /**
     * Retrieves the pre-shared key.
     *
     * <p>May be null if the profile is not using Pre-shared key authentication.
     */
    @Nullable
    public byte[] getPresharedKey() {
        return mPresharedKey == null ? null : Arrays.copyOf(mPresharedKey, mPresharedKey.length);
    }

    /**
     * Retrieves the certificate for the server's root CA.
     *
     * <p>May be null if the profile is not using RSA Digital Signature Authentication or
     * Username/Password authentication
     */
    @Nullable
    public X509Certificate getServerRootCaCert() {
        return mServerRootCaCert;
    }

    /**
     * Retrieves the username.
     *
     * <p>May be null if the profile is not using Username/Password authentication
     */
    @Nullable
    public String getUsername() {
        return mUsername;
    }

    /**
     * Retrieves the password.
     *
     * <p>May be null if the profile is not using Username/Password authentication
     */
    @Nullable
    public String getPassword() {
        return mPassword;
    }

    /**
     * Retrieves the RSA private key.
     *
     * <p>May be null if the profile is not using RSA Digital Signature authentication
     */
    @Nullable
    public PrivateKey getRsaPrivateKey() {
        return mRsaPrivateKey;
    }

    /** Retrieves the user certificate, if any was set. */
    @Nullable
    public X509Certificate getUserCert() {
        return mUserCert;
    }

    /** Retrieves the proxy information if any was set */
    @Nullable
    public ProxyInfo getProxyInfo() {
        return mProxyInfo;
    }

    /** Returns all the algorithms allowed by this VPN profile. */
    @NonNull
    public List<String> getAllowedAlgorithms() {
        return mAllowedAlgorithms;
    }

    /** Returns whether or not the VPN profile should be bypassable. */
    public boolean isBypassable() {
        return mIsBypassable;
    }

    /** Returns whether or not the VPN profile should be always considered metered. */
    public boolean isMetered() {
        return mIsMetered;
    }

    /** Retrieves the maximum MTU set for this VPN profile. */
    public int getMaxMtu() {
        return mMaxMtu;
    }

    @Override
    public int hashCode() {
        return Objects.hash(
                mType,
                mServerAddr,
                mUserIdentity,
                Arrays.hashCode(mPresharedKey),
                mServerRootCaCert,
                mUsername,
                mPassword,
                mRsaPrivateKey,
                mUserCert,
                mProxyInfo,
                mAllowedAlgorithms,
                mIsBypassable,
                mIsMetered,
                mMaxMtu);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Ikev2VpnProfile)) {
            return false;
        }

        final Ikev2VpnProfile other = (Ikev2VpnProfile) obj;
        return mType == other.mType
                && Objects.equals(mServerAddr, other.mServerAddr)
                && Objects.equals(mUserIdentity, other.mUserIdentity)
                && Arrays.equals(mPresharedKey, other.mPresharedKey)
                && Objects.equals(mServerRootCaCert, other.mServerRootCaCert)
                && Objects.equals(mUsername, other.mUsername)
                && Objects.equals(mPassword, other.mPassword)
                && Objects.equals(mRsaPrivateKey, other.mRsaPrivateKey)
                && Objects.equals(mUserCert, other.mUserCert)
                && Objects.equals(mProxyInfo, other.mProxyInfo)
                && Objects.equals(mAllowedAlgorithms, other.mAllowedAlgorithms)
                && mIsBypassable == other.mIsBypassable
                && mIsMetered == other.mIsMetered
                && mMaxMtu == other.mMaxMtu;
    }

    /**
     * Builds a VpnProfile instance for internal use, based on the stored IKEv2/IPsec parameters.
     *
     * <p>Redundant authentication information (from previous calls to other setAuth* methods) will
     * be discarded.
     *
     * @hide
     */
    @NonNull
    public VpnProfile toVpnProfile() throws IOException, GeneralSecurityException {
        final VpnProfile profile = new VpnProfile("" /* Key; value unused by IKEv2VpnProfile(s) */);
        profile.type = mType;
        profile.server = mServerAddr;
        profile.ipsecIdentifier = mUserIdentity;
        profile.proxy = mProxyInfo;
        profile.setAllowedAlgorithms(mAllowedAlgorithms);
        profile.isBypassable = mIsBypassable;
        profile.isMetered = mIsMetered;
        profile.maxMtu = mMaxMtu;
        profile.areAuthParamsInline = true;
        profile.saveLogin = true;

        switch (mType) {
            case TYPE_IKEV2_IPSEC_USER_PASS:
                profile.username = mUsername;
                profile.password = mPassword;
                profile.ipsecCaCert =
                        mServerRootCaCert == null ? "" : certificateToPemString(mServerRootCaCert);
                break;
            case TYPE_IKEV2_IPSEC_PSK:
                profile.ipsecSecret = encodeForIpsecSecret(mPresharedKey);
                break;
            case TYPE_IKEV2_IPSEC_RSA:
                profile.ipsecUserCert = certificateToPemString(mUserCert);
                profile.ipsecSecret =
                        PREFIX_INLINE + encodeForIpsecSecret(mRsaPrivateKey.getEncoded());
                profile.ipsecCaCert =
                        mServerRootCaCert == null ? "" : certificateToPemString(mServerRootCaCert);
                break;
            default:
                throw new IllegalArgumentException("Invalid auth method set");
        }

        return profile;
    }

    /**
     * Constructs a Ikev2VpnProfile from an internal-use VpnProfile instance.
     *
     * <p>Redundant authentication information (not related to profile type) will be discarded.
     *
     * @hide
     */
    @NonNull
    public static Ikev2VpnProfile fromVpnProfile(@NonNull VpnProfile profile)
            throws IOException, GeneralSecurityException {
        return fromVpnProfile(profile, null);
    }

    /**
     * Builds the Ikev2VpnProfile from the given profile.
     *
     * @param profile the source VpnProfile to build from
     * @param keyStore the Android Keystore instance to use to retrieve the private key, or null if
     *     the private key is PEM-encoded into the profile.
     * @return The IKEv2/IPsec VPN profile
     * @hide
     */
    @NonNull
    public static Ikev2VpnProfile fromVpnProfile(
            @NonNull VpnProfile profile, @Nullable KeyStore keyStore)
            throws IOException, GeneralSecurityException {
        final Builder builder = new Builder(profile.server, profile.ipsecIdentifier);
        builder.setProxy(profile.proxy);
        builder.setAllowedAlgorithms(profile.getAllowedAlgorithms());
        builder.setBypassable(profile.isBypassable);
        builder.setMetered(profile.isMetered);
        builder.setMaxMtu(profile.maxMtu);

        switch (profile.type) {
            case TYPE_IKEV2_IPSEC_USER_PASS:
                builder.setAuthUsernamePassword(
                        profile.username,
                        profile.password,
                        certificateFromPemString(profile.ipsecCaCert));
                break;
            case TYPE_IKEV2_IPSEC_PSK:
                builder.setAuthPsk(decodeFromIpsecSecret(profile.ipsecSecret));
                break;
            case TYPE_IKEV2_IPSEC_RSA:
                final PrivateKey key;
                if (profile.ipsecSecret.startsWith(PREFIX_KEYSTORE_ALIAS)) {
                    Objects.requireNonNull(keyStore, "Missing Keystore for aliased PrivateKey");

                    final String alias =
                            profile.ipsecSecret.substring(PREFIX_KEYSTORE_ALIAS.length());
                    key = AndroidKeyStoreProvider.loadAndroidKeyStorePrivateKeyFromKeystore(
                            keyStore, alias, Process.myUid());
                } else if (profile.ipsecSecret.startsWith(PREFIX_INLINE)) {
                    key = getPrivateKey(profile.ipsecSecret.substring(PREFIX_INLINE.length()));
                } else {
                    throw new IllegalArgumentException("Invalid RSA private key prefix");
                }

                final X509Certificate userCert = certificateFromPemString(profile.ipsecUserCert);
                final X509Certificate serverRootCa = certificateFromPemString(profile.ipsecCaCert);
                builder.setAuthDigitalSignature(userCert, key, serverRootCa);
                break;
            default:
                throw new IllegalArgumentException("Invalid auth method set");
        }

        return builder.build();
    }

    /**
     * Validates that the VpnProfile is acceptable for the purposes of an Ikev2VpnProfile.
     *
     * @hide
     */
    public static boolean isValidVpnProfile(@NonNull VpnProfile profile) {
        if (profile.server.isEmpty() || profile.ipsecIdentifier.isEmpty()) {
            return false;
        }

        switch (profile.type) {
            case TYPE_IKEV2_IPSEC_USER_PASS:
                if (profile.username.isEmpty() || profile.password.isEmpty()) {
                    return false;
                }
                break;
            case TYPE_IKEV2_IPSEC_PSK:
                if (profile.ipsecSecret.isEmpty()) {
                    return false;
                }
                break;
            case TYPE_IKEV2_IPSEC_RSA:
                if (profile.ipsecSecret.isEmpty() || profile.ipsecUserCert.isEmpty()) {
                    return false;
                }
                break;
            default:
                return false;
        }

        return true;
    }

    /**
     * Converts a X509 Certificate to a PEM-formatted string.
     *
     * <p>Must be public due to runtime-package restrictions.
     *
     * @hide
     */
    @NonNull
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static String certificateToPemString(@Nullable X509Certificate cert)
            throws IOException, CertificateEncodingException {
        if (cert == null) {
            return EMPTY_CERT;
        }

        // Credentials.convertToPem outputs ASCII bytes.
        return new String(Credentials.convertToPem(cert), StandardCharsets.US_ASCII);
    }

    /**
     * Decodes the provided Certificate(s).
     *
     * <p>Will use the first one if the certStr encodes more than one certificate.
     */
    @Nullable
    private static X509Certificate certificateFromPemString(@Nullable String certStr)
            throws CertificateException {
        if (certStr == null || EMPTY_CERT.equals(certStr)) {
            return null;
        }

        try {
            final List<X509Certificate> certs =
                    Credentials.convertFromPem(certStr.getBytes(StandardCharsets.US_ASCII));
            return certs.isEmpty() ? null : certs.get(0);
        } catch (IOException e) {
            throw new CertificateException(e);
        }
    }

    /** @hide */
    @NonNull
    public static String encodeForIpsecSecret(@NonNull byte[] secret) {
        checkNotNull(secret, MISSING_PARAM_MSG_TMPL, "secret");

        return Base64.getEncoder().encodeToString(secret);
    }

    @NonNull
    private static byte[] decodeFromIpsecSecret(@NonNull String encoded) {
        checkNotNull(encoded, MISSING_PARAM_MSG_TMPL, "encoded");

        return Base64.getDecoder().decode(encoded);
    }

    @NonNull
    private static PrivateKey getPrivateKey(@NonNull String keyStr)
            throws InvalidKeySpecException, NoSuchAlgorithmException {
        final PKCS8EncodedKeySpec privateKeySpec =
                new PKCS8EncodedKeySpec(decodeFromIpsecSecret(keyStr));
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(privateKeySpec);
    }

    private static void checkCert(@NonNull X509Certificate cert) {
        try {
            certificateToPemString(cert);
        } catch (GeneralSecurityException | IOException e) {
            throw new IllegalArgumentException("Certificate could not be encoded");
        }
    }

    private static @NonNull <T> T checkNotNull(
            final T reference, final String messageTemplate, final Object... messageArgs) {
        return Objects.requireNonNull(reference, String.format(messageTemplate, messageArgs));
    }

    /** A incremental builder for IKEv2 VPN profiles */
    public static final class Builder {
        private int mType = -1;
        @NonNull private final String mServerAddr;
        @NonNull private final String mUserIdentity;

        // PSK authentication
        @Nullable private byte[] mPresharedKey;

        // Username/Password, RSA authentication
        @Nullable private X509Certificate mServerRootCaCert;

        // Username/Password authentication
        @Nullable private String mUsername;
        @Nullable private String mPassword;

        // RSA Certificate authentication
        @Nullable private PrivateKey mRsaPrivateKey;
        @Nullable private X509Certificate mUserCert;

        @Nullable private ProxyInfo mProxyInfo;
        @NonNull private List<String> mAllowedAlgorithms = DEFAULT_ALGORITHMS;
        private boolean mIsBypassable = false;
        private boolean mIsMetered = true;
        private int mMaxMtu = PlatformVpnProfile.MAX_MTU_DEFAULT;

        /**
         * Creates a new builder with the basic parameters of an IKEv2/IPsec VPN.
         *
         * @param serverAddr the server that the VPN should connect to
         * @param identity the identity string to be used for IKEv2 authentication
         */
        public Builder(@NonNull String serverAddr, @NonNull String identity) {
            checkNotNull(serverAddr, MISSING_PARAM_MSG_TMPL, "serverAddr");
            checkNotNull(identity, MISSING_PARAM_MSG_TMPL, "identity");

            mServerAddr = serverAddr;
            mUserIdentity = identity;
        }

        private void resetAuthParams() {
            mPresharedKey = null;
            mServerRootCaCert = null;
            mUsername = null;
            mPassword = null;
            mRsaPrivateKey = null;
            mUserCert = null;
        }

        /**
         * Set the IKEv2 authentication to use the provided username/password.
         *
         * <p>Setting this will configure IKEv2 authentication using EAP-MSCHAPv2. Only one
         * authentication method may be set. This method will overwrite any previously set
         * authentication method.
         *
         * @param user the username to be used for EAP-MSCHAPv2 authentication
         * @param pass the password to be used for EAP-MSCHAPv2 authentication
         * @param serverRootCa the root certificate to be used for verifying the identity of the
         *     server
         * @return this {@link Builder} object to facilitate chaining of method calls
         * @throws IllegalArgumentException if any of the certificates were invalid or of an
         *     unrecognized format
         */
        @NonNull
        public Builder setAuthUsernamePassword(
                @NonNull String user,
                @NonNull String pass,
                @Nullable X509Certificate serverRootCa) {
            checkNotNull(user, MISSING_PARAM_MSG_TMPL, "user");
            checkNotNull(pass, MISSING_PARAM_MSG_TMPL, "pass");

            // Test to make sure all auth params can be encoded safely.
            if (serverRootCa != null) checkCert(serverRootCa);

            resetAuthParams();
            mUsername = user;
            mPassword = pass;
            mServerRootCaCert = serverRootCa;
            mType = VpnProfile.TYPE_IKEV2_IPSEC_USER_PASS;
            return this;
        }

        /**
         * Set the IKEv2 authentication to use Digital Signature Authentication with the given key.
         *
         * <p>Setting this will configure IKEv2 authentication using a Digital Signature scheme.
         * Only one authentication method may be set. This method will overwrite any previously set
         * authentication method.
         *
         * @param userCert the username to be used for RSA Digital signiture authentication
         * @param key the PrivateKey instance associated with the user ceritificate, used for
         *     constructing the signature
         * @param serverRootCa the root certificate to be used for verifying the identity of the
         *     server
         * @return this {@link Builder} object to facilitate chaining of method calls
         * @throws IllegalArgumentException if any of the certificates were invalid or of an
         *     unrecognized format
         */
        @NonNull
        public Builder setAuthDigitalSignature(
                @NonNull X509Certificate userCert,
                @NonNull PrivateKey key,
                @Nullable X509Certificate serverRootCa) {
            checkNotNull(userCert, MISSING_PARAM_MSG_TMPL, "userCert");
            checkNotNull(key, MISSING_PARAM_MSG_TMPL, "key");

            // Test to make sure all auth params can be encoded safely.
            checkCert(userCert);
            if (serverRootCa != null) checkCert(serverRootCa);

            resetAuthParams();
            mUserCert = userCert;
            mRsaPrivateKey = key;
            mServerRootCaCert = serverRootCa;
            mType = VpnProfile.TYPE_IKEV2_IPSEC_RSA;
            return this;
        }

        /**
         * Set the IKEv2 authentication to use Preshared keys.
         *
         * <p>Setting this will configure IKEv2 authentication using a Preshared Key. Only one
         * authentication method may be set. This method will overwrite any previously set
         * authentication method.
         *
         * @param psk the key to be used for Pre-Shared Key authentication
         * @return this {@link Builder} object to facilitate chaining of method calls
         */
        @NonNull
        public Builder setAuthPsk(@NonNull byte[] psk) {
            checkNotNull(psk, MISSING_PARAM_MSG_TMPL, "psk");

            resetAuthParams();
            mPresharedKey = psk;
            mType = VpnProfile.TYPE_IKEV2_IPSEC_PSK;
            return this;
        }

        /**
         * Sets whether apps can bypass this VPN connection.
         *
         * <p>By default, all traffic from apps are forwarded through the VPN interface and it is
         * not possible for unprivileged apps to side-step the VPN. If a VPN is set to bypassable,
         * apps may use methods such as {@link Network#getSocketFactory} or {@link
         * Network#openConnection} to instead send/receive directly over the underlying network or
         * any other network they have permissions for.
         *
         * @param isBypassable Whether or not the VPN should be considered bypassable. Defaults to
         *     {@code false}.
         * @return this {@link Builder} object to facilitate chaining of method calls
         */
        @NonNull
        public Builder setBypassable(boolean isBypassable) {
            mIsBypassable = isBypassable;
            return this;
        }

        /**
         * Sets a proxy for the VPN network.
         *
         * <p>Note that this proxy is only a recommendation and it may be ignored by apps.
         *
         * @param proxy the ProxyInfo to be set for the VPN network
         * @return this {@link Builder} object to facilitate chaining of method calls
         */
        @NonNull
        public Builder setProxy(@Nullable ProxyInfo proxy) {
            mProxyInfo = proxy;
            return this;
        }

        /**
         * Set the upper bound of the maximum transmission unit (MTU) of the VPN interface.
         *
         * <p>If it is not set, a safe value will be used. Additionally, the actual link MTU will be
         * dynamically calculated/updated based on the underlying link's mtu.
         *
         * @param mtu the MTU (in bytes) of the VPN interface
         * @return this {@link Builder} object to facilitate chaining of method calls
         * @throws IllegalArgumentException if the value is not at least the minimum IPv6 MTU (1280)
         */
        @NonNull
        public Builder setMaxMtu(int mtu) {
            // IPv6 MTU is greater; since profiles may be started by the system on IPv4 and IPv6
            // networks, the VPN must provide a link fulfilling the stricter of the two conditions
            // (at least that of the IPv6 MTU).
            if (mtu < LinkProperties.MIN_MTU_V6) {
                throw new IllegalArgumentException(
                        "Max MTU must be at least " + LinkProperties.MIN_MTU_V6);
            }
            mMaxMtu = mtu;
            return this;
        }

        /**
         * Marks the VPN network as metered.
         *
         * <p>A VPN network is classified as metered when the user is sensitive to heavy data usage
         * due to monetary costs and/or data limitations. In such cases, you should set this to
         * {@code true} so that apps on the system can avoid doing large data transfers. Otherwise,
         * set this to {@code false}. Doing so would cause VPN network to inherit its meteredness
         * from the underlying network.
         *
         * @param isMetered {@code true} if the VPN network should be treated as metered regardless
         *     of underlying network meteredness. Defaults to {@code true}.
         * @return this {@link Builder} object to facilitate chaining of method calls
         * @see NetworkCapabilities#NET_CAPABILITY_NOT_METERED
         */
        @NonNull
        public Builder setMetered(boolean isMetered) {
            mIsMetered = isMetered;
            return this;
        }

        /**
         * Sets the allowable set of IPsec algorithms
         *
         * <p>If set, this will constrain the set of algorithms that the IPsec tunnel will use for
         * integrity verification and encryption to the provided list.
         *
         * <p>The set of allowed IPsec algorithms is defined in {@link IpSecAlgorithm}. Adding of
         * algorithms that are considered insecure (such as AUTH_HMAC_MD5 and AUTH_HMAC_SHA1) is not
         * permitted, and will result in an IllegalArgumentException being thrown.
         *
         * <p>The provided algorithm list must contain at least one algorithm that provides
         * Authentication, and one that provides Encryption. Authenticated Encryption with
         * Associated Data (AEAD) algorithms provide both Authentication and Encryption.
         *
         * <p>By default, this profile will use any algorithm defined in {@link IpSecAlgorithm},
         * with the exception of those considered insecure (as described above).
         *
         * @param algorithmNames the list of supported IPsec algorithms
         * @return this {@link Builder} object to facilitate chaining of method calls
         * @see IpSecAlgorithm
         */
        @NonNull
        public Builder setAllowedAlgorithms(@NonNull List<String> algorithmNames) {
            checkNotNull(algorithmNames, MISSING_PARAM_MSG_TMPL, "algorithmNames");
            validateAllowedAlgorithms(algorithmNames);

            mAllowedAlgorithms = algorithmNames;
            return this;
        }

        /**
         * Validates, builds and provisions the VpnProfile.
         *
         * @throws IllegalArgumentException if any of the required keys or values were invalid
         */
        @NonNull
        public Ikev2VpnProfile build() {
            return new Ikev2VpnProfile(
                    mType,
                    mServerAddr,
                    mUserIdentity,
                    mPresharedKey,
                    mServerRootCaCert,
                    mUsername,
                    mPassword,
                    mRsaPrivateKey,
                    mUserCert,
                    mProxyInfo,
                    mAllowedAlgorithms,
                    mIsBypassable,
                    mIsMetered,
                    mMaxMtu);
        }
    }
}
