I am currently developing a simple instant messaging application (client and server AND a webapp, but the role of the webapp is irrelevant to the topic). It's basically a toy project. Yesterday I checked out and built the latest 0.9 MINA. Looking at the SumUp example, I managed to code a simple message-based protocol.

I want the communication to be encrypted. I want clients to authenticate with client certificates. I created sample certificates, key- and truststores for the server and an example client, added properly configured SSLFilters to filter chains and it worked. The problem is, I also want to authorize the clients with their certificates (i.e. retrieve user ID corresponding to the certificate, without having to embed the user ID in, for example, the certificate subject DN field).

The peer (client) certificate chain is stored in a SSLSession object. By the time the sessionOpened method of the IoHandler is called, the SSLSession does not yet exist. The SSLFilter can fire the SESSION_SECURED/SESSION_UNSECURED special messages, so it's possible to perform the authorization in the messageReceived method. I set the SSLFilter.USE_NOTIFICATION attribute in sessionCreated. Every time, the SESSION_SECURED message is fired twice by the SSLFilter, consecutively, with very similar stack traces. The SSLSession retrieved with sslFilter.getSSLSession(session) - where sslFilter is an instance of the filter and session is the IoSession passed to messageReceived - is the same for both messages. Technically, you can live with that, but either I'm missing something important, or it's a bug :) I checked whether it has to to with client authentication being enabled but no, with server authentication only the problem still occurs.
Relevant source code fragments:

Server main:

SSLContext ctx = prepareServerSslContext();
SSLFilter filt = new SSLFilter(ctx);
filt.setNeedClientAuth(true);
filt.setUseClientMode(false);
reg.getAcceptor(TransportType.SOCKET).getFilterChain().addLast("ssl", filt);

Client main:

IoConnector conn = new SocketConnector();
SSLFilter filt = new SSLFilter(prepareClientSslContext());
filt.setUseClientMode(true);
conn.getFilterChain().addLast("ssl", filt);

Server SessionHandler sessionCreated:

session.getFilterChain().addFirst("protocolFilter",
        new ProtocolCodecFilter(
                new NetworkProtocolCodecFactory())); // it's my class
session.setAttribute(SSLFilter.USE_NOTIFICATION, true);

Server SessionHandler messageReceived:

if (message == SSLFilter.SESSION_SECURED) {
        SSLSession sslSession = sslFilter.getSSLSession(session);
        ...do some stuff with sslSession.getPeerCertificates()
        // this code gets executed twice when it shouldn't
}
else {
        ...do the normal protocol communication
}

I'd greatly appreciate an answer. My source already looks ugly and having to code around this problem certainly wouldn't help :)

--
Janusz Nykiel; [EMAIL PROTECTED]

Reply via email to