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

Commit 465a8257 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "passpoint-r2: add validate function for R2 configuration"

parents cc79a989 b0499e95
Loading
Loading
Loading
Loading
+36 −6
Original line number Diff line number Diff line
@@ -20,10 +20,10 @@ import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
import android.net.wifi.hotspot2.pps.UpdateParameter;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.os.Parcel;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
@@ -467,24 +467,54 @@ public final class PasspointConfiguration implements Parcelable {
    }

    /**
     * Validate the configuration data.
     * Validate the R1 configuration data.
     *
     * @return true on success or false on failure
     * @hide
     */
    public boolean validate() {
        if (mHomeSp == null || !mHomeSp.validate()) {
        // Optional: PerProviderSubscription/<X+>/SubscriptionUpdate
        if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) {
            return false;
        }
        if (mCredential == null || !mCredential.validate()) {
        return validateForCommonR1andR2(true);
    }

    /**
     * Validate the R2 configuration data.
     *
     * @return true on success or false on failure
     * @hide
     */
    public boolean validateForR2() {
        // Required: PerProviderSubscription/UpdateIdentifier
        if (mUpdateIdentifier == Integer.MIN_VALUE) {
            return false;
        }
        if (mPolicy != null && !mPolicy.validate()) {

        // Required: PerProviderSubscription/<X+>/SubscriptionUpdate
        if (mSubscriptionUpdate == null || !mSubscriptionUpdate.validate()) {
            return false;
        }
        if (mSubscriptionUpdate != null && !mSubscriptionUpdate.validate()) {
        return validateForCommonR1andR2(false);
    }

    private boolean validateForCommonR1andR2(boolean isR1) {
        // Required: PerProviderSubscription/<X+>/HomeSP
        if (mHomeSp == null || !mHomeSp.validate()) {
            return false;
        }

        // Required: PerProviderSubscription/<X+>/Credential
        if (mCredential == null || !mCredential.validate(isR1)) {
            return false;
        }

        // Optional: PerProviderSubscription/<X+>/Policy
        if (mPolicy != null && !mPolicy.validate()) {
            return false;
        }

        if (mTrustRootCertList != null) {
            for (Map.Entry<String, byte[]> entry : mTrustRootCertList.entrySet()) {
                String url = entry.getKey();
+16 −8
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ package android.net.wifi.hotspot2.pps;

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

@@ -1019,10 +1019,11 @@ public final class Credential implements Parcelable {
    /**
     * Validate the configuration data.
     *
     * @param isR1 {@code true} if the configuration is for R1
     * @return true on success or false on failure
     * @hide
     */
    public boolean validate() {
    public boolean validate(boolean isR1) {
        if (TextUtils.isEmpty(mRealm)) {
            Log.d(TAG, "Missing realm");
            return false;
@@ -1035,11 +1036,11 @@ public final class Credential implements Parcelable {

        // Verify the credential.
        if (mUserCredential != null) {
            if (!verifyUserCredential()) {
            if (!verifyUserCredential(isR1)) {
                return false;
            }
        } else if (mCertCredential != null) {
            if (!verifyCertCredential()) {
            if (!verifyCertCredential(isR1)) {
                return false;
            }
        } else if (mSimCredential != null) {
@@ -1081,9 +1082,10 @@ public final class Credential implements Parcelable {
    /**
     * Verify user credential.
     *
     * @param isR1 {@code true} if credential is for R1
     * @return true if user credential is valid, false otherwise.
     */
    private boolean verifyUserCredential() {
    private boolean verifyUserCredential(boolean isR1) {
        if (mUserCredential == null) {
            Log.d(TAG, "Missing user credential");
            return false;
@@ -1095,7 +1097,10 @@ public final class Credential implements Parcelable {
        if (!mUserCredential.validate()) {
            return false;
        }
        if (mCaCertificate == null) {

        // 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) {
            Log.d(TAG, "Missing CA Certificate for user credential");
            return false;
        }
@@ -1106,9 +1111,10 @@ public final class Credential implements Parcelable {
     * Verify certificate credential, which is used for EAP-TLS.  This will verify
     * that the necessary client key and certificates are provided.
     *
     * @param isR1 {@code true} if credential is for R1
     * @return true if certificate credential is valid, false otherwise.
     */
    private boolean verifyCertCredential() {
    private boolean verifyCertCredential(boolean isR1) {
        if (mCertCredential == null) {
            Log.d(TAG, "Missing certificate credential");
            return false;
@@ -1123,7 +1129,9 @@ public final class Credential implements Parcelable {
        }

        // Verify required key and certificates for certificate credential.
        if (mCaCertificate == null) {
        // 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) {
            Log.d(TAG, "Missing CA Certificate for certificate credential");
            return false;
        }
+36 −4
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ public class PasspointConfigurationTest {
     */
    private static PasspointConfiguration createConfig() {
        PasspointConfiguration config = new PasspointConfiguration();
        config.setUpdateIdentifier(1234);
        config.setHomeSp(createHomeSp());
        config.setCredential(createCredential());
        config.setPolicy(createPolicy());
@@ -273,18 +274,37 @@ public class PasspointConfigurationTest {
    @Test
    public void validateDefaultConfig() throws Exception {
        PasspointConfiguration config = new PasspointConfiguration();

        assertFalse(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
     * Verify that a configuration contained all fields is valid.
     * Verify that a configuration containing all fields is valid for R1/R2.
     *
     * @throws Exception
     */
    @Test
    public void validateFullConfig() throws Exception {
        PasspointConfiguration config = createConfig();

        assertTrue(config.validate());
        assertTrue(config.validateForR2());
    }

    /**
     * Verify that a configuration containing all fields except for UpdateIdentifier is valid for
     * R1, but invalid for R2.
     *
     * @throws Exception
     */
    @Test
    public void validateFullConfigWithoutUpdateIdentifier() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setUpdateIdentifier(Integer.MIN_VALUE);

        assertTrue(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
@@ -296,7 +316,9 @@ public class PasspointConfigurationTest {
    public void validateConfigWithoutCredential() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setCredential(null);

        assertFalse(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
@@ -308,12 +330,14 @@ public class PasspointConfigurationTest {
    public void validateConfigWithoutHomeSp() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setHomeSp(null);

        assertFalse(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
     * Verify that a configuration without Policy is valid, since Policy configurations
     * are optional (applied for Hotspot 2.0 Release only).
     * are optional for R1 and R2.
     *
     * @throws Exception
     */
@@ -321,12 +345,14 @@ public class PasspointConfigurationTest {
    public void validateConfigWithoutPolicy() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setPolicy(null);

        assertTrue(config.validate());
        assertTrue(config.validateForR2());
    }

    /**
     * Verify that a configuration without subscription update is valid, since subscription
     * update configurations are optional (applied for Hotspot 2.0 Release only).
     * Verify that a configuration without subscription update is valid for R1 and invalid for R2,
     * since subscription update configuration is only applicable for R2.
     *
     * @throws Exception
     */
@@ -334,7 +360,9 @@ public class PasspointConfigurationTest {
    public void validateConfigWithoutSubscriptionUpdate() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setSubscriptionUpdate(null);

        assertTrue(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
@@ -352,12 +380,15 @@ public class PasspointConfigurationTest {
        trustRootCertList.put(new String(rawUrlBytes, StandardCharsets.UTF_8),
                new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        config.setTrustRootCertList(trustRootCertList);

        assertFalse(config.validate());

        trustRootCertList = new HashMap<>();
        trustRootCertList.put(null, new byte[CERTIFICATE_FINGERPRINT_BYTES]);
        config.setTrustRootCertList(trustRootCertList);

        assertFalse(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
@@ -382,6 +413,7 @@ public class PasspointConfigurationTest {
        trustRootCertList.put("test.cert.com", null);
        config.setTrustRootCertList(trustRootCertList);
        assertFalse(config.validate());
        assertFalse(config.validateForR2());
    }

    /**
+116 −22
Original line number Diff line number Diff line
@@ -24,14 +24,13 @@ import android.net.wifi.FakeKeys;
import android.os.Parcel;
import android.support.test.filters.SmallTest;

import org.junit.Test;

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 org.junit.Test;

/**
 * Unit tests for {@link android.net.wifi.hotspot2.pps.CredentialTest}.
@@ -169,7 +168,12 @@ public class CredentialTest {
    @Test
    public void validateUserCredential() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        assertTrue(cred.validate());

        // For R1 validation
        assertTrue(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -181,7 +185,12 @@ public class CredentialTest {
    public void validateUserCredentialWithoutCaCert() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.setCaCertificate(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -193,7 +202,12 @@ public class CredentialTest {
    public void validateUserCredentialWithEapTls() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.getUserCredential().setEapType(EAPConstants.EAP_TLS);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }


@@ -206,7 +220,12 @@ public class CredentialTest {
    public void validateUserCredentialWithoutRealm() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.setRealm(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -218,7 +237,12 @@ public class CredentialTest {
    public void validateUserCredentialWithoutUsername() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.getUserCredential().setUsername(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -230,7 +254,12 @@ public class CredentialTest {
    public void validateUserCredentialWithoutPassword() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.getUserCredential().setPassword(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -242,7 +271,12 @@ public class CredentialTest {
    public void validateUserCredentialWithoutAuthMethod() throws Exception {
        Credential cred = createCredentialWithUserCredential();
        cred.getUserCredential().setNonEapInnerMethod(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -255,7 +289,12 @@ public class CredentialTest {
    @Test
    public void validateCertCredential() throws Exception {
        Credential cred = createCredentialWithCertificateCredential();
        assertTrue(cred.validate());

        // For R1 validation
        assertTrue(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(true));
    }

    /**
@@ -267,7 +306,12 @@ public class CredentialTest {
    public void validateCertCredentialWithoutCaCert() throws Exception {
        Credential cred = createCredentialWithCertificateCredential();
        cred.setCaCertificate(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -279,7 +323,12 @@ public class CredentialTest {
    public void validateCertCredentialWithoutClientCertChain() throws Exception {
        Credential cred = createCredentialWithCertificateCredential();
        cred.setClientCertificateChain(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -291,7 +340,12 @@ public class CredentialTest {
    public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
        Credential cred = createCredentialWithCertificateCredential();
        cred.setClientPrivateKey(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -304,7 +358,12 @@ public class CredentialTest {
    public void validateCertCredentialWithMismatchFingerprint() throws Exception {
        Credential cred = createCredentialWithCertificateCredential();
        cred.getCertCredential().setCertSha256Fingerprint(new byte[32]);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -315,7 +374,12 @@ public class CredentialTest {
    @Test
    public void validateSimCredentialWithEapSim() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        assertTrue(cred.validate());

        // For R1 validation
        assertTrue(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -327,7 +391,12 @@ public class CredentialTest {
    public void validateSimCredentialWithEapAka() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        cred.getSimCredential().setEapType(EAPConstants.EAP_AKA);
        assertTrue(cred.validate());

        // For R1 validation
        assertTrue(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -339,7 +408,12 @@ public class CredentialTest {
    public void validateSimCredentialWithEapAkaPrime() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        cred.getSimCredential().setEapType(EAPConstants.EAP_AKA_PRIME);
        assertTrue(cred.validate());

        // For R1 validation
        assertTrue(cred.validate(true));

        // For R2 validation
        assertTrue(cred.validate(false));
    }

    /**
@@ -351,7 +425,12 @@ public class CredentialTest {
    public void validateSimCredentialWithoutIMSI() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        cred.getSimCredential().setImsi(null);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -363,7 +442,12 @@ public class CredentialTest {
    public void validateSimCredentialWithInvalidIMSI() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        cred.getSimCredential().setImsi("dummy");
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -375,7 +459,12 @@ public class CredentialTest {
    public void validateSimCredentialWithEapTls() throws Exception {
        Credential cred = createCredentialWithSimCredential();
        cred.getSimCredential().setEapType(EAPConstants.EAP_TLS);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**
@@ -391,7 +480,12 @@ public class CredentialTest {
        simCredential.setImsi("1234*");
        simCredential.setEapType(EAPConstants.EAP_SIM);
        cred.setSimCredential(simCredential);
        assertFalse(cred.validate());

        // For R1 validation
        assertFalse(cred.validate(true));

        // For R2 validation
        assertFalse(cred.validate(false));
    }

    /**