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