16bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker/* 26bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * Copyright (C) 2015 The Android Open Source Project 36bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * 46bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * Licensed under the Apache License, Version 2.0 (the "License"); 56bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * you may not use this file except in compliance with the License. 66bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * You may obtain a copy of the License at 76bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * 86bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * http://www.apache.org/licenses/LICENSE-2.0 96bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * 106bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * Unless required by applicable law or agreed to in writing, software 116bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * distributed under the License is distributed on an "AS IS" BASIS, 126bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 136bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * See the License for the specific language governing permissions and 146bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * limitations under the License. 156bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker */ 166bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 176bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerpackage android.security.net.config; 186bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 196bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport android.app.Activity; 2032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport android.os.Build; 216bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport android.test.ActivityUnitTestCase; 226bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport android.util.ArraySet; 236bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport android.util.Pair; 2432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.io.ByteArrayInputStream; 256bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport java.io.IOException; 266bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport java.net.Socket; 276bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport java.net.URL; 2832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.security.cert.Certificate; 2932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.security.cert.CertificateFactory; 3032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.security.cert.X509Certificate; 316bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport java.util.ArrayList; 326bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport java.util.Collections; 3332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.util.HashSet; 3432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport java.util.Set; 356bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport javax.net.ssl.HttpsURLConnection; 366bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport javax.net.ssl.SSLContext; 376bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport javax.net.ssl.SSLHandshakeException; 386bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerimport javax.net.ssl.TrustManager; 396bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 4032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubakerimport com.android.org.conscrypt.TrustedCertificateStore; 4132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 426bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubakerpublic class NetworkSecurityConfigTests extends ActivityUnitTestCase<Activity> { 436bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 446bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public NetworkSecurityConfigTests() { 456bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker super(Activity.class); 466bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 476bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 486bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker // SHA-256 of the G2 intermediate CA for android.com (as of 10/2015). 496bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker private static final byte[] G2_SPKI_SHA256 506bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = hexToBytes("ec722969cb64200ab6638f68ac538e40abab5b19a6485661042a1061c4612776"); 516bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 5232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker private static final byte[] TEST_CA_BYTES 5332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker = hexToBytes( 5432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker "3082036130820249a003020102020900bd54597d6750ea62300d06092a86" 5532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "4886f70d01010b05003047310b3009060355040613025553310b30090603" 5632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "5504080c0243413110300e060355040a0c07416e64726f69643119301706" 5732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "035504030c104e53436f6e6669672054657374204341301e170d31363032" 5832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "32343030313130325a170d3136303332353030313130325a3047310b3009" 5932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "060355040613025553310b300906035504080c0243413110300e06035504" 6032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "0a0c07416e64726f69643119301706035504030c104e53436f6e66696720" 6132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "5465737420434130820122300d06092a864886f70d01010105000382010f" 6232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "003082010a0282010100e15ce8fd5794029841e760d68d6e0159c9c67630" 6332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "089775bc728d83dae7e29e23fe5f6e113b789f4c5b22f052300ec6d5faa5" 6432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "724432e7bac96682792ef6e9617c939c4329dce8788cbdf3a11b621fac9e" 6532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "2edbec2d7e5e07296bbb544b89263137a6a31573a2362e05ca8ff9c886bf" 6632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "52df4ff93c45475145a40a83f2670e23669220a5a4bf2c6860edb78d3022" 6732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "192fb5dc5e8c118f70870f89da292dfe522751462f020ed556653c8b07f8" 6832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "89712a6e8196c457a637439e3073d7d917ab55aa51a146826367f7b5922a" 6932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "64fb2f95099de21eb98341fa76faa79ffbda123fe5b8adc614b16174e8b0" 7032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "dfdac2bbc4d526d2487ad2b009d53996ec23ffbd732112efa66b02030100" 7132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "01a350304e301d0603551d0e04160414f66e1a95486c879edd60a5756bc2" 7232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "f1f4677e128e301f0603551d23041830168014f66e1a95486c879edd60a5" 7332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "756bc2f1f4677e128e300c0603551d13040530030101ff300d06092a8648" 7432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "86f70d01010b05000382010100d2856130dccae24e5f8901900d94bc642f" 7532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "85466ab7cfa1066399077a168cd4b56603a9e2af9d2e58aec13101e338a4" 7632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "8e95e9c7a84d7991f0d381d4965eaada1b80fbbd8277445f449babe64f53" 7732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "ba625387460b592a1a97b14b8251115e6610350021a6e716ae22b905f8d4" 7832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "eae24e668e71b12ab51fd2f2bb600e074487dec720c3db14dbca504844b6" 7932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "933bb0248283ea95464747689c37d706d4839c7d0e9bd86abf98ddce5d36" 8032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "8b38bfe5062353e28d5be378827fade1caa6bba3df9cd9ebf83d839eae52" 8132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "780181f31973f15f982686ba6d899f7b644fd1f26c8ebb99f4c986faaf4c" 8232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker + "1b9e3d9d391943ce3fb9fa2e631bd66b8ef3d47fd85acf09ea3a30f15f"); 8332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 8432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker private static final X509Certificate TEST_CA_CERT; 8532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 8632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker static { 8732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker try { 8832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker CertificateFactory factory = CertificateFactory.getInstance("X.509"); 8932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker Certificate cert = factory.generateCertificate(new ByteArrayInputStream(TEST_CA_BYTES)); 9032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker TEST_CA_CERT = (X509Certificate) cert; 9132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } catch (Exception e) { 9232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker throw new RuntimeException(e); 9332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 9432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 9532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 9632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 976bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker private static byte[] hexToBytes(String s) { 986bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker int len = s.length(); 996bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker byte[] data = new byte[len / 2]; 1006bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker for (int i = 0; i < len; i += 2) { 1016bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit( 1026bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker s.charAt(i + 1), 16)); 1036bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1046bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker return data; 1056bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1066bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1076bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1086bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker /** 1096bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * Return a NetworkSecurityConfig that has an empty TrustAnchor set. This should always cause a 1106bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker * SSLHandshakeException when used for a connection. 1116bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker */ 1126bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker private NetworkSecurityConfig getEmptyConfig() { 11380a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker return new NetworkSecurityConfig.Builder().build(); 1146bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1156bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1166bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker private NetworkSecurityConfig getSystemStoreConfig() { 11780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker return new NetworkSecurityConfig.Builder() 11880a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .addCertificatesEntryRef( 11980a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) 12080a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 1216bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1226bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1236bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testEmptyConfig() throws Exception { 1246bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1256bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 1266bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ConfigSource testSource = 1276bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new TestConfigSource(domainMap, getEmptyConfig()); 1285f96702f582050c1598136ed2a748f76b981c94eChad Brubaker SSLContext context = TestUtils.getSSLContext(testSource); 1295f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionFails(context, "android.com", 443); 1306bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1316bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1326bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testEmptyPerNetworkSecurityConfig() throws Exception { 1336bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1346bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 1356bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 1366bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), getEmptyConfig())); 13780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig defaultConfig = getSystemStoreConfig(); 1385f96702f582050c1598136ed2a748f76b981c94eChad Brubaker SSLContext context = TestUtils.getSSLContext(new TestConfigSource(domainMap, defaultConfig)); 1395f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionFails(context, "android.com", 443); 1405f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "google.com", 443); 1416bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1426bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1436bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testBadPin() throws Exception { 1446bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pin> pins = new ArraySet<Pin>(); 1456bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker pins.add(new Pin("SHA-256", new byte[0])); 14680a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() 14780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .setPinSet(new PinSet(pins, Long.MAX_VALUE)) 14880a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .addCertificatesEntryRef( 14980a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) 15080a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 1516bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1526bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 1536bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 1546bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), domain)); 1556bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 1565f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getSystemStoreConfig())); 1575f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionFails(context, "android.com", 443); 1585f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "google.com", 443); 1596bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1606bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1616bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testGoodPin() throws Exception { 1626bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pin> pins = new ArraySet<Pin>(); 1636bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker pins.add(new Pin("SHA-256", G2_SPKI_SHA256)); 16480a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() 16580a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .setPinSet(new PinSet(pins, Long.MAX_VALUE)) 16680a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .addCertificatesEntryRef( 16780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) 16880a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 1696bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1706bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 1716bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 1726bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), domain)); 1736bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 1745f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 1755f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "android.com", 443); 1765f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443); 1776bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1786bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1796bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testOverridePins() throws Exception { 1806bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker // Use a bad pin + granting the system CA store the ability to override pins. 1816bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pin> pins = new ArraySet<Pin>(); 1826bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker pins.add(new Pin("SHA-256", new byte[0])); 18380a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() 18480a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .setPinSet(new PinSet(pins, Long.MAX_VALUE)) 18580a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .addCertificatesEntryRef( 18680a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker new CertificatesEntryRef(SystemCertificateSource.getInstance(), true)) 18780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 1886bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1896bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 1906bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 1916bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), domain)); 1926bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 1935f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 1945f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "android.com", 443); 1956bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 1966bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 1976bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testMostSpecificNetworkSecurityConfig() throws Exception { 1986bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 1996bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 2006bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 2016bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), getEmptyConfig())); 2026bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 2036bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("developer.android.com", false), getSystemStoreConfig())); 2046bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 2055f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 2065f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionFails(context, "android.com", 443); 2075f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443); 2086bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 2096bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 2106bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testSubdomainIncluded() throws Exception { 2116bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker // First try connecting to a subdomain of a domain entry that includes subdomains. 2126bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 2136bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 2146bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 2156bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), getSystemStoreConfig())); 2166bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 2175f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 2185f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionSucceeds(context, "developer.android.com", 443); 2196bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker // Now try without including subdomains. 2206bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 2216bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 2226bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", false), getSystemStoreConfig())); 2235f96702f582050c1598136ed2a748f76b981c94eChad Brubaker context = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 2245f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertConnectionFails(context, "developer.android.com", 443); 2256bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 2266bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker 22780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker public void testConfigBuilderUsesParents() throws Exception { 22880a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker // Check that a builder with a parent uses the parent's values when non is set. 22980a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig config = new NetworkSecurityConfig.Builder() 23011e45075221680dcc25e3da1d3c32710e5a98603Todd Kennedy .setParent(NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N, 1)) 23180a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 23280a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker assert(!config.getTrustAnchors().isEmpty()); 23380a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker } 23480a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker 23580a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker public void testConfigBuilderParentLoop() throws Exception { 23680a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig.Builder config1 = new NetworkSecurityConfig.Builder(); 23780a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig.Builder config2 = new NetworkSecurityConfig.Builder(); 23880a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker config1.setParent(config2); 23980a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker try { 24080a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker config2.setParent(config1); 24180a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker fail("Loop in NetworkSecurityConfig parents"); 24280a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker } catch (IllegalArgumentException expected) { 24380a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker } 24480a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker } 24580a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker 2466bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker public void testWithUrlConnection() throws Exception { 2476bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pin> pins = new ArraySet<Pin>(); 2486bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker pins.add(new Pin("SHA-256", G2_SPKI_SHA256)); 24980a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker NetworkSecurityConfig domain = new NetworkSecurityConfig.Builder() 25080a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .setPinSet(new PinSet(pins, Long.MAX_VALUE)) 25180a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .addCertificatesEntryRef( 25280a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker new CertificatesEntryRef(SystemCertificateSource.getInstance(), false)) 25380a73f5939364a07d8e83d3a90de6dc789e1b334Chad Brubaker .build(); 2546bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker ArraySet<Pair<Domain, NetworkSecurityConfig>> domainMap 2556bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker = new ArraySet<Pair<Domain, NetworkSecurityConfig>>(); 2566bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker domainMap.add(new Pair<Domain, NetworkSecurityConfig>( 2576bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker new Domain("android.com", true), domain)); 2586bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker SSLContext context 2595f96702f582050c1598136ed2a748f76b981c94eChad Brubaker = TestUtils.getSSLContext(new TestConfigSource(domainMap, getEmptyConfig())); 2605f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443); 2615f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertUrlConnectionSucceeds(context, "developer.android.com", 443); 2625f96702f582050c1598136ed2a748f76b981c94eChad Brubaker TestUtils.assertUrlConnectionFails(context, "google.com", 443); 2636bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker } 26432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker 26532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker public void testUserAddedCaOptIn() throws Exception { 26632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker TrustedCertificateStore store = new TrustedCertificateStore(); 26732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker try { 26832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker // Install the test CA. 26932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker store.installCertificate(TEST_CA_CERT); 27032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker NetworkSecurityConfig preNConfig = 27111e45075221680dcc25e3da1d3c32710e5a98603Todd Kennedy NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.M, 1).build(); 27232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker NetworkSecurityConfig nConfig = 27311e45075221680dcc25e3da1d3c32710e5a98603Todd Kennedy NetworkSecurityConfig.getDefaultBuilder(Build.VERSION_CODES.N, 1).build(); 27432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker Set<TrustAnchor> preNAnchors = preNConfig.getTrustAnchors(); 27532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker Set<TrustAnchor> nAnchors = nConfig.getTrustAnchors(); 27632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker Set<X509Certificate> preNCerts = new HashSet<X509Certificate>(); 27732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker for (TrustAnchor anchor : preNAnchors) { 27832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker preNCerts.add(anchor.certificate); 27932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 28032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker Set<X509Certificate> nCerts = new HashSet<X509Certificate>(); 28132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker for (TrustAnchor anchor : nAnchors) { 28232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker nCerts.add(anchor.certificate); 28332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 28432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker assertTrue(preNCerts.contains(TEST_CA_CERT)); 28532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker assertFalse(nCerts.contains(TEST_CA_CERT)); 28632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } finally { 28732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker // Delete the user added CA. We don't know the alias so just delete them all. 28832d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker for (String alias : store.aliases()) { 28932d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker if (store.isUser(alias)) { 29032d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker try { 29132d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker store.deleteCertificateEntry(alias); 29232d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } catch (Exception ignored) { 29332d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 29432d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 29532d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 29632d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 29732d2a1024f75f7e917f2aca18d34322a46d36bcbChad Brubaker } 2986bc1e3966c4890ee3d47b5e527b800f2700ed627Chad Brubaker} 299