[ 
https://issues.apache.org/jira/browse/DIRMINA-1122?focusedWorklogId=861070&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-861070
 ]

ASF GitHub Bot logged work on DIRMINA-1122:
-------------------------------------------

                Author: ASF GitHub Bot
            Created on: 08/May/23 19:31
            Start Date: 08/May/23 19:31
    Worklog Time Spent: 10m 
      Work Description: 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;
       }
   }
   ```




Issue Time Tracking
-------------------

    Worklog Id:     (was: 861070)
    Time Spent: 1h 20m  (was: 1h 10m)

> Add support for endpoint identification algorithm
> -------------------------------------------------
>
>                 Key: DIRMINA-1122
>                 URL: https://issues.apache.org/jira/browse/DIRMINA-1122
>             Project: MINA
>          Issue Type: Improvement
>          Components: Filter, SSL
>    Affects Versions: 2.0.22, 2.1.3
>            Reporter: Marcin L
>            Assignee: Jonathan Valliere
>            Priority: Minor
>             Fix For: 2.2.0
>
>         Attachments: 
> DIRMINA-1122_-_endpoint_identification_algorithm_support.patch
>
>          Time Spent: 1h 20m
>  Remaining Estimate: 0h
>
> Support for endpoint identification algorithm was added in Java 1.7. 
> Currently MINA supports providing single SNI name via 
> org.apache.mina.filter.ssl.SslFilter#PEER_ADDRESS session attribute, but 
> there is no way verifying it matches the certificate received.
> It would be nice if we could provide endpoint identification algorithm to 
> SslFilter so certificate's common name or subject alternative names are 
> verified.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@mina.apache.org
For additional commands, e-mail: dev-h...@mina.apache.org

Reply via email to