silb78
silb78

Reputation: 139

gRPC SSL No subject alternative names present

How can disable the hostnameverfifier in gRPC to avoid exception below?

java.security.cert.CertificateException: No subject alternative names present

Upvotes: 1

Views: 2627

Answers (2)

user1409784
user1409784

Reputation:

Just to elaborate on @Eric Anderson answer. In the gRPC's test certificates he points to there are 2 types *.cnf files used to generate the client and server certs

1.Generate client cert: openssl.cnf

2.Generate server cert: server1-openssl.cnf

at the very bottom of both files you will find the hostnames where you need to add the matching entries for the client and server

for example if you are local testing for client and server resolving on "localhost" then you would need for both openssl.cnf and server1-openssl.cnf to have

[alt_names]
DNS.1 = localhost

after this you would need to regenerate the certificates here is a simple script based on the grpc-java info here

#!/bin/bash
SERVER_CN=localhost
CLIENT_CN=localhost # Used when doing mutual TLS
TLS_KEY_PSSWD=somepsswd
echo "When prompted for cert information, everything is default except the common name which is set to localhost"
echo Generate CA key:
openssl genrsa -passout pass:TLS_KEY_PSSWD -des3 -out ca.key 4096
echo Generate CA:
openssl req -passin pass:TLS_KEY_PSSWD -x509 -new -nodes -key ca.key -out ca.pem -config conf/ca-openssl.cnf -days 3650 -extensions v3_req -subj "/CN=${SERVER_CN}"
echo  "Now that we’re a CA on all our devices, we can sign certificates for any new dev sites that need HTTPS"
echo Generate client key:
openssl genrsa  -out client.key.rsa 1024
openssl pkcs8 -topk8 -in client.key.rsa -out client.key -nocrypt
rm client.key.rsa
echo Generate client signing request:
openssl req -passin pass:TLS_KEY_PSSWD  -new -key client.key -out client.csr -subj "/CN=${CLIENT_CN}"
echo Generate client cert:
openssl ca -passin pass:TLS_KEY_PSSWD  -in client.csr -out client.pem -keyfile ca.key -cert ca.pem -verbose -config conf/openssl.cnf -days 3650 -updatedb
openssl x509 -in client.pem -out client.pem -outform PEM
echo Generate server key:
openssl genrsa -passout pass:TLS_KEY_PSSWD  -out server1.key.rsa 1024
openssl pkcs8 -topk8 -in server1.key.rsa -out server1.key -nocrypt
rm server1.key.rsa
echo Generate server signing request:
openssl req -passin pass:TLS_KEY_PSSWD -new -key server1.key -out server1.csr -config conf/server1-openssl.cnf  -subj "/CN=${CLIENT_CN}"
echo Generate server cert:
openssl ca -passin pass:TLS_KEY_PSSWD  -in server1.csr -out server1.pem -keyfile ca.key -cert ca.pem -verbose -config conf/server1-openssl.cnf -days 3650 -extensions v3_req -updatedb
openssl x509 -in server1.pem -out server1.pem -outform PEM

Upvotes: 0

Eric Anderson
Eric Anderson

Reputation: 26394

The recommended way to use test certificates where the hostname doesn't match is to call ManagedChannelBuilder.overrideAuthority("test-hostname"). This is functionally similar to adding test-hostname to /etc/hosts. This allows you to choose different IPs/DNS names with forAddress()/forTarget() without disabling security.

But it still seems like your certificate is a bit broken. Subject Alternative Name is required; using the certificate's Subject had been deprecated for a decades.

You may also be interested in using gRPC's test certificates. We provide TlsTesting to load them.

server = ServerBuilder.forPort(0)
    // Use test cert on server-side
    .useTransportSecurity(
        TlsTesting.loadCert("server1.pem"),
        TlsTesting.loadCert("server1.key"))
    // ...
    .build().start();

channel = NettyChannelBuilder
    .forAddress("localhost", server.getPort())
    // Trust test CA on client-side
    .sslContext(
        GrpcSslContexts.forClient()
            .trustManager(TlsTesting.loadCert("ca.pem"))
            .build())
    // Change hostname to match certificate
    .overrideAuthority("foo.test.google.fr")
    .build();

Upvotes: 4

Related Questions