0
votes

I want to set-up SSL on my GRPC server. For that I need certificate chain and a pkcs8 private key.

I have done the following:

Generate CA key:

openssl genrsa -des3 -out ca.key 4096

Generate CA certificate:

openssl req -new -x509 -days 365 -key ca.key -out ca.crt

Generate server key:

openssl genrsa -des3 -out server.key 4096

Generate server signing request:

openssl req -new -key server.key -out server.csr

Self-sign server certificate:

openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

Remove passphrase from the server key:

openssl rsa -in server.key -out server.key

Conver to pkcs8

openssl pkcs8 -topk8 -nocrypt -in server.key -out pkcs8_key.pem


Now that I have my server.cert and pkcs8_key.pem files, I've created the server as such:

InputStream certChain = MyServer.class.getResourceAsStream("/server.crt");
        InputStream privateKey = MyServer.class.getResourceAsStream("/pkcs8_key.pem");
        SslContext sslContext = GrpcSslContexts.forServer(certChain, privateKey, "password").build();


        Server server = NettyServerBuilder.forPort(8080)
                            .sslContext(sslContext)
                            .addService(new ChatService())
                            .addService(new HelloWorldService())
                            .useTransportSecurity(certChain, privateKey)
                            .build();

The classpath is configured properly.

The error stack I'm getting:

Exception in thread "main" java.lang.IllegalArgumentException: Input stream does not contain valid private key.
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:296)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.forServer(SslContextBuilder.java:104)
    at io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts.forServer(GrpcSslContexts.java:162)
    at server.MyServer.main(MyServer.java:20)
Caused by: java.io.IOException: overrun, bytes = 2353
    at javax.crypto.EncryptedPrivateKeyInfo.<init>(EncryptedPrivateKeyInfo.java:92)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.generateKeySpec(SslContext.java:978)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.getPrivateKeyFromByteBuffer(SslContext.java:1034)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContext.toPrivateKey(SslContext.java:1024)
    at io.grpc.netty.shaded.io.netty.handler.ssl.SslContextBuilder.keyManager(SslContextBuilder.java:294)
    ... 3 more
1

1 Answers

0
votes

The exception is being caused by this line:

SslContext sslContext = GrpcSslContexts
    .forServer(certChain, privateKey, "password").build();

Since your pkcs8 key has no password, you should not be passing a password and instead use the two-argument method:

SslContext sslContext = GrpcSslContexts
    .forServer(certChain, privateKey).build();

Note that calling useTransportSecurity() will overwrite your call to sslContext(), so you shouldn't call both. Calling both would break in the current code because forServer() consumes and close the provided InputStreams, so you'd be passing closed streams to useTransportSecurity().