blob: 9c8b749e1c93abd49009caa3c3a33a75fc8b1c6c [file] [log] [blame]
/*
* 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.assertFalse;
import static org.junit.Assert.assertTrue;
import android.net.wifi.EAPConstants;
import android.net.wifi.FakeKeys;
import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Arrays;
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[32];
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 = "1234*";
simCred.eapType = EAPConstants.EAP_SIM;
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 = EAPConstants.EAP_TTLS;
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));
}
/**
* Verify parcel read/write for a default/empty credential.
*
* @throws Exception
*/
@Test
public void verifyParcelWithDefault() throws Exception {
verifyParcel(new Credential());
}
/**
* Verify parcel read/write for a certificate credential.
*
* @throws Exception
*/
@Test
public void verifyParcelWithCertificateCredential() throws Exception {
verifyParcel(createCredentialWithCertificateCredential());
}
/**
* Verify parcel read/write for a SIM credential.
*
* @throws Exception
*/
@Test
public void verifyParcelWithSimCredential() throws Exception {
verifyParcel(createCredentialWithSimCredential());
}
/**
* Verify parcel read/write for an user credential.
*
* @throws Exception
*/
@Test
public void verifyParcelWithUserCredential() throws Exception {
verifyParcel(createCredentialWithUserCredential());
}
/**
* Verify a valid user credential.
* @throws Exception
*/
@Test
public void validateUserCredential() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
assertTrue(cred.validate());
}
/**
* Verify that an user credential without CA Certificate is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithoutCaCert() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
assertFalse(cred.validate());
}
/**
* Verify that an user credential with EAP type other than EAP-TTLS is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithEapTls() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
assertFalse(cred.validate());
}
/**
* Verify that an user credential without realm is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithoutRealm() throws Exception {
Credential cred = new Credential();
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
assertFalse(cred.validate());
}
/**
* Verify that an user credential without username is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithoutUsername() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
assertFalse(cred.validate());
}
/**
* Verify that an user credential without password is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithoutPassword() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
assertFalse(cred.validate());
}
/**
* Verify that an user credential without auth methoh (non-EAP inner method) is invalid.
*
* @throws Exception
*/
@Test
public void validateUserCredentialWithoutAuthMethod() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.caCertificate = FakeKeys.CA_CERT0;
assertFalse(cred.validate());
}
/**
* Verify a certificate credential. CA Certificate, client certificate chain,
* and client private key are all required. Also the digest for client
* certificate must match the fingerprint specified in the certificate credential.
*
* @throws Exception
*/
@Test
public void validateCertCredential() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup certificate credential.
cred.certCredential = new Credential.CertificateCredential();
cred.certCredential.certType = "x509v3";
cred.certCredential.certSha256FingerPrint =
MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
// Setup certificates and private key.
cred.caCertificate = FakeKeys.CA_CERT0;
cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
cred.clientPrivateKey = FakeKeys.RSA_KEY1;
assertTrue(cred.validate());
}
/**
* Verify that an certificate credential without CA Certificate is invalid.
*
* @throws Exception
*/
public void validateCertCredentialWithoutCaCert() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup certificate credential.
cred.certCredential = new Credential.CertificateCredential();
cred.certCredential.certType = "x509v3";
cred.certCredential.certSha256FingerPrint =
MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
// Setup certificates and private key.
cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
cred.clientPrivateKey = FakeKeys.RSA_KEY1;
assertFalse(cred.validate());
}
/**
* Verify that a certificate credential without client certificate chain is invalid.
*
* @throws Exception
*/
@Test
public void validateCertCredentialWithoutClientCertChain() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup certificate credential.
cred.certCredential = new Credential.CertificateCredential();
cred.certCredential.certType = "x509v3";
cred.certCredential.certSha256FingerPrint =
MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
// Setup certificates and private key.
cred.caCertificate = FakeKeys.CA_CERT0;
cred.clientPrivateKey = FakeKeys.RSA_KEY1;
assertFalse(cred.validate());
}
/**
* Verify that a certificate credential without client private key is invalid.
*
* @throws Exception
*/
@Test
public void validateCertCredentialWithoutClientPrivateKey() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup certificate credential.
cred.certCredential = new Credential.CertificateCredential();
cred.certCredential.certType = "x509v3";
cred.certCredential.certSha256FingerPrint =
MessageDigest.getInstance("SHA-256").digest(FakeKeys.CLIENT_CERT.getEncoded());
// Setup certificates and private key.
cred.caCertificate = FakeKeys.CA_CERT0;
cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
assertFalse(cred.validate());
}
/**
* Verify that a certificate credential with mismatch client certificate fingerprint
* is invalid.
*
* @throws Exception
*/
@Test
public void validateCertCredentialWithMismatchFingerprint() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup certificate credential.
cred.certCredential = new Credential.CertificateCredential();
cred.certCredential.certType = "x509v3";
cred.certCredential.certSha256FingerPrint = new byte[32];
Arrays.fill(cred.certCredential.certSha256FingerPrint, (byte)0);
// Setup certificates and private key.
cred.caCertificate = FakeKeys.CA_CERT0;
cred.clientCertificateChain = new X509Certificate[] {FakeKeys.CLIENT_CERT};
cred.clientPrivateKey = FakeKeys.RSA_KEY1;
assertFalse(cred.validate());
}
/**
* Verify a SIM credential using EAP-SIM.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithEapSim() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "1234*";
cred.simCredential.eapType = EAPConstants.EAP_SIM;
assertTrue(cred.validate());
}
/**
* Verify a SIM credential using EAP-AKA.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithEapAka() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "1234*";
cred.simCredential.eapType = EAPConstants.EAP_AKA;
assertTrue(cred.validate());
}
/**
* Verify a SIM credential using EAP-AKA-PRIME.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithEapAkaPrime() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "1234*";
cred.simCredential.eapType = EAPConstants.EAP_AKA_PRIME;
assertTrue(cred.validate());
}
/**
* Verify that a SIM credential without IMSI is invalid.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithoutIMSI() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.eapType = EAPConstants.EAP_SIM;
assertFalse(cred.validate());
}
/**
* Verify that a SIM credential with an invalid IMSI is invalid.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithInvalidIMSI() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "dummy";
cred.simCredential.eapType = EAPConstants.EAP_SIM;
assertFalse(cred.validate());
}
/**
* Verify that a SIM credential with invalid EAP type is invalid.
*
* @throws Exception
*/
@Test
public void validateSimCredentialWithEapTls() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "1234*";
cred.simCredential.eapType = EAPConstants.EAP_TLS;
assertFalse(cred.validate());
}
/**
* Verify that a credential contained both an user and a SIM credential is invalid.
*
* @throws Exception
*/
@Test
public void validateCredentialWithUserAndSimCredential() throws Exception {
Credential cred = new Credential();
cred.realm = "realm";
// Setup user credential with EAP-TTLS.
cred.userCredential = new Credential.UserCredential();
cred.userCredential.username = "username";
cred.userCredential.password = "password";
cred.userCredential.eapType = EAPConstants.EAP_TTLS;
cred.userCredential.nonEapInnerMethod = "MS-CHAP";
cred.caCertificate = FakeKeys.CA_CERT0;
// Setup SIM credential.
cred.simCredential = new Credential.SimCredential();
cred.simCredential.imsi = "1234*";
cred.simCredential.eapType = EAPConstants.EAP_SIM;
assertFalse(cred.validate());
}
/**
* Verify that copy constructor works when pass in a null source.
*
* @throws Exception
*/
@Test
public void validateCopyConstructorWithNullSource() throws Exception {
Credential copyCred = new Credential(null);
Credential defaultCred = new Credential();
assertTrue(copyCred.equals(defaultCred));
}
/**
* Verify that copy constructor works when pass in a source with user credential.
*
* @throws Exception
*/
@Test
public void validateCopyConstructorWithSourceWithUserCred() throws Exception {
Credential sourceCred = createCredentialWithUserCredential();
Credential copyCred = new Credential(sourceCred);
assertTrue(copyCred.equals(sourceCred));
}
/**
* Verify that copy constructor works when pass in a source with certificate credential.
*
* @throws Exception
*/
@Test
public void validateCopyConstructorWithSourceWithCertCred() throws Exception {
Credential sourceCred = createCredentialWithCertificateCredential();
Credential copyCred = new Credential(sourceCred);
assertTrue(copyCred.equals(sourceCred));
}
/**
* Verify that copy constructor works when pass in a source with SIM credential.
*
* @throws Exception
*/
@Test
public void validateCopyConstructorWithSourceWithSimCred() throws Exception {
Credential sourceCred = createCredentialWithSimCredential();
Credential copyCred = new Credential(sourceCred);
assertTrue(copyCred.equals(sourceCred));
}
}