Home | History | Annotate | Download | only in ssl
      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