157d73e33dc039f6fff06db52106a358192868060Jesse Wilson/*
257d73e33dc039f6fff06db52106a358192868060Jesse Wilson * Copyright (C) 2010 The Android Open Source Project
357d73e33dc039f6fff06db52106a358192868060Jesse Wilson *
457d73e33dc039f6fff06db52106a358192868060Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
557d73e33dc039f6fff06db52106a358192868060Jesse Wilson * you may not use this file except in compliance with the License.
657d73e33dc039f6fff06db52106a358192868060Jesse Wilson * You may obtain a copy of the License at
757d73e33dc039f6fff06db52106a358192868060Jesse Wilson *
857d73e33dc039f6fff06db52106a358192868060Jesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
957d73e33dc039f6fff06db52106a358192868060Jesse Wilson *
1057d73e33dc039f6fff06db52106a358192868060Jesse Wilson * Unless required by applicable law or agreed to in writing, software
1157d73e33dc039f6fff06db52106a358192868060Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
1257d73e33dc039f6fff06db52106a358192868060Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1357d73e33dc039f6fff06db52106a358192868060Jesse Wilson * See the License for the specific language governing permissions and
1457d73e33dc039f6fff06db52106a358192868060Jesse Wilson * limitations under the License.
1557d73e33dc039f6fff06db52106a358192868060Jesse Wilson */
1657d73e33dc039f6fff06db52106a358192868060Jesse Wilson
1757d73e33dc039f6fff06db52106a358192868060Jesse Wilsonpackage libcore.javax.net.ssl;
1857d73e33dc039f6fff06db52106a358192868060Jesse Wilson
1957d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.io.ByteArrayInputStream;
2057d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.io.InputStream;
2157d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.math.BigInteger;
2257d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.nio.charset.Charsets;
2357d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.security.Principal;
2457d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.security.PublicKey;
2557d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.security.cert.CertificateFactory;
2657d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.security.cert.X509Certificate;
2757d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.ArrayList;
2857d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.Collection;
2957d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.Date;
3057d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.LinkedList;
3157d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.List;
3257d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport java.util.Set;
3357d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport javax.net.ssl.DefaultHostnameVerifier;
3457d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport javax.net.ssl.DistinguishedNameParser;
3557d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport javax.security.auth.x500.X500Principal;
3657d73e33dc039f6fff06db52106a358192868060Jesse Wilsonimport junit.framework.TestCase;
3757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
3857d73e33dc039f6fff06db52106a358192868060Jesse Wilsonpublic final class DefaultHostnameVerifierTest extends TestCase {
3957d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private static final int ALT_UNKNOWN = 0;
4057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private static final int ALT_DNS_NAME = 2;
4157d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private static final int ALT_IPA_NAME = 7;
4257d73e33dc039f6fff06db52106a358192868060Jesse Wilson
4357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private final DefaultHostnameVerifier verifier = new DefaultHostnameVerifier();
4457d73e33dc039f6fff06db52106a358192868060Jesse Wilson
4557d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testGetFirstCn() {
4657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("", null);
4757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("ou=xxx", null);
4857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("ou=xxx,cn=xxx", "xxx");
4957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("ou=xxx+cn=yyy,cn=zzz+cn=abc", "yyy");
5057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=a,cn=b", "a");
5157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=Cc,cn=Bb,cn=Aa", "Cc");
5257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=imap.gmail.com", "imap.gmail.com");
5357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
5457d73e33dc039f6fff06db52106a358192868060Jesse Wilson
5557d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testGetFirstCnWithOid() {
5657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("2.5.4.3=a,ou=xxx", "a");
5757d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
5857d73e33dc039f6fff06db52106a358192868060Jesse Wilson
5957d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testGetFirstCnWithQuotedStrings() {
6057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=\"\\\" a ,=<>#;\"", "\" a ,=<>#;");
6157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=abc\\,def", "abc,def");
6257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
6357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
6457d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testGetFirstCnWithUtf8() {
6557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=Lu\\C4\\8Di\\C4\\87", "\u004c\u0075\u010d\u0069\u0107");
6657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
6757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
6857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testGetFirstCnWithWhitespace() {
6957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("ou=a, cn=  a  b  ,o=x", "a  b");
7057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFirstCn("cn=\"  a  b  \" ,o=x", "  a  b  ");
7157d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
7257d73e33dc039f6fff06db52106a358192868060Jesse Wilson
7357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private void assertFirstCn(String dn, String expected) {
7457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X500Principal principal = new X500Principal(dn);
7557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertEquals("dn:" + dn, expected, new DistinguishedNameParser(principal).find("cn"));
7657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
7757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
7857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testVerify() {
7957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("imap.g.com", new StubX509Certificate("cn=imap.g.com")));
8057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("imap.g.com", new StubX509Certificate("cn=imap2.g.com")));
8157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("imap.g.com", new StubX509Certificate("cn=sub.imap.g.com")));
8257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
8357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
8457d73e33dc039f6fff06db52106a358192868060Jesse Wilson    /**
8557d73e33dc039f6fff06db52106a358192868060Jesse Wilson     * If a subjectAltName extension of type ALT_DNS_NAME is present, that MUST
8657d73e33dc039f6fff06db52106a358192868060Jesse Wilson     * be used as the identity and the CN should be ignored.
8757d73e33dc039f6fff06db52106a358192868060Jesse Wilson     */
8857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectAltNameAndCn() {
8957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("imap.g.com", new StubX509Certificate("")
9057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")));
9157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("imap.g.com", new StubX509Certificate("cn=imap.g.com")
9257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.y.com")));
9357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("imap.g.com", new StubX509Certificate("")
9457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")));
9557d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
9657d73e33dc039f6fff06db52106a358192868060Jesse Wilson
9757d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectAltNameWithWildcard() {
9857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("imap.g.com", new StubX509Certificate("")
9957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "*.g.com")));
10057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
10157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
10257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectAltNameWithIpAddress() {
10357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("1.2.3.4", new StubX509Certificate("")
10457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")));
10557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("1.2.3.5", new StubX509Certificate("")
10657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")));
10757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("192.168.100.1", new StubX509Certificate("")
10857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "1.2.3.4")
10957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "192.168.100.1")));
11057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
11157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
11257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testUnknownSubjectAltName() {
11357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // Has unknown subject alternative names
11457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("imap.g.com", new StubX509Certificate("")
11557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
11657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
11757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
11857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
11957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
12057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
12157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")));
12257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("2.33.44.55", new StubX509Certificate("")
12357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
12457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
12557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
12657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
12757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
12857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
12957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")));
13057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("g.com", new StubX509Certificate("")
13157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
13257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
13357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
13457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
13557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
13657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
13757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")));
13857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("2.33.44.1", new StubX509Certificate("")
13957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 1")
14057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 2")
14157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "a.b.c.d")
14257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "*.google.com")
14357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_DNS_NAME, "imap.g.com")
14457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_IPA_NAME, "2.33.44.55")
14557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                .addSubjectAlternativeName(ALT_UNKNOWN, "random string 3")));
14657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
14757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
14857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testWildcardMatchesWildcardSuffix() {
14957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("b.c.d", "*.b.c.d"));
15057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "*.imap.google.com"));
15157d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
15257d73e33dc039f6fff06db52106a358192868060Jesse Wilson
15357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testWildcardMatchingSubstring() {
15457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("b.c.d", "b*.c.d"));
15557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "ima*.google.com"));
15657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
15757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
15857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testWildcardMatchingEmptySubstring() {
15957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "imap*.google.com"));
16057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
16157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
16257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testWildcardMatchesChildDomain() {
16357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("a.b.c.d", "*.c.d"));
16457d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
16557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
16657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testVerifyHostName() {
16757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("a.b.c.d", "a.b.c.d"));
16857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("a.b.c.d", "*.b.c.d"));
16957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("a.b.c.d", "*.*.c.d"));
17057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "imap.google.com"));
17157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("imap2.google.com", "imap.google.com"));
17257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "*.google.com"));
17357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap2.google.com", "*.google.com"));
17457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("imap.google.com", "*.googl.com"));
17557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("imap2.google2.com", "*.google3.com"));
17657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("imap.google.com", "a*.google.com"));
17757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verifyHostName("imap.google.com", "ix*.google.com"));
17857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verifyHostName("imap.google.com", "iMap.Google.Com"));
17957d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
18057d73e33dc039f6fff06db52106a358192868060Jesse Wilson
18157d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectOnlyCert() throws Exception {
18257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP, CN=www.example.com
18357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: n/a
18457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
18557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIIC0TCCAbmgAwIBAgIJANCQbJPPw31SMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV\n"
18657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1ODE4\n"
18757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WhgPMjA2NDEwMTUyMDU4MThaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu\n"
18857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDsdUJk\n"
18957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "4KxADA3vlDHxNbyC27Ozw4yiSVzPTHUct471YmdDRW3orO2P5a5hRnUGV70gjH9X\n"
19057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MU4oeOdWYAgXB9pxfLyr6621k1+uNrmaZtzp0ECH9twcwxNJJFDZsN7o9vt7V6Ej\n"
19157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "NN9weeqDr/aeQXo07a12vyVfR6jWO8jHB0e4aemwZNoYjNvM69fivQTse2ZoRVfj\n"
19257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "eSHhjRTX6I8ry4a31Hwt+fT1QiWWNN6o7+WOtpJAhX3eg4smhSD1svi2kOT8tdUe\n"
19357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "NS4hWlmXmumU9G4tI8PBurcLNTm7PB2lUlbn/IV18WavqKE/Uy/1WgAx+a1EJNdp\n"
19457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "i07AG1PsqaONKkf1AgMBAAEwDQYJKoZIhvcNAQEFBQADggEBAJrNsuL7fZZNC8gL\n"
19557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BdePJ7DYW2e7mXANU3bCBe2BZqmXKQxKwibZnEsqA+yMLqcSd8uxISlyHY2tw9wT\n"
19657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "4wB9KPIttfNLbwn/rk+MbOTHpvyF60d9WhJJVUkPBl8D4VuPSl+VnlA54kU9dtZN\n"
19757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "+ZYdxYbNtSsI/Flz9SCoOV79W9GhN+uYJhv6RwyIMIHeMpZpyX1xSUVx5dZlmerQ\n"
19857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WAUvghDH3fFRt2ZdnA4OXoKkTAaM3Pv7PUMsnah8bux6MQi0AuLMWFWOI1H34koH\n"
19957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "rs2oQLwOLnuifH52ey9+tJguabo+brlYYigAuWWFEzJfBzikDkIwnE/L7wlrypIk\n"
20057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "taXDWI4=\n"
20157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
20257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www.example.com", cert));
20357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www2.example.com", cert));
20457d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
20557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
20657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectAltOnlyCert() throws Exception {
20757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP (no CN)
20857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: DNS:www.example.com
20957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
21057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIICvTCCAaWgAwIBAgIJALbA0TZk2YmNMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV\n"
21157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMCAXDTEwMDExMjIwNTg1NFoYDzIwNjQxMDE1MjA1ODU0WjANMQswCQYD\n"
21257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMEg6acVC9V4\n"
21357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "xNGoLNVLPbqBc8IvMvcsc88dF6MW3d9VagX3aeWU8c79tI/KOV/1AOakH7WYxw/w\n"
21457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "yD8aOX7+9BK1Hu0qKKKbSM+ycqaMthXd6xytrNDsIx5WiGUz8zTko0Gk3orIR7p7\n"
21557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "rPcNzB/zwtESkscqPv85aEn7S/yClNkzLfEzm3CtaYOc0tfhBMyzi/ipXzGMxUmx\n"
21657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "PvOLr3v/Oz5pZEQw7Kxlm4+tAtn7bJlHziQ1UW4WPIy+T3hySBEpODFiqZi7Ok3X\n"
21757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "Zjxdii62fgo5B2Ee7q5Amo0mUIwcQTDjJ2CLAqzYnSh3tpiPJGjEIjmRyCoMQ1bx\n"
21857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "7D+y7nSPIq8CAwEAAaMeMBwwGgYDVR0RBBMwEYIPd3d3LmV4YW1wbGUuY29tMA0G\n"
21957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "CSqGSIb3DQEBBQUAA4IBAQBsGEh+nHc0l9FJTzWqvG3qs7i6XoJZdtThCDx4HjKJ\n"
22057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "8GMrJtreNN4JvIxn7KC+alVbnILjzCRO+c3rsnpxKBi5cp2imjuw5Kf/x2Seimb9\n"
22157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "UvZbaJvBVOzy4Q1IGef9bLy3wZzy2/WfBFyvPTAkgkRaX7LN2jnYOYVhNoNFrwqe\n"
22257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "EWxkA6fzrpyseUEFeGFFjGxRSRCDcQ25Eq6d9rkC1x21zNtt4QwZBO0wHrTy155M\n"
22357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "JPRynf9244Pn0Sr/wsnmdsTRFIFYynrc51hQ7DkwbUxpcaewkZzilru/SwZ3+pPT\n"
22457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "9JSqm5hJ1pg5WDlPkW7c/1VA0/141N52Q8MIU+2ZpuOj\n"
22557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
22657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www.example.com", cert));
22757d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www2.example.com", cert));
22857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
22957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
23057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectWithAltNamesCert() throws Exception {
23157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP, CN=www.example.com
23257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: DNS:www2.example.com, DNS:www3.example.com
23357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // * Subject should be ignored, because it has subject alt names.
23457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
23557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIIDBDCCAeygAwIBAgIJALv14qjcuhw9MA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV\n"
23657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjA1OTM4\n"
23757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WhgPMjA2NDEwMTUyMDU5MzhaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu\n"
23857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCiTVgU\n"
23957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "kBO9KNYZZLmiPR0eBrk8u61CLnm35BGKW8EFpDaINLbbIFIQvqOMekURON/N+xFY\n"
24057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "D8roo7aFZVuHWAUqFcOJ4e6NmviK5qocLihtzAexsw4f4AzZxM3A8kcLlWLyAt7e\n"
24157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "EVLxhcMHogY7GaF6q+33Z8p+zp6x3tj07mwyPrriCLse2PeRsRunZl/fp/VvRlr6\n"
24257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "YbC7CbRrhnIv5nqohs8BsbBiiFpxQftsMQmiXhY2LUzqY2RXUIOw24fHjoQkHTL2\n"
24357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "4z5nUM3b6ueQe+CBnobUS6fzK/36Nct4dRpev9i/ORdRLuIDKJ+QR16G1V/BJYBR\n"
24457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "dAK+3iXvg6z8vP1XAgMBAAGjMTAvMC0GA1UdEQQmMCSCEHd3dzIuZXhhbXBsZS5j\n"
24557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "b22CEHd3dzMuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQEFBQADggEBAJQNf38uXm3h\n"
24657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "0vsF+Yd6/HqM48Su7tWnTDAfTXnQZZkzjzITq3JXzquMXICktAVN2cLnT9zPfRAE\n"
24757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "8V8A3BNO5zXiR5W3o/mJP5HQ3/WxpzBGM2N+YmDCJyBoQrIVaAZaXAZUaBBvn5A+\n"
24857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "kEVfGWquwIFuvA67xegbJOCRLD4eUzRdNsn5+NFiakWO1tkFqEzqyQ0PNPviRjgu\n"
24957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "z9NxdPvd1JQOhydkucsPKJzlEBbGyL5QL/Jkot3Qy+FOeuNzgQUfAGtQgzRrsZDK\n"
25057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "hrTVypLSoRXuTB2aWilu4p6aNh84xTdyqo2avtNr2MiQMZIcdamBq8LdBIAShFXI\n"
25157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "h5G2eVGXH/Y=\n"
25257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
25357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www.example.com", cert));
25457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www2.example.com", cert));
25557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www3.example.com", cert));
25657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www4.example.com", cert));
25757d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
25857d73e33dc039f6fff06db52106a358192868060Jesse Wilson
25957d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testSubjectWithWildAltNamesCert() throws Exception {
26057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP, CN=www.example.com
26157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: DNS:*.example2.com
26257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // * Subject should be ignored, because it has subject alt names.
26357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
26457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIIC8DCCAdigAwIBAgIJAL/oWJ64VAdXMA0GCSqGSIb3DQEBBQUAMCcxCzAJBgNV\n"
26557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMRgwFgYDVQQDEw93d3cuZXhhbXBsZS5jb20wIBcNMTAwMTEyMjEwMDAx\n"
26657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WhgPMjA2NDEwMTUyMTAwMDFaMCcxCzAJBgNVBAYTAkpQMRgwFgYDVQQDEw93d3cu\n"
26757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "ZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbx1QB\n"
26857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "92iea7VybLYICA4MX4LWipYrRsgXUXQrcIQ3YLTQ9rH0VwScrHL4O4JDxgXCQnR+\n"
26957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "4VOzD42q1KXHJAqzqGUYCNPyvZEzkGCnQ4FBIUEmxZd5SNEefJVH3Z6GizYJomTh\n"
27057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "p78yDcoqymD9umxRC2cWFu8GscfFGMVyhsqLlOofu7UWOs22mkXPo43jDx+VOAoV\n"
27157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "n48YP3P57a2Eo0gcd4zVL00y62VegqBO/1LW38aTS7teiCBFc1TkNYa5I40yN9lP\n"
27257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "rB9ICHYQWyzf/7OxU9iauEK2w6DmSsQoLs9JzEhgeNZddkcc77ciSUCo2Hx0VpOJ\n"
27357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BFyf2rbryJeAk+FDAgMBAAGjHTAbMBkGA1UdEQQSMBCCDiouZXhhbXBsZTIuY29t\n"
27457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MA0GCSqGSIb3DQEBBQUAA4IBAQA2a14pRL+4laJ8sscQlucaDB/oSdb0cwhk4IkE\n"
27557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "kKl/ZKr6rKwPZ81sJRgzvI4imLbUAKt4AJHdpI9cIQUq1gw9bzil7LKwmFtFSPmC\n"
27657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MYb1iadaYrvp7RE4yXrWCcSbU0hup9JQLHTrHLlqLtRuU48NHMvWYThBcS9Q/hQp\n"
27757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "nJ/JxYy3am99MHALWLAfuRxQXhE4C5utDmBwI2KD6A8SA30s+CnuegmkYScuSqBu\n"
27857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "Y3R0HZvKzNIU3pwAm69HCJoG+/9MZEIDJb0WJc5UygxDT45XE9zQMQe4dBOTaNXT\n"
27957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "+ntgaB62kE10HzrzpqXAgoAWxWK4RzFcUpBWw9qYq9xOCewJ\n"
28057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
28157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www.example.com", cert));
28257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www2.example.com", cert));
28357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www.example2.com", cert));
28457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("abc.example2.com", cert));
28557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www.example3.com", cert));
28657d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
28757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
28857d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testWildAltNameOnlyCert() throws Exception {
28957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP
29057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: DNS:*.example.com
29157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
29257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIICuzCCAaOgAwIBAgIJAP82tgcvmAGxMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV\n"
29357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMCAXDTEwMDExMjIxMDAyN1oYDzIwNjQxMDE1MjEwMDI3WjANMQswCQYD\n"
29457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALs528EQbcB1\n"
29557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "x4BwxthQBZrgDJzoO7KPV3dhGYoeP8EnRjapZm+T/sj9P/O4HvfxjnB+fsjYSdmE\n"
29657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WWUtnFrP7wtG9DUC748Ea2PMV8WFhOG58dqBNIko5XzkHB7SxkNZD5S/0KQYMGLr\n"
29757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "rchDsDlmsEf2Qb6qiqpNEU70aSkExZJcH+B9nWdeBpsVFu7wtezwSWEc2NUa2bhW\n"
29857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "gcXQ/aafwHZ4o2PyGwy0sgS/UifqO9tEllC2tPleSNJOmYsVudv5Bz4Q0GG38BSz\n"
29957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "Pc0IcOoln0ZWpXbGr03V2vlXWCwzaFAl3I1T3O7YVqDiaSWoP+d0tHZzmw8aJLXd\n"
30057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "B+KaUUGxRPsCAwEAAaMcMBowGAYDVR0RBBEwD4INKi5leGFtcGxlLmNvbTANBgkq\n"
30157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "hkiG9w0BAQUFAAOCAQEAJbVan4QgJ0cvpJnK9UWIVJNC+UbP87RC5go2fQiTnmGv\n"
30257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "prOrIuMqz1+vGcpIheLTLctJRHPoadXq0+UbQEIaU3pQbY6C4nNdfl+hcvmJeqrt\n"
30357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "kOCcvmIamO68iNvTSeszuHuu4O38PefrW2Xd0nn7bjFZrzBzHFhTudmnqNliP3ue\n"
30457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "KKQpqkUt5lCytnH8V/u/UCWdvVx5LnUa2XFGVLi3ongBIojW5fvF+yxn9ADqxdrI\n"
30557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "va++ow5r1VxQXFJc0ZPzsDo+6TlktoDHaRQJGMqQomqHWT4i7F5UZgf6BHGfEUPU\n"
30657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "qep+GsF3QRHSBtpObWkVDZNFvky3a1iZ2q25+hFIqQ==\n"
30757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
30857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www.example.com", cert));
30957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("www2.example.com", cert));
31057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("www.example2.com", cert));
31157d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
31257d73e33dc039f6fff06db52106a358192868060Jesse Wilson
31357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    public void testAltIpOnlyCert() throws Exception {
31457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject: C=JP
31557d73e33dc039f6fff06db52106a358192868060Jesse Wilson        // subject alt names: IP Address:192.168.10.1
31657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        X509Certificate cert = parseCertificate("-----BEGIN CERTIFICATE-----\n"
31757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "MIICsjCCAZqgAwIBAgIJALrC37YAXFIeMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNV\n"
31857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "BAYTAkpQMCAXDTEwMDExMjIxMzk0NloYDzIwNjQxMDE1MjEzOTQ2WjANMQswCQYD\n"
31957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "VQQGEwJKUDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALr8s/4Abpby\n"
32057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "IYks5YCJE2nbWH7kj6XbwnRzsVP9RVC33bPoQ1M+2ZY24HqkigjQS/HEXR0s0bYh\n"
32157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "dewNUnTj1uGyGs6cYzsbu7x114vmVYqjxUo3hKjwfYiPeF6f3IE1vpLI7I2G32gq\n"
32257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "Zwm9c1/vXNHIdWQxCpFcuPA8P3YGfoApFX4pQPFplBUNAQqnjdmA68cbxxMC+1F3\n"
32357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "mX42D7iIEVwyVpah5HjyxjIZQlf3X7QBj0bCmkL+ibIHTALrkNNwNM6i4xzYLz/5\n"
32457d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "14GkN9ncHY87eSOk6r53ptER6mQMhCe9qPRjSHnpWTTyj6IXTaYe+dDQw657B80w\n"
32557d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "cSHL7Ed25zUCAwEAAaMTMBEwDwYDVR0RBAgwBocEwKgKATANBgkqhkiG9w0BAQUF\n"
32657d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "AAOCAQEAgrwrtOWZT3fbi1AafpGaAiOBWSJqYqRhtQy0AfiZBxv1U0XaYqmZmpnq\n"
32757d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "DVAqr0NkljowD28NBrxIFO5gBNum2ZOPDl2/5vjFn+IirUCJ9u9wS7zYkTCW2lQR\n"
32857d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "xE7Ic3mfWv7wUbKDfjlWqP1IDHUxwkrBTAl+HnwOPiaKKk1ttwcrgS8AHlqASe03\n"
32957d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "mlwnvJ+Stk54IneRaegL0L93sNAy63RZqnPCTxGz7eHcFwX8Jdr4sbxTxQqV6pIc\n"
33057d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "WPjHQcWfpkFzAF5wyOq0kveVfx0g5xPhOVDd+U+q7WastbXICpCoHp9FxISmZVik\n"
33157d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "sAyifp8agkYdzaSh55fFmKXlFnRsQw==\n"
33257d73e33dc039f6fff06db52106a358192868060Jesse Wilson                + "-----END CERTIFICATE-----");
33357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertTrue(verifier.verify("192.168.10.1", cert));
33457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        assertFalse(verifier.verify("192.168.10.2", cert));
33557d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
33657d73e33dc039f6fff06db52106a358192868060Jesse Wilson
33757d73e33dc039f6fff06db52106a358192868060Jesse Wilson    X509Certificate parseCertificate(String encoded) throws Exception {
33857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        InputStream in = new ByteArrayInputStream(encoded.getBytes(Charsets.US_ASCII));
33957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        return (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(in);
34057d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
34157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
34257d73e33dc039f6fff06db52106a358192868060Jesse Wilson    private static class StubX509Certificate extends X509Certificate {
34357d73e33dc039f6fff06db52106a358192868060Jesse Wilson        private final X500Principal subjectX500Principal;
34457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        private Collection<List<?>> subjectAlternativeNames;
34557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
34657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        public StubX509Certificate(String subjectDn) {
34757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            subjectX500Principal = new X500Principal(subjectDn);
34857d73e33dc039f6fff06db52106a358192868060Jesse Wilson            subjectAlternativeNames = null;
34957d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
35057d73e33dc039f6fff06db52106a358192868060Jesse Wilson
35157d73e33dc039f6fff06db52106a358192868060Jesse Wilson        public StubX509Certificate addSubjectAlternativeName(int type, String name) {
35257d73e33dc039f6fff06db52106a358192868060Jesse Wilson            if (subjectAlternativeNames == null) {
35357d73e33dc039f6fff06db52106a358192868060Jesse Wilson                subjectAlternativeNames = new ArrayList<List<?>>();
35457d73e33dc039f6fff06db52106a358192868060Jesse Wilson            }
35557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            LinkedList<Object> entry = new LinkedList<Object>();
35657d73e33dc039f6fff06db52106a358192868060Jesse Wilson            entry.add(type);
35757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            entry.add(name);
35857d73e33dc039f6fff06db52106a358192868060Jesse Wilson            subjectAlternativeNames.add(entry);
35957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            return this;
36057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
36157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
36257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Collection<List<?>> getSubjectAlternativeNames() {
36357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            return subjectAlternativeNames;
36457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
36557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
36657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public X500Principal getSubjectX500Principal() {
36757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            return subjectX500Principal;
36857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
36957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
37057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public void checkValidity() {
37157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
37257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
37357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
37457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public void checkValidity(Date date) {
37557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
37657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
37757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
37857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public int getBasicConstraints() {
37957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
38057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
38157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
38257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Principal getIssuerDN() {
38357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
38457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
38557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
38657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public boolean[] getIssuerUniqueID() {
38757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
38857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
38957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
39057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public boolean[] getKeyUsage() {
39157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
39257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
39357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
39457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Date getNotAfter() {
39557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
39657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
39757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
39857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Date getNotBefore() {
39957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
40057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
40157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
40257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public BigInteger getSerialNumber() {
40357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
40457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
40557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
40657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public String getSigAlgName() {
40757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
40857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
40957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
41057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public String getSigAlgOID() {
41157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
41257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
41357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
41457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public byte[] getSigAlgParams() {
41557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
41657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
41757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
41857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public byte[] getSignature() {
41957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
42057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
42157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
42257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Principal getSubjectDN() {
42357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
42457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
42557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
42657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public boolean[] getSubjectUniqueID() {
42757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
42857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
42957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
43057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public byte[] getTBSCertificate() {
43157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
43257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
43357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
43457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public int getVersion() {
43557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
43657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
43757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
43857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public byte[] getEncoded() {
43957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
44057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
44157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
44257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public PublicKey getPublicKey() {
44357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
44457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
44557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
44657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public String toString() {
44757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
44857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
44957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
45057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public void verify(PublicKey key) {
45157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
45257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
45357d73e33dc039f6fff06db52106a358192868060Jesse Wilson
45457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public void verify(PublicKey key, String sigProvider) {
45557d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
45657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
45757d73e33dc039f6fff06db52106a358192868060Jesse Wilson
45857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Set<String> getCriticalExtensionOIDs() {
45957d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
46057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
46157d73e33dc039f6fff06db52106a358192868060Jesse Wilson
46257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public byte[] getExtensionValue(String oid) {
46357d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
46457d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
46557d73e33dc039f6fff06db52106a358192868060Jesse Wilson
46657d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public Set<String> getNonCriticalExtensionOIDs() {
46757d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
46857d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
46957d73e33dc039f6fff06db52106a358192868060Jesse Wilson
47057d73e33dc039f6fff06db52106a358192868060Jesse Wilson        @Override public boolean hasUnsupportedCriticalExtension() {
47157d73e33dc039f6fff06db52106a358192868060Jesse Wilson            throw new UnsupportedOperationException();
47257d73e33dc039f6fff06db52106a358192868060Jesse Wilson        }
47357d73e33dc039f6fff06db52106a358192868060Jesse Wilson    }
47457d73e33dc039f6fff06db52106a358192868060Jesse Wilson}
475