ZKHostnameVerifierTest.java
/**
* 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.
*/
package org.apache.zookeeper.common;
import static org.junit.jupiter.api.Assertions.fail;
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.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* Note: These test cases (and resources) have been taken from the Apache HttpComponents project.
*/
public class ZKHostnameVerifierTest {
private ZKHostnameVerifier impl;
@BeforeEach
public void setup() {
impl = new ZKHostnameVerifier();
}
@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);
impl.verify("foo.co.jp", x509);
impl.verify("\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);
in = new ByteArrayInputStream(CertificatesToPlayWith.S_GOOGLE_COM);
x509 = (X509Certificate) cf.generateCertificate(in);
impl.verify("*.google.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.S_GOOGLE_COM);
x509 = (X509Certificate) cf.generateCertificate(in);
impl.verify("*.Google.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.IP_1_1_1_1);
x509 = (X509Certificate) cf.generateCertificate(in);
impl.verify("1.1.1.1", x509);
exceptionPlease(impl, "1.1.1.2", x509);
exceptionPlease(impl, "dummy-value.com", x509);
in = new ByteArrayInputStream(CertificatesToPlayWith.EMAIL_ALT_SUBJECT_NAME);
x509 = (X509Certificate) cf.generateCertificate(in);
impl.verify("www.company.com", x509);
}
private void exceptionPlease(final ZKHostnameVerifier hv, final String host,
final X509Certificate x509) {
try {
hv.verify(host, x509);
fail("HostnameVerifier shouldn't allow [" + host + "]");
} catch (final SSLException e) {
// whew! we're okay!
}
}
}