blob: 4b7a014f25dc1b130c7dfae5f7c6f4da950e578d [file] [log] [blame]
Chad Brubaker5f967022015-11-04 23:55:29 -08001/*
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
17package android.security.net.config;
18
19import android.content.Context;
Chad Brubaker5ac2ea12017-10-18 10:35:04 -070020import android.content.pm.ApplicationInfo;
Chad Brubaker5f967022015-11-04 23:55:29 -080021import android.test.AndroidTestCase;
22import android.test.MoreAsserts;
23import android.util.ArraySet;
24import android.util.Pair;
25import java.io.IOException;
Chad Brubakerdd586a42015-12-10 18:32:40 -080026import java.net.InetAddress;
Chad Brubaker5f967022015-11-04 23:55:29 -080027import java.net.Socket;
28import java.net.URL;
Chad Brubaker5a1078f2015-11-10 12:26:18 -080029import java.security.KeyStore;
30import java.security.Provider;
31import java.security.Security;
32import java.security.cert.X509Certificate;
Chad Brubaker5f967022015-11-04 23:55:29 -080033import java.util.ArrayList;
34import java.util.Collections;
Chad Brubaker08d36202015-11-09 13:38:51 -080035import java.util.Set;
Chad Brubaker5f967022015-11-04 23:55:29 -080036import javax.net.ssl.HttpsURLConnection;
37import javax.net.ssl.SSLContext;
38import javax.net.ssl.SSLHandshakeException;
Chad Brubakerdd586a42015-12-10 18:32:40 -080039import javax.net.ssl.SSLSocket;
Chad Brubaker5f967022015-11-04 23:55:29 -080040import javax.net.ssl.TrustManager;
Chad Brubaker5a1078f2015-11-10 12:26:18 -080041import javax.net.ssl.TrustManagerFactory;
Chad Brubaker5f967022015-11-04 23:55:29 -080042
43public class XmlConfigTests extends AndroidTestCase {
44
Chad Brubaker08d36202015-11-09 13:38:51 -080045 private final static String DEBUG_CA_SUBJ = "O=AOSP, CN=Test debug CA";
46
Chad Brubaker5f967022015-11-04 23:55:29 -080047 public void testEmptyConfigFile() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -070048 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_config,
49 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -080050 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
67 public void testEmptyAnchors() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -070068 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.empty_trust,
69 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -080070 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
86 public void testBasicDomainConfig() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -070087 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.domain1,
88 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -080089 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);
Chad Brubakerdd586a42015-12-10 18:32:40 -0800112 // 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 }
Chad Brubaker5f967022015-11-04 23:55:29 -0800121 }
122
123 public void testBasicPinning() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700124 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.pins1,
125 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800126 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
139 public void testExpiredPin() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700140 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.expired_pin,
141 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800142 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
154 public void testOverridesPins() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700155 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.override_pins,
156 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800157 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
169 public void testBadPin() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700170 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin,
171 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800172 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
185 public void testMultipleDomains() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700186 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_domains,
187 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800188 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
207 public void testMultipleDomainConfigs() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700208 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.multiple_configs,
209 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800210 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
223 public void testIncludeSubdomains() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700224 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.subdomains,
225 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800226 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
237 public void testAttributes() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700238 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.attributes,
239 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800240 ApplicationConfig appConfig = new ApplicationConfig(source);
241 assertFalse(appConfig.hasPerDomainConfigs());
242 NetworkSecurityConfig config = appConfig.getConfigForHostname("");
243 assertTrue(config.isHstsEnforced());
244 assertFalse(config.isCleartextTrafficPermitted());
245 }
246
247 public void testResourcePemCertificateSource() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700248 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_pem,
249 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800250 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
264 public void testResourceDerCertificateSource() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700265 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.resource_anchors_der,
266 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800267 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
Chad Brubakerbd173c22015-11-06 23:02:37 -0800281 public void testNestedDomainConfigs() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700282 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains,
283 TestUtils.makeApplicationInfo());
Chad Brubakerbd173c22015-11-06 23:02:37 -0800284 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
300 public void testNestedDomainConfigsOverride() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700301 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.nested_domains_override,
302 TestUtils.makeApplicationInfo());
Chad Brubakerbd173c22015-11-06 23:02:37 -0800303 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
Chad Brubaker08d36202015-11-09 13:38:51 -0800312 public void testDebugOverridesDisabled() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700313 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic,
314 TestUtils.makeApplicationInfo());
Chad Brubaker08d36202015-11-09 13:38:51 -0800315 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
324 public void testBasicDebugOverrides() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700325 ApplicationInfo info = TestUtils.makeApplicationInfo();
326 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
327 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_basic, info);
Chad Brubaker08d36202015-11-09 13:38:51 -0800328 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
340 public void testDebugOverridesWithDomain() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700341 ApplicationInfo info = TestUtils.makeApplicationInfo();
342 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
343 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, info);
Chad Brubaker08d36202015-11-09 13:38:51 -0800344 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
360 public void testDebugInherit() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700361 ApplicationInfo info = TestUtils.makeApplicationInfo();
362 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
363 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.debug_domain, info);
Chad Brubaker08d36202015-11-09 13:38:51 -0800364 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
Chad Brubaker5f967022015-11-04 23:55:29 -0800381 private void testBadConfig(int configId) throws Exception {
382 try {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700383 XmlConfigSource source = new XmlConfigSource(getContext(), configId,
384 TestUtils.makeApplicationInfo());
Chad Brubaker5f967022015-11-04 23:55:29 -0800385 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
395 public void testBadConfig0() throws Exception {
396 testBadConfig(R.xml.bad_config0);
397 }
398
399 public void testBadConfig1() throws Exception {
400 testBadConfig(R.xml.bad_config1);
401 }
402
403 public void testBadConfig2() throws Exception {
404 testBadConfig(R.xml.bad_config2);
405 }
406
407 public void testBadConfig3() throws Exception {
408 testBadConfig(R.xml.bad_config3);
409 }
410
411 public void testBadConfig4() throws Exception {
412 testBadConfig(R.xml.bad_config4);
413 }
414
415 public void testBadConfig5() throws Exception {
416 testBadConfig(R.xml.bad_config4);
417 }
Chad Brubaker5a1078f2015-11-10 12:26:18 -0800418
419 public void testTrustManagerKeystore() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700420 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.bad_pin,
421 TestUtils.makeApplicationInfo());
Chad Brubaker5a1078f2015-11-10 12:26:18 -0800422 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 }
Chad Brubakerd3af9622015-11-16 10:48:20 -0800441
442 public void testDebugDedup() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700443 ApplicationInfo info = TestUtils.makeApplicationInfo();
444 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
445 XmlConfigSource source = new XmlConfigSource(getContext(), R.xml.override_dedup, info);
Chad Brubakerd3af9622015-11-16 10:48:20 -0800446 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 }
Chad Brubaker567f6f242016-02-29 14:02:32 -0800461
462 public void testExtraDebugResource() throws Exception {
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700463 ApplicationInfo info = TestUtils.makeApplicationInfo();
464 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
Chad Brubaker567f6f242016-02-29 14:02:32 -0800465 XmlConfigSource source =
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700466 new XmlConfigSource(getContext(), R.xml.extra_debug_resource, info);
Chad Brubaker567f6f242016-02-29 14:02:32 -0800467 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.
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700473 source = new XmlConfigSource(getContext(), R.xml.extra_debug_resource,
474 TestUtils.makeApplicationInfo());
Chad Brubaker567f6f242016-02-29 14:02:32 -0800475 appConfig = new ApplicationConfig(source);
476 assertFalse(appConfig.hasPerDomainConfigs());
477 config = appConfig.getConfigForHostname("");
478 MoreAsserts.assertEmpty(config.getTrustAnchors());
479 }
480
481 public void testExtraDebugResourceIgnored() throws Exception {
482 // Verify that parsing the extra debug config resource fails only when debugging is true.
483 XmlConfigSource source =
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700484 new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource,
485 TestUtils.makeApplicationInfo());
Chad Brubaker567f6f242016-02-29 14:02:32 -0800486 ApplicationConfig appConfig = new ApplicationConfig(source);
487 // Force parsing the config file.
488 appConfig.getConfigForHostname("");
489
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700490 ApplicationInfo info = TestUtils.makeApplicationInfo();
491 info.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
492 source = new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource, info);
Chad Brubaker567f6f242016-02-29 14:02:32 -0800493 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 }
Chad Brubaker7cc736d2016-03-23 14:59:14 -0700500
501 public void testDomainWhitespaceTrimming() throws Exception {
502 XmlConfigSource source =
Chad Brubaker5ac2ea12017-10-18 10:35:04 -0700503 new XmlConfigSource(getContext(), R.xml.domain_whitespace,
504 TestUtils.makeApplicationInfo());
Chad Brubaker7cc736d2016-03-23 14:59:14 -0700505 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 }
Chad Brubaker5f967022015-11-04 23:55:29 -0800513}