[C++] How to simulate GO tls config InsecureSkipVerify

273 views
Skip to first unread message

David Audrain

unread,
Mar 29, 2018, 6:36:59 PM3/29/18
to grpc.io
Hi,

My C++ Client tries to connect my dev server using TLS but connection keeps failing while checking the dev server certificate.

The go version uses the following workaround to skip the verification:

    grpcOpts := []grpc.DialOption{}
    creds
:= credentials.NewTLS(&tls.Config{InsecureSkipVerify: *insecureSkipVerify})
    grpcOpts
= append(grpcOpts, grpc.WithTransportCredentials(creds))

What is the equivalent with C++ GRPC library?

Should I use ChannelArguments::SetSslTargetNameOverride ?

Thank you,
David

ncte...@google.com

unread,
Apr 4, 2018, 1:33:03 PM4/4/18
to grpc.io
That seems like the right way to go about it.

Are you running into trouble? what are the errors?

David Audrain

unread,
Apr 4, 2018, 5:02:02 PM4/4/18
to grpc.io
I've implemented a tls version of helloworld/greeter_client and server.

First test case (failing one)

Then I followed theses steps to create certificate, keys, etc... 

greeter_tls_server is run
~/sources/github.com/grpc/grpc/examples/cpp/helloworld$ ./greeter_tls_server localhost 50051 ca.crt server.crt server.key

greeter_tls_client is run
~/sources/github.com/grpc/grpc/examples/cpp/helloworld$ ./greeter_tls_client localhost 50051 localhost ca.crt

greeter_tls_client fails
SSL target name override : SET TO [localhost]
E0404
16:43:27.918287000 140735524692800 ssl_transport_security.cc:1063] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
E0404
16:43:27.933634000 140735524692800 ssl_transport_security.cc:1063] Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED.
14: Connect Failed
Greeter TLS received: RPC failed

Java HelloWorldTlsClient from grpc-java succeeds:
~/sources/github.com/grpc/grpc-java/examples$ ./build/install/examples/bin/hello-world-tls-client localhost 50051 ca.crt
Apr 04, 2018 4:40:52 PM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
INFO
: Will try to greet localhost ...
Apr 04, 2018 4:40:52 PM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
INFO
: Greeting: TLS Hello localhost

Second test case (success)

The grpc repository contains certificate and keys generated in src/core/tsi/test_creds. (BTW I've not been able to regenerate theses files myself following the provided README)

This second test case uses the credentials of grpc repository.

greeter_tls_server:
~/sources/github.com/grpc/grpc/examples/cpp/helloworld$ ./greeter_tls_server localhost 50051 ../../../src/core/tsi/test_creds/ca.pem ../../../src/core/tsi/test_creds/server0.pem ../../../src/core/tsi/test_creds/server0.key

greeter_tls_client succeeds:
~/sources/github.com/grpc/grpc/examples/cpp/helloworld$ ./greeter_tls_client localhost 50051 foo.test.google.com.au ../../../src/core/tsi/test_creds/ca.pem
SSL target name
override : SET TO [foo.test.google.com.au]

Greeter TLS received: TLS Hello world


Java HelloWorldTlsClient fails (I guess the domain *.test.google.com.au should be specified somewhere)
Apr 04, 2018 4:54:10 PM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
INFO
: Will try to greet localhost ...
Apr 04, 2018 4:54:10 PM io.grpc.examples.helloworldtls.HelloWorldClientTls greet
WARNING
: RPC failed: Status{code=UNAVAILABLE, description=io exception, cause=javax.net.ssl.SSLHandshakeException: General OpenSslEngine problem
 at io
.netty.handler.ssl.ReferenceCountedOpenSslContext$AbstractCertificateVerifier.verify(ReferenceCountedOpenSslContext.java:634)
....
Caused by: java.security.cert.CertificateException: No name matching localhost found
 at sun
.security.util.HostnameChecker.matchDNS(HostnameChecker.java:221)



Conclusion : Using the credentials from the grpc repository, greeter_tls_client works ok against greeter_tls_server.

Questions : What is wrong with the credentials generation provided on the grpc-java example README?

Noah Eisen

unread,
Apr 6, 2018, 9:38:52 PM4/6/18
to david....@gmail.com, Eric Anderson, grpc.io
I am linking in Eric (ej...@google.com)

Looks like #3992 added the example of generating credentials. Any input on why that won't work for a C++ TLS greeter service (copying the github creds will work)

--
You received this message because you are subscribed to the Google Groups "grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email to grpc-io+u...@googlegroups.com.
To post to this group, send email to grp...@googlegroups.com.
Visit this group at https://groups.google.com/group/grpc-io.
To view this discussion on the web visit https://groups.google.com/d/msgid/grpc-io/a0abe609-d93e-40a9-9aeb-45149e60551b%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Audrain

unread,
Apr 6, 2018, 10:30:34 PM4/6/18
to grpc.io
Hi Noah,

I've been able to generate certificates and key that work ok with greeter_tls_client and greeter_tls_server.
One needs to run certs.sh to generate root, intermediate and server keys, signing requests and certificates. The cnf files are expect to be along certs.sh. And everything is generated in ca subfolder.

Then just test this way

./greeter_tls_server localhost 50051 ca/intermediate/certs/ca-chain.cert.pem ca/intermediate/certs/server.pem ca/intermediate/private/server.key


./greeter_tls_client localhost 50051 server.com ca/intermediate/certs/ca-chain.cert.pem
SSL target name
override : SET TO [server.com]

Greeter TLS received: TLS Hello world

HelloWorldTlsClient java example will only work if server's CSR Common Name is set to localhost. To test this case
  • Set SERVER_COMMON_NAME to localhost inside certs.sh (instead of server.com)
  • Remove ca dir
  • Run certs.sh again
May be HelloWorldTlsClient should be changed so it enables to specify the SslTargetNameOverride like C++ greeter.

hello-world-tls-client localhost 50051 ca/intermediate/certs/ca-chain.cert.pem

It looks like the C++ version (or may be my specific build) is unable to perform handshake with a specific type of CA chain/CSR/Key.

Regards,
David
intermediate_openssl.cnf
root_openssl.cnf
certs.sh

Eric Anderson

unread,
Apr 9, 2018, 1:56:44 PM4/9/18
to David Audrain, grpc.io
There's a lot in this thread...

On Thursday, March 29, 2018 at 3:36:59 PM UTC-7, David Audrain wrote:
The go version uses the following workaround to skip the verification:

    grpcOpts := []grpc.DialOption{}
    creds 
:= credentials.NewTLS(&tls.Config{InsecureSkipVerify: *insecureSkipVerify})
    grpcOpts 
= append(grpcOpts, grpc.WithTransportCredentials(creds))

What is the equivalent with C++ GRPC library?

Should I use ChannelArguments::SetSslTargetNameOverride ?

There isn't an equivalent of InsecureSkipVerify in C++ (to my knowledge). But yes, SetSslTargetNameOverride is the thing to use (to my knowledge). The Go equivalent of that API is grpc.WithAuthority(). The Java equivalent is ManagedChannelBuilder.overrideAuthority().

I strongly suggest using those APIs over things like InsecureSkipVerify, as it doesn't disable any part of the TLS checks. It's basically the equivalent of a hostname override in /etc/hosts, but more convenient.

On Wed, Apr 4, 2018 at 2:02 PM David Audrain <david....@gmail.com> wrote:
Questions : What is wrong with the credentials generation provided on the grpc-java example README?

I don't think anything is. When creating the server certificate you need to change the CN to match how you will contact it, as is documented:
# Changes these CN's to match your hosts in your environment if needed.
SERVER_CN=localhost

I could be mistaken, but it's a bit hard to notice without seeing the Java command line invocation. Alternatively, change how you contact it to match the certificate (e.g., with /etc/hosts).

On Fri, Apr 6, 2018 at 7:30 PM, David Audrain <david....@gmail.com> wrote:
HelloWorldTlsClient java example will only work if server's CSR Common Name is set to localhost. To test this case
  • Set SERVER_COMMON_NAME to localhost inside certs.sh (instead of server.com)
  • Remove ca dir
  • Run certs.sh again
May be HelloWorldTlsClient should be changed so it enables to specify the SslTargetNameOverride like C++ greeter.

I think you're misunderstanding the purpose of HelloWorldTlsClient. It's meant to be close to a "real" client, not a "test" client. That's why it doesn't use overrideAuthority and doesn't use our test certs. You shouldn't typically use SslTargetNameOverride in a real client.

I will note that the client was an external contribution and pretty recently added, so things could potentially be improved with it.
Reply all
Reply to author
Forward
0 new messages