netty / netty-tcnative

A fork of Apache Tomcat Native, based on finagle-native

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

OpenSsl, tcnative with pkcs#11 hsm

grun077 opened this issue · comments

I want to use Netty together with OpenSsl and a hardware security module (hsm). As a proof of concept I succesfully started a OpenSsl server connected to a hsm by using the following command and configuration.

env OPENSSL_CONF=openssl.cnf openssl s_server -curves brainpoolP256r1 -engine pkcs11 -keyform engine -cert TLS-Cert.pem -key 'pkcs11:object=f4ec939ae6ddbd924b3c24893630e1291be92984'

Content of openssl.cnf

openssl_conf = openssl_def

[openssl_def]
engines = engine_section

[engine_section]
pkcs11 = pkcs11_section

[pkcs11_section]
engine_id = pkcs11
dynamic_path = /usr/lib/x86_64-linux-gnu/engines-1.1/pkcs11.so
# HSM lib
MODULE_PATH = /mylibs/libcs_pkcs11_R3.so
PIN = "0000"

Now i am struggling to transfer this to netty with tcnative. We compiled tcnative with OpenSsl static. A tls handshake with Netty, OpenSsl and without a hsm is possible by the using the static library.

SslContext sslCtx = SslContextBuilder
                .forServer(
                        EchoServer.class.getResourceAsStream("/TLS_Pub.pem"),
                        EchoServer.class.getResourceAsStream("/TLS-Key.pem"))
                .protocols(SslProtocols.TLS_v1_2)
                .ciphers(ciphers, IdentityCipherSuiteFilter.INSTANCE_DEFAULTING_TO_SUPPORTED_CIPHERS)
                .sslProvider(SslProvider.OPENSSL)
                .build();

Now I wondering how to add the hsm support?

I tried to use

File file = new File("/tmp/keys/TLS_Pub.crt");
OpenSslX509KeyManagerFactory factory =  OpenSslX509KeyManagerFactory.newEngineBased(file, null);

 SslContext sslCtx = SslContextBuilder
                .forServer(factory)
                .protocols(SslProtocols.TLS_v1_2)
                .ciphers(ciphers, IdentityCipherSuiteFilter.INSTANCE_DEFAULTING_TO_SUPPORTED_CIPHERS)
                .sslProvider(SslProvider.OPENSSL)
                .build();

but i get the following exception

Exception in thread "main" java.security.UnrecoverableKeyException: Unable to load key from engine
      at io.netty.handler.ssl.OpenSslX509KeyManagerFactory$OpenSslKeyStore$1.engineGetKey(OpenSslX509KeyManagerFactory.java:316)
      at java.base/java.security.KeyStore.getKey(Unknown Source)
      at java.base/sun.security.ssl.SunX509KeyManagerImpl.<init>(Unknown Source)
      at java.base/sun.security.ssl.KeyManagerFactoryImpl$SunX509.engineInit(Unknown Source)
      at java.base/javax.net.ssl.KeyManagerFactory.init(Unknown Source)
      at io.netty.handler.ssl.OpenSslX509KeyManagerFactory$OpenSslKeyManagerFactorySpi.engineInit(OpenSslX509KeyManagerFactory.java:128)
      at java.base/javax.net.ssl.KeyManagerFactory.init(Unknown Source)
      at io.netty.handler.ssl.OpenSslX509KeyManagerFactory.newEngineBased(OpenSslX509KeyManagerFactory.java:262)
      at io.netty.handler.ssl.OpenSslX509KeyManagerFactory.newEngineBased(OpenSslX509KeyManagerFactory.java:246)
      at netty.testing.echoserver.EchoServer.main(EchoServer.java:40)
Caused by: java.lang.Exception: Unable to load private key (error:26096043:engine routines:ENGINE_load_private_key:passed a null parameter)
      at io.netty.internal.tcnative.SSL.loadPrivateKeyFromEngine(Native Method)
      at io.netty.handler.ssl.OpenSslX509KeyManagerFactory$OpenSslKeyStore$1.engineGetKey(OpenSslX509KeyManagerFactory.java:313)

Netty is using "key" as alias. I am wondering how one can create a delegate key or alias / label configuration to access a specific PKCS#11 key.

@grun077 could you please share some details on how did you resolve this issue?

To set the alias i implemented two approaches. I implemented a custom keymanager:

CustomServerAliasKeyManager extends X509ExtendedKeyManager

and i tried a custom keystore

CustomServerAliasKeyStore extends KeyStore

In both cases I can set the key alias as a parameter in the constructor.

During debugging I can see that the right alias is used and passed. Unfortunately i was not able to retrieve the private key. I got a internal openssl error.