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 */ 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. 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 // Silly test because no-one would ever be able to lookup an IP address 125 // using "*.co.jp". 126 assertTrue(verifier.verify("*.co.jp", session)); 127 assertFalse(verifier.verify("foo.co.jp", session)); 128 assertFalse(verifier.verify("\u82b1\u5b50.co.jp", session)); 129 130 in = new ByteArrayInputStream(X509_WILD_FOO_BAR_HANAKO); 131 x509 = (X509Certificate) cf.generateCertificate(in); 132 session = new mySSLSession(new X509Certificate[] {x509}); 133 // try the foo.com variations 134 assertFalse(verifier.verify("foo.com", session)); 135 assertTrue(verifier.verify("www.foo.com", session)); 136 assertTrue(verifier.verify("\u82b1\u5b50.foo.com", session)); 137 assertTrue(verifier.verify("a.b.foo.com", session)); 138 // these checks test alternative subjects. The test data contains an 139 // alternative subject starting with a japanese kanji character. This is 140 // not supported by Android because the underlying implementation from 141 // harmony follows the definition from rfc 1034 page 10 for alternative 142 // subject names. This causes the code to drop all alternative subjects. 143 // assertFalse(verifier.verify("bar.com", session)); 144 // assertTrue(verifier.verify("www.bar.com", session)); 145 // assertTrue(verifier.verify("\u82b1\u5b50.bar.com", session)); 146 // assertTrue(verifier.verify("a.b.bar.com", session)); 147 } 148 149 public void testSubjectAlt() throws Exception { 150 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 151 InputStream in = new ByteArrayInputStream(X509_MULTIPLE_SUBJECT_ALT); 152 X509Certificate x509 = (X509Certificate) cf.generateCertificate(in); 153 mySSLSession session = new mySSLSession(new X509Certificate[] {x509}); 154 155 HostnameVerifier verifier = HttpsURLConnection.getDefaultHostnameVerifier(); 156 String expected = "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,ST=Unknown,C=CH"; 157 assertEquals(new X500Principal(expected), 158 x509.getSubjectX500Principal()); 159 160 assertTrue(verifier.verify("localhost", session)); 161 assertTrue(verifier.verify("localhost.localdomain", session)); 162 // TODO support IP addresses 163 assertTrue(verifier.verify("127.0.0.1", session)); 164 165 assertFalse(verifier.verify("local.host", session)); 166 assertFalse(verifier.verify("127.0.0.2", session)); 167 168 } 169 } 170