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: Ecco Park <eccopark@google.com>
This commit is contained in:
Ecco Park
2019-01-09 11:04:27 -08:00
parent 88b835f9b8
commit ccbce520d8
2 changed files with 61 additions and 25 deletions

View File

@@ -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;
}

View File

@@ -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) {
Credential.CertificateCredential certCred,
Credential.SimCredential simCred,
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());
}
/**