Reputation: 549
I know nothing about SSL/TLS and am trying to use SSL/TLS channel in gRPC by following instructions found online. Here is the server code:
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp ={"a","b"};
grpc::SslServerCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs="";
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
std::shared_ptr<grpc::ServerCredentials> creds;
creds = grpc::SslServerCredentials(ssl_opts);
ServerBuilder builder;
builder.AddListeningPort(server_address, creds);
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
The server won't start and terminates with following error.
E1115 13:00:55.657846941 17129 ssl_transport_security.c:636] Invalid cert chain file.
E1115 13:00:55.657936436 17129 security_connector.c:830] Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
E1115 13:00:55.657954952 17129 server_secure_chttp2.c:344] {"created":"@1479243655.657946821","description":"Unable to create secure server with credentials of type Ssl.","file":"src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c","file_line":242,"security_status":1}
Server listening on 0.0.0.0:50051
Segmentation fault (core dumped)
All I want to do is just use SSL for server and client communication. Looks like I am missing proper certificates in the server and believe similar things needed in client. Since I don't have any background in SSL it would be great if anybody can point me to examples about how to create those certificates and use properly for gRPC communication.
Upvotes: 8
Views: 12390
Reputation: 549
It appears to be problem with the way the certificates are created. I forgot the post in StackOverflow that had shown how to create the certificates. Used that method and plugged-in the key and certificates to make it work.
Here is how I created the key (server.key) and the certificates (server.crt).
mypass="pass123"
echo Generate server key:
openssl genrsa -passout pass:$mypass -des3 -out server.key 4096
echo Generate server signing request:
openssl req -passin pass:$mypass -new -key server.key -out server.csr -subj "/C=US/ST=CA/L=SanFrancisco/O=Google/OU=youtube/CN=localhost"
echo Self-sign server certificate:
openssl x509 -req -passin pass:$mypass -days 365 -in server.csr -signkey server.key -set_serial 01 -out server.crt
echo Remove passphrase from server key:
openssl rsa -passin pass:$mypass -in server.key -out server.key
rm server.csr
Pay attention to the use of localhost
here. Same should be used at the time of client channel creation.
I modified the example from grpc code base to use these. The server that looked like below.
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
std::string servercert = read_keycert("server.crt");
std::string serverkey = read_keycert("server.key");
grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp;
pkcp.private_key = serverkey;
pkcp.cert_chain = servercert;
grpc::SslServerCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs="";
ssl_opts.pem_key_cert_pairs.push_back(pkcp);
std::shared_ptr<grpc::ServerCredentials> creds;
creds = grpc::SslServerCredentials(ssl_opts);
ServerBuilder builder;
builder.AddListeningPort(server_address, creds);
builder.RegisterService(&service);
std::unique_ptr<Server> server(builder.BuildAndStart());
server->Wait();
In client only certificate is required. Here is how it is used in my case.
std::string cacert = read_keycert("server.crt");
grpc::SslCredentialsOptions ssl_opts;
ssl_opts.pem_root_certs=cacert;
auto ssl_creds = grpc::SslCredentials(ssl_opts);
GreeterClient greeter(grpc::CreateChannel("localhost:50051", ssl_creds));
The way the key and certificates are generated and used is different in each use case. I think if two servers communicate then these may be different. Not sure. Hope this helps some newbie to start with secure SSL/TLS in gRPC C++.
Upvotes: 20