/**
 * Copyright (c) 2016, 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.wifi.hotspot2.pps;

import android.net.wifi.EAPConstants;
import android.net.wifi.ParcelUtil;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

/**
 * Class representing Credential subtree in the PerProviderSubscription (PPS)
 * Management Object (MO) tree.
 * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0
 * Release 2 Technical Specification.
 *
 * In addition to the fields in the Credential subtree, this will also maintain necessary
 * information for the private key and certificates associated with this credential.
 */
public final class Credential implements Parcelable {
    private static final String TAG = "Credential";

    /**
     * Max string length for realm.  Refer to Credential/Realm node in Hotspot 2.0 Release 2
     * Technical Specification Section 9.1 for more info.
     */
    private static final int MAX_REALM_BYTES = 253;

    /**
     * The time this credential is created. It is in the format of number
     * of milliseconds since January 1, 1970, 00:00:00 GMT.
     * Using Long.MIN_VALUE to indicate unset value.
     */
    private long mCreationTimeInMillis = Long.MIN_VALUE;
    /**
     * @hide
     */
    public void setCreationTimeInMillis(long creationTimeInMillis) {
        mCreationTimeInMillis = creationTimeInMillis;
    }
    /**
     * @hide
     */
    public long getCreationTimeInMillis() {
        return mCreationTimeInMillis;
    }

    /**
     * The time this credential will expire. It is in the format of number
     * of milliseconds since January 1, 1970, 00:00:00 GMT.
    * Using Long.MIN_VALUE to indicate unset value.
     */
    private long mExpirationTimeInMillis = Long.MIN_VALUE;
    /**
     * @hide
     */
    public void setExpirationTimeInMillis(long expirationTimeInMillis) {
        mExpirationTimeInMillis = expirationTimeInMillis;
    }
    /**
     * @hide
     */
    public long getExpirationTimeInMillis() {
        return mExpirationTimeInMillis;
    }

    /**
     * The realm associated with this credential.  It will be used to determine
     * if this credential can be used to authenticate with a given hotspot by
     * comparing the realm specified in that hotspot's ANQP element.
     */
    private String mRealm = null;
    /**
     * Set the realm associated with this credential.
     *
     * @param realm The realm to set to
     */
    public void setRealm(String realm) {
        mRealm = realm;
    }
    /**
     * Get the realm associated with this credential.
     *
     * @return the realm associated with this credential
     */
    public String getRealm() {
        return mRealm;
    }

    /**
     * When set to true, the device should check AAA (Authentication, Authorization,
     * and Accounting) server's certificate during EAP (Extensible Authentication
     * Protocol) authentication.
     */
    private boolean mCheckAaaServerCertStatus = false;
    /**
     * @hide
     */
    public void setCheckAaaServerCertStatus(boolean checkAaaServerCertStatus) {
        mCheckAaaServerCertStatus = checkAaaServerCertStatus;
    }
    /**
     * @hide
     */
    public boolean getCheckAaaServerCertStatus() {
        return mCheckAaaServerCertStatus;
    }

    /**
     * Username-password based credential.
     * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree.
     */
    public static final class UserCredential implements Parcelable {
        /**
         * Maximum string length for username.  Refer to Credential/UsernamePassword/Username
         * node in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
         */
        private static final int MAX_USERNAME_BYTES = 63;

        /**
         * Maximum string length for password.  Refer to Credential/UsernamePassword/Password
         * in Hotspot 2.0 Release 2 Technical Specification Section 9.1 for more info.
         */
        private static final int MAX_PASSWORD_BYTES = 255;

        /**
         * Supported authentication methods.
         * @hide
         */
        public static final String AUTH_METHOD_PAP = "PAP";
        /** @hide */
        public static final String AUTH_METHOD_MSCHAP = "MS-CHAP";
        /** @hide */
        public static final String AUTH_METHOD_MSCHAPV2 = "MS-CHAP-V2";

        /**
         * Supported Non-EAP inner methods.  Refer to
         * Credential/UsernamePassword/EAPMethod/InnerEAPType in Hotspot 2.0 Release 2 Technical
         * Specification Section 9.1 for more info.
         */
        private static final Set<String> SUPPORTED_AUTH = new HashSet<String>(
                Arrays.asList(AUTH_METHOD_PAP, AUTH_METHOD_MSCHAP, AUTH_METHOD_MSCHAPV2));

        /**
         * Username of the credential.
         */
        private String mUsername = null;
        /**
         * Set the username associated with this user credential.
         *
         * @param username The username to set to
         */
        public void setUsername(String username) {
            mUsername = username;
        }
        /**
         * Get the username associated with this user credential.
         *
         * @return the username associated with this user credential
         */
        public String getUsername() {
            return mUsername;
        }

        /**
         * Base64-encoded password.
         */
        private String mPassword = null;
        /**
         * Set the Base64-encoded password associated with this user credential.
         *
         * @param password The password to set to
         */
        public void setPassword(String password) {
            mPassword = password;
        }
        /**
         * Get the Base64-encoded password associated with this user credential.
         *
         * @return the Base64-encoded password associated with this user credential
         */
        public String getPassword() {
            return mPassword;
        }

        /**
         * Flag indicating if the password is machine managed.
         */
        private boolean mMachineManaged = false;
        /**
         * @hide
         */
        public void setMachineManaged(boolean machineManaged) {
            mMachineManaged = machineManaged;
        }
        /**
         * @hide
         */
        public boolean getMachineManaged() {
            return mMachineManaged;
        }

        /**
         * The name of the application used to generate the password.
         */
        private String mSoftTokenApp = null;
        /**
         * @hide
         */
        public void setSoftTokenApp(String softTokenApp) {
            mSoftTokenApp = softTokenApp;
        }
        /**
         * @hide
         */
        public String getSoftTokenApp() {
            return mSoftTokenApp;
        }

        /**
         * Flag indicating if this credential is usable on other mobile devices as well.
         */
        private boolean mAbleToShare = false;
        /**
         * @hide
         */
        public void setAbleToShare(boolean ableToShare) {
            mAbleToShare = ableToShare;
        }
        /**
         * @hide
         */
        public boolean getAbleToShare() {
            return mAbleToShare;
        }

        /**
         * EAP (Extensible Authentication Protocol) method type.
         * Refer to
         * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
         * EAP Numbers</a> for valid values.
         * Using Integer.MIN_VALUE to indicate unset value.
         */
        private int mEapType = Integer.MIN_VALUE;
        /**
         * Set the EAP (Extensible Authentication Protocol) method type associated with this
         * user credential.
         * Refer to
         * <a href="http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4">
         * EAP Numbers</a> for valid values.
         *
         * @param eapType The EAP method type associated with this user credential
         */
        public void setEapType(int eapType) {
            mEapType = eapType;
        }
        /**
         * Get the EAP (Extensible Authentication Protocol) method type associated with this
         * user credential.
         *
         * @return EAP method type
         */
        public int getEapType() {
            return mEapType;
        }

        /**
         * Non-EAP inner authentication method.
         */
        private String mNonEapInnerMethod = null;
        /**
         * Set the inner non-EAP method associated with this user credential.
         *
         * @param nonEapInnerMethod The non-EAP inner method to set to
         */
        public void setNonEapInnerMethod(String nonEapInnerMethod) {
            mNonEapInnerMethod = nonEapInnerMethod;
        }
        /**
         * Get the inner non-EAP method associated with this user credential.
         *
         * @return Non-EAP inner method associated with this user credential
         */
        public String getNonEapInnerMethod() {
            return mNonEapInnerMethod;
        }

        /**
         * Constructor for creating UserCredential with default values.
         */
        public UserCredential() {}

        /**
         * Copy constructor.
         *
         * @param source The source to copy from
         */
        public UserCredential(UserCredential source) {
            if (source != null) {
                mUsername = source.mUsername;
                mPassword = source.mPassword;
                mMachineManaged = source.mMachineManaged;
                mSoftTokenApp = source.mSoftTokenApp;
                mAbleToShare = source.mAbleToShare;
                mEapType = source.mEapType;
                mNonEapInnerMethod = source.mNonEapInnerMethod;
            }
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(mUsername);
            dest.writeString(mPassword);
            dest.writeInt(mMachineManaged ? 1 : 0);
            dest.writeString(mSoftTokenApp);
            dest.writeInt(mAbleToShare ? 1 : 0);
            dest.writeInt(mEapType);
            dest.writeString(mNonEapInnerMethod);
        }

        @Override
        public boolean equals(Object thatObject) {
            if (this == thatObject) {
                return true;
            }
            if (!(thatObject instanceof UserCredential)) {
                return false;
            }

            UserCredential that = (UserCredential) thatObject;
            return TextUtils.equals(mUsername, that.mUsername)
                    && TextUtils.equals(mPassword, that.mPassword)
                    && mMachineManaged == that.mMachineManaged
                    && TextUtils.equals(mSoftTokenApp, that.mSoftTokenApp)
                    && mAbleToShare == that.mAbleToShare
                    && mEapType == that.mEapType
                    && TextUtils.equals(mNonEapInnerMethod, that.mNonEapInnerMethod);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mUsername, mPassword, mMachineManaged, mSoftTokenApp,
                    mAbleToShare, mEapType, mNonEapInnerMethod);
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("Username: ").append(mUsername).append("\n");
            builder.append("MachineManaged: ").append(mMachineManaged).append("\n");
            builder.append("SoftTokenApp: ").append(mSoftTokenApp).append("\n");
            builder.append("AbleToShare: ").append(mAbleToShare).append("\n");
            builder.append("EAPType: ").append(mEapType).append("\n");
            builder.append("AuthMethod: ").append(mNonEapInnerMethod).append("\n");
            return builder.toString();
        }

        /**
         * Validate the configuration data.
         *
         * @return true on success or false on failure
         * @hide
         */
        public boolean validate() {
            if (TextUtils.isEmpty(mUsername)) {
                Log.d(TAG, "Missing username");
                return false;
            }
            if (mUsername.getBytes(StandardCharsets.UTF_8).length > MAX_USERNAME_BYTES) {
                Log.d(TAG, "username exceeding maximum length: "
                        + mUsername.getBytes(StandardCharsets.UTF_8).length);
                return false;
            }

            if (TextUtils.isEmpty(mPassword)) {
                Log.d(TAG, "Missing password");
                return false;
            }
            if (mPassword.getBytes(StandardCharsets.UTF_8).length > MAX_PASSWORD_BYTES) {
                Log.d(TAG, "password exceeding maximum length: "
                        + mPassword.getBytes(StandardCharsets.UTF_8).length);
                return false;
            }

            // Only supports EAP-TTLS for user credential.
            if (mEapType != EAPConstants.EAP_TTLS) {
                Log.d(TAG, "Invalid EAP Type for user credential: " + mEapType);
                return false;
            }

            // Verify Non-EAP inner method for EAP-TTLS.
            if (!SUPPORTED_AUTH.contains(mNonEapInnerMethod)) {
                Log.d(TAG, "Invalid non-EAP inner method for EAP-TTLS: " + mNonEapInnerMethod);
                return false;
            }
            return true;
        }

        public static final @android.annotation.NonNull Creator<UserCredential> CREATOR =
            new Creator<UserCredential>() {
                @Override
                public UserCredential createFromParcel(Parcel in) {
                    UserCredential userCredential = new UserCredential();
                    userCredential.setUsername(in.readString());
                    userCredential.setPassword(in.readString());
                    userCredential.setMachineManaged(in.readInt() != 0);
                    userCredential.setSoftTokenApp(in.readString());
                    userCredential.setAbleToShare(in.readInt() != 0);
                    userCredential.setEapType(in.readInt());
                    userCredential.setNonEapInnerMethod(in.readString());
                    return userCredential;
                }

                @Override
                public UserCredential[] newArray(int size) {
                    return new UserCredential[size];
                }
            };
    }
    private UserCredential mUserCredential = null;
    /**
     * Set the user credential information.
     *
     * @param userCredential The user credential to set to
     */
    public void setUserCredential(UserCredential userCredential) {
        mUserCredential = userCredential;
    }
    /**
     * Get the user credential information.
     *
     * @return user credential information
     */
    public UserCredential getUserCredential() {
        return mUserCredential;
    }

    /**
     * Certificate based credential.  This is used for EAP-TLS.
     * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree.
     */
    public static final class CertificateCredential implements Parcelable {
        /**
         * Supported certificate types.
         * @hide
         */
        public static final String CERT_TYPE_X509V3 = "x509v3";

        /**
         * Certificate SHA-256 fingerprint length.
         */
        private static final int CERT_SHA256_FINGER_PRINT_LENGTH = 32;

        /**
         * Certificate type.
         */
        private String mCertType = null;
        /**
         * Set the certificate type associated with this certificate credential.
         *
         * @param certType The certificate type to set to
         */
        public void setCertType(String certType) {
            mCertType = certType;
        }
        /**
         * Get the certificate type associated with this certificate credential.
         *
         * @return certificate type
         */
        public String getCertType() {
            return mCertType;
        }

        /**
         * The SHA-256 fingerprint of the certificate.
         */
        private byte[] mCertSha256Fingerprint = null;
        /**
         * Set the certificate SHA-256 fingerprint associated with this certificate credential.
         *
         * @param certSha256Fingerprint The certificate fingerprint to set to
         */
        public void setCertSha256Fingerprint(byte[] certSha256Fingerprint) {
            mCertSha256Fingerprint = certSha256Fingerprint;
        }
        /**
         * Get the certificate SHA-256 fingerprint associated with this certificate credential.
         *
         * @return certificate SHA-256 fingerprint
         */
        public byte[] getCertSha256Fingerprint() {
            return mCertSha256Fingerprint;
        }

        /**
         * Constructor for creating CertificateCredential with default values.
         */
        public CertificateCredential() {}

        /**
         * Copy constructor.
         *
         * @param source The source to copy from
         */
        public CertificateCredential(CertificateCredential source) {
            if (source != null) {
                mCertType = source.mCertType;
                if (source.mCertSha256Fingerprint != null) {
                    mCertSha256Fingerprint = Arrays.copyOf(source.mCertSha256Fingerprint,
                                                          source.mCertSha256Fingerprint.length);
                }
            }
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(mCertType);
            dest.writeByteArray(mCertSha256Fingerprint);
        }

        @Override
        public boolean equals(Object thatObject) {
            if (this == thatObject) {
                return true;
            }
            if (!(thatObject instanceof CertificateCredential)) {
                return false;
            }

            CertificateCredential that = (CertificateCredential) thatObject;
            return TextUtils.equals(mCertType, that.mCertType)
                    && Arrays.equals(mCertSha256Fingerprint, that.mCertSha256Fingerprint);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mCertType, Arrays.hashCode(mCertSha256Fingerprint));
        }

        @Override
        public String toString() {
            return "CertificateType: " + mCertType + "\n";
        }

        /**
         * Validate the configuration data.
         *
         * @return true on success or false on failure
         * @hide
         */
        public boolean validate() {
            if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) {
                Log.d(TAG, "Unsupported certificate type: " + mCertType);
                return false;
            }
            if (mCertSha256Fingerprint == null
                    || mCertSha256Fingerprint.length != CERT_SHA256_FINGER_PRINT_LENGTH) {
                Log.d(TAG, "Invalid SHA-256 fingerprint");
                return false;
            }
            return true;
        }

        public static final @android.annotation.NonNull Creator<CertificateCredential> CREATOR =
            new Creator<CertificateCredential>() {
                @Override
                public CertificateCredential createFromParcel(Parcel in) {
                    CertificateCredential certCredential = new CertificateCredential();
                    certCredential.setCertType(in.readString());
                    certCredential.setCertSha256Fingerprint(in.createByteArray());
                    return certCredential;
                }

                @Override
                public CertificateCredential[] newArray(int size) {
                    return new CertificateCredential[size];
                }
            };
    }
    private CertificateCredential mCertCredential = null;
    /**
     * Set the certificate credential information.
     *
     * @param certCredential The certificate credential to set to
     */
    public void setCertCredential(CertificateCredential certCredential) {
        mCertCredential = certCredential;
    }
    /**
     * Get the certificate credential information.
     *
     * @return certificate credential information
     */
    public CertificateCredential getCertCredential() {
        return mCertCredential;
    }

    /**
     * SIM (Subscriber Identify Module) based credential.
     * Contains fields under PerProviderSubscription/Credential/SIM subtree.
     */
    public static final class SimCredential implements Parcelable {
        /**
         * Maximum string length for IMSI.
         */
        private static final int MAX_IMSI_LENGTH = 15;

        /**
         * International Mobile Subscriber Identity, is used to identify the user
         * of a cellular network and is a unique identification associated with all
         * cellular networks
         */
        private String mImsi = null;
        /**
         * Set the IMSI (International Mobile Subscriber Identity) associated with this SIM
         * credential.
         *
         * @param imsi The IMSI to set to
         */
        public void setImsi(String imsi) {
            mImsi = imsi;
        }
        /**
         * Get the IMSI (International Mobile Subscriber Identity) associated with this SIM
         * credential.
         *
         * @return IMSI associated with this SIM credential
         */
        public String getImsi() {
            return mImsi;
        }

        /**
         * EAP (Extensible Authentication Protocol) method type for using SIM credential.
         * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4
         * for valid values.
         * Using Integer.MIN_VALUE to indicate unset value.
         */
        private int mEapType = Integer.MIN_VALUE;
        /**
         * Set the EAP (Extensible Authentication Protocol) method type associated with this
         * SIM credential.
         *
         * @param eapType The EAP method type to set to
         */
        public void setEapType(int eapType) {
            mEapType = eapType;
        }
        /**
         * Get the EAP (Extensible Authentication Protocol) method type associated with this
         * SIM credential.
         *
         * @return EAP method type associated with this SIM credential
         */
        public int getEapType() {
            return mEapType;
        }

        /**
         * Constructor for creating SimCredential with default values.
         */
        public SimCredential() {}

        /**
         * Copy constructor
         *
         * @param source The source to copy from
         */
        public SimCredential(SimCredential source) {
            if (source != null) {
                mImsi = source.mImsi;
                mEapType = source.mEapType;
            }
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public boolean equals(Object thatObject) {
            if (this == thatObject) {
                return true;
            }
            if (!(thatObject instanceof SimCredential)) {
                return false;
            }

            SimCredential that = (SimCredential) thatObject;
            return TextUtils.equals(mImsi, that.mImsi)
                    && mEapType == that.mEapType;
        }

        @Override
        public int hashCode() {
            return Objects.hash(mImsi, mEapType);
        }

        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            String imsi;
            if (mImsi != null) {
                if (mImsi.length() > 6 && mImsi.charAt(6) != '*') {
                    // Truncate the full IMSI from the log
                    imsi = mImsi.substring(0, 6) + "****";
                } else {
                    imsi = mImsi;
                }
                builder.append("IMSI: ").append(imsi).append("\n");
            }
            builder.append("EAPType: ").append(mEapType).append("\n");
            return builder.toString();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(mImsi);
            dest.writeInt(mEapType);
        }

        /**
         * Validate the configuration data.
         *
         * @return true on success or false on failure
         * @hide
         */
        public boolean validate() {
            // Note: this only validate the format of IMSI string itself.  Additional verification
            // will be done by WifiService at the time of provisioning to verify against the IMSI
            // of the SIM card installed in the device.
            if (!verifyImsi()) {
                return false;
            }
            if (mEapType != EAPConstants.EAP_SIM && mEapType != EAPConstants.EAP_AKA
                    && mEapType != EAPConstants.EAP_AKA_PRIME) {
                Log.d(TAG, "Invalid EAP Type for SIM credential: " + mEapType);
                return false;
            }
            return true;
        }

        public static final @android.annotation.NonNull Creator<SimCredential> CREATOR =
            new Creator<SimCredential>() {
                @Override
                public SimCredential createFromParcel(Parcel in) {
                    SimCredential simCredential = new SimCredential();
                    simCredential.setImsi(in.readString());
                    simCredential.setEapType(in.readInt());
                    return simCredential;
                }

                @Override
                public SimCredential[] newArray(int size) {
                    return new SimCredential[size];
                }
            };

        /**
         * Verify the IMSI (International Mobile Subscriber Identity) string.  The string
         * should contain zero or more numeric digits, and might ends with a "*" for prefix
         * matching.
         *
         * @return true if IMSI is valid, false otherwise.
         */
        private boolean verifyImsi() {
            if (TextUtils.isEmpty(mImsi)) {
                Log.d(TAG, "Missing IMSI");
                return false;
            }
            if (mImsi.length() > MAX_IMSI_LENGTH) {
                Log.d(TAG, "IMSI exceeding maximum length: " + mImsi.length());
                return false;
            }

            // Locate the first non-digit character.
            int nonDigit;
            char stopChar = '\0';
            for (nonDigit = 0; nonDigit < mImsi.length(); nonDigit++) {
                stopChar = mImsi.charAt(nonDigit);
                if (stopChar < '0' || stopChar > '9') {
                    break;
                }
            }

            if (nonDigit == mImsi.length()) {
                return true;
            }
            else if (nonDigit == mImsi.length()-1 && stopChar == '*') {
                // Prefix matching.
                return true;
            }
            return false;
        }
    }
    private SimCredential mSimCredential = null;
    /**
     * Set the SIM credential information.
     *
     * @param simCredential The SIM credential to set to
     */
    public void setSimCredential(SimCredential simCredential) {
        mSimCredential = simCredential;
    }
    /**
     * Get the SIM credential information.
     *
     * @return SIM credential information
     */
    public SimCredential getSimCredential() {
        return mSimCredential;
    }

    /**
     * CA (Certificate Authority) X509 certificates.
     */
    private X509Certificate[] mCaCertificates = null;

    /**
     * Set the CA (Certification Authority) certificate associated with this credential.
     *
     * @param caCertificate The CA certificate to set to
     */
    public void setCaCertificate(X509Certificate caCertificate) {
        mCaCertificates = null;
        if (caCertificate != null) {
            mCaCertificates = new X509Certificate[] {caCertificate};
        }
    }

    /**
     * Set the CA (Certification Authority) certificates associated with this credential.
     *
     * @param caCertificates The list of CA certificates to set to
     * @hide
     */
    public void setCaCertificates(X509Certificate[] caCertificates) {
        mCaCertificates = caCertificates;
    }

    /**
     * Get the CA (Certification Authority) certificate associated with this credential.
     *
     * @return CA certificate associated with this credential, {@code null} if certificate is not
     * set or certificate is more than one.
     */
    public X509Certificate getCaCertificate() {
        return mCaCertificates == null || mCaCertificates.length > 1 ? null : mCaCertificates[0];
    }

    /**
     * Get the CA (Certification Authority) certificates associated with this credential.
     *
     * @return The list of CA certificates associated with this credential
     * @hide
     */
    public X509Certificate[] getCaCertificates() {
        return mCaCertificates;
    }

    /**
     * Client side X509 certificate chain.
     */
    private X509Certificate[] mClientCertificateChain = null;
    /**
     * Set the client certificate chain associated with this credential.
     *
     * @param certificateChain The client certificate chain to set to
     */
    public void setClientCertificateChain(X509Certificate[] certificateChain) {
        mClientCertificateChain = certificateChain;
    }
    /**
     * Get the client certificate chain associated with this credential.
     *
     * @return client certificate chain associated with this credential
     */
    public X509Certificate[] getClientCertificateChain() {
        return mClientCertificateChain;
    }

    /**
     * Client side private key.
     */
    private PrivateKey mClientPrivateKey = null;
    /**
     * Set the client private key associated with this credential.
     *
     * @param clientPrivateKey the client private key to set to
     */
    public void setClientPrivateKey(PrivateKey clientPrivateKey) {
        mClientPrivateKey = clientPrivateKey;
    }
    /**
     * Get the client private key associated with this credential.
     *
     * @return client private key associated with this credential.
     */
    public PrivateKey getClientPrivateKey() {
        return mClientPrivateKey;
    }

    /**
     * Constructor for creating Credential with default values.
     */
    public Credential() {}

    /**
     * Copy constructor.
     *
     * @param source The source to copy from
     */
    public Credential(Credential source) {
        if (source != null) {
            mCreationTimeInMillis = source.mCreationTimeInMillis;
            mExpirationTimeInMillis = source.mExpirationTimeInMillis;
            mRealm = source.mRealm;
            mCheckAaaServerCertStatus = source.mCheckAaaServerCertStatus;
            if (source.mUserCredential != null) {
                mUserCredential = new UserCredential(source.mUserCredential);
            }
            if (source.mCertCredential != null) {
                mCertCredential = new CertificateCredential(source.mCertCredential);
            }
            if (source.mSimCredential != null) {
                mSimCredential = new SimCredential(source.mSimCredential);
            }
            if (source.mClientCertificateChain != null) {
                mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain,
                                                        source.mClientCertificateChain.length);
            }
            if (source.mCaCertificates != null) {
                mCaCertificates = Arrays.copyOf(source.mCaCertificates,
                        source.mCaCertificates.length);
            }

            mClientPrivateKey = source.mClientPrivateKey;
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(mCreationTimeInMillis);
        dest.writeLong(mExpirationTimeInMillis);
        dest.writeString(mRealm);
        dest.writeInt(mCheckAaaServerCertStatus ? 1 : 0);
        dest.writeParcelable(mUserCredential, flags);
        dest.writeParcelable(mCertCredential, flags);
        dest.writeParcelable(mSimCredential, flags);
        ParcelUtil.writeCertificates(dest, mCaCertificates);
        ParcelUtil.writeCertificates(dest, mClientCertificateChain);
        ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
    }

    @Override
    public boolean equals(Object thatObject) {
        if (this == thatObject) {
            return true;
        }
        if (!(thatObject instanceof Credential)) {
            return false;
        }

        Credential that = (Credential) thatObject;
        return TextUtils.equals(mRealm, that.mRealm)
                && mCreationTimeInMillis == that.mCreationTimeInMillis
                && mExpirationTimeInMillis == that.mExpirationTimeInMillis
                && mCheckAaaServerCertStatus == that.mCheckAaaServerCertStatus
                && (mUserCredential == null ? that.mUserCredential == null
                    : mUserCredential.equals(that.mUserCredential))
                && (mCertCredential == null ? that.mCertCredential == null
                    : mCertCredential.equals(that.mCertCredential))
                && (mSimCredential == null ? that.mSimCredential == null
                    : mSimCredential.equals(that.mSimCredential))
                && isX509CertificatesEquals(mCaCertificates, that.mCaCertificates)
                && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
                && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mCreationTimeInMillis, mExpirationTimeInMillis, mRealm,
                mCheckAaaServerCertStatus, mUserCredential, mCertCredential, mSimCredential,
                mClientPrivateKey, Arrays.hashCode(mCaCertificates),
                Arrays.hashCode(mClientCertificateChain));
    }

    /**
     * Get a unique identifier for Credential. This identifier depends only on items that remain
     * constant throughout the lifetime of a subscription's credentials.
     *
     * @hide
     * @return a Unique identifier for a Credential object
     */
    public int getUniqueId() {
        return Objects.hash(mUserCredential, mCertCredential, mSimCredential, mRealm);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Realm: ").append(mRealm).append("\n");
        builder.append("CreationTime: ").append(mCreationTimeInMillis != Long.MIN_VALUE
                ? new Date(mCreationTimeInMillis) : "Not specified").append("\n");
        builder.append("ExpirationTime: ").append(mExpirationTimeInMillis != Long.MIN_VALUE
                ? new Date(mExpirationTimeInMillis) : "Not specified").append("\n");
        builder.append("CheckAAAServerStatus: ").append(mCheckAaaServerCertStatus).append("\n");
        if (mUserCredential != null) {
            builder.append("UserCredential Begin ---\n");
            builder.append(mUserCredential);
            builder.append("UserCredential End ---\n");
        }
        if (mCertCredential != null) {
            builder.append("CertificateCredential Begin ---\n");
            builder.append(mCertCredential);
            builder.append("CertificateCredential End ---\n");
        }
        if (mSimCredential != null) {
            builder.append("SIMCredential Begin ---\n");
            builder.append(mSimCredential);
            builder.append("SIMCredential End ---\n");
        }
        return builder.toString();
    }

    /**
     * Validate the configuration data.
     *
     * @return true on success or false on failure
     * @hide
     */
    public boolean validate() {
        if (TextUtils.isEmpty(mRealm)) {
            Log.d(TAG, "Missing realm");
            return false;
        }
        if (mRealm.getBytes(StandardCharsets.UTF_8).length > MAX_REALM_BYTES) {
            Log.d(TAG, "realm exceeding maximum length: "
                    + mRealm.getBytes(StandardCharsets.UTF_8).length);
            return false;
        }

        // Verify the credential.
        if (mUserCredential != null) {
            if (!verifyUserCredential()) {
                return false;
            }
        } else if (mCertCredential != null) {
            if (!verifyCertCredential()) {
                return false;
            }
        } else if (mSimCredential != null) {
            if (!verifySimCredential()) {
                return false;
            }
        } else {
            Log.d(TAG, "Missing required credential");
            return false;
        }

        return true;
    }

    public static final @android.annotation.NonNull Creator<Credential> CREATOR =
        new Creator<Credential>() {
            @Override
            public Credential createFromParcel(Parcel in) {
                Credential credential = new Credential();
                credential.setCreationTimeInMillis(in.readLong());
                credential.setExpirationTimeInMillis(in.readLong());
                credential.setRealm(in.readString());
                credential.setCheckAaaServerCertStatus(in.readInt() != 0);
                credential.setUserCredential(in.readParcelable(null));
                credential.setCertCredential(in.readParcelable(null));
                credential.setSimCredential(in.readParcelable(null));
                credential.setCaCertificates(ParcelUtil.readCertificates(in));
                credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
                credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
                return credential;
            }

            @Override
            public Credential[] newArray(int size) {
                return new Credential[size];
            }
        };

    /**
     * Verify user credential.
     * If no CA certificate is provided, then the system uses the CAs in the trust store.
     *
     * @return true if user credential is valid, false otherwise.
     */
    private boolean verifyUserCredential() {
        if (mUserCredential == null) {
            Log.d(TAG, "Missing user credential");
            return false;
        }
        if (mCertCredential != null || mSimCredential != null) {
            Log.d(TAG, "Contained more than one type of credential");
            return false;
        }
        if (!mUserCredential.validate()) {
            return false;
        }

        return true;
    }

    /**
     * Verify certificate credential, which is used for EAP-TLS.  This will verify
     * that the necessary client key and certificates are provided.
     * If no CA certificate is provided, then the system uses the CAs in the trust store.
     *
     * @return true if certificate credential is valid, false otherwise.
     */
    private boolean verifyCertCredential() {
        if (mCertCredential == null) {
            Log.d(TAG, "Missing certificate credential");
            return false;
        }
        if (mUserCredential != null || mSimCredential != null) {
            Log.d(TAG, "Contained more than one type of credential");
            return false;
        }

        if (!mCertCredential.validate()) {
            return false;
        }

        if (mClientPrivateKey == null) {
            Log.d(TAG, "Missing client private key for certificate credential");
            return false;
        }
        try {
            // Verify SHA-256 fingerprint for client certificate.
            if (!verifySha256Fingerprint(mClientCertificateChain,
                    mCertCredential.getCertSha256Fingerprint())) {
                Log.d(TAG, "SHA-256 fingerprint mismatch");
                return false;
            }
        } catch (NoSuchAlgorithmException | CertificateEncodingException e) {
            Log.d(TAG, "Failed to verify SHA-256 fingerprint: " + e.getMessage());
            return false;
        }

        return true;
    }

    /**
     * Verify SIM credential.
     *
     * @return true if SIM credential is valid, false otherwise.
     */
    private boolean verifySimCredential() {
        if (mSimCredential == null) {
            Log.d(TAG, "Missing SIM credential");
            return false;
        }
        if (mUserCredential != null || mCertCredential != null) {
            Log.d(TAG, "Contained more than one type of credential");
            return false;
        }
        return mSimCredential.validate();
    }

    private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) {
        if (key1 == null && key2 == null) {
            return true;
        }

        /* Return false if only one of them is null */
        if (key1 == null || key2 == null) {
            return false;
        }

        return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) &&
                Arrays.equals(key1.getEncoded(), key2.getEncoded());
    }

    /**
     * Verify two X.509 certificates are identical.
     *
     * @param cert1 a certificate to compare
     * @param cert2 a certificate to compare
     * @return {@code true} if given certificates are the same each other, {@code false} otherwise.
     * @hide
     */
    public static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) {
        if (cert1 == null && cert2 == null) {
            return true;
        }

        /* Return false if only one of them is null */
        if (cert1 == null || cert2 == null) {
            return false;
        }

        boolean result = false;
        try {
            result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded());
        } catch (CertificateEncodingException e) {
            /* empty, return false. */
        }
        return result;
    }

    private static boolean isX509CertificatesEquals(X509Certificate[] certs1,
                                                    X509Certificate[] certs2) {
        if (certs1 == null && certs2 == null) {
            return true;
        }

        /* Return false if only one of them is null */
        if (certs1 == null || certs2 == null) {
            return false;
        }

        if (certs1.length != certs2.length) {
            return false;
        }

        for (int i = 0; i < certs1.length; i++) {
            if (!isX509CertificateEquals(certs1[i], certs2[i])) {
                return false;
            }
        }

        return true;
    }

    /**
     * Verify that the digest for a certificate in the certificate chain matches expected
     * fingerprint.  The certificate that matches the fingerprint is the client certificate.
     *
     * @param certChain Chain of certificates
     * @param expectedFingerprint The expected SHA-256 digest of the client certificate
     * @return true if the certificate chain contains a matching certificate, false otherwise
     * @throws NoSuchAlgorithmException
     * @throws CertificateEncodingException
     */
    private static boolean verifySha256Fingerprint(X509Certificate[] certChain,
                                                   byte[] expectedFingerprint)
            throws NoSuchAlgorithmException, CertificateEncodingException {
        if (certChain == null) {
            return false;
        }
        MessageDigest digester = MessageDigest.getInstance("SHA-256");
        for (X509Certificate certificate : certChain) {
            digester.reset();
            byte[] fingerprint = digester.digest(certificate.getEncoded());
            if (Arrays.equals(expectedFingerprint, fingerprint)) {
                return true;
            }
        }
        return false;
    }
}
