Ported existing test cases to new default HostnameVerifier impl
git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@1618868 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
d2400e0758
commit
95c0f4857e
|
@ -146,8 +146,8 @@ public final class DefaultHostnameVerifier implements HostnameVerifier {
|
|||
final String normalisedHost = normaliseAddress(host);
|
||||
for (int i = 0; i < subjectAlts.size(); i++) {
|
||||
final String subjectAlt = subjectAlts.get(i);
|
||||
final String normalizedsSubjectAlt = normaliseAddress(subjectAlt);
|
||||
if (normalisedHost.equals(normalizedsSubjectAlt)) {
|
||||
final String normalizedSubjectAlt = normaliseAddress(subjectAlt);
|
||||
if (normalisedHost.equals(normalizedSubjectAlt)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ public final class DefaultHostnameVerifier implements HostnameVerifier {
|
|||
static void matchDNSName(final String host, final List<String> subjectAlts) throws SSLException {
|
||||
for (int i = 0; i < subjectAlts.size(); i++) {
|
||||
final String subjectAlt = subjectAlts.get(i);
|
||||
if (matchIdentity(host, subjectAlt)) {
|
||||
if (matchIdentityStrict(host, subjectAlt)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ public final class DefaultHostnameVerifier implements HostnameVerifier {
|
|||
}
|
||||
|
||||
static void matchCN(final String host, final String cn) throws SSLException {
|
||||
if (!matchIdentity(host, cn)) {
|
||||
if (!matchIdentityStrict(host, cn)) {
|
||||
throw new SSLException("Certificate for <" + host + "> doesn't match " +
|
||||
"common name of the certificate subject: " + cn);
|
||||
}
|
||||
|
@ -246,12 +246,12 @@ public final class DefaultHostnameVerifier implements HostnameVerifier {
|
|||
}
|
||||
|
||||
static List<String> extractSubjectAlts(final X509Certificate cert, final int subjectType) {
|
||||
List<String> subjectAltList = null;
|
||||
Collection<List<?>> c = null;
|
||||
try {
|
||||
c = cert.getSubjectAlternativeNames();
|
||||
} catch(final CertificateParsingException ignore) {
|
||||
}
|
||||
List<String> subjectAltList = null;
|
||||
if (c != null) {
|
||||
for (final List<?> aC : c) {
|
||||
final List<?> list = aC;
|
||||
|
|
|
@ -27,9 +27,16 @@
|
|||
|
||||
package org.apache.http.conn.ssl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -37,6 +44,210 @@ import org.junit.Test;
|
|||
*/
|
||||
public class TestDefaultHostnameVerifier {
|
||||
|
||||
private DefaultHostnameVerifier impl;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
impl = DefaultHostnameVerifier.INSTANCE;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerify() throws Exception {
|
||||
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
InputStream in;
|
||||
X509Certificate x509;
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
|
||||
impl.verify("foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
exceptionPlease(impl, "bar.com", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_HANAKO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
impl.verify("\u82b1\u5b50.co.jp", x509);
|
||||
exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
exceptionPlease(impl, "foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
impl.verify("bar.com", x509);
|
||||
exceptionPlease(impl, "a.bar.com", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_FOO_BAR_HANAKO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
exceptionPlease(impl, "foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
impl.verify("bar.com", x509);
|
||||
exceptionPlease(impl, "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 );
|
||||
// impl.verify("\u82b1\u5b50.co.jp", x509 );
|
||||
exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
impl.verify("foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_NO_CNS_FOO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
impl.verify("foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_THREE_CNS_FOO_BAR_HANAKO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
exceptionPlease(impl, "foo.com", x509);
|
||||
exceptionPlease(impl, "a.foo.com", x509);
|
||||
exceptionPlease(impl, "bar.com", x509);
|
||||
exceptionPlease(impl, "a.bar.com", x509);
|
||||
impl.verify("\u82b1\u5b50.co.jp", x509);
|
||||
exceptionPlease(impl, "a.\u82b1\u5b50.co.jp", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_WILD_FOO);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
exceptionPlease(impl, "foo.com", x509);
|
||||
impl.verify("www.foo.com", x509);
|
||||
impl.verify("\u82b1\u5b50.foo.com", x509);
|
||||
exceptionPlease(impl, "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".
|
||||
impl.verify("*.co.jp", x509);
|
||||
exceptionPlease(impl, "foo.co.jp", x509);
|
||||
exceptionPlease(impl, "\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(impl, "foo.com", x509);
|
||||
exceptionPlease(impl, "www.foo.com", x509);
|
||||
exceptionPlease(impl, "\u82b1\u5b50.foo.com", x509);
|
||||
exceptionPlease(impl, "a.b.foo.com", x509);
|
||||
// try the bar.com variations
|
||||
exceptionPlease(impl, "bar.com", x509);
|
||||
impl.verify("www.bar.com", x509);
|
||||
impl.verify("\u82b1\u5b50.bar.com", x509);
|
||||
exceptionPlease(impl, "a.b.bar.com", x509);
|
||||
|
||||
in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_VALUE_AVA);
|
||||
x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
impl.verify("repository.infonotary.com", x509);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSubjectAlt() throws Exception {
|
||||
final CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
final InputStream in = new ByteArrayInputStream(CertificatesToPlayWith.X509_MULTIPLE_SUBJECT_ALT);
|
||||
final X509Certificate x509 = (X509Certificate) cf.generateCertificate(in);
|
||||
|
||||
Assert.assertEquals("CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=CH",
|
||||
x509.getSubjectDN().getName());
|
||||
|
||||
impl.verify("localhost.localdomain", x509);
|
||||
impl.verify("127.0.0.1", x509);
|
||||
|
||||
try {
|
||||
impl.verify("localhost", x509);
|
||||
Assert.fail("SSLException should have been thrown");
|
||||
} catch (final SSLException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
impl.verify("local.host", x509);
|
||||
Assert.fail("SSLException should have been thrown");
|
||||
} catch (final SSLException ex) {
|
||||
// expected
|
||||
}
|
||||
try {
|
||||
impl.verify("127.0.0.2", x509);
|
||||
Assert.fail("SSLException should have been thrown");
|
||||
} catch (final SSLException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
public void exceptionPlease(final DefaultHostnameVerifier hv, final String host,
|
||||
final X509Certificate x509) {
|
||||
try {
|
||||
hv.verify(host, x509);
|
||||
Assert.fail("HostnameVerifier shouldn't allow [" + host + "]");
|
||||
}
|
||||
catch(final SSLException e) {
|
||||
// whew! we're okay!
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIdentityMatching() {
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.c", "*.b.c"));
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "*.b.c"));
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.b.c", "*.b.c"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.b.c", "*.b.c")); // subdomain not OK
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.uk", "*.gov.uk"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.gov.uk", "*.gov.uk")); // Bad 2TLD
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.gov.uk", "*.gov.uk"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.uk", "*.gov.uk")); // BBad 2TLD/no subdomain allowed
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.com", "*.gov.com"));
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.gov.com", "*.gov.com"));
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("s.a.gov.com", "*.gov.com"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.com", "*.gov.com")); // no subdomain allowed
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.gov.uk", "a*.gov.uk"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.gov.uk", "a*.gov.uk")); // Bad 2TLD
|
||||
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentity("s.a.gov.uk", "a*.gov.uk")); // Bad 2TLD
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("s.a.gov.uk", "a*.gov.uk")); // Bad 2TLD/no subdomain allowed
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHTTPCLIENT_1097() {
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.b.c", "a*.b.c"));
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("a.b.c", "a*.b.c"));
|
||||
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("a.a.b.c", "a*.b.c"));
|
||||
Assert.assertFalse(DefaultHostnameVerifier.matchIdentityStrict("a.a.b.c", "a*.b.c"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHTTPCLIENT_1255() {
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentity("mail.a.b.c.com", "m*.a.b.c.com"));
|
||||
Assert.assertTrue(DefaultHostnameVerifier.matchIdentityStrict("mail.a.b.c.com", "m*.a.b.c.com"));
|
||||
}
|
||||
|
||||
@Test // Check compressed IPv6 hostname matching
|
||||
public void testHTTPCLIENT_1316() throws Exception{
|
||||
final String host1 = "2001:0db8:aaaa:bbbb:cccc:0:0:0001";
|
||||
DefaultHostnameVerifier.matchIPv6Address(host1, Arrays.asList("2001:0db8:aaaa:bbbb:cccc:0:0:0001"));
|
||||
DefaultHostnameVerifier.matchIPv6Address(host1, Arrays.asList("2001:0db8:aaaa:bbbb:cccc::1"));
|
||||
try {
|
||||
DefaultHostnameVerifier.matchIPv6Address(host1, Arrays.asList("2001:0db8:aaaa:bbbb:cccc::10"));
|
||||
Assert.fail("SSLException expected");
|
||||
} catch (SSLException expected) {
|
||||
}
|
||||
final String host2 = "2001:0db8:aaaa:bbbb:cccc::1";
|
||||
DefaultHostnameVerifier.matchIPv6Address(host2, Arrays.asList("2001:0db8:aaaa:bbbb:cccc:0:0:0001"));
|
||||
DefaultHostnameVerifier.matchIPv6Address(host2, Arrays.asList("2001:0db8:aaaa:bbbb:cccc::1"));
|
||||
try {
|
||||
DefaultHostnameVerifier.matchIPv6Address(host2, Arrays.asList("2001:0db8:aaaa:bbbb:cccc::10"));
|
||||
Assert.fail("SSLException expected");
|
||||
} catch (SSLException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractCN() throws Exception {
|
||||
Assert.assertEquals("blah", DefaultHostnameVerifier.extractCN("cn=blah, ou=blah, o=blah"));
|
||||
|
@ -47,16 +258,16 @@ public class TestDefaultHostnameVerifier {
|
|||
Assert.assertEquals("blah, blah", DefaultHostnameVerifier.extractCN("cn=\"blah, blah\", ou=blah, o=blah"));
|
||||
Assert.assertEquals("blah, blah", DefaultHostnameVerifier.extractCN("cn=blah\\, blah, ou=blah, o=blah"));
|
||||
Assert.assertEquals("blah", DefaultHostnameVerifier.extractCN("c = cn=uuh, cn=blah, ou=blah, o=blah"));
|
||||
}
|
||||
|
||||
@Test(expected = SSLException.class)
|
||||
public void testExtractCNMissing() throws Exception {
|
||||
DefaultHostnameVerifier.extractCN("blah,blah");
|
||||
}
|
||||
|
||||
@Test(expected = SSLException.class)
|
||||
public void testExtractCNNull() throws Exception {
|
||||
DefaultHostnameVerifier.extractCN("cn,o=blah");
|
||||
try {
|
||||
DefaultHostnameVerifier.extractCN("blah,blah");
|
||||
Assert.fail("SSLException expected");
|
||||
} catch (SSLException expected) {
|
||||
}
|
||||
try {
|
||||
DefaultHostnameVerifier.extractCN("cn,o=blah");
|
||||
Assert.fail("SSLException expected");
|
||||
} catch (SSLException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue