Skip to content

Commit 7da0fd3

Browse files
committed
Test blocking IO and NIO in hostname verification test
Not costly to test both IO modes and makes iterating easier. References #394
1 parent fcc3dbb commit 7da0fd3

File tree

3 files changed

+91
-78
lines changed

3 files changed

+91
-78
lines changed

src/test/java/com/rabbitmq/client/test/BrokerTestCase.java

+1-13
Original file line numberDiff line numberDiff line change
@@ -352,18 +352,6 @@ protected String generateExchangeName() {
352352
}
353353

354354
protected SSLContext getSSLContext() throws NoSuchAlgorithmException {
355-
SSLContext c = null;
356-
357-
// pick the first protocol available, preferring TLSv1.2, then TLSv1,
358-
// falling back to SSLv3 if running on an ancient/crippled JDK
359-
for(String proto : Arrays.asList("TLSv1.2", "TLSv1", "SSLv3")) {
360-
try {
361-
c = SSLContext.getInstance(proto);
362-
return c;
363-
} catch (NoSuchAlgorithmException x) {
364-
// keep trying
365-
}
366-
}
367-
throw new NoSuchAlgorithmException();
355+
return TestUtils.getSSLContext();
368356
}
369357
}

src/test/java/com/rabbitmq/client/test/TestUtils.java

+19
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,10 @@
3030
import com.rabbitmq.tools.Host;
3131
import org.slf4j.LoggerFactory;
3232

33+
import javax.net.ssl.SSLContext;
3334
import java.io.IOException;
35+
import java.security.NoSuchAlgorithmException;
36+
import java.util.Arrays;
3437
import java.util.Collection;
3538
import java.util.Collections;
3639
import java.util.concurrent.Callable;
@@ -64,6 +67,22 @@ public static void close(Connection connection) {
6467
}
6568
}
6669

70+
public static SSLContext getSSLContext() throws NoSuchAlgorithmException {
71+
SSLContext c = null;
72+
73+
// pick the first protocol available, preferring TLSv1.2, then TLSv1,
74+
// falling back to SSLv3 if running on an ancient/crippled JDK
75+
for(String proto : Arrays.asList("TLSv1.2", "TLSv1", "SSLv3")) {
76+
try {
77+
c = SSLContext.getInstance(proto);
78+
return c;
79+
} catch (NoSuchAlgorithmException x) {
80+
// keep trying
81+
}
82+
}
83+
throw new NoSuchAlgorithmException();
84+
}
85+
6786
public static boolean isVersion37orLater(Connection connection) {
6887
String currentVersion = null;
6988
try {

src/test/java/com/rabbitmq/client/test/ssl/HostnameVerification.java

+71-65
Original file line numberDiff line numberDiff line change
@@ -18,87 +18,93 @@
1818
import com.rabbitmq.client.Address;
1919
import com.rabbitmq.client.ConnectionFactory;
2020
import com.rabbitmq.client.test.TestUtils;
21+
import org.junit.BeforeClass;
2122
import org.junit.Test;
23+
import org.junit.runner.RunWith;
24+
import org.junit.runners.Parameterized;
2225

2326
import javax.net.ssl.KeyManagerFactory;
2427
import javax.net.ssl.SSLContext;
2528
import javax.net.ssl.SSLHandshakeException;
2629
import javax.net.ssl.TrustManagerFactory;
2730
import java.io.FileInputStream;
28-
import java.io.IOException;
29-
import java.security.KeyManagementException;
3031
import java.security.KeyStore;
31-
import java.security.KeyStoreException;
32-
import java.security.NoSuchAlgorithmException;
33-
import java.security.UnrecoverableKeyException;
34-
import java.security.cert.CertificateException;
35-
import java.util.concurrent.TimeoutException;
32+
import java.util.function.Consumer;
3633

34+
import static com.rabbitmq.client.test.TestUtils.getSSLContext;
3735
import static java.util.Collections.singletonList;
3836
import static org.junit.Assert.assertNotNull;
3937
import static org.junit.Assert.fail;
4038

41-
public class HostnameVerification extends UnverifiedConnection {
42-
43-
public void openConnection()
44-
throws IOException, TimeoutException {
45-
try {
46-
String keystorePath = System.getProperty("test-keystore.ca");
47-
assertNotNull(keystorePath);
48-
String keystorePasswd = System.getProperty("test-keystore.password");
49-
assertNotNull(keystorePasswd);
50-
char[] keystorePassword = keystorePasswd.toCharArray();
51-
52-
KeyStore tks = KeyStore.getInstance("JKS");
53-
tks.load(new FileInputStream(keystorePath), keystorePassword);
54-
55-
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
56-
tmf.init(tks);
57-
58-
String p12Path = System.getProperty("test-client-cert.path");
59-
assertNotNull(p12Path);
60-
String p12Passwd = System.getProperty("test-client-cert.password");
61-
assertNotNull(p12Passwd);
62-
KeyStore ks = KeyStore.getInstance("PKCS12");
63-
char[] p12Password = p12Passwd.toCharArray();
64-
ks.load(new FileInputStream(p12Path), p12Password);
65-
66-
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
67-
kmf.init(ks, p12Password);
68-
69-
SSLContext c = getSSLContext();
70-
c.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
71-
c.init(null, tmf.getTrustManagers(), null);
72-
73-
connectionFactory = TestUtils.connectionFactory();
74-
connectionFactory.useSslProtocol(c);
75-
connectionFactory.enableHostnameVerification();
76-
} catch (NoSuchAlgorithmException ex) {
77-
throw new IOException(ex.toString());
78-
} catch (KeyManagementException ex) {
79-
throw new IOException(ex.toString());
80-
} catch (KeyStoreException ex) {
81-
throw new IOException(ex.toString());
82-
} catch (CertificateException ex) {
83-
throw new IOException(ex.toString());
84-
} catch (UnrecoverableKeyException ex) {
85-
throw new IOException(ex.toString());
86-
}
87-
88-
try {
89-
connection = connectionFactory.newConnection(
90-
() -> singletonList(new Address("127.0.0.1", ConnectionFactory.DEFAULT_AMQP_OVER_SSL_PORT)));
91-
fail("The server certificate isn't issued for 127.0.0.1, the TLS handshake should have failed");
92-
} catch (SSLHandshakeException ignored) {
93-
} catch (IOException e) {
94-
fail();
95-
}
39+
@RunWith(Parameterized.class)
40+
public class HostnameVerification {
41+
42+
static SSLContext sslContext;
43+
@Parameterized.Parameter
44+
public Consumer<ConnectionFactory> customizer;
45+
46+
@Parameterized.Parameters
47+
public static Object[] data() {
48+
return new Object[] {
49+
blockingIo(enableHostnameVerification()),
50+
nio(enableHostnameVerification()),
51+
};
52+
}
53+
54+
private static Consumer<ConnectionFactory> blockingIo(final Consumer<ConnectionFactory> customizer) {
55+
return connectionFactory -> {
56+
connectionFactory.useBlockingIo();
57+
customizer.accept(connectionFactory);
58+
};
9659
}
9760

98-
public void openChannel() {
61+
private static Consumer<ConnectionFactory> nio(final Consumer<ConnectionFactory> customizer) {
62+
return connectionFactory -> {
63+
connectionFactory.useNio();
64+
customizer.accept(connectionFactory);
65+
};
66+
}
67+
68+
private static Consumer<ConnectionFactory> enableHostnameVerification() {
69+
return connectionFactory -> connectionFactory.enableHostnameVerification();
70+
}
71+
72+
@BeforeClass
73+
public static void initCrypto() throws Exception {
74+
String keystorePath = System.getProperty("test-keystore.ca");
75+
assertNotNull(keystorePath);
76+
String keystorePasswd = System.getProperty("test-keystore.password");
77+
assertNotNull(keystorePasswd);
78+
char[] keystorePassword = keystorePasswd.toCharArray();
79+
80+
KeyStore tks = KeyStore.getInstance("JKS");
81+
tks.load(new FileInputStream(keystorePath), keystorePassword);
82+
83+
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
84+
tmf.init(tks);
85+
86+
String p12Path = System.getProperty("test-client-cert.path");
87+
assertNotNull(p12Path);
88+
String p12Passwd = System.getProperty("test-client-cert.password");
89+
assertNotNull(p12Passwd);
90+
KeyStore ks = KeyStore.getInstance("PKCS12");
91+
char[] p12Password = p12Passwd.toCharArray();
92+
ks.load(new FileInputStream(p12Path), p12Password);
93+
94+
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
95+
kmf.init(ks, p12Password);
96+
97+
sslContext = getSSLContext();
98+
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
9999
}
100100

101-
@Test
102-
public void sSL() {
101+
@Test(expected = SSLHandshakeException.class)
102+
public void hostnameVerificationFailsBecauseCertificateNotIssuedForLoopbackInterface() throws Exception {
103+
ConnectionFactory connectionFactory = TestUtils.connectionFactory();
104+
connectionFactory.useSslProtocol(sslContext);
105+
customizer.accept(connectionFactory);
106+
connectionFactory.newConnection(
107+
() -> singletonList(new Address("127.0.0.1", ConnectionFactory.DEFAULT_AMQP_OVER_SSL_PORT)));
108+
fail("The server certificate isn't issued for 127.0.0.1, the TLS handshake should have failed");
103109
}
104110
}

0 commit comments

Comments
 (0)