gRpc with TLS Client Authentication using SunPKCS1

2019-07-31 16:06发布

问题:

I have some java 8 application, using gRPC for network communication. To secure that, I use TLS with client authentication. Now, I try to switch from software keys to a smart card, holding the private key and certificate (chain) for the client authentication. My code to make netty inside gRPC's use the sun pkcs#11 provider looks as follows:

static NettyChannelBuilder getChannel(final String host, final int port, 
  final File trustAnchorsFile) throws Exception{
  String configName = "pkcs11.cfg"; // FIXME


  SunPKCS11 sunpkcs11 = new SunPKCS11(configName);
  Security.addProvider(sunpkcs11);
  KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", sunpkcs11,
        new KeyStore.PasswordProtection("11111111".toCharArray())); //FIXME

  KeyManagerFactory factory = KeyManagerFactory.getInstance("NewSunX509");  
  KeyStoreBuilderParameters param = new KeyStoreBuilderParameters(scBuilder);
  factory.init(param);
  SslContextBuilder builder = GrpcSslContexts.forClient(); 

  builder = builder.trustManager(trustAnchorsFile)
                 .keyManager(factory)
                 .clientAuth(ClientAuth.REQUIRE);

  return NettyChannelBuilder.forAddress(host, port).sslContext(builder.build());
}

testing that code I see, that it authenticates against the smart card (providing some wrong PIN (instead of the "11111111") decreases the corresponding retry counter on card. In addition, using a debug version of the pkcs11 dll, being used by the sun pkcs11 provider, I see, that the sun provider authenticates, lists all keys, reads all certificates and so (quite often), but does not try to perform some private key operation. In addition, providing -Djava.security.debug=sunpkcs11 to the JVM does not give any further inside (I stumbled accros that at SSL Client Authentication with smart card works in Java 6 but fails in Java 7).

Using wireshark to look into the TLS protocol handshake it looks like, the client tries to omit the client authentication part which makes the server closing the connection. This leads then to some exception on the client:

io.grpc.StatusRuntimeException: UNAVAILABLE: Channel closed while performing protocol negotiation at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:227) at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:208) at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:141)

providing the very same key and certificates from the smartcard as PEM files to the SslContextBuilder does result in a working connection, so I conclude, that the certificate(s) and the key itself do not form the problem, but maybe/probably some configuration of sunpkcs11?

Does anybody succeeded using gRPC with PKCS#15 smartcards / PKCS#11 tokens? Does anybody have further suggestions, how to easily understand, what fails here?