diff options
| author | 2016-10-26 22:13:57 +0000 | |
|---|---|---|
| committer | 2016-10-26 22:13:57 +0000 | |
| commit | 1a5da2b533940e357f83d2058d39cf87c5ecd428 (patch) | |
| tree | d7a7849d698ac64193ae2bf1996f8819bc6786f9 | |
| parent | e266c375598acb4c3f72976485379f6148c9ebcf (diff) | |
| parent | bae4becf6997843cddf0d0c1dfa1f63e4580e6f8 (diff) | |
Merge changes I69c1931b,I6b08f52d
* changes:
wifi: hotspot2: omadm: add XML parser for parsing OMA-DM XML string
wifi: hotspot2: initial implementation of PasspointConfiguration
12 files changed, 1155 insertions, 0 deletions
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl new file mode 100644 index 000000000000..6b1cea8edb5a --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2; + +parcelable PasspointConfiguration; diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java new file mode 100644 index 000000000000..18aae534d098 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2; + +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSP; +import android.os.Parcelable; +import android.os.Parcel; + +/** + * Class representing Passpoint configuration. This contains configurations specified in + * PerProviderSubscription (PPS) Management Object (MO) tree. + * + * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 + * Release 2 Technical Specification. + * + * Currently, only HomeSP and Credential subtrees are supported. + * + * @hide + */ +public final class PasspointConfiguration implements Parcelable { + public HomeSP homeSp = null; + public Credential credential = null; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(homeSp, flags); + dest.writeParcelable(credential, flags); + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof PasspointConfiguration)) { + return false; + } + PasspointConfiguration that = (PasspointConfiguration) thatObject; + return (homeSp == null ? that.homeSp == null : homeSp.equals(that.homeSp)) && + (credential == null ? that.credential == null : + credential.equals(that.credential)); + } + + public static final Creator<PasspointConfiguration> CREATOR = + new Creator<PasspointConfiguration>() { + @Override + public PasspointConfiguration createFromParcel(Parcel in) { + PasspointConfiguration config = new PasspointConfiguration(); + config.homeSp = in.readParcelable(null); + config.credential = in.readParcelable(null); + return config; + } + @Override + public PasspointConfiguration[] newArray(int size) { + return new PasspointConfiguration[size]; + } + }; +} diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java new file mode 100644 index 000000000000..e87698cb7ed1 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/omadm/XMLNode.java @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.omadm; + +import android.text.TextUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * A class represent a node in an XML tree. Each node is an XML element. + * Used by {@link XMLParser} for parsing/converting each XML element to XMLNode. + * + * @hide + */ +public class XMLNode { + private final String mTag; + private final List<XMLNode> mChildren; + private final XMLNode mParent; + private StringBuilder mTextBuilder; + private String mText; + + public XMLNode(XMLNode parent, String tag) { + mTag = tag; + mParent = parent; + mChildren = new ArrayList<>(); + mTextBuilder = new StringBuilder(); + mText = null; + } + + /** + * Adding a text to this node. Invoked by {@link XMLParser#characters}. + * + * @param text String to be added + */ + public void addText(String text) { + mTextBuilder.append(text); + } + + /** + * Adding a child node to this node. Invoked by {@link XMLParser#startElement}. + * + * @param child XMLNode to be added + */ + public void addChild(XMLNode child) { + mChildren.add(child); + } + + /** + * Invoked when the end of the XML element is detected. Used for further processing + * of the text enclosed within this XML element. Invoked by {@link XMLParser#endElement}. + */ + public void close() { + // Remove the leading and the trailing whitespaces. + mText = mTextBuilder.toString().trim(); + mTextBuilder = null; + } + + public String getTag() { + return mTag; + } + + public XMLNode getParent() { + return mParent; + } + + public String getText() { + return mText; + } + + public List<XMLNode> getChildren() { + return mChildren; + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof XMLNode)) { + return false; + } + XMLNode that = (XMLNode) thatObject; + + return TextUtils.equals(mTag, that.mTag) && + TextUtils.equals(mText, that.mText) && + mChildren.equals(that.mChildren); + } +} diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java new file mode 100644 index 000000000000..948052c9bf8a --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/omadm/XMLParser.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.omadm; + +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +import android.text.TextUtils; + +import java.io.IOException; +import java.io.StringReader; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +/** + * Class for parsing an XML string to an XML tree represented by {@link XMLNode}. + * + * The original XML string: + * <root> + * <tag1>text1</tag1> + * <tag2> + * <tag3>text3</tag3> + * </tag2> + * </root> + * + * The XML tree representation: + * [root] + * | + * | + * [tag1, text1]-----|-----[tag2] + * | + * | + * [tag3, text3] + * + * @hide + */ +public class XMLParser extends DefaultHandler { + private XMLNode mRoot = null; + private XMLNode mCurrent = null; + + public XMLNode parse(String text) throws IOException, SAXException { + if (TextUtils.isEmpty(text)) { + throw new IOException("XML string not provided"); + } + + // Reset pointers. + mRoot = null; + mCurrent = null; + + try { + SAXParser parser = SAXParserFactory.newInstance().newSAXParser(); + parser.parse(new InputSource(new StringReader(text)), this); + return mRoot; + } catch (ParserConfigurationException pce) { + throw new SAXException(pce); + } + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes attributes) + throws SAXException { + XMLNode parent = mCurrent; + + mCurrent = new XMLNode(parent, qName); + + if (mRoot == null) { + mRoot = mCurrent; + } else if (parent == null) { + throw new SAXException("More than one root nodes"); + } else { + parent.addChild(mCurrent); + } + } + + @Override + public void endElement(String uri, String localName, String qName) throws SAXException { + if (!qName.equals(mCurrent.getTag())) { + throw new SAXException("End tag '" + qName + "' doesn't match current node: " + + mCurrent); + } + + mCurrent.close(); + mCurrent = mCurrent.getParent(); + } + + @Override + public void characters(char[] ch, int start, int length) throws SAXException { + mCurrent.addText(new String(ch, start, length)); + } +} diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl new file mode 100644 index 000000000000..3d8e8330c2c4 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.pps; + +parcelable Credential; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java new file mode 100644 index 000000000000..92dbd8afb2d3 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java @@ -0,0 +1,376 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.pps; + +import android.net.wifi.ParcelUtil; +import android.os.Parcelable; +import android.os.Parcel; +import android.text.TextUtils; + +import java.security.PrivateKey; +import java.security.cert.CertificateEncodingException; +import java.security.cert.X509Certificate; +import java.util.Arrays; + +/** + * Class representing Credential subtree in the PerProviderSubscription (PPS) + * Management Object (MO) tree. + * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 + * Release 2 Technical Specification. + * + * In addition to the fields in the Credential subtree, this will also maintain necessary + * information for the private key and certificates associated with this credential. + * + * Currently we only support the nodes that are used by Hotspot 2.0 Release 1. + * + * @hide + */ +public final class Credential implements Parcelable { + /** + * The realm associated with this credential. It will be used to determine + * if this credential can be used to authenticate with a given hotspot by + * comparing the realm specified in that hotspot's ANQP element. + */ + public String realm = null; + + /** + * Username-password based credential. + * Contains the fields under PerProviderSubscription/Credential/UsernamePassword subtree. + */ + public static final class UserCredential implements Parcelable { + /** + * Username of the credential. + */ + public String username = null; + + /** + * Base64-encoded password. + */ + public String password = null; + + /** + * EAP (Extensible Authentication Protocol) method type. + * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4 + * for valid values. + * Using Integer.MIN_VALUE to indicate unset value. + */ + public int eapType = Integer.MIN_VALUE; + + /** + * Non-EAP inner authentication method. + */ + public String nonEapInnerMethod = null; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(username); + dest.writeString(password); + dest.writeInt(eapType); + dest.writeString(nonEapInnerMethod); + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof UserCredential)) { + return false; + } + + UserCredential that = (UserCredential) thatObject; + return TextUtils.equals(username, that.username) && + TextUtils.equals(password, that.password) && + eapType == that.eapType && + TextUtils.equals(nonEapInnerMethod, that.nonEapInnerMethod); + } + + public static final Creator<UserCredential> CREATOR = + new Creator<UserCredential>() { + @Override + public UserCredential createFromParcel(Parcel in) { + UserCredential userCredential = new UserCredential(); + userCredential.username = in.readString(); + userCredential.password = in.readString(); + userCredential.eapType = in.readInt(); + userCredential.nonEapInnerMethod = in.readString(); + return userCredential; + } + + @Override + public UserCredential[] newArray(int size) { + return new UserCredential[size]; + } + }; + } + public UserCredential userCredential = null; + + /** + * Certificate based credential. + * Contains fields under PerProviderSubscription/Credential/DigitalCertificate subtree. + */ + public static final class CertificateCredential implements Parcelable { + /** + * Certificate type. Valid values are "802.1ar" and "x509v3". + */ + public String certType = null; + + /** + * The SHA-256 fingerprint of the certificate. + */ + public byte[] certSha256FingerPrint = null; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(certType); + dest.writeByteArray(certSha256FingerPrint); + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof CertificateCredential)) { + return false; + } + + CertificateCredential that = (CertificateCredential) thatObject; + return TextUtils.equals(certType, that.certType) && + Arrays.equals(certSha256FingerPrint, that.certSha256FingerPrint); + } + + public static final Creator<CertificateCredential> CREATOR = + new Creator<CertificateCredential>() { + @Override + public CertificateCredential createFromParcel(Parcel in) { + CertificateCredential certCredential = new CertificateCredential(); + certCredential.certType = in.readString(); + certCredential.certSha256FingerPrint = in.createByteArray(); + return certCredential; + } + + @Override + public CertificateCredential[] newArray(int size) { + return new CertificateCredential[size]; + } + }; + } + public CertificateCredential certCredential = null; + + /** + * SIM (Subscriber Identify Module) based credential. + * Contains fields under PerProviderSubscription/Credential/SIM subtree. + */ + public static final class SimCredential implements Parcelable { + /** + * International Mobile device Subscriber Identity. + */ + public String imsi = null; + + /** + * EAP (Extensible Authentication Protocol) method type for using SIM credential. + * Refer to http://www.iana.org/assignments/eap-numbers/eap-numbers.xml#eap-numbers-4 + * for valid values. + * Using Integer.MIN_VALUE to indicate unset value. + */ + public int eapType = Integer.MIN_VALUE; + + @Override + public int describeContents() { + return 0; + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof SimCredential)) { + return false; + } + + SimCredential that = (SimCredential) thatObject; + return TextUtils.equals(imsi, that.imsi) && + eapType == that.eapType; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(imsi); + dest.writeInt(eapType); + } + + public static final Creator<SimCredential> CREATOR = + new Creator<SimCredential>() { + @Override + public SimCredential createFromParcel(Parcel in) { + SimCredential simCredential = new SimCredential(); + simCredential.imsi = in.readString(); + simCredential.eapType = in.readInt(); + return simCredential; + } + + @Override + public SimCredential[] newArray(int size) { + return new SimCredential[size]; + } + }; + } + public SimCredential simCredential = null; + + /** + * CA (Certificate Authority) X509 certificate. + */ + public X509Certificate caCertificate = null; + + /** + * Client side X509 certificate chain. + */ + public X509Certificate[] clientCertificateChain = null; + + /** + * Client side private key. + */ + public PrivateKey clientPrivateKey = null; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(realm); + dest.writeParcelable(userCredential, flags); + dest.writeParcelable(certCredential, flags); + dest.writeParcelable(simCredential, flags); + ParcelUtil.writeCertificate(dest, caCertificate); + ParcelUtil.writeCertificates(dest, clientCertificateChain); + ParcelUtil.writePrivateKey(dest, clientPrivateKey); + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof Credential)) { + return false; + } + + Credential that = (Credential) thatObject; + return TextUtils.equals(realm, that.realm) && + (userCredential == null ? that.userCredential == null : + userCredential.equals(that.userCredential)) && + (certCredential == null ? that.certCredential == null : + certCredential.equals(that.certCredential)) && + (simCredential == null ? that.simCredential == null : + simCredential.equals(that.simCredential)) && + isX509CertificateEquals(caCertificate, that.caCertificate) && + isX509CertificatesEquals(clientCertificateChain, that.clientCertificateChain) && + isPrivateKeyEquals(clientPrivateKey, that.clientPrivateKey); + } + + public static final Creator<Credential> CREATOR = + new Creator<Credential>() { + @Override + public Credential createFromParcel(Parcel in) { + Credential credential = new Credential(); + credential.realm = in.readString(); + credential.userCredential = in.readParcelable(null); + credential.certCredential = in.readParcelable(null); + credential.simCredential = in.readParcelable(null); + credential.caCertificate = ParcelUtil.readCertificate(in); + credential.clientCertificateChain = ParcelUtil.readCertificates(in); + credential.clientPrivateKey = ParcelUtil.readPrivateKey(in); + return credential; + } + + @Override + public Credential[] newArray(int size) { + return new Credential[size]; + } + }; + + private static boolean isPrivateKeyEquals(PrivateKey key1, PrivateKey key2) { + if (key1 == null && key2 == null) { + return true; + } + + /* Return false if only one of them is null */ + if (key1 == null || key2 == null) { + return false; + } + + return TextUtils.equals(key1.getAlgorithm(), key2.getAlgorithm()) && + Arrays.equals(key1.getEncoded(), key2.getEncoded()); + } + + private static boolean isX509CertificateEquals(X509Certificate cert1, X509Certificate cert2) { + if (cert1 == null && cert2 == null) { + return true; + } + + /* Return false if only one of them is null */ + if (cert1 == null || cert2 == null) { + return false; + } + + boolean result = false; + try { + result = Arrays.equals(cert1.getEncoded(), cert2.getEncoded()); + } catch (CertificateEncodingException e) { + /* empty, return false. */ + } + return result; + } + + private static boolean isX509CertificatesEquals(X509Certificate[] certs1, + X509Certificate[] certs2) { + if (certs1 == null && certs2 == null) { + return true; + } + + /* Return false if only one of them is null */ + if (certs1 == null || certs2 == null) { + return false; + } + + if (certs1.length != certs2.length) { + return false; + } + + for (int i = 0; i < certs1.length; i++) { + if (!isX509CertificateEquals(certs1[i], certs2[i])) { + return false; + } + } + + return true; + } +} diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl new file mode 100644 index 000000000000..62d5603b5982 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.pps; + +parcelable HomeSP; diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java new file mode 100644 index 000000000000..2acc8bec8007 --- /dev/null +++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSP.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.pps; + +import android.os.Parcelable; +import android.os.Parcel; +import android.text.TextUtils; + +import java.util.Arrays; + +/** + * Class representing HomeSP subtree in PerProviderSubscription (PPS) + * Management Object (MO) tree. + * + * For more info, refer to Hotspot 2.0 PPS MO defined in section 9.1 of the Hotspot 2.0 + * Release 2 Technical Specification. + * + * Currently we only support the nodes that are used by Hotspot 2.0 Release 1. + * + * @hide + */ +public final class HomeSP implements Parcelable { + /** + * FQDN (Fully Qualified Domain Name) of this home service provider. + */ + public String fqdn = null; + + /** + * Friendly name of this home service provider. + */ + public String friendlyName = null; + + /** + * List of Organization Identifiers (OIs) identifying a roaming consortium of + * which this provider is a member. + */ + public long[] roamingConsortiumOIs = null; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(fqdn); + dest.writeString(friendlyName); + dest.writeLongArray(roamingConsortiumOIs); + } + + @Override + public boolean equals(Object thatObject) { + if (this == thatObject) { + return true; + } + if (!(thatObject instanceof HomeSP)) { + return false; + } + HomeSP that = (HomeSP) thatObject; + + return TextUtils.equals(fqdn, that.fqdn) && + TextUtils.equals(friendlyName, that.friendlyName) && + Arrays.equals(roamingConsortiumOIs, that.roamingConsortiumOIs); + } + + public static final Creator<HomeSP> CREATOR = + new Creator<HomeSP>() { + @Override + public HomeSP createFromParcel(Parcel in) { + HomeSP homeSp = new HomeSP(); + homeSp.fqdn = in.readString(); + homeSp.friendlyName = in.readString(); + homeSp.roamingConsortiumOIs = in.createLongArray(); + return homeSp; + } + + @Override + public HomeSP[] newArray(int size) { + return new HomeSP[size]; + } + }; +} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java new file mode 100644 index 000000000000..be11f0ee64c0 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/hotspot2/PasspointConfigurationTest.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.net.wifi.hotspot2; + +import static org.junit.Assert.assertTrue; + +import android.net.wifi.hotspot2.pps.Credential; +import android.net.wifi.hotspot2.pps.HomeSP; +import android.os.Parcel; +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.hotspot2.PasspointConfiguration}. + */ +@SmallTest +public class PasspointConfigurationTest { + + private static HomeSP createHomeSp() { + HomeSP homeSp = new HomeSP(); + homeSp.fqdn = "fqdn"; + homeSp.friendlyName = "friendly name"; + homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66}; + return homeSp; + } + + private static Credential createCredential() { + Credential cred = new Credential(); + cred.realm = "realm"; + cred.userCredential = null; + cred.certCredential = null; + cred.simCredential = null; + cred.caCertificate = null; + cred.clientCertificateChain = null; + cred.clientPrivateKey = null; + return cred; + } + + private static void verifyParcel(PasspointConfiguration writeConfig) throws Exception { + Parcel parcel = Parcel.obtain(); + writeConfig.writeToParcel(parcel, 0); + + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + PasspointConfiguration readConfig = + PasspointConfiguration.CREATOR.createFromParcel(parcel); + assertTrue(readConfig.equals(writeConfig)); + } + + @Test + public void verifyParcelWithDefault() throws Exception { + verifyParcel(new PasspointConfiguration()); + } + + @Test + public void verifyParcelWithHomeSPAndCredential() throws Exception { + PasspointConfiguration config = new PasspointConfiguration(); + config.homeSp = createHomeSp(); + config.credential = createCredential(); + verifyParcel(config); + } + + @Test + public void verifyParcelWithHomeSPOnly() throws Exception { + PasspointConfiguration config = new PasspointConfiguration(); + config.homeSp = createHomeSp(); + verifyParcel(config); + } + + @Test + public void verifyParcelWithCredentialOnly() throws Exception { + PasspointConfiguration config = new PasspointConfiguration(); + config.credential = createCredential(); + verifyParcel(config); + } +}
\ No newline at end of file diff --git a/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java new file mode 100644 index 000000000000..c2dcec693b83 --- /dev/null +++ b/wifi/tests/src/android/net/wifi/hotspot2/omadm/XMLParserTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.wifi.hotspot2.omadm; + +import static org.junit.Assert.assertTrue; + +import android.net.wifi.hotspot2.omadm.XMLNode; +import android.net.wifi.hotspot2.omadm.XMLParser; +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; + +import java.io.IOException; + +/** + * Unit tests for {@link android.net.wifi.hotspot2.omadm.XMLParser}. + */ +@SmallTest +public class XMLParserTest { + XMLParser mParser; + + private static XMLNode createNode(XMLNode parent, String tag, String text) { + XMLNode node = new XMLNode(parent, tag); + node.addText(text); + if (parent != null) + parent.addChild(node); + node.close(); + return node; + } + + /** + * Setup before tests. + */ + @Before + public void setUp() throws Exception { + mParser = new XMLParser(); + } + + @Test(expected = IOException.class) + public void parseNullXML() throws Exception { + mParser.parse(null); + } + + @Test(expected = IOException.class) + public void parseEmptyXML() throws Exception { + mParser.parse(new String()); + } + + @Test(expected = SAXException.class) + public void parseMalformedXML() throws Exception { + String malformedXmlTree = "<root><child1>test1</child2></root>"; + mParser.parse(malformedXmlTree); + } + + @Test + public void parseValidXMLTree() throws Exception { + String xmlTree = "<root><child1>test1</child1><child2>test2</child2></root>"; + + // Construct the expected XML tree. + XMLNode expectedRoot = createNode(null, "root", ""); + createNode(expectedRoot, "child1", "test1"); + createNode(expectedRoot, "child2", "test2"); + + XMLNode actualRoot = mParser.parse(xmlTree); + assertTrue(actualRoot.equals(expectedRoot)); + } +} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java new file mode 100644 index 000000000000..68ac4efa214f --- /dev/null +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/CredentialTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.net.wifi.hotspot2.pps; + +import static org.junit.Assert.assertTrue; + +import android.net.wifi.FakeKeys; +import android.os.Parcel; +import android.test.suitebuilder.annotation.SmallTest; + +import java.security.PrivateKey; +import java.security.cert.X509Certificate; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.hotspot2.pps.CredentialTest}. + */ +@SmallTest +public class CredentialTest { + private static Credential createCredential(Credential.UserCredential userCred, + Credential.CertificateCredential certCred, + Credential.SimCredential simCred, + X509Certificate caCert, + X509Certificate[] clientCertificateChain, + PrivateKey clientPrivateKey) { + Credential cred = new Credential(); + cred.realm = "realm"; + cred.userCredential = userCred; + cred.certCredential = certCred; + cred.simCredential = simCred; + cred.caCertificate = caCert; + cred.clientCertificateChain = clientCertificateChain; + cred.clientPrivateKey = clientPrivateKey; + return cred; + } + + private static Credential createCredentialWithCertificateCredential() { + Credential.CertificateCredential certCred = new Credential.CertificateCredential(); + certCred.certType = "x509v3"; + certCred.certSha256FingerPrint = new byte[256]; + return createCredential(null, certCred, null, FakeKeys.CA_CERT0, + new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1); + } + + private static Credential createCredentialWithSimCredential() { + Credential.SimCredential simCred = new Credential.SimCredential(); + simCred.imsi = "imsi"; + simCred.eapType = 1; + return createCredential(null, null, simCred, null, null, null); + } + + private static Credential createCredentialWithUserCredential() { + Credential.UserCredential userCred = new Credential.UserCredential(); + userCred.username = "username"; + userCred.password = "password"; + userCred.eapType = 1; + userCred.nonEapInnerMethod = "MS-CHAP"; + return createCredential(userCred, null, null, FakeKeys.CA_CERT0, + new X509Certificate[] {FakeKeys.CLIENT_CERT}, FakeKeys.RSA_KEY1); + } + + private static void verifyParcel(Credential writeCred) { + Parcel parcel = Parcel.obtain(); + writeCred.writeToParcel(parcel, 0); + + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + Credential readCred = Credential.CREATOR.createFromParcel(parcel); + assertTrue(readCred.equals(writeCred)); + } + + @Test + public void verifyParcelWithDefault() throws Exception { + verifyParcel(new Credential()); + } + + @Test + public void verifyParcelWithCertificateCredential() throws Exception { + verifyParcel(createCredentialWithCertificateCredential()); + } + + @Test + public void verifyParcelWithSimCredential() throws Exception { + verifyParcel(createCredentialWithSimCredential()); + } + + @Test + public void verifyParcelWithUserCredential() throws Exception { + verifyParcel(createCredentialWithUserCredential()); + } +} diff --git a/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java new file mode 100644 index 000000000000..0d2da6404e7f --- /dev/null +++ b/wifi/tests/src/android/net/wifi/hotspot2/pps/HomeSPTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.net.wifi.hotspot2.pps; + +import static org.junit.Assert.assertTrue; + +import android.os.Parcel; +import android.test.suitebuilder.annotation.SmallTest; + +import java.util.HashMap; + +import org.junit.Test; + +/** + * Unit tests for {@link android.net.wifi.hotspot2.pps.HomeSP}. + */ +@SmallTest +public class HomeSPTest { + private static HomeSP createHomeSp() { + HomeSP homeSp = new HomeSP(); + homeSp.fqdn = "fqdn"; + homeSp.friendlyName = "friendly name"; + homeSp.roamingConsortiumOIs = new long[] {0x55, 0x66}; + return homeSp; + } + + private static void verifyParcel(HomeSP writeHomeSp) throws Exception { + Parcel parcel = Parcel.obtain(); + writeHomeSp.writeToParcel(parcel, 0); + + parcel.setDataPosition(0); // Rewind data position back to the beginning for read. + HomeSP readHomeSp = HomeSP.CREATOR.createFromParcel(parcel); + assertTrue(readHomeSp.equals(writeHomeSp)); + } + + @Test + public void verifyParcelWithEmptyHomeSP() throws Exception { + verifyParcel(new HomeSP()); + } + + @Test + public void verifyParcelWithValidHomeSP() throws Exception { + verifyParcel(createHomeSp()); + } +} |