SSL connection failure on gRPC v1.4.x

356 views
Skip to first unread message

amitw...@gmail.com

unread,
Sep 10, 2017, 9:42:22 AM9/10/17
to grpc.io
After updating my C# client and C# server from gRPC v1.3.6 to v1.4.1, I encountered a problem the client could not establish a secure SSL connection to the server, when passing empty private key from the client side.

The server is configured like this:
var cacert = config.ChannelRootCertificates; // ca.crt
var servercert = config.ChannelCertificateChain; // server.crt
var serverkey = config.ChannelPrivateKey; // server.key
var keypair = new KeyCertificatePair(servercert, serverkey);
var sslCredentials = new SslServerCredentials(new List<KeyCertificatePair>() { keypair }, cacert, false); // **** don't forceClientAuth

The client is configured like this:
var cacert = Encoding.ASCII.GetString(Certificates.ca);
var clientcert = Encoding.ASCII.GetString(Certificates.client);
var clientkey = Encoding.ASCII.GetString(Certificates.clientkey);
var keypair = new KeyCertificatePair(clientcert, null); // **** Passing NULL private key for the client
var sslCredentials = new SslCredentials(cacert, keypair);

Up to version 1.3.6, the connection was established successfully.
The NULL private key means that the server does not enforce the identity of the client (but the client still enforces the identity of the server).
When I change the private key parameter in the KeyCertificatePair, to the real private key, the connection works fine.

My question is:
  1. Did the authentication logic was intentionally changed between the versions, and the failure is a feature and not a bug?
  2. Under those circumstances, how can I establish an SSL connection without making the client to have a private key? (I don't care about authenticating the client's identity in the server)
Thanks!




Jan Tattermusch

unread,
Sep 14, 2017, 8:10:19 AM9/14/17
to grpc.io
Looking at your code, there's seems to be a flaw -  when using SslCredentials, you can either use 
1. the root certificate (cacert) in case you only want to authenticate the server and you don't care about authenticating the client. Example: "new SslCredentials(cacert)"  - this seems to be what you want.
2. or you provide the full key certificate pair on the client, which will allow authenticating the client on the server. Example: new SslCredentials(cacert, new KeyCertificatePair(clientcert, privatekey));

What you are doing is something in-between these two and doesn't really make much sense.
Also, the KeyCertificatePair doesn't accept null for the private key and it's been like since 2years ago. 
So I have trouble believing that your snippet actually worked in C# 1.3.6 version at all.

amitw...@gmail.com

unread,
Sep 16, 2017, 5:58:15 AM9/16/17
to grpc.io
Thank you for your help!
You are correct, I have to use the first option.
In gRPC 1.3.6 I used an empty string as the private key, not NULL. So, it might have been a bug in the SSL library, that allowed me doing so, and now it is fixed and the connection fails.
The connection failure is silent without any indication in both client and server - just a "connect failed" message in the client.
It now appears that the new gRPC 1.6.0 doesn't work well with older (1.3.6/1.3.8) clients and experience disconnections from time to time - as I described here
Is this a known issue?
Thanks
Reply all
Reply to author
Forward
0 new messages