Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7705a0d6 authored by Rubin Xu's avatar Rubin Xu
Browse files

resolve merge conflicts of b84954cf to master.

Change-Id: I8a5a1a989968c46ea4807db9e7e06b298244876d
parents a74e729f b84954cf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -23957,6 +23957,7 @@ package android.net.wifi {
    method public java.lang.String getAltSubjectMatch();
    method public java.lang.String getAnonymousIdentity();
    method public java.security.cert.X509Certificate getCaCertificate();
    method public java.security.cert.X509Certificate[] getCaCertificates();
    method public java.security.cert.X509Certificate getClientCertificate();
    method public java.lang.String getDomainSuffixMatch();
    method public int getEapMethod();
@@ -23969,6 +23970,7 @@ package android.net.wifi {
    method public void setAltSubjectMatch(java.lang.String);
    method public void setAnonymousIdentity(java.lang.String);
    method public void setCaCertificate(java.security.cert.X509Certificate);
    method public void setCaCertificates(java.security.cert.X509Certificate[]);
    method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
    method public void setDomainSuffixMatch(java.lang.String);
    method public void setEapMethod(int);
+2 −0
Original line number Diff line number Diff line
@@ -25839,6 +25839,7 @@ package android.net.wifi {
    method public java.lang.String getAltSubjectMatch();
    method public java.lang.String getAnonymousIdentity();
    method public java.security.cert.X509Certificate getCaCertificate();
    method public java.security.cert.X509Certificate[] getCaCertificates();
    method public java.security.cert.X509Certificate getClientCertificate();
    method public java.lang.String getDomainSuffixMatch();
    method public int getEapMethod();
@@ -25851,6 +25852,7 @@ package android.net.wifi {
    method public void setAltSubjectMatch(java.lang.String);
    method public void setAnonymousIdentity(java.lang.String);
    method public void setCaCertificate(java.security.cert.X509Certificate);
    method public void setCaCertificates(java.security.cert.X509Certificate[]);
    method public void setClientKeyEntry(java.security.PrivateKey, java.security.cert.X509Certificate);
    method public void setDomainSuffixMatch(java.lang.String);
    method public void setEapMethod(int);
+174 −10
Original line number Diff line number Diff line
@@ -15,12 +15,14 @@
 */
package android.net.wifi;

import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
import android.security.Credentials;
import android.text.TextUtils;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
@@ -71,6 +73,13 @@ public class WifiEnterpriseConfig implements Parcelable {
     */
    public static final String KEYSTORE_URI = "keystore://";

    /**
     * String representing the keystore URI used for wpa_supplicant,
     * Unlike #KEYSTORE_URI, this supports a list of space-delimited aliases
     * @hide
     */
    public static final String KEYSTORES_URI = "keystores://";

    /**
     * String to set the engine value to when it should be enabled.
     * @hide
@@ -101,10 +110,12 @@ public class WifiEnterpriseConfig implements Parcelable {
    public static final String REALM_KEY           = "realm";
    /** @hide */
    public static final String PLMN_KEY            = "plmn";
    /** @hide */
    public static final String CA_CERT_ALIAS_DELIMITER = " ";


    private HashMap<String, String> mFields = new HashMap<String, String>();
    private X509Certificate mCaCert;
    private X509Certificate[] mCaCerts;
    private PrivateKey mClientPrivateKey;
    private X509Certificate mClientCertificate;

@@ -136,7 +147,7 @@ public class WifiEnterpriseConfig implements Parcelable {
            dest.writeString(entry.getValue());
        }

        writeCertificate(dest, mCaCert);
        writeCertificates(dest, mCaCerts);

        if (mClientPrivateKey != null) {
            String algorithm = mClientPrivateKey.getAlgorithm();
@@ -151,6 +162,17 @@ public class WifiEnterpriseConfig implements Parcelable {
        writeCertificate(dest, mClientCertificate);
    }

    private void writeCertificates(Parcel dest, X509Certificate[] cert) {
        if (cert != null && cert.length != 0) {
            dest.writeInt(cert.length);
            for (int i = 0; i < cert.length; i++) {
                writeCertificate(dest, cert[i]);
            }
        } else {
            dest.writeInt(0);
        }
    }

    private void writeCertificate(Parcel dest, X509Certificate cert) {
        if (cert != null) {
            try {
@@ -176,7 +198,7 @@ public class WifiEnterpriseConfig implements Parcelable {
                        enterpriseConfig.mFields.put(key, value);
                    }

                    enterpriseConfig.mCaCert = readCertificate(in);
                    enterpriseConfig.mCaCerts = readCertificates(in);

                    PrivateKey userKey = null;
                    int len = in.readInt();
@@ -199,6 +221,18 @@ public class WifiEnterpriseConfig implements Parcelable {
                    return enterpriseConfig;
                }

                private X509Certificate[] readCertificates(Parcel in) {
                    X509Certificate[] certs = null;
                    int len = in.readInt();
                    if (len > 0) {
                        certs = new X509Certificate[len];
                        for (int i = 0; i < len; i++) {
                            certs[i] = readCertificate(in);
                        }
                    }
                    return certs;
                }

                private X509Certificate readCertificate(Parcel in) {
                    X509Certificate cert = null;
                    int len = in.readInt();
@@ -398,6 +432,36 @@ public class WifiEnterpriseConfig implements Parcelable {
        return getFieldValue(PASSWORD_KEY, "");
    }

    /**
     * Encode a CA certificate alias so it does not contain illegal character.
     * @hide
     */
    public static String encodeCaCertificateAlias(String alias) {
        byte[] bytes = alias.getBytes(StandardCharsets.UTF_8);
        StringBuilder sb = new StringBuilder(bytes.length * 2);
        for (byte o : bytes) {
            sb.append(String.format("%02x", o & 0xFF));
        }
        return sb.toString();
    }

    /**
     * Decode a previously-encoded CA certificate alias.
     * @hide
     */
    public static String decodeCaCertificateAlias(String alias) {
        byte[] data = new byte[alias.length() >> 1];
        for (int n = 0, position = 0; n < alias.length(); n += 2, position++) {
            data[position] = (byte) Integer.parseInt(alias.substring(n,  n + 2), 16);
        }
        try {
            return new String(data, StandardCharsets.UTF_8);
        } catch (NumberFormatException e) {
            e.printStackTrace();
            return alias;
        }
    }

    /**
     * Set CA certificate alias.
     *
@@ -411,6 +475,35 @@ public class WifiEnterpriseConfig implements Parcelable {
        setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX);
    }

    /**
     * Set CA certificate aliases. When creating installing the corresponding certificate to
     * the keystore, please use alias encoded by {@link #encodeCaCertificateAlias(String)}.
     *
     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
     * a certificate.
     * </p>
     * @param aliases identifies the certificate
     * @hide
     */
    public void setCaCertificateAliases(@Nullable String[] aliases) {
        if (aliases == null) {
            setFieldValue(CA_CERT_KEY, null, CA_CERT_PREFIX);
        } else if (aliases.length == 1) {
            // Backwards compatibility: use the original cert prefix if setting only one alias.
            setCaCertificateAlias(aliases[0]);
        } else {
            // Use KEYSTORES_URI which supports multiple aliases.
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < aliases.length; i++) {
                if (i > 0) {
                    sb.append(CA_CERT_ALIAS_DELIMITER);
                }
                sb.append(encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + aliases[i]));
            }
            setFieldValue(CA_CERT_KEY, sb.toString(), KEYSTORES_URI);
        }
    }

    /**
     * Get CA certificate alias
     * @return alias to the CA certificate
@@ -420,6 +513,32 @@ public class WifiEnterpriseConfig implements Parcelable {
        return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
    }

    /**
     * Get CA certificate aliases
     * @return alias to the CA certificate
     * @hide
     */
    @Nullable public String[] getCaCertificateAliases() {
        String value = getFieldValue(CA_CERT_KEY, "");
        if (value.startsWith(CA_CERT_PREFIX)) {
            // Backwards compatibility: parse the original alias prefix.
            return new String[] {getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX)};
        } else if (value.startsWith(KEYSTORES_URI)) {
            String values = value.substring(KEYSTORES_URI.length());

            String[] aliases = TextUtils.split(values, CA_CERT_ALIAS_DELIMITER);
            for (int i = 0; i < aliases.length; i++) {
                aliases[i] = decodeCaCertificateAlias(aliases[i]);
                if (aliases[i].startsWith(Credentials.CA_CERTIFICATE)) {
                    aliases[i] = aliases[i].substring(Credentials.CA_CERTIFICATE.length());
                }
            }
            return aliases.length != 0 ? aliases : null;
        } else {
            return TextUtils.isEmpty(value) ? null : new String[] {value};
        }
    }

    /**
     * Specify a X.509 certificate that identifies the server.
     *
@@ -431,31 +550,76 @@ public class WifiEnterpriseConfig implements Parcelable {
     * @param cert X.509 CA certificate
     * @throws IllegalArgumentException if not a CA certificate
     */
    public void setCaCertificate(X509Certificate cert) {
    public void setCaCertificate(@Nullable X509Certificate cert) {
        if (cert != null) {
            if (cert.getBasicConstraints() >= 0) {
                mCaCert = cert;
                mCaCerts = new X509Certificate[] {cert};
            } else {
                throw new IllegalArgumentException("Not a CA certificate");
            }
        } else {
            mCaCert = null;
            mCaCerts = null;
        }
    }

    /**
     * Get CA certificate
     * Get CA certificate. If multiple CA certificates are configured previously,
     * return the first one.
     * @return X.509 CA certificate
     */
    public X509Certificate getCaCertificate() {
        return mCaCert;
    @Nullable public X509Certificate getCaCertificate() {
        if (mCaCerts != null && mCaCerts.length > 0) {
            return mCaCerts[0];
        } else {
            return null;
        }
    }

    /**
     * Specify a list of X.509 certificates that identifies the server. The validation
     * passes if the CA of server certificate matches one of the given certificates.

     * <p>Default names are automatically assigned to the certificates and used
     * with this configuration. The framework takes care of installing the
     * certificates when the config is saved and removing the certificates when
     * the config is removed.
     *
     * @param certs X.509 CA certificates
     * @throws IllegalArgumentException if any of the provided certificates is
     *     not a CA certificate
     */
    public void setCaCertificates(@Nullable X509Certificate[] certs) {
        if (certs != null) {
            X509Certificate[] newCerts = new X509Certificate[certs.length];
            for (int i = 0; i < certs.length; i++) {
                if (certs[i].getBasicConstraints() >= 0) {
                    newCerts[i] = certs[i];
                } else {
                    throw new IllegalArgumentException("Not a CA certificate");
                }
            }
            mCaCerts = newCerts;
        } else {
            mCaCerts = null;
        }
    }

    /**
     * Get CA certificates.
     */
    @Nullable public X509Certificate[] getCaCertificates() {
        if (mCaCerts != null || mCaCerts.length > 0) {
            return mCaCerts;
        } else {
            return null;
        }
    }

    /**
     * @hide
     */
    public void resetCaCertificate() {
        mCaCert = null;
        mCaCerts = null;
    }

    /** Set Client certificate alias.