You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Rémy Maucherat <re...@apache.org> on 2015/05/18 17:46:59 UTC

OpenSSL JSSE SSLEngine implementation

Hi,

As part of a university project, Numa de Montmollin, a student interning
@redhat, has worked on adapting to Tomcat some code I discovered inside the
Netty project, which implements a SSL engine using OpenSSL.

Normally, this sort of thing is supposed to be done using JCE, as was
attempted earlier by the Apache Juice project. However, JCE is very complex
(which probably explains the failure of Juice), is difficult to use for the
end user, and may not even yield optimal performance. The Netty folks
instead smartly identified a spot in the JSSE API that could be hacked and
(ab)used it (I am not certain this was intended, since the SPI API on
SSLContext forces use of JCE instead). Effectively, this allows replacing
the regular SSLEngine with an equivalent backed by OpenSSL, and it is
rather simple to achieve once you know what to do.

Early performance results show the NIO(2) connector with SSL being
equivalent or maybe even slightly faster than the APR connector, with JSSE
very far behind. With SSL being nearly mandatory in the new protocols, SSL
performance becomes a very important factor.

For speed testing of the prototype, I used my obligatory:
ab -c 100 -n 100000 -k -Z "AES128-GCM-SHA256"
https://127.0.0.1:8443/tomcat.gif
Notes:
- JSSE is very bad at GCM, it needs a JVM fix (OTOH, without it, it is
still significantly slower).
- The performance is better with direct buffers (where it matches APR for
me) but it remains very acceptable without it if needed (for example for
scatter/gather calls). There's no reason not to use direct buffers for the
SecureNIO(2)Channel however. The forked Tomcat 8 has a ready to use demo
config in its conf folder.

The code is here:
- Tomcat 8 fork: https://github.com/rmaucher/tomcat80-openssl
- Native fork: https://github.com/rmaucher/tomcat-native-openssl

Technically:
- The Java code [except the JNI update obviously] is self contained since I
added in trunk the SSLContext interface that is used as the main hook.
- The native code is simply the vanilla native Netty code forked from
tcnative. The student has no plan to make any further changes to it.
- Trunk SSL config was unstable so this uses Tomcat 8. I've started porting
it today (incl cleanup and package renaming), I expect I'll  be done very
quickly.
- The configuration is a WIP. [with the trunk port, the SNI changes are
taking care of a major item here, since they have both types of config]

The hardest to merge by far is the native portion. The Netty fork has some
fixes (apparently), feature additions (poller, NPN/ALPN, OSCP, from what I
saw) in addition to the (many) new SSL methods needed for the SSL engine
implementation. So there's a need for review on how and what to merge.

Comments ?

Thanks,
Rémy

Re: OpenSSL JSSE SSLEngine implementation

Posted by Rémy Maucherat <re...@apache.org>.
2015-05-18 21:42 GMT+02:00 Mark Thomas <ma...@apache.org>:

> Very, very nice.
>
> On the native side, I'm all for taking as much as we can. No reason not
> to aim for something that the Netty folks can just use without having to
> patch locally.
>
> Thanks. I'm continuing to work on it in trunk now (
https://github.com/rmaucher/tomcat ), but there's still a good amount of
work.

For the native portion, I agree with your proposal, even if some portions
are not immediately useful for Tomcat (for example, the APR connector would
have to be rewritten to take advantage of the async APR API wrapper),
building and managing a custom native is very annoying. Tomcat-native is
readily available, so it would make people's life easier.

Rémy

Re: OpenSSL JSSE SSLEngine implementation

Posted by Mark Thomas <ma...@apache.org>.
On 18/05/2015 16:46, Rémy Maucherat wrote:
> Hi,
> 
> As part of a university project, Numa de Montmollin, a student interning
> @redhat, has worked on adapting to Tomcat some code I discovered inside the
> Netty project, which implements a SSL engine using OpenSSL.
> 
> Normally, this sort of thing is supposed to be done using JCE, as was
> attempted earlier by the Apache Juice project. However, JCE is very complex
> (which probably explains the failure of Juice), is difficult to use for the
> end user, and may not even yield optimal performance. The Netty folks
> instead smartly identified a spot in the JSSE API that could be hacked and
> (ab)used it (I am not certain this was intended, since the SPI API on
> SSLContext forces use of JCE instead). Effectively, this allows replacing
> the regular SSLEngine with an equivalent backed by OpenSSL, and it is
> rather simple to achieve once you know what to do.
> 
> Early performance results show the NIO(2) connector with SSL being
> equivalent or maybe even slightly faster than the APR connector, with JSSE
> very far behind. With SSL being nearly mandatory in the new protocols, SSL
> performance becomes a very important factor.
> 
> For speed testing of the prototype, I used my obligatory:
> ab -c 100 -n 100000 -k -Z "AES128-GCM-SHA256"
> https://127.0.0.1:8443/tomcat.gif
> Notes:
> - JSSE is very bad at GCM, it needs a JVM fix (OTOH, without it, it is
> still significantly slower).
> - The performance is better with direct buffers (where it matches APR for
> me) but it remains very acceptable without it if needed (for example for
> scatter/gather calls). There's no reason not to use direct buffers for the
> SecureNIO(2)Channel however. The forked Tomcat 8 has a ready to use demo
> config in its conf folder.
> 
> The code is here:
> - Tomcat 8 fork: https://github.com/rmaucher/tomcat80-openssl
> - Native fork: https://github.com/rmaucher/tomcat-native-openssl
> 
> Technically:
> - The Java code [except the JNI update obviously] is self contained since I
> added in trunk the SSLContext interface that is used as the main hook.
> - The native code is simply the vanilla native Netty code forked from
> tcnative. The student has no plan to make any further changes to it.
> - Trunk SSL config was unstable so this uses Tomcat 8. I've started porting
> it today (incl cleanup and package renaming), I expect I'll  be done very
> quickly.
> - The configuration is a WIP. [with the trunk port, the SNI changes are
> taking care of a major item here, since they have both types of config]
> 
> The hardest to merge by far is the native portion. The Netty fork has some
> fixes (apparently), feature additions (poller, NPN/ALPN, OSCP, from what I
> saw) in addition to the (many) new SSL methods needed for the SSL engine
> implementation. So there's a need for review on how and what to merge.
> 
> Comments ?

Very, very nice.

On the native side, I'm all for taking as much as we can. No reason not
to aim for something that the Netty folks can just use without having to
patch locally.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: OpenSSL JSSE SSLEngine implementation

Posted by Rémy Maucherat <re...@apache.org>.
2015-05-21 19:48 GMT+02:00 Christopher Schultz <chris@christopherschultz.net
>:

> Rémy,
>
> On 5/18/15 11:46 AM, Rémy Maucherat wrote:
> > Early performance results show the NIO(2) connector with SSL being
> > equivalent or maybe even slightly faster than the APR connector, with
> JSSE
> > very far behind. With SSL being nearly mandatory in the new protocols,
> SSL
> > performance becomes a very important factor.
>
> Jean-Frederic has no doubt shared with you his investigations into
> (non-) accelerated crypto in the JVM due to various bugs. It will be
> interesting to see what kind of performance improvement JSSE gets when
> the JVM can finally stop doing all that crypto in Java-land.
>

I got a GCM fix that improves AES-GCM, but it takes forever to make it into
releases. Maybe Java 9 I guess ;)

>
> If the performance is comparable, I'd say that sticking with the
> vendor-supported JSSE crypto is a better bet: less code to maintain,
> fewer code paths to test for all configurations, etc.
>
> But this is still a very interesting project nonetheless. It's entirely
> possible that nobody at Oracle/OpenJDK/etc. cares about
> hardware-accelerated crypto, and it might not come along any time soon.
>
> In that case, Tomcat does really need a TLS solution with decent
> performance.
>
> OpenSSL still looks much better [as demonstrated in the APR connector]
[even with the fix mentioned above]. Another benefit is it has many more
features [ciphers] and is consistent across JVM versions. And as you say
it's an interesting small experiment.

Rémy

Re: OpenSSL JSSE SSLEngine implementation

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Rémy,

On 5/18/15 11:46 AM, Rémy Maucherat wrote:
> Early performance results show the NIO(2) connector with SSL being
> equivalent or maybe even slightly faster than the APR connector, with JSSE
> very far behind. With SSL being nearly mandatory in the new protocols, SSL
> performance becomes a very important factor.

Jean-Frederic has no doubt shared with you his investigations into
(non-) accelerated crypto in the JVM due to various bugs. It will be
interesting to see what kind of performance improvement JSSE gets when
the JVM can finally stop doing all that crypto in Java-land.

If the performance is comparable, I'd say that sticking with the
vendor-supported JSSE crypto is a better bet: less code to maintain,
fewer code paths to test for all configurations, etc.

But this is still a very interesting project nonetheless. It's entirely
possible that nobody at Oracle/OpenJDK/etc. cares about
hardware-accelerated crypto, and it might not come along any time soon.

In that case, Tomcat does really need a TLS solution with decent
performance.

-chris