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

Commit ccbce520 authored by Ecco Park's avatar Ecco Park
Browse files

passpoint-r2: handle multiple CA certificates



This is required to save the AAA root CA certs for PPS MO.
Put @hide for new API because this is only used for wifi service.

Bug: 117717842
Test: ./frameworks/base/wifi/tests/runtests.sh
Test: tested with R1 AP for installing profile and R2 AP for connection
Change-Id: Ib84c030024d3429140cd80bb622fd23ca608b9bb
Signed-off-by: default avatarEcco Park <eccopark@google.com>
parent 88b835f9
Loading
Loading
Loading
Loading
+45 −14
Original line number Diff line number Diff line
@@ -572,7 +572,7 @@ public final class Credential implements Parcelable {

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

        @Override
@@ -842,24 +842,50 @@ public final class Credential implements Parcelable {
    }

    /**
     * CA (Certificate Authority) X509 certificate.
     * CA (Certificate Authority) X509 certificates.
     */
    private X509Certificate mCaCertificate = null;
    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) {
        mCaCertificate = 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
     * @return CA certificate associated with this credential, {@code null} if certificate is not
     * set or certificate is more than one.
     */
    public X509Certificate getCaCertificate() {
        return mCaCertificate;
        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;
    }

    /**
@@ -933,7 +959,11 @@ public final class Credential implements Parcelable {
                mClientCertificateChain = Arrays.copyOf(source.mClientCertificateChain,
                                                        source.mClientCertificateChain.length);
            }
            mCaCertificate = source.mCaCertificate;
            if (source.mCaCertificates != null) {
                mCaCertificates = Arrays.copyOf(source.mCaCertificates,
                        source.mCaCertificates.length);
            }

            mClientPrivateKey = source.mClientPrivateKey;
        }
    }
@@ -952,7 +982,7 @@ public final class Credential implements Parcelable {
        dest.writeParcelable(mUserCredential, flags);
        dest.writeParcelable(mCertCredential, flags);
        dest.writeParcelable(mSimCredential, flags);
        ParcelUtil.writeCertificate(dest, mCaCertificate);
        ParcelUtil.writeCertificates(dest, mCaCertificates);
        ParcelUtil.writeCertificates(dest, mClientCertificateChain);
        ParcelUtil.writePrivateKey(dest, mClientPrivateKey);
    }
@@ -977,16 +1007,17 @@ public final class Credential implements Parcelable {
                    : mCertCredential.equals(that.mCertCredential))
                && (mSimCredential == null ? that.mSimCredential == null
                    : mSimCredential.equals(that.mSimCredential))
                && isX509CertificateEquals(mCaCertificate, that.mCaCertificate)
                && isX509CertificatesEquals(mCaCertificates, that.mCaCertificates)
                && isX509CertificatesEquals(mClientCertificateChain, that.mClientCertificateChain)
                && isPrivateKeyEquals(mClientPrivateKey, that.mClientPrivateKey);
    }

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

    @Override
@@ -1067,7 +1098,7 @@ public final class Credential implements Parcelable {
                credential.setUserCredential(in.readParcelable(null));
                credential.setCertCredential(in.readParcelable(null));
                credential.setSimCredential(in.readParcelable(null));
                credential.setCaCertificate(ParcelUtil.readCertificate(in));
                credential.setCaCertificates(ParcelUtil.readCertificates(in));
                credential.setClientCertificateChain(ParcelUtil.readCertificates(in));
                credential.setClientPrivateKey(ParcelUtil.readPrivateKey(in));
                return credential;
@@ -1100,7 +1131,7 @@ public final class Credential implements Parcelable {

        // CA certificate is required for R1 Passpoint profile.
        // For R2, it is downloaded using cert URL provided in PPS MO after validation completes.
        if (isR1 && mCaCertificate == null) {
        if (isR1 && mCaCertificates == null) {
            Log.d(TAG, "Missing CA Certificate for user credential");
            return false;
        }
@@ -1131,7 +1162,7 @@ public final class Credential implements Parcelable {
        // Verify required key and certificates for certificate credential.
        // CA certificate is required for R1 Passpoint profile.
        // For R2, it is downloaded using cert URL provided in PPS MO after validation completes.
        if (isR1 && mCaCertificate == null) {
        if (isR1 && mCaCertificates == null) {
            Log.d(TAG, "Missing CA Certificate for certificate credential");
            return false;
        }
+16 −11
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.net.wifi.hotspot2.pps;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

@@ -44,17 +45,16 @@ public class CredentialTest {
     * @param userCred Instance of UserCredential
     * @param certCred Instance of CertificateCredential
     * @param simCred Instance of SimCredential
     * @param caCert CA certificate
     * @param clientCertificateChain Chain of client certificates
     * @param clientPrivateKey Client private key
     * @param caCerts CA certificates
     * @return {@link Credential}
     */
    private static Credential createCredential(Credential.UserCredential userCred,
            Credential.CertificateCredential certCred,
            Credential.SimCredential simCred,
                                               X509Certificate caCert,
                                               X509Certificate[] clientCertificateChain,
                                               PrivateKey clientPrivateKey) {
            X509Certificate[] clientCertificateChain, PrivateKey clientPrivateKey,
            X509Certificate... caCerts) {
        Credential cred = new Credential();
        cred.setCreationTimeInMillis(123455L);
        cred.setExpirationTimeInMillis(2310093L);
@@ -63,7 +63,11 @@ public class CredentialTest {
        cred.setUserCredential(userCred);
        cred.setCertCredential(certCred);
        cred.setSimCredential(simCred);
        cred.setCaCertificate(caCert);
        if (caCerts != null && caCerts.length == 1) {
            cred.setCaCertificate(caCerts[0]);
        } else {
            cred.setCaCertificates(caCerts);
        }
        cred.setClientCertificateChain(clientCertificateChain);
        cred.setClientPrivateKey(clientPrivateKey);
        return cred;
@@ -80,8 +84,8 @@ public class CredentialTest {
        certCred.setCertType("x509v3");
        certCred.setCertSha256Fingerprint(
                MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded()));
        return createCredential(null, certCred, null, FakeKeys.CA_CERT0,
                new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1);
        return createCredential(null, certCred, null, new X509Certificate[] {FakeKeys.CLIENT_CERT},
                FakeKeys.RSA_KEY1, FakeKeys.CA_CERT0, FakeKeys.CA_CERT1);
    }

    /**
@@ -93,7 +97,7 @@ public class CredentialTest {
        Credential.SimCredential simCred = new Credential.SimCredential();
        simCred.setImsi("1234*");
        simCred.setEapType(EAPConstants.EAP_SIM);
        return createCredential(null, null, simCred, null, null, null);
        return createCredential(null, null, simCred, null, null, (X509Certificate[]) null);
    }

    /**
@@ -110,7 +114,7 @@ public class CredentialTest {
        userCred.setSoftTokenApp("TestApp");
        userCred.setEapType(EAPConstants.EAP_TTLS);
        userCred.setNonEapInnerMethod("MS-CHAP");
        return createCredential(userCred, null, null, FakeKeys.CA_CERT0, null, null);
        return createCredential(userCred, null, null, null, null, FakeKeys.CA_CERT0);
    }

    private static void verifyParcel(Credential writeCred) {
@@ -120,6 +124,7 @@ public class CredentialTest {
        parcel.setDataPosition(0);    // Rewind data position back to the beginning for read.
        Credential readCred = Credential.CREATOR.createFromParcel(parcel);
        assertTrue(readCred.equals(writeCred));
        assertEquals(writeCred.hashCode(), readCred.hashCode());
    }

    /**