Home | History | Annotate | Download | only in config
      1 /*
      2  * Copyright (C) 2015 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.security.net.config;
     18 
     19 import android.content.Context;
     20 import android.test.AndroidTestCase;
     21 import android.test.MoreAsserts;
     22 import android.util.ArraySet;
     23 import android.util.Pair;
     24 import java.io.IOException;
     25 import java.net.InetAddress;
     26 import java.net.Socket;
     27 import java.net.URL;
     28 import java.security.KeyStore;
     29 import java.security.Provider;
     30 import java.security.Security;
     31 import java.security.cert.X509Certificate;
     32 import java.util.ArrayList;
     33 import java.util.Collections;
     34 import java.util.Set;
     35 import javax.net.ssl.HttpsURLConnection;
     36 import javax.net.ssl.SSLContext;
     37 import javax.net.ssl.SSLHandshakeException;
     38 import javax.net.ssl.SSLSocket;
     39 import javax.net.ssl.TrustManager;
     40 import javax.net.ssl.TrustManagerFactory;
     41 
     42 public class XmlConfigTests extends AndroidTestCase {
     43 
     44     private final static String DEBUG_CA_SUBJ = "O=AOSP, CN=Test debug CA";
     45 
     46     public void testEmptyConfigFile() throws Exception {
     47         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_config);
     48         ApplicationConfig appConfig = new ApplicationConfig(source);
     49         assertFalse(appConfig.hasPerDomainConfigs());
     50         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
     51         assertNotNull(config);
     52         // Check defaults.
     53         assertTrue(config.isCleartextTrafficPermitted());
     54         assertFalse(config.isHstsEnforced());
     55         assertFalse(config.getTrustAnchors().isEmpty());
     56         PinSet pinSet = config.getPins();
     57         assertTrue(pinSet.pins.isEmpty());
     58         // Try some connections.
     59         SSLContext context = TestUtils.getSSLContext(source);
     60         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
     61         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
     62         TestUtils.assertUrlConnectionSucceeds(context, "google.com", 443);
     63     }
     64 
     65     public void testEmptyAnchors() throws Exception {
     66         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_trust);
     67         ApplicationConfig appConfig = new ApplicationConfig(source);
     68         assertFalse(appConfig.hasPerDomainConfigs());
     69         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
     70         assertNotNull(config);
     71         // Check defaults.
     72         assertTrue(config.isCleartextTrafficPermitted());
     73         assertFalse(config.isHstsEnforced());
     74         assertTrue(config.getTrustAnchors().isEmpty());
     75         PinSet pinSet = config.getPins();
     76         assertTrue(pinSet.pins.isEmpty());
     77         SSLContext context = TestUtils.getSSLContext(source);
     78         TestUtils.assertConnectionFails(context, "android.com", 443);
     79         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
     80         TestUtils.assertUrlConnectionFails(context, "google.com", 443);
     81     }
     82 
     83     public void testBasicDomainConfig() throws Exception {
     84         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.domain1);
     85         ApplicationConfig appConfig = new ApplicationConfig(source);
     86         assertTrue(appConfig.hasPerDomainConfigs());
     87         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
     88         assertNotNull(config);
     89         // Check defaults.
     90         assertTrue(config.isCleartextTrafficPermitted());
     91         assertFalse(config.isHstsEnforced());
     92         assertTrue(config.getTrustAnchors().isEmpty());
     93         PinSet pinSet = config.getPins();
     94         assertTrue(pinSet.pins.isEmpty());
     95         // Check android.com.
     96         config = appConfig.getConfigForHostname("android.com");
     97         assertTrue(config.isCleartextTrafficPermitted());
     98         assertFalse(config.isHstsEnforced());
     99         assertFalse(config.getTrustAnchors().isEmpty());
    100         pinSet = config.getPins();
    101         assertTrue(pinSet.pins.isEmpty());
    102         // Try connections.
    103         SSLContext context = TestUtils.getSSLContext(source);
    104         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    105         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
    106         TestUtils.assertUrlConnectionFails(context, "google.com", 443);
    107         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    108         // Check that sockets created without the hostname fail with per-domain configs
    109         SSLSocket socket = (SSLSocket) context.getSocketFactory()
    110                 .createSocket(InetAddress.getByName("android.com"), 443);
    111         try {
    112         socket.startHandshake();
    113         socket.getInputStream();
    114         fail();
    115         } catch (IOException expected) {
    116         }
    117     }
    118 
    119     public void testBasicPinning() throws Exception {
    120         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.pins1);
    121         ApplicationConfig appConfig = new ApplicationConfig(source);
    122         assertTrue(appConfig.hasPerDomainConfigs());
    123         // Check android.com.
    124         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    125         PinSet pinSet = config.getPins();
    126         assertFalse(pinSet.pins.isEmpty());
    127         // Try connections.
    128         SSLContext context = TestUtils.getSSLContext(source);
    129         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    130         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    131         TestUtils.assertConnectionSucceeds(context, "google.com", 443);
    132     }
    133 
    134     public void testExpiredPin() throws Exception {
    135         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.expired_pin);
    136         ApplicationConfig appConfig = new ApplicationConfig(source);
    137         assertTrue(appConfig.hasPerDomainConfigs());
    138         // Check android.com.
    139         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    140         PinSet pinSet = config.getPins();
    141         assertFalse(pinSet.pins.isEmpty());
    142         // Try connections.
    143         SSLContext context = TestUtils.getSSLContext(source);
    144         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    145         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    146     }
    147 
    148     public void testOverridesPins() throws Exception {
    149         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.override_pins);
    150         ApplicationConfig appConfig = new ApplicationConfig(source);
    151         assertTrue(appConfig.hasPerDomainConfigs());
    152         // Check android.com.
    153         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    154         PinSet pinSet = config.getPins();
    155         assertFalse(pinSet.pins.isEmpty());
    156         // Try connections.
    157         SSLContext context = TestUtils.getSSLContext(source);
    158         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    159         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    160     }
    161 
    162     public void testBadPin() throws Exception {
    163         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin);
    164         ApplicationConfig appConfig = new ApplicationConfig(source);
    165         assertTrue(appConfig.hasPerDomainConfigs());
    166         // Check android.com.
    167         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    168         PinSet pinSet = config.getPins();
    169         assertFalse(pinSet.pins.isEmpty());
    170         // Try connections.
    171         SSLContext context = TestUtils.getSSLContext(source);
    172         TestUtils.assertConnectionFails(context, "android.com", 443);
    173         TestUtils.assertUrlConnectionFails(context, "android.com", 443);
    174         TestUtils.assertConnectionSucceeds(context, "google.com", 443);
    175     }
    176 
    177     public void testMultipleDomains() throws Exception {
    178         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_domains);
    179         ApplicationConfig appConfig = new ApplicationConfig(source);
    180         assertTrue(appConfig.hasPerDomainConfigs());
    181         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    182         assertTrue(config.isCleartextTrafficPermitted());
    183         assertFalse(config.isHstsEnforced());
    184         assertFalse(config.getTrustAnchors().isEmpty());
    185         PinSet pinSet = config.getPins();
    186         assertTrue(pinSet.pins.isEmpty());
    187         // Both android.com and google.com should use the same config
    188         NetworkSecurityConfig other = appConfig.getConfigForHostname("google.com");
    189         assertEquals(config, other);
    190         // Try connections.
    191         SSLContext context = TestUtils.getSSLContext(source);
    192         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    193         TestUtils.assertConnectionSucceeds(context, "google.com", 443);
    194         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
    195         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    196     }
    197 
    198     public void testMultipleDomainConfigs() throws Exception {
    199         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_configs);
    200         ApplicationConfig appConfig = new ApplicationConfig(source);
    201         assertTrue(appConfig.hasPerDomainConfigs());
    202         // Should be two different config objects
    203         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    204         NetworkSecurityConfig other = appConfig.getConfigForHostname("google.com");
    205         MoreAsserts.assertNotEqual(config, other);
    206         // Try connections.
    207         SSLContext context = TestUtils.getSSLContext(source);
    208         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    209         TestUtils.assertConnectionSucceeds(context, "google.com", 443);
    210         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    211     }
    212 
    213     public void testIncludeSubdomains() throws Exception {
    214         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.subdomains);
    215         ApplicationConfig appConfig = new ApplicationConfig(source);
    216         assertTrue(appConfig.hasPerDomainConfigs());
    217         // Try connections.
    218         SSLContext context = TestUtils.getSSLContext(source);
    219         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    220         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    221         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    222         TestUtils.assertUrlConnectionSucceeds(context, "developer.android.com", 443);
    223         TestUtils.assertConnectionFails(context, "google.com", 443);
    224     }
    225 
    226     public void testAttributes() throws Exception {
    227         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.attributes);
    228         ApplicationConfig appConfig = new ApplicationConfig(source);
    229         assertFalse(appConfig.hasPerDomainConfigs());
    230         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
    231         assertTrue(config.isHstsEnforced());
    232         assertFalse(config.isCleartextTrafficPermitted());
    233     }
    234 
    235     public void testResourcePemCertificateSource() throws Exception {
    236         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_pem);
    237         ApplicationConfig appConfig = new ApplicationConfig(source);
    238         // Check android.com.
    239         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    240         assertTrue(config.isCleartextTrafficPermitted());
    241         assertFalse(config.isHstsEnforced());
    242         assertEquals(2, config.getTrustAnchors().size());
    243         // Try connections.
    244         SSLContext context = TestUtils.getSSLContext(source);
    245         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    246         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
    247         TestUtils.assertUrlConnectionFails(context, "google.com", 443);
    248         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    249     }
    250 
    251     public void testResourceDerCertificateSource() throws Exception {
    252         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_der);
    253         ApplicationConfig appConfig = new ApplicationConfig(source);
    254         // Check android.com.
    255         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    256         assertTrue(config.isCleartextTrafficPermitted());
    257         assertFalse(config.isHstsEnforced());
    258         assertEquals(2, config.getTrustAnchors().size());
    259         // Try connections.
    260         SSLContext context = TestUtils.getSSLContext(source);
    261         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    262         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
    263         TestUtils.assertUrlConnectionFails(context, "google.com", 443);
    264         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    265     }
    266 
    267     public void testNestedDomainConfigs() throws Exception {
    268         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains);
    269         ApplicationConfig appConfig = new ApplicationConfig(source);
    270         assertTrue(appConfig.hasPerDomainConfigs());
    271         NetworkSecurityConfig parent = appConfig.getConfigForHostname("android.com");
    272         NetworkSecurityConfig child = appConfig.getConfigForHostname("developer.android.com");
    273         MoreAsserts.assertNotEqual(parent, child);
    274         MoreAsserts.assertEmpty(parent.getPins().pins);
    275         MoreAsserts.assertNotEmpty(child.getPins().pins);
    276         // Check that the child inherited the cleartext value and anchors.
    277         assertFalse(child.isCleartextTrafficPermitted());
    278         MoreAsserts.assertNotEmpty(child.getTrustAnchors());
    279         // Test connections.
    280         SSLContext context = TestUtils.getSSLContext(source);
    281         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    282         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    283     }
    284 
    285     public void testNestedDomainConfigsOverride() throws Exception {
    286         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains_override);
    287         ApplicationConfig appConfig = new ApplicationConfig(source);
    288         assertTrue(appConfig.hasPerDomainConfigs());
    289         NetworkSecurityConfig parent = appConfig.getConfigForHostname("android.com");
    290         NetworkSecurityConfig child = appConfig.getConfigForHostname("developer.android.com");
    291         MoreAsserts.assertNotEqual(parent, child);
    292         assertTrue(parent.isCleartextTrafficPermitted());
    293         assertFalse(child.isCleartextTrafficPermitted());
    294     }
    295 
    296     public void testDebugOverridesDisabled() throws Exception {
    297         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic, false);
    298         ApplicationConfig appConfig = new ApplicationConfig(source);
    299         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
    300         Set<TrustAnchor> anchors = config.getTrustAnchors();
    301         MoreAsserts.assertEmpty(anchors);
    302         SSLContext context = TestUtils.getSSLContext(source);
    303         TestUtils.assertConnectionFails(context, "android.com", 443);
    304         TestUtils.assertConnectionFails(context, "developer.android.com", 443);
    305     }
    306 
    307     public void testBasicDebugOverrides() throws Exception {
    308         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic, true);
    309         ApplicationConfig appConfig = new ApplicationConfig(source);
    310         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
    311         Set<TrustAnchor> anchors = config.getTrustAnchors();
    312         MoreAsserts.assertNotEmpty(anchors);
    313         for (TrustAnchor anchor : anchors) {
    314             assertTrue(anchor.overridesPins);
    315         }
    316         SSLContext context = TestUtils.getSSLContext(source);
    317         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    318         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    319     }
    320 
    321     public void testDebugOverridesWithDomain() throws Exception {
    322         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, true);
    323         ApplicationConfig appConfig = new ApplicationConfig(source);
    324         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    325         Set<TrustAnchor> anchors = config.getTrustAnchors();
    326         boolean foundDebugCA = false;
    327         for (TrustAnchor anchor : anchors) {
    328             if (anchor.certificate.getSubjectDN().toString().equals(DEBUG_CA_SUBJ)) {
    329                 foundDebugCA = true;
    330                 assertTrue(anchor.overridesPins);
    331             }
    332         }
    333         assertTrue(foundDebugCA);
    334         SSLContext context = TestUtils.getSSLContext(source);
    335         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    336         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    337     }
    338 
    339     public void testDebugInherit() throws Exception {
    340         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, true);
    341         ApplicationConfig appConfig = new ApplicationConfig(source);
    342         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    343         Set<TrustAnchor> anchors = config.getTrustAnchors();
    344         boolean foundDebugCA = false;
    345         for (TrustAnchor anchor : anchors) {
    346             if (anchor.certificate.getSubjectDN().toString().equals(DEBUG_CA_SUBJ)) {
    347                 foundDebugCA = true;
    348                 assertTrue(anchor.overridesPins);
    349             }
    350         }
    351         assertTrue(foundDebugCA);
    352         assertTrue(anchors.size() > 1);
    353         SSLContext context = TestUtils.getSSLContext(source);
    354         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    355         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    356     }
    357 
    358     private void testBadConfig(int configId) throws Exception {
    359         try {
    360             XmlConfigSource source = new XmlConfigSource(getContext(), configId);
    361             ApplicationConfig appConfig = new ApplicationConfig(source);
    362             appConfig.getConfigForHostname("android.com");
    363             fail("Bad config " + getContext().getResources().getResourceName(configId)
    364                     + " did not fail to parse");
    365         } catch (RuntimeException e) {
    366             MoreAsserts.assertAssignableFrom(XmlConfigSource.ParserException.class,
    367                     e.getCause());
    368         }
    369     }
    370 
    371     public void testBadConfig0() throws Exception {
    372         testBadConfig(R.xml.bad_config0);
    373     }
    374 
    375     public void testBadConfig1() throws Exception {
    376         testBadConfig(R.xml.bad_config1);
    377     }
    378 
    379     public void testBadConfig2() throws Exception {
    380         testBadConfig(R.xml.bad_config2);
    381     }
    382 
    383     public void testBadConfig3() throws Exception {
    384         testBadConfig(R.xml.bad_config3);
    385     }
    386 
    387     public void testBadConfig4() throws Exception {
    388         testBadConfig(R.xml.bad_config4);
    389     }
    390 
    391     public void testBadConfig5() throws Exception {
    392         testBadConfig(R.xml.bad_config4);
    393     }
    394 
    395     public void testTrustManagerKeystore() throws Exception {
    396         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin, true);
    397         ApplicationConfig appConfig = new ApplicationConfig(source);
    398         Provider provider = new NetworkSecurityConfigProvider();
    399         TrustManagerFactory tmf =
    400                 TrustManagerFactory.getInstance("PKIX", provider);
    401         KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
    402         keystore.load(null);
    403         int i = 0;
    404         for (X509Certificate cert : SystemCertificateSource.getInstance().getCertificates()) {
    405             keystore.setEntry(String.valueOf(i),
    406                     new KeyStore.TrustedCertificateEntry(cert),
    407                     null);
    408             i++;
    409         }
    410         tmf.init(keystore);
    411         TrustManager[] tms = tmf.getTrustManagers();
    412         SSLContext context = SSLContext.getInstance("TLS");
    413         context.init(null, tms, null);
    414         TestUtils.assertConnectionSucceeds(context, "android.com" , 443);
    415     }
    416 
    417     public void testDebugDedup() throws Exception {
    418         XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.override_dedup, true);
    419         ApplicationConfig appConfig = new ApplicationConfig(source);
    420         assertTrue(appConfig.hasPerDomainConfigs());
    421         // Check android.com.
    422         NetworkSecurityConfig config = appConfig.getConfigForHostname("android.com");
    423         PinSet pinSet = config.getPins();
    424         assertFalse(pinSet.pins.isEmpty());
    425         // Check that all TrustAnchors come from the override pins debug source.
    426         for (TrustAnchor anchor : config.getTrustAnchors()) {
    427             assertTrue(anchor.overridesPins);
    428         }
    429         // Try connections.
    430         SSLContext context = TestUtils.getSSLContext(source);
    431         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    432         TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443);
    433     }
    434 
    435     public void testExtraDebugResource() throws Exception {
    436         XmlConfigSource source =
    437                 new XmlConfigSource(getContext(), R.xml.extra_debug_resource, true);
    438         ApplicationConfig appConfig = new ApplicationConfig(source);
    439         assertFalse(appConfig.hasPerDomainConfigs());
    440         NetworkSecurityConfig config = appConfig.getConfigForHostname("");
    441         MoreAsserts.assertNotEmpty(config.getTrustAnchors());
    442 
    443         // Check that the _debug file is ignored if debug is false.
    444         source = new XmlConfigSource(getContext(), R.xml.extra_debug_resource, false);
    445         appConfig = new ApplicationConfig(source);
    446         assertFalse(appConfig.hasPerDomainConfigs());
    447         config = appConfig.getConfigForHostname("");
    448         MoreAsserts.assertEmpty(config.getTrustAnchors());
    449     }
    450 
    451     public void testExtraDebugResourceIgnored() throws Exception {
    452         // Verify that parsing the extra debug config resource fails only when debugging is true.
    453         XmlConfigSource source =
    454                 new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource, false);
    455         ApplicationConfig appConfig = new ApplicationConfig(source);
    456         // Force parsing the config file.
    457         appConfig.getConfigForHostname("");
    458 
    459         source = new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource, true);
    460         appConfig = new ApplicationConfig(source);
    461         try {
    462             appConfig.getConfigForHostname("");
    463             fail("Bad extra debug resource did not fail to parse");
    464         } catch (RuntimeException expected) {
    465         }
    466     }
    467 
    468     public void testDomainWhitespaceTrimming() throws Exception {
    469         XmlConfigSource source =
    470                 new XmlConfigSource(getContext(), R.xml.domain_whitespace, false);
    471         ApplicationConfig appConfig = new ApplicationConfig(source);
    472         NetworkSecurityConfig defaultConfig = appConfig.getConfigForHostname("");
    473         MoreAsserts.assertNotEqual(defaultConfig, appConfig.getConfigForHostname("developer.android.com"));
    474         MoreAsserts.assertNotEqual(defaultConfig, appConfig.getConfigForHostname("android.com"));
    475         SSLContext context = TestUtils.getSSLContext(source);
    476         TestUtils.assertConnectionSucceeds(context, "android.com", 443);
    477         TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443);
    478     }
    479 }
    480