/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.ogt.http.conn.ssl;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLException;
import org.apache.ogt.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.ogt.http.conn.ssl.BrowserCompatHostnameVerifier;
import org.apache.ogt.http.conn.ssl.SSLSocketFactory;
import org.apache.ogt.http.conn.ssl.StrictHostnameVerifier;
import org.apache.ogt.http.conn.ssl.X509HostnameVerifier;
import org.junit.Assert;
import org.junit.Test;
/**
* Unit tests for {@link X509HostnameVerifier}.
*/
public class TestHostnameVerifier {
@Test
public void testVerify() throws Exception {
X509HostnameVerifier DEFAULT = new BrowserCompatHostnameVerifier();
X509HostnameVerifier STRICT = new StrictHostnameVerifier();
X509HostnameVerifier ALLOW_ALL = new AllowAllHostnameVerifier();
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream in;
X509Certificate x509;
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("foo.com", x509);
STRICT.verify("foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
exceptionPlease(DEFAULT, "bar.com", x509);
exceptionPlease(STRICT, "bar.com", x509);
ALLOW_ALL.verify("foo.com", x509);
ALLOW_ALL.verify("a.foo.com", x509);
ALLOW_ALL.verify("bar.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_HANAKO);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("\u82b1\u5b50.co.jp", x509);
STRICT.verify("\u82b1\u5b50.co.jp", x509);
exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509);
exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("foo.com", x509);
STRICT.verify("foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
DEFAULT.verify("bar.com", x509);
STRICT.verify("bar.com", x509);
exceptionPlease(DEFAULT, "a.bar.com", x509);
exceptionPlease(STRICT, "a.bar.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR_HANAKO);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("foo.com", x509);
STRICT.verify("foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
DEFAULT.verify("bar.com", x509);
STRICT.verify("bar.com", x509);
exceptionPlease(DEFAULT, "a.bar.com", x509);
exceptionPlease(STRICT, "a.bar.com", x509);
/*
Java isn't extracting international subjectAlts properly. (Or
OpenSSL isn't storing them properly).
*/
// DEFAULT.verify("\u82b1\u5b50.co.jp", x509 );
// STRICT.verify("\u82b1\u5b50.co.jp", x509 );
exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509);
exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("foo.com", x509);
STRICT.verify("foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
x509 = (X509Certificate) cf.generateCertificate(in);
DEFAULT.verify("foo.com", x509);
STRICT.verify("foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_THREE_CNS_FOO_BAR_HANAKO);
x509 = (X509Certificate) cf.generateCertificate(in);
exceptionPlease(DEFAULT, "foo.com", x509);
exceptionPlease(STRICT, "foo.com", x509);
exceptionPlease(DEFAULT, "a.foo.com", x509);
exceptionPlease(STRICT, "a.foo.com", x509);
exceptionPlease(DEFAULT, "bar.com", x509);
exceptionPlease(STRICT, "bar.com", x509);
exceptionPlease(DEFAULT, "a.bar.com", x509);
exceptionPlease(STRICT, "a.bar.com", x509);
DEFAULT.verify("\u82b1\u5b50.co.jp", x509);
STRICT.verify("\u82b1\u5b50.co.jp", x509);
exceptionPlease(DEFAULT, "a.\u82b1\u5b50.co.jp", x509);
exceptionPlease(STRICT, "a.\u82b1\u5b50.co.jp", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO);
x509 = (X509Certificate) cf.generateCertificate(in);
exceptionPlease(DEFAULT, "foo.com", x509);
exceptionPlease(STRICT, "foo.com", x509);
DEFAULT.verify("www.foo.com", x509);
STRICT.verify("www.foo.com", x509);
DEFAULT.verify("\u82b1\u5b50.foo.com", x509);
STRICT.verify("\u82b1\u5b50.foo.com", x509);
DEFAULT.verify("a.b.foo.com", x509);
exceptionPlease(STRICT, "a.b.foo.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_CO_JP);
x509 = (X509Certificate) cf.generateCertificate(in);
// Silly test because no-one would ever be able to lookup an IP address
// using "*.co.jp".
DEFAULT.verify("*.co.jp", x509);
STRICT.verify("*.co.jp", x509);
exceptionPlease(DEFAULT, "foo.co.jp", x509);
exceptionPlease(STRICT, "foo.co.jp", x509);
exceptionPlease(DEFAULT, "\u82b1\u5b50.co.jp", x509);
exceptionPlease(STRICT, "\u82b1\u5b50.co.jp", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO_BAR_HANAKO);
x509 = (X509Certificate) cf.generateCertificate(in);
// try the foo.com variations
exceptionPlease(DEFAULT, "foo.com", x509);
exceptionPlease(STRICT, "foo.com", x509);
DEFAULT.verify("www.foo.com", x509);
STRICT.verify("www.foo.com", x509);
DEFAULT.verify("\u82b1\u5b50.foo.com", x509);
STRICT.verify("\u82b1\u5b50.foo.com", x509);
DEFAULT.verify("a.b.foo.com", x509);
exceptionPlease(STRICT, "a.b.foo.com", x509);
// try the bar.com variations
exceptionPlease(DEFAULT, "bar.com", x509);
exceptionPlease(STRICT, "bar.com", x509);
DEFAULT.verify("www.bar.com", x509);
STRICT.verify("www.bar.com", x509);
DEFAULT.verify("\u82b1\u5b50.bar.com", x509);
STRICT.verify("\u82b1\u5b50.bar.com", x509);
DEFAULT.verify("a.b.bar.com", x509);
exceptionPlease(STRICT, "a.b.bar.com", x509);
// try the \u82b1\u5b50.co.jp variations
/*
Java isn't extracting international subjectAlts properly. (Or
OpenSSL isn't storing them properly).
*/
//exceptionPlease( DEFAULT, "\u82b1\u5b50.co.jp", x509 );
//exceptionPlease( STRICT, "\u82b1\u5b50.co.jp", x509 );
//DEFAULT.verify("www.\u82b1\u5b50.co.jp", x509 );
//STRICT.verify("www.\u82b1\u5b50.co.jp", x509 );
//DEFAULT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 );
//STRICT.verify("\u82b1\u5b50.\u82b1\u5b50.co.jp", x509 );
//DEFAULT.verify("a.b.\u82b1\u5b50.co.jp", x509 );
//exceptionPlease(STRICT,"a.b.\u82b1\u5b50.co.jp", x509 );
}
@Test
public void testSubjectAlt() throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_SUBJECT_ALT);
X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
X509HostnameVerifier verifier = SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER;
Assert.assertEquals("CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CH",
x509.getSubjectDN().getName());
verifier.verify("localhost", x509);
verifier.verify("localhost.localdomain", x509);
verifier.verify("127.0.0.1", x509);
try {
verifier.verify("local.host", x509);
Assert.fail("SSLException should have been thrown");
} catch (SSLException ex) {
// expected
}
try {
verifier.verify("127.0.0.2", x509);
Assert.fail("SSLException should have been thrown");
} catch (SSLException ex) {
// expected
}
}
public void exceptionPlease(X509HostnameVerifier hv, String host,
X509Certificate x509) {
try {
hv.verify(host, x509);
Assert.fail("HostnameVerifier shouldn't allow [" + host + "]");
}
catch(SSLException e) {
// whew! we're okay!
}
}
}