• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with this
4  * work for additional information regarding copyright ownership. The ASF
5  * licenses this file to You under the Apache License, Version 2.0 (the
6  * "License"); you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 
18 package tests.api.javax.net.ssl;
19 
20 import java.io.ByteArrayInputStream;
21 import java.io.InputStream;
22 import java.net.URL;
23 import java.security.cert.CertificateFactory;
24 import java.security.cert.X509Certificate;
25 import javax.net.ssl.HostnameVerifier;
26 import javax.net.ssl.HttpsURLConnection;
27 import javax.net.ssl.SSLSession;
28 import javax.security.auth.x500.X500Principal;
29 import junit.framework.TestCase;
30 import org.apache.harmony.xnet.tests.support.mySSLSession;
31 
32 /**
33  * Tests for <code>HostnameVerifier</code> class constructors and methods.
34  *
35  */
36 public class HostnameVerifierTest extends TestCase implements
37         CertificatesToPlayWith {
38 
39     /**
40      * javax.net.ssl.HostnameVerifier#verify(String hostname, SSLSession
41      *        session)
42      */
test_verify()43     public final void test_verify() throws Exception {
44         mySSLSession session = new mySSLSession("localhost", 1080, null);
45         HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
46         assertFalse(hv.verify("localhost", session));
47     }
48 
49     // copied and modified from apache http client test suite.
testVerify()50     public void testVerify() throws Exception {
51         CertificateFactory cf = CertificateFactory.getInstance("X.509");
52         InputStream in;
53         X509Certificate x509;
54         in = new ByteArrayInputStream(X509_FOO);
55         x509 = (X509Certificate) cf.generateCertificate(in);
56         mySSLSession session = new mySSLSession(new X509Certificate[] {x509});
57 
58         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
59         assertTrue(verifier.verify("foo.com", session));
60         assertFalse(verifier.verify("a.foo.com", session));
61         assertFalse(verifier.verify("bar.com", session));
62 
63         in = new ByteArrayInputStream(X509_HANAKO);
64         x509 = (X509Certificate) cf.generateCertificate(in);
65         session = new mySSLSession(new X509Certificate[] {x509});
66         assertTrue(verifier.verify("\u82b1\u5b50.co.jp", session));
67         assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
68 
69         in = new ByteArrayInputStream(X509_FOO_BAR);
70         x509 = (X509Certificate) cf.generateCertificate(in);
71         session = new mySSLSession(new X509Certificate[] {x509});
72         assertTrue(verifier.verify("foo.com", session));
73         assertFalse(verifier.verify("a.foo.com", session));
74         assertTrue(verifier.verify("bar.com", session));
75         assertFalse(verifier.verify("a.bar.com", session));
76 
77         in = new ByteArrayInputStream(X509_FOO_BAR_HANAKO);
78         x509 = (X509Certificate) cf.generateCertificate(in);
79         session = new mySSLSession(new X509Certificate[] {x509});
80         assertTrue(verifier.verify("foo.com", session));
81         assertFalse(verifier.verify("a.foo.com", session));
82         // these checks test alternative subjects. The test data contains an
83         // alternative subject starting with a japanese kanji character. This is
84         // not supported by Android because the underlying implementation from
85         // harmony follows the definition from rfc 1034 page 10 for alternative
86         // subject names. This causes the code to drop all alternative subjects.
87         // assertTrue(verifier.verify("bar.com", session));
88         // assertFalse(verifier.verify("a.bar.com", session));
89         // assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
90 
91         in = new ByteArrayInputStream(X509_NO_CNS_FOO);
92         x509 = (X509Certificate) cf.generateCertificate(in);
93         session = new mySSLSession(new X509Certificate[] {x509});
94         assertTrue(verifier.verify("foo.com", session));
95         assertFalse(verifier.verify("a.foo.com", session));
96 
97         in = new ByteArrayInputStream(X509_NO_CNS_FOO);
98         x509 = (X509Certificate) cf.generateCertificate(in);
99         session = new mySSLSession(new X509Certificate[] {x509});
100         assertTrue(verifier.verify("foo.com", session));
101         assertFalse(verifier.verify("a.foo.com", session));
102 
103         in = new ByteArrayInputStream(X509_THREE_CNS_FOO_BAR_HANAKO);
104         x509 = (X509Certificate) cf.generateCertificate(in);
105         session = new mySSLSession(new X509Certificate[] {x509});
106         assertFalse(verifier.verify("foo.com", session));
107         assertFalse(verifier.verify("a.foo.com", session));
108         assertFalse(verifier.verify("bar.com", session));
109         assertFalse(verifier.verify("a.bar.com", session));
110         assertTrue(verifier.verify("\u82b1\u5b50.co.jp", session));
111         assertFalse(verifier.verify("a.\u82b1\u5b50.co.jp", session));
112 
113         in = new ByteArrayInputStream(X509_WILD_FOO);
114         x509 = (X509Certificate) cf.generateCertificate(in);
115         session = new mySSLSession(new X509Certificate[] {x509});
116         assertFalse(verifier.verify("foo.com", session));
117         assertTrue(verifier.verify("www.foo.com", session));
118         assertTrue(verifier.verify("\u82b1\u5b50.foo.com", session));
119         assertTrue(verifier.verify("a.b.foo.com", session));
120 
121         in = new ByteArrayInputStream(X509_WILD_CO_JP);
122         x509 = (X509Certificate) cf.generateCertificate(in);
123         session = new mySSLSession(new X509Certificate[] {x509});
124         assertFalse(verifier.verify("foo.co.jp", session));
125         assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session));
126 
127         in = new ByteArrayInputStream(X509_WILD_FOO_BAR_HANAKO);
128         x509 = (X509Certificate) cf.generateCertificate(in);
129         session = new mySSLSession(new X509Certificate[] {x509});
130         // try the foo.com variations
131         assertFalse(verifier.verify("foo.com", session));
132         assertTrue(verifier.verify("www.foo.com", session));
133         assertTrue(verifier.verify("\u82b1\u5b50.foo.com", session));
134         assertTrue(verifier.verify("a.b.foo.com", session));
135         // these checks test alternative subjects. The test data contains an
136         // alternative subject starting with a japanese kanji character. This is
137         // not supported by Android because the underlying implementation from
138         // harmony follows the definition from rfc 1034 page 10 for alternative
139         // subject names. This causes the code to drop all alternative subjects.
140         // assertFalse(verifier.verify("bar.com", session));
141         // assertTrue(verifier.verify("www.bar.com", session));
142         // assertTrue(verifier.verify("\u82b1\u5b50.bar.com", session));
143         // assertTrue(verifier.verify("a.b.bar.com", session));
144     }
145 
testSubjectAlt()146     public void testSubjectAlt() throws Exception {
147         CertificateFactory cf = CertificateFactory.getInstance("X.509");
148         InputStream in = new ByteArrayInputStream(X509_MULTIPLE_SUBJECT_ALT);
149         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
150         mySSLSession session = new mySSLSession(new X509Certificate[] {x509});
151 
152         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
153         String expected = "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=CH";
154         assertEquals(new X500Principal(expected),
155                      x509.getSubjectX500Principal());
156 
157         assertTrue(verifier.verify("localhost", session));
158         assertTrue(verifier.verify("localhost.localdomain", session));
159         assertFalse(verifier.verify("local.host", session));
160     }
161 
testVerifyIpAddress()162     public void testVerifyIpAddress() throws Exception {
163         CertificateFactory cf = CertificateFactory.getInstance("X.509");
164         InputStream in = new ByteArrayInputStream(X509_MULTIPLE_SUBJECT_ALT);
165         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
166         mySSLSession session = new mySSLSession(new X509Certificate[] { x509 });
167         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
168 
169         assertTrue(verifier.verify("127.0.0.1", session));
170         assertFalse(verifier.verify("127.0.0.2", session));
171     }
172 
testWildcardsCannotMatchIpAddresses()173     public void testWildcardsCannotMatchIpAddresses() throws Exception {
174         // openssl req -x509 -nodes -days 36500 -subj '/CN=*.0.0.1' -newkey rsa:512 -out cert.pem
175         String cert = "-----BEGIN CERTIFICATE-----\n"
176                 + "MIIBkjCCATygAwIBAgIJAMdemqOwd/BEMA0GCSqGSIb3DQEBBQUAMBIxEDAOBgNV\n"
177                 + "BAMUByouMC4wLjEwIBcNMTAxMjIwMTY0NDI1WhgPMjExMDExMjYxNjQ0MjVaMBIx\n"
178                 + "EDAOBgNVBAMUByouMC4wLjEwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAqY8c9Qrt\n"
179                 + "YPWCvb7lclI+aDHM6fgbJcHsS9Zg8nUOh5dWrS7AgeA25wyaokFl4plBbbHQe2j+\n"
180                 + "cCjsRiJIcQo9HwIDAQABo3MwcTAdBgNVHQ4EFgQUJ436TZPJvwCBKklZZqIvt1Yt\n"
181                 + "JjEwQgYDVR0jBDswOYAUJ436TZPJvwCBKklZZqIvt1YtJjGhFqQUMBIxEDAOBgNV\n"
182                 + "BAMUByouMC4wLjGCCQDHXpqjsHfwRDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEB\n"
183                 + "BQUAA0EAk9i88xdjWoewqvE+iMC9tD2obMchgFDaHH0ogxxiRaIKeEly3g0uGxIt\n"
184                 + "fl2WRY8hb4x+zRrwsFaLEpdEvqcjOQ==\n"
185                 + "-----END CERTIFICATE-----";
186         CertificateFactory cf = CertificateFactory.getInstance("X.509");
187         InputStream in = new ByteArrayInputStream(cert.getBytes("UTF-8"));
188         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
189         mySSLSession session = new mySSLSession(new X509Certificate[] { x509 });
190         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
191 
192         assertFalse(verifier.verify("127.0.0.1", session));
193     }
194 
testWildcardsMustHaveTwoDots()195     public void testWildcardsMustHaveTwoDots() throws Exception {
196         // openssl req -x509 -nodes -days 36500 -subj '/CN=*.com' -newkey rsa:512 -out cert.pem
197         String cert = "-----BEGIN CERTIFICATE-----\n"
198                 + "MIIBjDCCATagAwIBAgIJAOVulXCSu6HuMA0GCSqGSIb3DQEBBQUAMBAxDjAMBgNV\n"
199                 + "BAMUBSouY29tMCAXDTEwMTIyMDE2NDkzOFoYDzIxMTAxMTI2MTY0OTM4WjAQMQ4w\n"
200                 + "DAYDVQQDFAUqLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDJd8xqni+h7Iaz\n"
201                 + "ypItivs9kPuiJUqVz+SuJ1C05SFc3PmlRCvwSIfhyD67fHcbMdl+A/LrIjhhKZJe\n"
202                 + "1joO0+pFAgMBAAGjcTBvMB0GA1UdDgQWBBS4Iuzf5w8JdCp+EtBfdFNudf6+YzBA\n"
203                 + "BgNVHSMEOTA3gBS4Iuzf5w8JdCp+EtBfdFNudf6+Y6EUpBIwEDEOMAwGA1UEAxQF\n"
204                 + "Ki5jb22CCQDlbpVwkruh7jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA0EA\n"
205                 + "U6LFxmZr31lFyis2/T68PpjAppc0DpNQuA2m/Y7oTHBDi55Fw6HVHCw3lucuWZ5d\n"
206                 + "qUYo4ES548JdpQtcLrW2sA==\n"
207                 + "-----END CERTIFICATE-----";
208         CertificateFactory cf = CertificateFactory.getInstance("X.509");
209         InputStream in = new ByteArrayInputStream(cert.getBytes("UTF-8"));
210         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
211         mySSLSession session = new mySSLSession(new X509Certificate[] { x509 });
212         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
213 
214         assertFalse(verifier.verify("google.com", session));
215     }
216 
testSubjectAltName()217     public void testSubjectAltName() throws Exception {
218         /*
219          * $ cat ./cert.cnf
220          * [req]
221          * distinguished_name=distinguished_name
222          * req_extensions=req_extensions
223          * x509_extensions=x509_extensions
224          * [distinguished_name]
225          * [req_extensions]
226          * [x509_extensions]
227          * subjectAltName=DNS:bar.com,DNS:baz.com
228          *
229          * $ openssl req -x509 -nodes -days 36500 -subj '/CN=foo.com' -config ./cert.cnf \
230          *     -newkey rsa:512 -out cert.pem
231          */
232         String cert = "-----BEGIN CERTIFICATE-----\n"
233                 + "MIIBPTCB6KADAgECAgkA7zoHaaqNGHQwDQYJKoZIhvcNAQEFBQAwEjEQMA4GA1UE\n"
234                 + "AxMHZm9vLmNvbTAgFw0xMDEyMjAxODM5MzZaGA8yMTEwMTEyNjE4MzkzNlowEjEQ\n"
235                 + "MA4GA1UEAxMHZm9vLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+gmoSxF+8\n"
236                 + "hbV+rgRQqHIJd50216OWQJbU3BvdlPbca779NYO4+UZWTFdBM8BdQqs3H4B5Agvp\n"
237                 + "y7HeSff1F7XRAgMBAAGjHzAdMBsGA1UdEQQUMBKCB2Jhci5jb22CB2Jhei5jb20w\n"
238                 + "DQYJKoZIhvcNAQEFBQADQQBXpZZPOY2Dy1lGG81JTr8L4or9jpKacD7n51eS8iqI\n"
239                 + "oTznPNuXHU5bFN0AAGX2ij47f/EahqTpo5RdS95P4sVm\n"
240                 + "-----END CERTIFICATE-----";
241         CertificateFactory cf = CertificateFactory.getInstance("X.509");
242         InputStream in = new ByteArrayInputStream(cert.getBytes("UTF-8"));
243         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
244         mySSLSession session = new mySSLSession(new X509Certificate[] { x509 });
245         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
246 
247         assertTrue(verifier.verify("foo.com", session));
248         assertTrue(verifier.verify("bar.com", session));
249         assertTrue(verifier.verify("baz.com", session));
250         assertFalse(verifier.verify("a.foo.com", session));
251         assertFalse(verifier.verify("quux.com", session));
252     }
253 
testSubjectAltNameWithWildcard()254     public void testSubjectAltNameWithWildcard() throws Exception {
255         /*
256          * $ cat ./cert.cnf
257          * [req]
258          * distinguished_name=distinguished_name
259          * req_extensions=req_extensions
260          * x509_extensions=x509_extensions
261          * [distinguished_name]
262          * [req_extensions]
263          * [x509_extensions]
264          * subjectAltName=DNS:bar.com,DNS:*.baz.com
265          *
266          * $ openssl req -x509 -nodes -days 36500 -subj '/CN=foo.com' -config ./cert.cnf \
267          *     -newkey rsa:512 -out cert.pem
268          */
269         String cert = "-----BEGIN CERTIFICATE-----\n"
270                 + "MIIBPzCB6qADAgECAgkAnv/7Jv5r7pMwDQYJKoZIhvcNAQEFBQAwEjEQMA4GA1UE\n"
271                 + "AxMHZm9vLmNvbTAgFw0xMDEyMjAxODQ2MDFaGA8yMTEwMTEyNjE4NDYwMVowEjEQ\n"
272                 + "MA4GA1UEAxMHZm9vLmNvbTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDAz2YXnyog\n"
273                 + "YdYLSFr/OEgSumtwqtZKJTB4wqTW/eKbBCEzxnyUMxWZIqUGu353PzwfOuWp2re3\n"
274                 + "nvVV+QDYQlh9AgMBAAGjITAfMB0GA1UdEQQWMBSCB2Jhci5jb22CCSouYmF6LmNv\n"
275                 + "bTANBgkqhkiG9w0BAQUFAANBAB8yrSl8zqy07i0SNYx2B/FnvQY734pxioaqFWfO\n"
276                 + "Bqo1ZZl/9aPHEWIwBrxYNVB0SGu/kkbt/vxqOjzzrkXukmI=\n"
277                 + "-----END CERTIFICATE-----";
278         CertificateFactory cf = CertificateFactory.getInstance("X.509");
279         InputStream in = new ByteArrayInputStream(cert.getBytes("UTF-8"));
280         X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
281         mySSLSession session = new mySSLSession(new X509Certificate[] { x509 });
282         HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier();
283 
284         assertTrue(verifier.verify("foo.com", session));
285         assertTrue(verifier.verify("bar.com", session));
286         assertTrue(verifier.verify("a.baz.com", session));
287         assertFalse(verifier.verify("baz.com", session));
288         assertFalse(verifier.verify("a.foo.com", session));
289         assertFalse(verifier.verify("a.bar.com", session));
290         assertFalse(verifier.verify("quux.com", session));
291     }
292 }
293