• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package android.net.wifi;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertNotNull;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
27 import static org.junit.Assume.assumeTrue;
28 
29 import android.net.wifi.WifiEnterpriseConfig.Eap;
30 import android.net.wifi.WifiEnterpriseConfig.Phase2;
31 import android.net.wifi.hotspot2.PasspointConfiguration;
32 import android.os.Parcel;
33 import android.security.Credentials;
34 
35 import androidx.test.filters.SmallTest;
36 
37 import com.android.modules.utils.build.SdkLevel;
38 
39 import org.junit.Before;
40 import org.junit.Test;
41 
42 import java.security.PrivateKey;
43 import java.security.cert.X509Certificate;
44 
45 /**
46  * Unit tests for {@link android.net.wifi.WifiEnterpriseConfig}.
47  */
48 @SmallTest
49 public class WifiEnterpriseConfigTest {
50     // Maintain a ground truth of the keystore uri prefix which is expected by wpa_supplicant.
51     public static final String KEYSTORE_URI = "keystore://";
52     public static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
53     public static final String KEYSTORES_URI = "keystores://";
54     private static final String TEST_DOMAIN_SUFFIX_MATCH = "domainSuffixMatch";
55     private static final String TEST_ALT_SUBJECT_MATCH = "DNS:server.test.com";
56     private static final String TEST_DECORATED_IDENTITY_PREFIX = "androidwifi.dev!";
57 
58     private WifiEnterpriseConfig mEnterpriseConfig;
59 
60     @Before
setUp()61     public void setUp() throws Exception {
62         mEnterpriseConfig = new WifiEnterpriseConfig();
63     }
64 
65     @Test
testGetEmptyCaCertificate()66     public void testGetEmptyCaCertificate() {
67         // A newly-constructed WifiEnterpriseConfig object should have no CA certificate.
68         assertNull(mEnterpriseConfig.getCaCertificate());
69         assertNull(mEnterpriseConfig.getCaCertificates());
70         // Setting CA certificate to null explicitly.
71         mEnterpriseConfig.setCaCertificate(null);
72         assertNull(mEnterpriseConfig.getCaCertificate());
73         // Setting CA certificate to null using setCaCertificates().
74         mEnterpriseConfig.setCaCertificates(null);
75         assertNull(mEnterpriseConfig.getCaCertificates());
76         // Setting CA certificate to zero-length array.
77         mEnterpriseConfig.setCaCertificates(new X509Certificate[0]);
78         assertNull(mEnterpriseConfig.getCaCertificates());
79     }
80 
81     @Test
testSetGetSingleCaCertificate()82     public void testSetGetSingleCaCertificate() {
83         X509Certificate cert0 = FakeKeys.CA_CERT0;
84         mEnterpriseConfig.setCaCertificate(cert0);
85         assertEquals(mEnterpriseConfig.getCaCertificate(), cert0);
86     }
87 
88     @Test
testSetGetMultipleCaCertificates()89     public void testSetGetMultipleCaCertificates() {
90         X509Certificate cert0 = FakeKeys.CA_CERT0;
91         X509Certificate cert1 = FakeKeys.CA_CERT1;
92         mEnterpriseConfig.setCaCertificates(new X509Certificate[] {cert0, cert1});
93         X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
94         assertEquals(result.length, 2);
95         assertTrue(result[0] == cert0 && result[1] == cert1);
96     }
97 
98     @Test
testSetClientKeyEntryWithNull()99     public void testSetClientKeyEntryWithNull() {
100         mEnterpriseConfig.setClientKeyEntry(null, null);
101         assertNull(mEnterpriseConfig.getClientCertificateChain());
102         assertNull(mEnterpriseConfig.getClientCertificate());
103         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
104         assertNull(mEnterpriseConfig.getClientCertificateChain());
105         assertNull(mEnterpriseConfig.getClientCertificate());
106 
107         // Setting the client certificate to null should clear the existing chain.
108         PrivateKey clientKey = FakeKeys.RSA_KEY1;
109         X509Certificate clientCert0 = FakeKeys.CLIENT_CERT;
110         X509Certificate clientCert1 = FakeKeys.CA_CERT1;
111         mEnterpriseConfig.setClientKeyEntry(clientKey, clientCert0);
112         assertNotNull(mEnterpriseConfig.getClientCertificate());
113         mEnterpriseConfig.setClientKeyEntry(null, null);
114         assertNull(mEnterpriseConfig.getClientCertificate());
115         assertNull(mEnterpriseConfig.getClientCertificateChain());
116 
117         // Setting the chain to null should clear the existing chain.
118         X509Certificate[] clientChain = new X509Certificate[] {clientCert0, clientCert1};
119         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
120         assertNotNull(mEnterpriseConfig.getClientCertificateChain());
121         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(null, null);
122         assertNull(mEnterpriseConfig.getClientCertificate());
123         assertNull(mEnterpriseConfig.getClientCertificateChain());
124     }
125 
126     @Test
testSetClientCertificateChain()127     public void testSetClientCertificateChain() {
128         PrivateKey clientKey = FakeKeys.RSA_KEY1;
129         X509Certificate cert0 = FakeKeys.CLIENT_CERT;
130         X509Certificate cert1 = FakeKeys.CA_CERT1;
131         X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
132         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
133         X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
134         assertEquals(result.length, 2);
135         assertTrue(result[0] == cert0 && result[1] == cert1);
136         assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
137     }
138 
139     @Test
testSetGetClientKeyPairAlias()140     public void testSetGetClientKeyPairAlias() {
141         assumeTrue(SdkLevel.isAtLeastS());
142 
143         final String alias = "alias";
144         mEnterpriseConfig.setClientKeyPairAlias(alias);
145         assertEquals(alias, mEnterpriseConfig.getClientKeyPairAlias());
146         assertEquals(alias, mEnterpriseConfig.getClientKeyPairAliasInternal());
147     }
148 
isClientCertificateChainInvalid(X509Certificate[] clientChain)149     private boolean isClientCertificateChainInvalid(X509Certificate[] clientChain) {
150         boolean exceptionThrown = false;
151         try {
152             PrivateKey clientKey = FakeKeys.RSA_KEY1;
153             mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
154         } catch (IllegalArgumentException e) {
155             exceptionThrown = true;
156         }
157         return exceptionThrown;
158     }
159 
160     @Test
testSetInvalidClientCertificateChain()161     public void testSetInvalidClientCertificateChain() {
162         X509Certificate clientCert = FakeKeys.CLIENT_CERT;
163         X509Certificate caCert = FakeKeys.CA_CERT1;
164         assertTrue("Invalid client certificate",
165                 isClientCertificateChainInvalid(new X509Certificate[] {caCert, caCert}));
166         assertTrue("Invalid CA certificate",
167                 isClientCertificateChainInvalid(new X509Certificate[] {clientCert, clientCert}));
168         assertTrue("Both certificates invalid",
169                 isClientCertificateChainInvalid(new X509Certificate[] {caCert, clientCert}));
170     }
171 
172     @Test
testSaveSingleCaCertificateAlias()173     public void testSaveSingleCaCertificateAlias() {
174         final String alias = "single_alias 0";
175         mEnterpriseConfig.setCaCertificateAliases(new String[] {alias});
176         assertEquals(getCaCertField(), CA_CERT_PREFIX + alias);
177     }
178 
179     @Test
testLoadSingleCaCertificateAlias()180     public void testLoadSingleCaCertificateAlias() {
181         final String alias = "single_alias 1";
182         setCaCertField(CA_CERT_PREFIX + alias);
183         String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
184         assertEquals(aliases.length, 1);
185         assertEquals(aliases[0], alias);
186     }
187 
188     @Test
testSaveMultipleCaCertificates()189     public void testSaveMultipleCaCertificates() {
190         final String alias0 = "single_alias 0";
191         final String alias1 = "single_alias 1";
192         mEnterpriseConfig.setCaCertificateAliases(new String[] {alias0, alias1});
193         assertEquals(getCaCertField(), String.format("%s%s %s",
194                 KEYSTORES_URI,
195                 WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
196                 WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
197     }
198 
199     @Test
testLoadMultipleCaCertificates()200     public void testLoadMultipleCaCertificates() {
201         final String alias0 = "single_alias 0";
202         final String alias1 = "single_alias 1";
203         setCaCertField(String.format("%s%s %s",
204                 KEYSTORES_URI,
205                 WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias0),
206                 WifiEnterpriseConfig.encodeCaCertificateAlias(Credentials.CA_CERTIFICATE + alias1)));
207         String[] aliases = mEnterpriseConfig.getCaCertificateAliases();
208         assertEquals(aliases.length, 2);
209         assertEquals(aliases[0], alias0);
210         assertEquals(aliases[1], alias1);
211     }
212 
getCaCertField()213     private String getCaCertField() {
214         return mEnterpriseConfig.getFieldValue(WifiEnterpriseConfig.CA_CERT_KEY);
215     }
216 
setCaCertField(String value)217     private void setCaCertField(String value) {
218         mEnterpriseConfig.setFieldValue(WifiEnterpriseConfig.CA_CERT_KEY, value);
219     }
220 
221     // Retrieves the value for a specific key supplied to wpa_supplicant.
222     private class SupplicantConfigExtractor implements WifiEnterpriseConfig.SupplicantSaver {
223         private String mValue = null;
224         private String mKey;
225 
SupplicantConfigExtractor(String key)226         SupplicantConfigExtractor(String key) {
227             mKey = key;
228         }
229 
230         @Override
saveValue(String key, String value)231         public boolean saveValue(String key, String value) {
232             if (key.equals(mKey)) {
233                 mValue = value;
234             }
235             return true;
236         }
237 
getValue()238         public String getValue() {
239             return mValue;
240         }
241     }
242 
getSupplicantEapMethod()243     private String getSupplicantEapMethod() {
244         SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
245                 WifiEnterpriseConfig.EAP_KEY);
246         mEnterpriseConfig.saveToSupplicant(entryExtractor);
247         return entryExtractor.getValue();
248     }
249 
getSupplicantPhase2Method()250     private String getSupplicantPhase2Method() {
251         SupplicantConfigExtractor entryExtractor = new SupplicantConfigExtractor(
252                 WifiEnterpriseConfig.PHASE2_KEY);
253         mEnterpriseConfig.saveToSupplicant(entryExtractor);
254         return entryExtractor.getValue();
255     }
256 
257     /** Verifies the default value for EAP outer and inner methods */
258     @Test
eapInnerDefault()259     public void eapInnerDefault() {
260         assertEquals(null, getSupplicantEapMethod());
261         assertEquals(null, getSupplicantPhase2Method());
262     }
263 
264     /** Verifies that the EAP inner method is reset when we switch to TLS */
265     @Test
eapPhase2MethodForTls()266     public void eapPhase2MethodForTls() {
267         // Initially select an EAP method that supports an phase2.
268         mEnterpriseConfig.setEapMethod(Eap.PEAP);
269         mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
270         assertEquals("PEAP", getSupplicantEapMethod());
271         assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
272 
273         // Change the EAP method to another type which supports a phase2.
274         mEnterpriseConfig.setEapMethod(Eap.TTLS);
275         assertEquals("TTLS", getSupplicantEapMethod());
276         assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
277 
278         // Change the EAP method to TLS which does not support a phase2.
279         mEnterpriseConfig.setEapMethod(Eap.TLS);
280         assertEquals(null, getSupplicantPhase2Method());
281     }
282 
283     /** Verfies that the EAP inner method is reset when we switch phase2 to NONE */
284     @Test
eapPhase2None()285     public void eapPhase2None() {
286         // Initially select an EAP method that supports an phase2.
287         mEnterpriseConfig.setEapMethod(Eap.PEAP);
288         mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
289         assertEquals("PEAP", getSupplicantEapMethod());
290         assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
291 
292         // Change the phase2 method to NONE and ensure the value is cleared.
293         mEnterpriseConfig.setPhase2Method(Phase2.NONE);
294         assertEquals(null, getSupplicantPhase2Method());
295     }
296 
297     /** Verfies that the correct "autheap" parameter is supplied for TTLS/GTC. */
298     @Test
peapGtcToTtls()299     public void peapGtcToTtls() {
300         mEnterpriseConfig.setEapMethod(Eap.PEAP);
301         mEnterpriseConfig.setPhase2Method(Phase2.GTC);
302         assertEquals("PEAP", getSupplicantEapMethod());
303         assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
304 
305         mEnterpriseConfig.setEapMethod(Eap.TTLS);
306         assertEquals("TTLS", getSupplicantEapMethod());
307         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
308     }
309 
310     /** Verfies that the correct "auth" parameter is supplied for PEAP/GTC. */
311     @Test
ttlsGtcToPeap()312     public void ttlsGtcToPeap() {
313         mEnterpriseConfig.setEapMethod(Eap.TTLS);
314         mEnterpriseConfig.setPhase2Method(Phase2.GTC);
315         assertEquals("TTLS", getSupplicantEapMethod());
316         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
317 
318         mEnterpriseConfig.setEapMethod(Eap.PEAP);
319         assertEquals("PEAP", getSupplicantEapMethod());
320         assertEquals("\"auth=GTC\"", getSupplicantPhase2Method());
321     }
322 
323     /** Verfies PEAP/SIM, PEAP/AKA, PEAP/AKA'. */
324     @Test
peapSimAkaAkaPrime()325     public void peapSimAkaAkaPrime() {
326         mEnterpriseConfig.setEapMethod(Eap.PEAP);
327         mEnterpriseConfig.setPhase2Method(Phase2.SIM);
328         assertEquals("PEAP", getSupplicantEapMethod());
329         assertEquals("\"auth=SIM\"", getSupplicantPhase2Method());
330 
331         mEnterpriseConfig.setPhase2Method(Phase2.AKA);
332         assertEquals("\"auth=AKA\"", getSupplicantPhase2Method());
333 
334         mEnterpriseConfig.setPhase2Method(Phase2.AKA_PRIME);
335         assertEquals("\"auth=AKA'\"", getSupplicantPhase2Method());
336     }
337 
338     /**
339      * Verifies that the copy constructor preseves both the masked password and inner method
340      * information.
341      */
342     @Test
copyConstructor()343     public void copyConstructor() {
344         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
345         enterpriseConfig.setPassword("*");
346         enterpriseConfig.setEapMethod(Eap.TTLS);
347         enterpriseConfig.setPhase2Method(Phase2.GTC);
348         mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
349         assertEquals("TTLS", getSupplicantEapMethod());
350         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
351         assertEquals("*", mEnterpriseConfig.getPassword());
352     }
353 
354     /**
355      * Verifies that the copy from external ignores masked passwords and preserves the
356      * inner method information.
357      */
358     @Test
copyFromExternal()359     public void copyFromExternal() {
360         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
361         enterpriseConfig.setPassword("*");
362         enterpriseConfig.setEapMethod(Eap.TTLS);
363         enterpriseConfig.setPhase2Method(Phase2.GTC);
364         enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
365         mEnterpriseConfig = new WifiEnterpriseConfig();
366         mEnterpriseConfig.copyFromExternal(enterpriseConfig, "*");
367         assertEquals("TTLS", getSupplicantEapMethod());
368         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
369         assertNotEquals("*", mEnterpriseConfig.getPassword());
370         assertEquals(enterpriseConfig.getOcsp(), mEnterpriseConfig.getOcsp());
371     }
372 
373     /** Verfies that parceling a WifiEnterpriseConfig preseves method information. */
374     @Test
parcelConstructor()375     public void parcelConstructor() {
376         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
377         enterpriseConfig.setEapMethod(Eap.TTLS);
378         enterpriseConfig.setPhase2Method(Phase2.GTC);
379         Parcel parcel = Parcel.obtain();
380         enterpriseConfig.writeToParcel(parcel, 0);
381         parcel.setDataPosition(0);  // Allow parcel to be read from the beginning.
382         mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
383         assertEquals("TTLS", getSupplicantEapMethod());
384         assertEquals("\"autheap=GTC\"", getSupplicantPhase2Method());
385     }
386 
387     /**
388      * Verifies that parceling a WifiEnterpriseConfig preserves the key
389      * and certificates information.
390      */
391     @Test
parcelConfigWithKeyAndCerts()392     public void parcelConfigWithKeyAndCerts() throws Exception {
393         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
394         PrivateKey clientKey = FakeKeys.RSA_KEY1;
395         X509Certificate clientCert = FakeKeys.CLIENT_CERT;
396         X509Certificate[] caCerts = new X509Certificate[] {FakeKeys.CA_CERT0, FakeKeys.CA_CERT1};
397         enterpriseConfig.setClientKeyEntry(clientKey, clientCert);
398         enterpriseConfig.setCaCertificates(caCerts);
399         Parcel parcel = Parcel.obtain();
400         enterpriseConfig.writeToParcel(parcel, 0);
401 
402         parcel.setDataPosition(0);  // Allow parcel to be read from the beginning.
403         mEnterpriseConfig = WifiEnterpriseConfig.CREATOR.createFromParcel(parcel);
404         PrivateKey actualClientKey = mEnterpriseConfig.getClientPrivateKey();
405         X509Certificate actualClientCert = mEnterpriseConfig.getClientCertificate();
406         X509Certificate[] actualCaCerts = mEnterpriseConfig.getCaCertificates();
407 
408         /* Verify client private key. */
409         assertNotNull(actualClientKey);
410         assertEquals(clientKey.getAlgorithm(), actualClientKey.getAlgorithm());
411         assertArrayEquals(clientKey.getEncoded(), actualClientKey.getEncoded());
412 
413         /* Verify client certificate. */
414         assertNotNull(actualClientCert);
415         assertArrayEquals(clientCert.getEncoded(), actualClientCert.getEncoded());
416 
417         /* Verify CA certificates. */
418         assertNotNull(actualCaCerts);
419         assertEquals(caCerts.length, actualCaCerts.length);
420         for (int i = 0; i < caCerts.length; i++) {
421             assertNotNull(actualCaCerts[i]);
422             assertArrayEquals(caCerts[i].getEncoded(), actualCaCerts[i].getEncoded());
423         }
424     }
425 
426     /** Verifies proper operation of the getKeyId() method. */
427     @Test
getKeyId()428     public void getKeyId() {
429         assertEquals("NULL", mEnterpriseConfig.getKeyId(null));
430         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
431         enterpriseConfig.setEapMethod(Eap.TTLS);
432         enterpriseConfig.setPhase2Method(Phase2.GTC);
433         assertEquals("TTLS_GTC", mEnterpriseConfig.getKeyId(enterpriseConfig));
434         mEnterpriseConfig.setEapMethod(Eap.PEAP);
435         mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
436         assertEquals("PEAP_MSCHAPV2", mEnterpriseConfig.getKeyId(enterpriseConfig));
437     }
438 
439     /** Verifies that passwords are not displayed in toString. */
440     @Test
passwordNotInToString()441     public void passwordNotInToString() {
442         String password = "supersecret";
443         mEnterpriseConfig.setPassword(password);
444         assertFalse(mEnterpriseConfig.toString().contains(password));
445     }
446 
447     /** Verifies that certificate ownership flag is set correctly */
448     @Test
testIsAppInstalledDeviceKeyAndCert()449     public void testIsAppInstalledDeviceKeyAndCert() {
450         // First make sure that app didn't install anything
451         assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
452         assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
453 
454         // Then app loads keys via the enterprise config API
455         PrivateKey clientKey = FakeKeys.RSA_KEY1;
456         X509Certificate cert0 = FakeKeys.CLIENT_CERT;
457         X509Certificate cert1 = FakeKeys.CA_CERT1;
458         X509Certificate[] clientChain = new X509Certificate[] {cert0, cert1};
459         mEnterpriseConfig.setClientKeyEntryWithCertificateChain(clientKey, clientChain);
460         X509Certificate[] result = mEnterpriseConfig.getClientCertificateChain();
461         assertEquals(result.length, 2);
462         assertTrue(result[0] == cert0 && result[1] == cert1);
463         assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
464 
465         // Make sure it is the owner now
466         assertTrue(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
467         assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
468     }
469 
470     /** Verifies that certificate ownership flag is set correctly */
471     @Test
testIsAppInstalledCaCert()472     public void testIsAppInstalledCaCert() {
473         // First make sure that app didn't install anything
474         assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
475         assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
476 
477         // Then app loads CA cert via the enterprise config API
478         X509Certificate cert = FakeKeys.CA_CERT1;
479         mEnterpriseConfig.setCaCertificate(cert);
480         X509Certificate result = mEnterpriseConfig.getCaCertificate();
481         assertTrue(result == cert);
482 
483         // Make sure it is the owner now
484         assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
485         assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
486     }
487 
488     /** Verifies that certificate ownership flag is set correctly */
489     @Test
testIsAppInstalledCaCerts()490     public void testIsAppInstalledCaCerts() {
491         // First make sure that app didn't install anything
492         assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
493         assertFalse(mEnterpriseConfig.isAppInstalledCaCert());
494 
495         // Then app loads CA cert via the enterprise config API
496         X509Certificate cert0 = FakeKeys.CA_CERT0;
497         X509Certificate cert1 = FakeKeys.CA_CERT1;
498         X509Certificate[] cert = new X509Certificate[] {cert0, cert1};
499 
500         mEnterpriseConfig.setCaCertificates(cert);
501         X509Certificate[] result = mEnterpriseConfig.getCaCertificates();
502         assertEquals(result.length, 2);
503         assertTrue(result[0] == cert0 && result[1] == cert1);
504 //        assertTrue(mEnterpriseConfig.getClientCertificate() == cert0);
505 
506         // Make sure it is the owner now
507         assertFalse(mEnterpriseConfig.isAppInstalledDeviceKeyAndCert());
508         assertTrue(mEnterpriseConfig.isAppInstalledCaCert());
509     }
510 
511     /** Verifies that OCSP value is set correctly. */
512     @Test
testOcspSetGet()513     public void testOcspSetGet() throws Exception {
514         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
515 
516         enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_NONE);
517         assertEquals(WifiEnterpriseConfig.OCSP_NONE, enterpriseConfig.getOcsp());
518 
519         enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS);
520         assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_CERT_STATUS, enterpriseConfig.getOcsp());
521 
522         enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS);
523         assertEquals(WifiEnterpriseConfig.OCSP_REQUEST_CERT_STATUS, enterpriseConfig.getOcsp());
524 
525         enterpriseConfig.setOcsp(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS);
526         assertEquals(WifiEnterpriseConfig.OCSP_REQUIRE_ALL_NON_TRUSTED_CERTS_STATUS,
527                 enterpriseConfig.getOcsp());
528     }
529 
530     /** Verifies that an exception is thrown when invalid OCSP is set. */
531     @Test
testInvalidOcspValue()532     public void testInvalidOcspValue() {
533         WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
534         try {
535             enterpriseConfig.setOcsp(-1);
536             fail("Should raise an IllegalArgumentException here.");
537         } catch (IllegalArgumentException e) {
538             // expected exception.
539         }
540     }
541 
542     /** Verifies that the EAP inner method is reset when we switch to Unauth-TLS */
543     @Test
eapPhase2MethodForUnauthTls()544     public void eapPhase2MethodForUnauthTls() {
545         // Initially select an EAP method that supports an phase2.
546         mEnterpriseConfig.setEapMethod(Eap.PEAP);
547         mEnterpriseConfig.setPhase2Method(Phase2.MSCHAPV2);
548         assertEquals("PEAP", getSupplicantEapMethod());
549         assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
550 
551         // Change the EAP method to another type which supports a phase2.
552         mEnterpriseConfig.setEapMethod(Eap.TTLS);
553         assertEquals("TTLS", getSupplicantEapMethod());
554         assertEquals("\"auth=MSCHAPV2\"", getSupplicantPhase2Method());
555 
556         // Change the EAP method to Unauth-TLS which does not support a phase2.
557         mEnterpriseConfig.setEapMethod(Eap.UNAUTH_TLS);
558         assertEquals(null, getSupplicantPhase2Method());
559     }
560 
561     @Test
testIsEnterpriseConfigServerCertNotEnabled()562     public void testIsEnterpriseConfigServerCertNotEnabled() {
563         WifiEnterpriseConfig baseConfig = new WifiEnterpriseConfig();
564         baseConfig.setEapMethod(Eap.PEAP);
565         baseConfig.setPhase2Method(Phase2.MSCHAPV2);
566         assertTrue(baseConfig.isEapMethodServerCertUsed());
567         assertFalse(baseConfig.isServerCertValidationEnabled());
568 
569         WifiEnterpriseConfig noMatchConfig = new WifiEnterpriseConfig(baseConfig);
570         noMatchConfig.setCaCertificate(FakeKeys.CA_CERT0);
571         // Missing match disables validation.
572         assertTrue(baseConfig.isEapMethodServerCertUsed());
573         assertFalse(baseConfig.isServerCertValidationEnabled());
574 
575         WifiEnterpriseConfig noCaConfig = new WifiEnterpriseConfig(baseConfig);
576         noCaConfig.setDomainSuffixMatch(TEST_DOMAIN_SUFFIX_MATCH);
577         // Missing CA certificate disables validation.
578         assertTrue(baseConfig.isEapMethodServerCertUsed());
579         assertFalse(baseConfig.isServerCertValidationEnabled());
580 
581         WifiEnterpriseConfig noValidationConfig = new WifiEnterpriseConfig();
582         noValidationConfig.setEapMethod(Eap.AKA);
583         assertFalse(noValidationConfig.isEapMethodServerCertUsed());
584     }
585 
586     @Test
testIsEnterpriseConfigServerCertEnabledWithPeap()587     public void testIsEnterpriseConfigServerCertEnabledWithPeap() {
588         testIsEnterpriseConfigServerCertEnabled(Eap.PEAP);
589     }
590 
591     @Test
testIsEnterpriseConfigServerCertEnabledWithTls()592     public void testIsEnterpriseConfigServerCertEnabledWithTls() {
593         testIsEnterpriseConfigServerCertEnabled(Eap.TLS);
594     }
595 
596     @Test
testIsEnterpriseConfigServerCertEnabledWithTTLS()597     public void testIsEnterpriseConfigServerCertEnabledWithTTLS() {
598         testIsEnterpriseConfigServerCertEnabled(Eap.TTLS);
599     }
600 
601     @Test
testSetGetDecoratedIdentityPrefix()602     public void testSetGetDecoratedIdentityPrefix() {
603         assumeTrue(SdkLevel.isAtLeastS());
604         WifiEnterpriseConfig config = new WifiEnterpriseConfig();
605 
606         assertNull(config.getDecoratedIdentityPrefix());
607         config.setDecoratedIdentityPrefix(TEST_DECORATED_IDENTITY_PREFIX);
608         assertEquals(TEST_DECORATED_IDENTITY_PREFIX, config.getDecoratedIdentityPrefix());
609     }
610 
611     /**
612      * Verify that the set decorated identity prefix doesn't accept a malformed input.
613      *
614      * @throws Exception
615      */
616     @Test (expected = IllegalArgumentException.class)
testSetDecoratedIdentityPrefixWithInvalidValue()617     public void testSetDecoratedIdentityPrefixWithInvalidValue() {
618         assumeTrue(SdkLevel.isAtLeastS());
619         PasspointConfiguration config = new PasspointConfiguration();
620 
621         config.setDecoratedIdentityPrefix(TEST_DECORATED_IDENTITY_PREFIX.replace('!', 'a'));
622     }
623 
testIsEnterpriseConfigServerCertEnabled(int eapMethod)624     private void testIsEnterpriseConfigServerCertEnabled(int eapMethod) {
625         WifiEnterpriseConfig configWithCertAndDomainSuffixMatch = createEnterpriseConfig(eapMethod,
626                 Phase2.NONE, FakeKeys.CA_CERT0, null, TEST_DOMAIN_SUFFIX_MATCH, null);
627         assertTrue(configWithCertAndDomainSuffixMatch.isEapMethodServerCertUsed());
628         assertTrue(configWithCertAndDomainSuffixMatch.isServerCertValidationEnabled());
629 
630         WifiEnterpriseConfig configWithCertAndAltSubjectMatch = createEnterpriseConfig(eapMethod,
631                 Phase2.NONE, FakeKeys.CA_CERT0, null, null, TEST_ALT_SUBJECT_MATCH);
632         assertTrue(configWithCertAndAltSubjectMatch.isEapMethodServerCertUsed());
633         assertTrue(configWithCertAndAltSubjectMatch.isServerCertValidationEnabled());
634 
635         WifiEnterpriseConfig configWithAliasAndDomainSuffixMatch = createEnterpriseConfig(eapMethod,
636                 Phase2.NONE, null, new String[]{"alias1", "alisa2"}, TEST_DOMAIN_SUFFIX_MATCH,
637                 null);
638         assertTrue(configWithAliasAndDomainSuffixMatch.isEapMethodServerCertUsed());
639         assertTrue(configWithAliasAndDomainSuffixMatch.isServerCertValidationEnabled());
640 
641         WifiEnterpriseConfig configWithAliasAndAltSubjectMatch = createEnterpriseConfig(eapMethod,
642                 Phase2.NONE, null, new String[]{"alias1", "alisa2"}, null, TEST_ALT_SUBJECT_MATCH);
643         assertTrue(configWithAliasAndAltSubjectMatch.isEapMethodServerCertUsed());
644         assertTrue(configWithAliasAndAltSubjectMatch.isServerCertValidationEnabled());
645     }
646 
createEnterpriseConfig(int eapMethod, int phase2Method, X509Certificate caCertificate, String[] aliases, String domainSuffixMatch, String altSubjectMatch)647     private WifiEnterpriseConfig createEnterpriseConfig(int eapMethod, int phase2Method,
648             X509Certificate caCertificate, String[] aliases, String domainSuffixMatch,
649             String altSubjectMatch) {
650         WifiEnterpriseConfig config = new WifiEnterpriseConfig();
651         config.setEapMethod(eapMethod);
652         config.setPhase2Method(phase2Method);
653         config.setCaCertificate(caCertificate);
654         config.setCaCertificateAliases(aliases);
655         config.setDomainSuffixMatch(domainSuffixMatch);
656         config.setAltSubjectMatch(altSubjectMatch);
657         return config;
658     }
659 }
660