/*
* Copyright 2016 The Netty Project
*
* The Netty Project 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 io.netty.handler.ssl;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertNotNull;
import java.io.InputStream;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import org.junit.Test;
public class SslContextTrustManagerTest {
@Test
public void testUsingAllCAs() throws Exception {
runTests(new String[] { "tm_test_ca_1a.pem", "tm_test_ca_1b.pem",
"tm_test_ca_2.pem" }, new String[] { "tm_test_eec_1.pem",
"tm_test_eec_2.pem", "tm_test_eec_3.pem" }, new boolean[] {
true, true, true });
}
@Test
public void testUsingAllCAsWithDuplicates() throws Exception {
runTests(new String[] { "tm_test_ca_1a.pem", "tm_test_ca_1b.pem",
"tm_test_ca_2.pem", "tm_test_ca_2.pem" },
new String[] { "tm_test_eec_1.pem", "tm_test_eec_2.pem",
"tm_test_eec_3.pem" },
new boolean[] { true, true, true });
}
@Test
public void testUsingCAsOneAandB() throws Exception {
runTests(new String[] { "tm_test_ca_1a.pem", "tm_test_ca_1b.pem", },
new String[] { "tm_test_eec_1.pem", "tm_test_eec_2.pem",
"tm_test_eec_3.pem" }, new boolean[] { true, true,
false });
}
@Test
public void testUsingCAsOneAandTwo() throws Exception {
runTests(new String[] { "tm_test_ca_1a.pem", "tm_test_ca_2.pem" },
new String[] { "tm_test_eec_1.pem", "tm_test_eec_2.pem",
"tm_test_eec_3.pem" }, new boolean[] { true, false,
true });
}
/**
*
* @param caResources
* an array of paths to CA Certificates in PEM format to load
* from the classpath (relative to this class).
* @param eecResources
* an array of paths to Server Certificates in PEM format in to
* load from the classpath (relative to this class).
* @param expectations
* an array of expecting results for each EEC Server Certificate
* (the array is expected to have the same length the previous
* argument, and be arrange in matching order: true means
* expected to be valid, false otherwise.
*/
private static void runTests(String[] caResources, String[] eecResources,
boolean[] expectations) throws Exception {
X509TrustManager tm = getTrustManager(caResources);
X509Certificate[] eecCerts = loadCertCollection(eecResources);
for (int i = 0; i < eecResources.length; i++) {
X509Certificate eecCert = eecCerts[i];
assertNotNull("Cannot use cert " + eecResources[i], eecCert);
try {
tm.checkServerTrusted(new X509Certificate[] { eecCert }, "RSA");
if (!expectations[i]) {
fail(String.format(
"Certificate %s was expected not to be valid when using CAs %s, but its "
+ "verification passed.", eecResources[i],
Arrays.asList(caResources)));
}
} catch (CertificateException e) {
if (expectations[i]) {
fail(String.format(
"Certificate %s was expected to be valid when using CAs %s, but its "
+ "verification failed.", eecResources[i],
Arrays.asList(caResources)));
}
}
}
}
private static X509TrustManager getTrustManager(String[] resourceNames)
throws Exception {
X509Certificate[] certCollection = loadCertCollection(resourceNames);
TrustManagerFactory tmf = SslContext.buildTrustManagerFactory(
certCollection, null);
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
return (X509TrustManager) tm;
}
}
throw new Exception(
"Unable to find any X509TrustManager from this factory.");
}
private static X509Certificate[] loadCertCollection(String[] resourceNames)
throws Exception {
CertificateFactory certFactory = CertificateFactory
.getInstance("X.509");
X509Certificate[] certCollection = new X509Certificate[resourceNames.length];
for (int i = 0; i < resourceNames.length; i++) {
String resourceName = resourceNames[i];
InputStream is = null;
try {
is = SslContextTest.class.getResourceAsStream(resourceName);
assertNotNull("Cannot find " + resourceName, is);
certCollection[i] = (X509Certificate) certFactory
.generateCertificate(is);
} finally {
if (is != null) {
is.close();
}
}
}
return certCollection;
}
}