1

I am using the Rust's tonic library for GRPC with TLS.

I get the following error

thread 'main' panicked at 'Failed to create request insight client: tonic::transport::Error(Transport,
   hyper::Error(Connect, Custom { kind: InvalidData, error: InvalidCertificate(NotValidForName) }))'

The same certificate works for other languages.

curl --cacert <path to cert> -vv <server>

shows the expected certificate subject name.

This is how the ClientTlsConfig and Channel is created:

    let tls = ClientTlsConfig::new()
        .domain_name("server") // <server> matches the certificate subject name
        .ca_certificate(Certificate::from_pem(client_ca_data));
    let channel = Channel::from_shared(endpoint.to_string()) // endpoint is http://server:50051
                    .unwrap()
                    .tls_config(tls_config)?
                    .connect()
                    .await?;

It is not clear what the next steps are.

dmeister
  • 34,704
  • 19
  • 73
  • 95

1 Answers1

4

I had the same issue when using the rustls to establish connection between server and the client. Apparently, the rust is strict in handling such errors according to RFC regulations. Please use the following bash script to regenerate the key and self-signed certificates for your case. The generated files will exist under keys directory. Remember to change the [alt_names] based on your settings.

#!/bin/sh
mkdir -p keys
cd keys/

# source: https://users.rust-lang.org/t/use-tokio-tungstenite-with-rustls-instead-of-native-tls-for-secure-websockets/90130

# Create unencrypted private key and a CSR (certificate signing request)
openssl req -newkey rsa:2048 -nodes -subj "/C=FI/CN=vahid" -keyout key.pem -out key.csr

# Create self-signed certificate (`cert.pem`) with the private key and CSR
openssl x509 -signkey key.pem -in key.csr -req -days 365 -out cert.pem

# Create a self-signed root CA
openssl req -x509 -sha256 -nodes -subj "/C=FI/CN=vahid" -days 1825 -newkey rsa:2048 -keyout rootCA.key -out rootCA.crt


# Create file localhost.ext with the following content:
cat <<'EOF' >> localhost.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName = @alt_names
[alt_names]
DNS.1 = server
IP.1 = <The Ip of the server!>
EOF

# Sign the CSR (`cert.pem`) with the root CA certificate and private key
# => this overwrites `cert.pem` because it gets signed
openssl x509 -req -CA rootCA.crt -CAkey rootCA.key -in key.csr -out cert.pem -days 365 -CAcreateserial -extfile localhost.ext

Please make sure that the client has the rootCA.crt in your code. Something like this:

    let tls = ClientTlsConfig::new()
        .domain_name("server") // <server> matches the certificate subject name
        .ca_certificate(Certificate::from_pem("keys/rootCA.crt"));
  • Big thank you. I had the same problem rustls and a PostgreSQL server. Used my server's IP address, ran above shell, changed owner and group to postgres, changed mod to 0600, set the PostgreSQL ssl_cert_file to cert.pem and ssl_key_file to key.pem, and used the rootCA.crt for the rustls certificate and finally the tokio_postgres_rustls could build a MakeRustlsConnect (usually named 'tls' in the examples) in order to connect with tokio_postgres that was accepted. – WeakPointer Jun 05 '23 at 18:06
  • You sir were sent from heaven! Uploading cert.pem, key.pem and using rootCA.crt worked finally!! Python did not throw any error messages, neither did AWS's Fargate Load Balancer, through rust I am finally here and this worked :D – superfuzzy Jul 13 '23 at 12:40