elecharny commented on PR #26:
URL: https://github.com/apache/mina/pull/26#issuecomment-1538929098
Actually, all the handshakes are passing, which make the *shouldFailXXX*
tests failing.
Here is the modified test class for MINA 2.2.X:
```
package org.apache.mina.filter.ssl;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.filterchain.IoFilterChain;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.FilterEvent;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.apache.mina.util.AvailablePortFinder;
import org.junit.Before;
import org.junit.Test;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.TrustManagerFactory;
import java.net.InetSocketAddress;
import java.security.KeyStore;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Test SNI matching scenarios. (tests for DIRMINA-1122)
*
* <pre>
* emptykeystore.sslTest - empty keystore
* server-cn.keystore - keystore with single certificate chain
(CN=mina)
* client-cn.truststore - keystore with trusted certificate
* server-san-ext.keystore - keystore with single certificate chain
(CN=mina;SAN=*.bbb.ccc,xxx.yyy)
* client-san-ext.truststore - keystore with trusted certificate
* </pre>
*/
public class SslIdentificationAlgorithmTest {
private static final String KEY_MANAGER_FACTORY_ALGORITHM;
static {
String algorithm =
Security.getProperty("ssl.KeyManagerFactory.algorithm");
if (algorithm == null) {
algorithm = KeyManagerFactory.getDefaultAlgorithm();
}
KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
}
private int port;
private CountDownLatch handshakeDone;
@Before
public void setUp() {
port = AvailablePortFinder.getNextAvailable(5555);
handshakeDone = new CountDownLatch(2);
}
@Test
public void
shouldAuthenticateWhenServerCertificateCommonNameMatchesClientSNI() throws
Exception {
SSLContext acceptorContext = createSSLContext("server-cn.keystore",
"emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-cn.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "mina");
assertTrue(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldFailAuthenticationWhenServerCertificateCommonNameDoesNotMatchClientSNI()
throws Exception {
SSLContext acceptorContext = createSSLContext("server-cn.keystore",
"emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-cn.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "example.com");
assertFalse(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldFailAuthenticationWhenClientMissingSNIAndIdentificationAlgorithmProvided()
throws Exception {
SSLContext acceptorContext = createSSLContext("server-cn.keystore",
"emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-cn.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, null);
assertFalse(handshakeDone.await(10, TimeUnit.SECONDS));
}
/**
* Subject Alternative Name (SAN) scenarios
*/
@Test
public void
shouldAuthenticateWhenServerCertificateAlternativeNameMatchesClientSNIExactly()
throws Exception {
SSLContext acceptorContext =
createSSLContext("server-san-ext.keystore", "emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-san-ext.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "xxx.yyy");
assertTrue(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldAuthenticateWhenServerCertificateAlternativeNameMatchesClientSNIViaWildcard()
throws Exception {
SSLContext acceptorContext =
createSSLContext("server-san-ext.keystore", "emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-san-ext.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "aaa.bbb.ccc");
assertTrue(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldFailAuthenticationWhenServerCommonNameMatchesSNIAndSNINotInAlternativeName()
throws Exception {
SSLContext acceptorContext =
createSSLContext("server-san-ext.keystore", "emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-san-ext.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "mina");
assertFalse(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldFailAuthenticationWhenMatchingAlternativeNameWildcardExactly() throws
Exception {
SSLContext acceptorContext =
createSSLContext("server-san-ext.keystore", "emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-san-ext.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "*.bbb.ccc");
assertFalse(handshakeDone.await(10, TimeUnit.SECONDS));
}
@Test
public void
shouldFailAuthenticationWhenMatchingAlternativeNameWithTooManyLabels() throws
Exception {
SSLContext acceptorContext =
createSSLContext("server-san-ext.keystore", "emptykeystore.sslTest");
SSLContext connectorContext =
createSSLContext("emptykeystore.sslTest", "client-san-ext.truststore");
startAcceptor(acceptorContext);
startConnector(connectorContext, "mmm.nnn.bbb.ccc");
assertFalse(handshakeDone.await(10, TimeUnit.SECONDS));
}
private void startAcceptor(SSLContext sslContext) throws Exception {
NioSocketAcceptor acceptor = new NioSocketAcceptor();
acceptor.setReuseAddress(true);
SslFilter sslFilter = new SslFilter(sslContext);
sslFilter.setEnabledProtocols(new String[] {"TLSv1.2"});
DefaultIoFilterChainBuilder filters = acceptor.getFilterChain();
filters.addLast("ssl", sslFilter);
filters.addLast("text", new ProtocolCodecFilter(new
TextLineCodecFactory()));
acceptor.setHandler(new IoHandlerAdapter() {
@Override
public void sessionOpened(IoSession session) {
session.write("acceptor write");
}
@Override
public void event(IoSession session, FilterEvent event) {
if (event == SslEvent.SECURED) {
handshakeDone.countDown();
}
}
});
acceptor.bind(new InetSocketAddress(port));
}
private void startConnector(SSLContext sslContext, final String sni) {
NioSocketConnector connector = new NioSocketConnector();
SslFilter sslFilter = new SslFilter(sslContext) {
@Override
public void onPreAdd(IoFilterChain parent, String name,
NextFilter nextFilter) throws SSLException {
if (sni != null) {
IoSession session = parent.getSession();
session.setAttribute(SslFilter.PEER_ADDRESS, new
InetSocketAddress(sni, port));
}
super.onPreAdd(parent, name, nextFilter);
}
};
sslFilter.setUseClientMode(true);
sslFilter.setEndpointIdentificationAlgorithm("HTTPS");
sslFilter.setEnabledProtocols(new String[] {"TLSv1.2"});
DefaultIoFilterChainBuilder filters = connector.getFilterChain();
filters.addLast("ssl", sslFilter);
filters.addLast("text", new ProtocolCodecFilter(new
TextLineCodecFactory()));
connector.setHandler(new IoHandlerAdapter() {
@Override
public void sessionOpened(IoSession session) {
session.write("connector write");
}
@Override
public void event(IoSession session, FilterEvent event) {
if (event == SslEvent.SECURED) {
handshakeDone.countDown();
}
}
});
connector.connect(new InetSocketAddress("localhost", port));
}
private SSLContext createSSLContext(String keyStorePath, String
trustStorePath) throws Exception {
char[] password = "password".toCharArray();
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(SslTest.class.getResourceAsStream(keyStorePath),
password);
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
kmf.init(keyStore, password);
KeyStore trustStore = KeyStore.getInstance("JKS");
trustStore.load(SslTest.class.getResourceAsStream(trustStorePath),
password);
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
tmf.init(trustStore);
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return ctx;
}
}
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]