I'm trying to write a GRPC server that talks to both a C++ and golang client. Since this is all internal to our system, there will be a self-signed certificate that signs the server certificate, and the server will sign the client certificates.
I'm able to connect to the server from the golang client. However, the C++ client doesn't connect, and I see a bunch of errors from the ssl layer. What am I doing incorrectly in my configuration of the C++ grpc client?
(My certificates all use a 2048bit RSA key for now)
Here are the client codes that I thought were equivalent (error handling elided):
Golang:
import (
"crypto/tls"
"io/ioutil"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
func getConnection(hostPort string) (*grpc.ClientConn, error) {
var config tls.Config
cert, _ := tls.LoadX509KeyPair("client.crt", "client.key")
config.Certificates = append(config.Certificates, cert)
b, _ := ioutil.ReadFile("root.crt")
config.RootCAs.AppendCertsFromPEM(b)
options := grpc.WithTransportCredentials(credentials.NewTLS(config))
return grpc.Dial(hostPort, options)
}
C++:
#include <fstream>
#include <string>
#include <grpc++/grpc++.h>
std::shared_ptr<grpc::Channel> get_connection(const std::string& host_port) {
auto contents = [](const std::string& filename) -> std::string {
std::ifstream fh(filename);
std::stringstream buffer;
buffer << fh.rdbuf();
fh.close();
return buffer.str();
};
auto ssl_options = grpc::SslCredentialsOptions();
ssl_options.pem_cert_chain = contents("client.crt");
ssl_options.pem_private_key = contents("client.key");
ssl_options.pem_root_certs = contents("root.crt");
auto creds = grpc::SslCredentials(ssl_options);
auto channel = grpc::CreateChannel(hostport, creds);
}
My error messages:
C++ Client error messages
D0322 14:42:12.882767371 11701 env_linux.c:77] Warning: insecure environment read function 'getenv' used
getting job record
E0322 14:42:12.930157873 11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.930231627 11701 handshake.c:128] Security handshake failed: {"created":"@1490218932.930210185","description":"Handshake failed","file":"src/core/lib/security/transport/handshake.c","file_line":264,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
E0322 14:42:12.964082644 11701 ssl_transport_security.c:945] Handshake failed with fatal error SSL_ERROR_SSL: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed.
E0322 14:42:12.964134746 11701 handshake.c:128] Security handshake failed: {"created":"@1490218932.964114213","description":"Handshake failed","file":"src/core/lib/security/transport/handshake.c","file_line":264,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}
std::string JobServerClient::getJobRecord(const string&) const: GRPC connection error 14 []
Golang Client error messages
2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport: connection error: desc = "transport: EOF"
2017/03/22 17:42:12 grpc: Server.Serve failed to create ServerTransport: connection error: desc = "transport: EOF"
What additional debugging can I do to determine where the C++ client is going awry?