dev@grizzly.java.net

Re: Grizzly 2.0: SSL support

From: Jeanfrancois Arcand <Jeanfrancois.Arcand_at_Sun.COM>
Date: Mon, 17 Nov 2008 11:30:12 -0500

Salut,

Oleksiy Stashok wrote:
> Hi,
>
> I would like to ask for the community feedback on current SSL
> implementation in Grizzly 2.0
>
> Unlike Grizzly 1.x, Grizzly 2.0 doesn't have special SSL transport, but
> uses SSL Encoder and Decoder Transformers.
> Transformer API is topic for separate email and blog ;).

Blog? Long time I saw one from you (:-) :-) :-))


Just in several
> words - Transformer knows how to transform data from one representation
> to another.

Needs to improve the JavaDocs :-) I think it is time to publish the API
online :-) :-)


>
> In our case:
> SSLEncoderTransformer encodes plaintext input Buffer into TLS/SSL
> encoded output Buffer.
> SSLDecoderTransformer decodes TLS/SSL encoded Buffer into plaintext data
> Buffer.
>
> SSLCodec - incapsulates encoder and decoder transformers and SSL
> configuration objects.
>
> It's possible to work with SSL in both standalone and Filter modes.
>
> 1) Standalone mode.
> In standalone mode developer should implicitly initialize SSL connection
> with SSL handshake. And then use Connection I/O methods (read/write) to
> send and receive data.
>
> Example:
>
>
> Connection connection = null;
>
> // Initiate the SSLCodec
> SSLCodec sslCodec = new SSLCodec(createSSLContext());

Can you describe what you need to create inside the createSSLContext()?


>
> TCPNIOTransport transport =
> TransportManager.instance().createTCPTransport();

I think we have discused that part already :-), but should we rename
TransportManager to TransportManagerFactory, and replace instance() with
getInstance()?



> try {
> transport.bind(PORT);
> transport.start();
>
> // Connect client
> ConnectFuture future = transport.connect("localhost", PORT);
> connection = (TCPNIOConnection) future.get(10,
> TimeUnit.SECONDS);

This is not related to SSL only, but since we are on the topic, I think
we need to have a a way to execute asynchronous connect. Right now the
connect operation is blocking (10 seconds). I would like to be able to
pass some CallbackHandler (or CompletionHandler like NIO.2) so
asynchronous operations without blocking.


>
> // Run handshake
> Future handshakeFuture = sslCodec.handshake(connection);
>
> // Wait until handshake will be completed
> handshakeFuture.get(10, TimeUnit.SECONDS);

Same here. We need a CompletionHandler.


>
> MemoryManager memoryManager = transport.getMemoryManager();
> Buffer message = MemoryUtils.wrap(memoryManager, "Hello
> world!");

What MemoryUtil.wrap does exactly?


>
> // Write the message with SSLCodec.getEncoder() parameter.
> Future writeFuture = connection.write(null, message, null,
> sslCodec.getEncoder(), 10, TimeUnit.SECONDS);
> writeFuture.get();

To make the review easier, do you think you can reference the method
description/javadoc from here? So people don't have to checkout the code
  to understand the sample :-). Here, writeFuture.get() doesn't block,
right?

>
> // Obtain the Buffer, which corresponds to the SSLEngine
> requirements.
> Buffer receiverBuffer = SSLResourcesAccessor.getInstance().
> obtainAppBuffer(connection);

Hum...do we really need another "Factory" to get the receiverBuffer?
Should this be retrieved from the Transport instance instead. I'm -1 on
having a specialized object (at least with this current API). Should we
have a concept of Context/Session?


>
> // Read the message with SSLCodec.getDecoder() parameter
> Future readFuture =
> connection.read(receiverBuffer, null,
> sslCodec.getDecoder(), null, 10, TimeUnit.SECONDS);
> .....................................................
>
>
> 2) Filter mode.
> In Filter mode developer should just add SSLFilter to the transport
> filter chain. The SSLFilter itself has a SSLCodec, which in its turn has
> SSL encode/decode transformers and SSL configuration.
>
> Example (SSL Echo server)
>
> Connection connection = null;
> SSLCodec sslCodec = new SSLCodec(createSSLContext());
>
> TCPNIOTransport transport =
> TransportManager.instance().createTCPTransport();
> transport.getFilterChain().add(new TransportFilter());
> // Add SSLFilter
> transport.getFilterChain().add(new SSLFilter(sslCodec));
> transport.getFilterChain().add(new EchoFilter());

Inside the EchoFilter, calling connection.write() will make sure the
output is encrypted if SSL is used, and clean if not, right? That's
something we don't support in 1.x and that would be nice if Filter can
be written without knowing which transport is used.


>
> try {
> transport.bind(PORT);
> transport.start();
>
> ...................
>
>
> Will appreciate the feedback.

I think we need to update the main page (grizzly.dev.java.net) with the
following information:

+ Javadocs
+ XREF Code
+ Samples (like the on above).

Great work!

-- Jeanfrancois




>
> Thanks.
>
> WBR,
> Alexey.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: dev-help_at_grizzly.dev.java.net
>