18f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki/* 28f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * Copyright (C) 2010 The Android Open Source Project 38f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * 48f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * Licensed under the Apache License, Version 2.0 (the "License"); 58f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * you may not use this file except in compliance with the License. 68f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * You may obtain a copy of the License at 78f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * 88f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * http://www.apache.org/licenses/LICENSE-2.0 98f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * 108f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * Unless required by applicable law or agreed to in writing, software 118f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * distributed under the License is distributed on an "AS IS" BASIS, 128f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * See the License for the specific language governing permissions and 148f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * limitations under the License. 158f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki */ 160dc59e78e18493aecd37427531d093e800846c3eBrett Chabotpackage com.android.internal.net; 178f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 182269d1572e5fcfb725ea55f5764d8c3280d69f6dDianne Hackbornimport com.android.internal.net.DomainNameValidator; 190dc59e78e18493aecd37427531d093e800846c3eBrett Chabotimport com.android.frameworks.coretests.R; 200dc59e78e18493aecd37427531d093e800846c3eBrett Chabotimport com.android.frameworks.coretests.R.raw; 21691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 22691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onukiimport android.test.AndroidTestCase; 23691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 24691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onukiimport java.io.InputStream; 258f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.math.BigInteger; 268f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.InvalidKeyException; 278f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.NoSuchAlgorithmException; 288f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.NoSuchProviderException; 298f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.Principal; 308f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.PublicKey; 318f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.SignatureException; 328f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.CertificateEncodingException; 338f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.CertificateException; 348f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.CertificateExpiredException; 35691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onukiimport java.security.cert.CertificateFactory; 368f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.CertificateNotYetValidException; 378f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.CertificateParsingException; 388f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.security.cert.X509Certificate; 398f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.ArrayList; 408f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.Collection; 418f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.Date; 428f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.LinkedList; 438f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.List; 448f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport java.util.Set; 458f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 468f028a94fc533e75077485a7d11a04e4de820335Makoto Onukiimport javax.security.auth.x500.X500Principal; 478f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 48691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onukipublic class DomainNameValidatorTest extends AndroidTestCase { 498f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private static final int ALT_UNKNOWN = 0; 508f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private static final int ALT_DNS_NAME = 2; 518f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private static final int ALT_IPA_NAME = 7; 528f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 538f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki /** 54691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki * Tests {@link DomainNameValidator#match}, using a simple {@link X509Certificate} 55691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki * implementation. 568f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki */ 578f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void testMatch() { 588f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("11", new StubX509Certificate("cn=imap.g.com"), "imap.g.com", true); 598f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("12", new StubX509Certificate("cn=imap2.g.com"), "imap.g.com", false); 608f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("13", new StubX509Certificate("cn=sub.imap.g.com"), "imap.g.com", false); 618f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 628f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki // If a subjectAltName extension of type dNSName is present, that MUST 638f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki // be used as the identity 648f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("21", new StubX509Certificate("") 658f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com") 668f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "imap.g.com", false); 678f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("22", new StubX509Certificate("cn=imap.g.com") // This cn should be ignored 688f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com") 698f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "imap.g.com", false); 708f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("23", new StubX509Certificate("") 718f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") 728f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "imap.g.com", true); 738f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 748f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki // With wildcards 758f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("24", new StubX509Certificate("") 768f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "*.g.com") 778f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "imap.g.com", true); 788f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 798f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki // host name is ip address 808f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("31", new StubX509Certificate("") 818f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") 828f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "1.2.3.4", true); 838f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("32", new StubX509Certificate("") 848f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") 858f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "1.2.3.5", false); 868f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("32", new StubX509Certificate("") 878f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4") 888f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "192.168.100.1") 898f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "192.168.100.1", true); 908f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 918f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki // Has unknown subject alternative names 928f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("41", new StubX509Certificate("") 938f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") 948f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") 958f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") 968f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") 978f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") 988f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") 998f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") 1008f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "imap.g.com", true); 1018f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1028f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("42", new StubX509Certificate("") 1038f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") 1048f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") 1058f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") 1068f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") 1078f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") 1088f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") 1098f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") 1108f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "2.33.44.55", true); 1118f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1128f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("43", new StubX509Certificate("") 1138f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") 1148f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") 1158f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") 1168f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") 1178f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") 1188f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") 1198f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") 1208f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "g.com", false); 1218f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1228f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatch("44", new StubX509Certificate("") 1238f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1") 1248f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2") 1258f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d") 1268f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com") 1278f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com") 1288f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55") 1298f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3") 1308f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki , "2.33.44.1", false); 1318f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 1328f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1338f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private void checkMatch(String message, X509Certificate certificate, String thisDomain, 1348f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki boolean expected) { 1358f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki Boolean actual = DomainNameValidator.match(certificate, thisDomain); 1368f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki assertEquals(message, (Object) expected, (Object) actual); 1378f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 1388f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1398f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki /** 1408f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * Tests {@link DomainNameValidator#matchDns} 1418f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki */ 1428f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void testMatchDns() { 1438f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("11", "a.b.c.d", "a.b.c.d", true); 1448f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("12", "a.b.c.d", "*.b.c.d", true); 1458f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("13", "b.c.d", "*.b.c.d", true); 1468f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("14", "b.c.d", "b*.c.d", true); 1478f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1488f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("15", "a.b.c.d", "*.*.c.d", false); 1498f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("16", "a.b.c.d", "*.c.d", false); 1508f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1518f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("21", "imap.google.com", "imap.google.com", true); 1528f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("22", "imap2.google.com", "imap.google.com", false); 1538f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("23", "imap.google.com", "*.google.com", true); 1548f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("24", "imap2.google.com", "*.google.com", true); 1558f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("25", "imap.google.com", "*.googl.com", false); 1568f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("26", "imap2.google2.com", "*.google3.com", false); 1578f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("27", "imap.google.com", "ima*.google.com", true); 1588f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("28", "imap.google.com", "imap*.google.com", true); 1598f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("29", "imap.google.com", "*.imap.google.com", true); 1608f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1618f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("41", "imap.google.com", "a*.google.com", false); 1628f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("42", "imap.google.com", "ix*.google.com", false); 1638f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1648f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki checkMatchDns("51", "imap.google.com", "iMap.Google.Com", true); 1658f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 1668f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1678f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private void checkMatchDns(String message, String thisDomain, String thatDomain, 1688f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki boolean expected) { 1698f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki boolean actual = DomainNameValidator.matchDns(thisDomain, thatDomain); 1708f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki assertEquals(message, expected, actual); 1718f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 1728f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 1738f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki /** 174691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki * Test {@link DomainNameValidator#match} with actual certificates. 175691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki */ 176691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki public void testWithActualCert() throws Exception { 177691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject_only 178691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 179691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP, CN=www.example.com 180691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: n/a 181691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("11", R.raw.subject_only, "www.example.com", true); 182691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("12", R.raw.subject_only, "www2.example.com", false); 183691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 184691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject_alt_only 185691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 186691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP (no CN) 187691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: DNS:www.example.com 188691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("21", R.raw.subject_alt_only, "www.example.com", true); 189691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("22", R.raw.subject_alt_only, "www2.example.com", false); 190691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 191691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject_with_alt_names 192691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 193691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP, CN=www.example.com 194691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: DNS:www2.example.com, DNS:www3.example.com 195691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // * Subject should be ignored, because it has subject alt names. 196691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("31", R.raw.subject_with_alt_names, "www.example.com", false); 197691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("32", R.raw.subject_with_alt_names, "www2.example.com", true); 198691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("33", R.raw.subject_with_alt_names, "www3.example.com", true); 199691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("34", R.raw.subject_with_alt_names, "www4.example.com", false); 200691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 201691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject_with_wild_alt_name 202691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 203691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP, CN=www.example.com 204691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: DNS:*.example2.com 205691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // * Subject should be ignored, because it has subject alt names. 206691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("41", R.raw.subject_with_wild_alt_name, "www.example.com", false); 207691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("42", R.raw.subject_with_wild_alt_name, "www2.example.com", false); 208691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("43", R.raw.subject_with_wild_alt_name, "www.example2.com", true); 209691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("44", R.raw.subject_with_wild_alt_name, "abc.example2.com", true); 210691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("45", R.raw.subject_with_wild_alt_name, "www.example3.com", false); 211691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 212691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // wild_alt_name_only 213691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 214691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP 215691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: DNS:*.example.com 216691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("51", R.raw.wild_alt_name_only, "www.example.com", true); 217691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("52", R.raw.wild_alt_name_only, "www2.example.com", true); 218691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("53", R.raw.wild_alt_name_only, "www.example2.com", false); 219691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 220691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // wild_alt_name_only 221691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // 222691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject: C=JP 223691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki // subject alt names: IP Address:192.168.10.1 224691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.1", true); 225691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkWithActualCert("61", R.raw.alt_ip_only, "192.168.10.2", false); 226691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki } 227691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 228691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki private void checkWithActualCert(String message, int resId, String domain, 229691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki boolean expected) throws Exception { 230691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki CertificateFactory factory = CertificateFactory.getInstance("X509"); 231691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki InputStream certStream = getContext().getResources().openRawResource(resId); 232691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki X509Certificate certificate = (X509Certificate) factory.generateCertificate(certStream); 233691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 234691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki checkMatch(message, certificate, domain, expected); 235691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki } 236691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki 237691c07031ab2d53e3e0942c7148927af61ae21b1Makoto Onuki /** 2388f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki * Minimal {@link X509Certificate} implementation for {@link DomainNameValidator}. 2398f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki */ 2408f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private static class StubX509Certificate extends X509Certificate { 2418f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private final X500Principal subjectX500Principal; 2428f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki private Collection<List<?>> subjectAlternativeNames; 2438f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2448f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public StubX509Certificate(String subjectDn) { 2458f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki subjectX500Principal = new X500Principal(subjectDn); 2468f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki subjectAlternativeNames = null; 2478f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2488f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2498f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public StubX509Certificate addSubjectAlternativeName(int type, String name) { 2508f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki if (subjectAlternativeNames == null) { 2518f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki subjectAlternativeNames = new ArrayList<List<?>>(); 2528f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2538f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki LinkedList<Object> entry = new LinkedList<Object>(); 2548f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki entry.add(type); 2558f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki entry.add(name); 2568f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki subjectAlternativeNames.add(entry); 2578f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki return this; 2588f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2598f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2608f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2618f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Collection<List<?>> getSubjectAlternativeNames() throws CertificateParsingException { 2628f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki return subjectAlternativeNames; 2638f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2648f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2658f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2668f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public X500Principal getSubjectX500Principal() { 2678f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki return subjectX500Principal; 2688f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2698f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2708f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2718f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void checkValidity() throws CertificateExpiredException, 2728f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki CertificateNotYetValidException { 2738f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 2748f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2758f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2768f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2778f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void checkValidity(Date date) throws CertificateExpiredException, 2788f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki CertificateNotYetValidException { 2798f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 2808f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2818f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2828f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2838f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public int getBasicConstraints() { 2848f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 2858f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2868f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2878f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2888f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Principal getIssuerDN() { 2898f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 2908f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2918f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2928f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2938f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public boolean[] getIssuerUniqueID() { 2948f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 2958f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 2968f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 2978f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 2988f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public boolean[] getKeyUsage() { 2998f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3008f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3018f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3028f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3038f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Date getNotAfter() { 3048f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3058f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3068f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3078f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3088f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Date getNotBefore() { 3098f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3108f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3118f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3128f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3138f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public BigInteger getSerialNumber() { 3148f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3158f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3168f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3178f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3188f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public String getSigAlgName() { 3198f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3208f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3218f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3228f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3238f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public String getSigAlgOID() { 3248f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3258f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3268f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3278f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3288f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public byte[] getSigAlgParams() { 3298f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3308f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3318f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3328f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3338f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public byte[] getSignature() { 3348f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3358f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3368f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3378f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3388f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Principal getSubjectDN() { 3398f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3408f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3418f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3428f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3438f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public boolean[] getSubjectUniqueID() { 3448f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3458f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3468f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3478f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3488f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public byte[] getTBSCertificate() throws CertificateEncodingException { 3498f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3508f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3518f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3528f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3538f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public int getVersion() { 3548f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3558f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3568f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3578f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3588f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public byte[] getEncoded() throws CertificateEncodingException { 3598f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3608f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3618f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3628f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3638f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public PublicKey getPublicKey() { 3648f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3658f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3668f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3678f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3688f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public String toString() { 3698f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3708f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3718f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3728f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3738f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void verify(PublicKey key) throws CertificateException, NoSuchAlgorithmException, 3748f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki InvalidKeyException, NoSuchProviderException, SignatureException { 3758f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3768f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3778f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3788f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki @Override 3798f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public void verify(PublicKey key, String sigProvider) throws CertificateException, 3808f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, 3818f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki SignatureException { 3828f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3838f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3848f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3858f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Set<String> getCriticalExtensionOIDs() { 3868f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3878f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3888f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3898f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public byte[] getExtensionValue(String oid) { 3908f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3918f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3928f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3938f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public Set<String> getNonCriticalExtensionOIDs() { 3948f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3958f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 3968f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki 3978f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki public boolean hasUnsupportedCriticalExtension() { 3988f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki throw new RuntimeException("Method not implemented"); 3998f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 4008f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki } 4018f028a94fc533e75077485a7d11a04e4de820335Makoto Onuki} 402