I'm having a bit of trouble sorting out how to adapt my Dart gRPC client to use the same TLS settings that are working with my Go client. I've already validated that I can interface with the server suppling the correct CA cert, client cert and client key. In Go I'm using:
pemServerCA, err := ioutil.ReadFile("pems/ca-cert.pem")
if err != nil {
return nil, err
}
certPool := x509.NewCertPool()
if !certPool.AppendCertsFromPEM(pemServerCA) {
return nil, fmt.Errorf("failed to add server CA's certificate")
}
// Load client's certificate and private key
clientCert, err := tls.LoadX509KeyPair("pems/client-cert.pem", "pems/client-key.pem")
if err != nil {
return nil, err
}
// Create the credentials and return it
config := &tls.Config{
Certificates: []tls.Certificate{clientCert},
RootCAs: certPool,
}
Just supplying that in case it helps demonstrate what's working. In Dart I'm doing this:
ChannelCredentials credentials = ChannelCredentials.secure(
certificates: utf8.encode(grpcCertificate),
onBadCertificate: (certificate, host) {
return host == apiURL + ':' + apiPort.toString();
},
);
grpcCertificate contains the contents of client-key.pem. I suspect this is not correct. I'm not very skilled with certificates like this so I'm a bit at a loss. What value should I be supplying to certificates to achieve a successful handshake with the server?
From the above it seems like I need to parse my PEMs into X.509. In Go that's super easy, not sure how to handle this in Dart.
Edit: I've made a bit of progress:
List<int> list = grpcCertificate.codeUnits;
Uint8List cert = Uint8List.fromList(list);
ChannelCredentials credentials = ChannelCredentials.secure(
certificates: cert,
authority: 'localhost',
onBadCertificate: (certificate, host) {
return host == apiURL + ':' + apiPort.toString();
},
);
The server seems to hate this less and spits out:
flutter: gRPC Error (code: 14, codeName: UNAVAILABLE, message: Error connecting: TlsException: Failure trusting builtin roots (OS Error:
BAD_PKCS12_DATA(pkcs8_x509.c:645), errno = 0), details: null, rawResponse: null)
Thanks.