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

Commit 9d4f41f2 authored by Jimmy Chen's avatar Jimmy Chen Committed by Android (Google) Code Review
Browse files

Merge "wifi: common name support in PPS-MO profile"

parents 8bd25aff 3c9c642f
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.net.wifi.hotspot2;

import android.annotation.Nullable;
import android.net.wifi.hotspot2.pps.Credential;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.net.wifi.hotspot2.pps.Policy;
@@ -77,6 +78,29 @@ public final class PasspointConfiguration implements Parcelable {
     */
    public HomeSp getHomeSp() { return mHomeSp; }

    /**
     * Configurations under AAAServerTrustedNames subtree.
     */
    private String[] mAaaServerTrustedNames = null;
    /**
     * Set the AAA server trusted names information.
     *
     * @param aaaServerTrustedNames The AAA server trusted names information to set to
     * @hide
     */
    public void setAaaServerTrustedNames(@Nullable String[] aaaServerTrustedNames) {
        mAaaServerTrustedNames = aaaServerTrustedNames;
    }
    /**
     * Get the AAA server trusted names information.
     *
     * @return AAA server trusted names information
     * @hide
     */
    public @Nullable String[] getAaaServerTrustedNames() {
        return mAaaServerTrustedNames;
    }

    /**
     * Configurations under Credential subtree.
     */
@@ -409,6 +433,7 @@ public final class PasspointConfiguration implements Parcelable {
        mUsageLimitTimeLimitInMinutes = source.mUsageLimitTimeLimitInMinutes;
        mUsageLimitUsageTimePeriodInMinutes = source.mUsageLimitUsageTimePeriodInMinutes;
        mServiceFriendlyNames = source.mServiceFriendlyNames;
        mAaaServerTrustedNames = source.mAaaServerTrustedNames;
    }

    @Override
@@ -432,6 +457,7 @@ public final class PasspointConfiguration implements Parcelable {
        dest.writeLong(mUsageLimitStartTimeInMillis);
        dest.writeLong(mUsageLimitDataLimit);
        dest.writeLong(mUsageLimitTimeLimitInMinutes);
        dest.writeStringArray(mAaaServerTrustedNames);
        Bundle bundle = new Bundle();
        bundle.putSerializable("serviceFriendlyNames",
                (HashMap<String, String>) mServiceFriendlyNames);
@@ -448,6 +474,8 @@ public final class PasspointConfiguration implements Parcelable {
        }
        PasspointConfiguration that = (PasspointConfiguration) thatObject;
        return (mHomeSp == null ? that.mHomeSp == null : mHomeSp.equals(that.mHomeSp))
                && (mAaaServerTrustedNames == null ? that.mAaaServerTrustedNames == null
                : Arrays.equals(mAaaServerTrustedNames, that.mAaaServerTrustedNames))
                && (mCredential == null ? that.mCredential == null
                : mCredential.equals(that.mCredential))
                && (mPolicy == null ? that.mPolicy == null : mPolicy.equals(that.mPolicy))
@@ -517,6 +545,10 @@ public final class PasspointConfiguration implements Parcelable {
            builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet())
                    .append("\n");
        }
        if (mAaaServerTrustedNames != null) {
            builder.append("AAAServerTrustedNames: ")
                    .append(String.join(";", mAaaServerTrustedNames)).append("\n");
        }
        if (mServiceFriendlyNames != null) {
            builder.append("ServiceFriendlyNames: ").append(mServiceFriendlyNames);
        }
@@ -619,6 +651,7 @@ public final class PasspointConfiguration implements Parcelable {
                config.setUsageLimitStartTimeInMillis(in.readLong());
                config.setUsageLimitDataLimit(in.readLong());
                config.setUsageLimitTimeLimitInMinutes(in.readLong());
                config.setAaaServerTrustedNames(in.createStringArray());
                Bundle bundle = in.readBundle();
                Map<String, String> friendlyNamesMap = (HashMap) bundle.getSerializable(
                        "serviceFriendlyNames");
+130 −3
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;

import org.xml.sax.SAXException;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
@@ -36,8 +38,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;

import org.xml.sax.SAXException;

/**
 * Utility class for converting OMA-DM (Open Mobile Alliance's Device Management)
 * PPS-MO (PerProviderSubscription Management Object) XML tree to a
@@ -146,6 +146,47 @@ public final class PpsMoParser {
    private static final String NODE_CREDENTIAL_PRIORITY = "CredentialPriority";
    private static final String NODE_EXTENSION = "Extension";

    /**
     * Fields under Extension/Android subtree.
     */
    /*
     * This node is used to put Android specific extension nodes and must be put
     * under "Extension" node. Nodes with unknown names are allowed under this subtree.
     * If there is any new node added in later release, it won't break older release parsing.
     * <p>
     * Ex:
     * <Node>
     *   <NodeName>Extension</NodeName>
     *   <Node>
     *     <NodeName>Android</NodeName>
     *     <Node>
     *       <NodeName>AndroidSpecificAttribute</NodeName>
     *       <Value>AndroidSpecificValue</Value>
     *     </Node>
     *     <Node>
     *       <NodeName>AndroidSpecificAttribute2</NodeName>
     *       <Value>AndroidSpecificValue2</Value>
     *     </Node>
     *   </Node>
     * </Node>
     */
    private static final String NODE_VENDOR_ANDROID = "Android";
    /*
     * This node describes AAA server trusted names. The trusted name must be put in
     * a leaf named "FQDN". More than one trusted names can be provided by using
     * semicolons to separate the strings (e.g., example.org;example.com).
     * <p>
     * Ex:
     * <Node>
     *   <NodeName>AAAServerTrustedNames</NodeName>
     *   <Node>
     *     <NodeName>FQDN</NodeName>
     *     <Value>trusted.com;auth.net</Value>
     *  </Node>
     * <Node>
     */
    private static final String NODE_AAA_SERVER_TRUSTED_NAMES = "AAAServerTrustedNames";

    /**
     * Fields under HomeSP subtree.
     */
@@ -633,7 +674,7 @@ public final class PpsMoParser {
                    break;
                case NODE_EXTENSION:
                    // All vendor specific information will be under this node.
                    Log.d(TAG, "Ignore Extension node for vendor specific information");
                    parseExtension(child, config);
                    break;
                default:
                    throw new ParsingException("Unknown node: " + child.getName());
@@ -1571,6 +1612,92 @@ public final class PpsMoParser {
        }
    }

    /**
     * Parse configurations under PerProviderSubscription/Extension/Android/AAAServerTrustedNames
     * subtree.
     *
     * @param node PPSNode representing the root of the
     *             PerProviderSubscription/Extension/Android/AAAServerTrustedNames subtree
     * @return String[] list of trusted name
     * @throws ParsingException
     */
    private static String[] parseAaaServerTrustedNames(PPSNode node) throws ParsingException {
        if (node.isLeaf()) {
            throw new ParsingException("Leaf node not expected for AAAServerTrustedNames instance");
        }
        String fqdnListStr = null;
        String[] fqdnListArray = null;
        for (PPSNode child : node.getChildren()) {
            switch (child.getName()) {
                case NODE_FQDN:
                    fqdnListStr = getPpsNodeValue(child);
                    fqdnListArray = fqdnListStr.split(";");
                    break;
                default:
                    throw new ParsingException(
                            "Unknown node under AAAServerTrustedNames instance: "
                            + child.getName());
            }
        }
        if (fqdnListArray == null) {
            throw new ParsingException("AAAServerTrustedNames instance missing FQDN field");
        }

        return fqdnListArray;
    }

    /**
     * Parse configurations under PerProviderSubscription/Extension/Android subtree.
     *
     * @param node PPSNode representing the root of PerProviderSubscription/Extension
     *             subtree
     * @param config Instance of {@link PasspointConfiguration}
     * @throws ParsingException
     */
    private static void parseVendorAndroidExtension(PPSNode node, PasspointConfiguration config)
            throws ParsingException {
        if (node.isLeaf()) {
            throw new ParsingException("Leaf node not expected for Extension");
        }
        for (PPSNode child : node.getChildren()) {
            switch (child.getName()) {
                case NODE_AAA_SERVER_TRUSTED_NAMES:
                    config.setAaaServerTrustedNames(parseAaaServerTrustedNames(child));
                    break;
                default:
                    // Don't raise an exception for unknown nodes to avoid breaking old release
                    Log.w(TAG, "Unknown node under Android Extension: " + child.getName());
            }
        }
    }

    /**
     * Parse configurations under PerProviderSubscription/Extension subtree.
     *
     * @param node PPSNode representing the root of PerProviderSubscription/Extension
     *             subtree
     * @param config Instance of {@link PasspointConfiguration}
     * @throws ParsingException
     */
    private static void parseExtension(PPSNode node, PasspointConfiguration config)
            throws ParsingException {
        if (node.isLeaf()) {
            throw new ParsingException("Leaf node not expected for Extension");
        }
        for (PPSNode child : node.getChildren()) {
            switch (child.getName()) {
                case NODE_VENDOR_ANDROID:
                    parseVendorAndroidExtension(child, config);
                    break;
                default:
                    // Unknown nodes under Extension won't raise exception.
                    // This allows adding new nodes in the future and
                    // won't break older release.
                    Log.w(TAG, "Unknown node under Extension: " + child.getName());
            }
        }
    }

    /**
     * Convert a hex string to a byte array.
     *
+1 −0
Original line number Diff line number Diff line
@@ -1135,6 +1135,7 @@ public final class Credential implements Parcelable {
            Log.d(TAG, "Missing CA Certificate for user credential");
            return false;
        }

        return true;
    }

+24 −0
Original line number Diff line number Diff line
@@ -19,6 +19,30 @@
          <NodeName>VendorSpecific</NodeName>
          <Value>Test</Value>
        </Node>
        <Node>
          <NodeName>VendorExtension</NodeName>
          <Node>
            <NodeName>VendorAttribute</NodeName>
            <Value>VendorValue</Value>
          </Node>
        </Node>
        <Node>
          <NodeName>Android</NodeName>
          <Node>
            <NodeName>AAAServerTrustedNames</NodeName>
            <Node>
              <NodeName>FQDN</NodeName>
              <Value>trusted.fqdn.com;another-trusted.fqdn.com</Value>
            </Node>
          </Node>
          <Node>
            <NodeName>NewSubTree</NodeName>
            <Node>
              <NodeName>NewAttribute</NodeName>
              <Value>NewValue</Value>
            </Node>
          </Node>
        </Node>
      </Node>
      <Node>
        <NodeName>HomeSP</NodeName>
+30 −0
Original line number Diff line number Diff line
@@ -149,6 +149,8 @@ public class PasspointConfigurationTest {
        PasspointConfiguration config = new PasspointConfiguration();
        config.setUpdateIdentifier(1234);
        config.setHomeSp(createHomeSp());
        config.setAaaServerTrustedNames(
                new String[] {"trusted.fqdn.com", "another-trusted.fqdn.com"});
        config.setCredential(createCredential());
        config.setPolicy(createPolicy());
        config.setSubscriptionUpdate(createSubscriptionUpdate());
@@ -283,6 +285,19 @@ public class PasspointConfigurationTest {
        verifyParcel(config);
    }

    /**
     * Verify parcel read/write for a configuration that doesn't contain AAA server trusted names
     * list.
     *
     * @throws Exception
     */
    @Test
    public void verifyParcelWithoutAaaServerTrustedNames() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setAaaServerTrustedNames(null);
        verifyParcel(config);
    }

    /**
     * Verify that a default/empty configuration is invalid.
     *
@@ -382,6 +397,21 @@ public class PasspointConfigurationTest {
        assertFalse(config.validateForR2());
    }

    /**
     * Verify that a configuration without AAA server trusted names is valid for R1 and R2,
     * since AAA server trusted names are optional for R1 and R2.
     *
     * @throws Exception
     */
    @Test
    public void validateConfigWithoutAaaServerTrustedNames() throws Exception {
        PasspointConfiguration config = createConfig();
        config.setAaaServerTrustedNames(null);

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

    /**
     * Verify that a configuration with a trust root certificate URL exceeding the max size
     * is invalid.
Loading