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 On Friday, April 6, 2018 at 9:38:52 PM UTC-4, Noah Eisen wrote: > > I am linking in Eric (ej...@google.com <javascript:>) > > Looks like #3992 <https://github.com/grpc/grpc-java/pull/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) > > On Wed, Apr 4, 2018 at 2:02 PM David Audrain <david....@gmail.com > <javascript:>> wrote: > >> I've implemented a tls version of helloworld/greeter_client >> <https://github.com/daudrain/grpc/blob/cpp_greeter_tls_example/examples/cpp/helloworld/greeter_tls_client.cc> >> >> and server >> <https://github.com/daudrain/grpc/blob/cpp_greeter_tls_example/examples/cpp/helloworld/greeter_tls_server.cc> >> . >> >> First test case (failing one) >> >> Then I followed theses steps >> <https://github.com/grpc/grpc-java/blob/master/examples/README.md#generating-self-signed-certificates-for-use-with-grpc> >> >> 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 >> <https://github.com/grpc/grpc/tree/master/src/core/tsi/test_creds>. (BTW >> I've not been able to regenerate theses files myself following the provided >> README >> <https://github.com/grpc/grpc/blob/master/src/core/tsi/test_creds/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 >> <https://github.com/grpc/grpc-java/blob/master/examples/README.md#generating-self-signed-certificates-for-use-with-grpc> >> ? >> >> >> On Wednesday, April 4, 2018 at 1:33:03 PM UTC-4, ncte...@google.com >> wrote: >> >>> That seems like the right way to go about it. >>> >>> Are you running into trouble? what are the errors? >>> >>> On Thursday, March 29, 2018 at 3:36:59 PM UTC-7, David Audrain wrote: >>>> >>>> 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 >>>> >>> -- >> 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 <javascript:>. >> To post to this group, send email to grp...@googlegroups.com >> <javascript:>. >> 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 >> >> <https://groups.google.com/d/msgid/grpc-io/a0abe609-d93e-40a9-9aeb-45149e60551b%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> For more options, visit https://groups.google.com/d/optout. >> > -- 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+unsubscr...@googlegroups.com. To post to this group, send email to grpc-io@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/c3805331-bb2c-4a28-b644-ca1520d34841%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
intermediate_openssl.cnf
Description: Binary data
root_openssl.cnf
Description: Binary data
#!/bin/bash # Composed from https://jamielinux.com/docs/openssl-certificate-authority/index.html # and https://github.com/grpc/grpc/blob/v1.10.1/src/core/tsi/test_creds/README log_error() { echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')] ERROR: $@" >&2 } ROOT_COMMON_NAME=localhost INTERMEDIATE_COMMON_NAME=localhost SERVER_COMMON_NAME=server.com CLIENT_COMMON_NAME=client.com ROOT_SUBJECT="/C=CA/ST=Quebec/L=Somewhere/O=Cool Inc/OU=Cool Department/CN=${ROOT_COMMON_NAME}/EA=foo@localhost" INTERMEDIATE_SUBJECT="/C=CA/ST=Quebec/L=Somewhere/O=Cool Inc/OU=Cool Department/CN=${INTERMEDIATE_COMMON_NAME}/EA=foo@localhost" EXE_DIR="$PWD" EXE_DIR=`echo $(cd ${EXE_DIR}; pwd)` ROOT_DIR="${EXE_DIR}/ca" INTERMEDIATE_DIR="${ROOT_DIR}/intermediate" pass="1111" root_conf="${EXE_DIR}/root_openssl.cnf" if ! [[ -f "${root_conf}" ]]; then log_error "Could not find root openssl configuration ${root_conf}" exit 1 fi intermediate_conf="${EXE_DIR}/intermediate_openssl.cnf" if ! [[ -f "${intermediate_conf}" ]]; then log_error "Could not find intermediate openssl configuration ${intermediate_conf}" exit 1 fi echo "Prepare the root directory" # Create the directory structure. # The index.txt and serial files act as a flat file database to keep track of signed certificates. mkdir "${ROOT_DIR}" cd "${ROOT_DIR}" mkdir certs crl newcerts private chmod 700 private touch index.txt echo 1000 > serial sed -e "s#ROOT_DIR#${ROOT_DIR}#g" "${root_conf}" > openssl.cnf echo "Create the root key" openssl genrsa -passout pass:"${pass}" -aes256 -out private/ca.key.pem 4096 if [[ "$?" -ne 0 ]]; then log_error "Fail creating the root key" exit 1 fi chmod 400 private/ca.key.pem echo "Create the root certificate" openssl req -passin pass:"${pass}" -config openssl.cnf \ -key private/ca.key.pem \ -new -x509 -days 7300 -sha256 -extensions v3_ca \ -out certs/ca.cert.pem \ -subj "${ROOT_SUBJECT}" if [[ "$?" -ne 0 ]]; then log_error "Fail creating the root certificate" exit 1 fi chmod 444 certs/ca.cert.pem echo "Verify the root certificate" openssl x509 -noout -text -in certs/ca.cert.pem if [[ "$?" -ne 0 ]]; then log_error "Fail checking the root certificate" exit 1 fi echo "Prepare the intermediate directory" # Create the same directory structure used for the root CA files. # It’s convenient to also create a csr directory to hold certificate signing requests. mkdir "${INTERMEDIATE_DIR}" cd "${INTERMEDIATE_DIR}" mkdir certs crl csr newcerts private chmod 700 private touch index.txt echo 1000 > serial # Add a crlnumber file to the intermediate CA directory tree. # crlnumber is used to keep track of certificate revocation lists. echo 1000 > crlnumber sed -e "s#INTERMEDIATE_DIR#${INTERMEDIATE_DIR}#g" "${intermediate_conf}" > openssl.cnf cd "${ROOT_DIR}" echo "Create the intermediate key" openssl genrsa -passout pass:"${pass}" -aes256 -out intermediate/private/intermediate.key.pem 4096 if [[ "$?" -ne 0 ]]; then log_error "Fail creating the intermediate key" exit 1 fi chmod 400 intermediate/private/intermediate.key.pem echo "Create the intermediate certificate signing request (CSR)" openssl req -passin pass:"${pass}" -config intermediate/openssl.cnf -new -sha256 \ -key intermediate/private/intermediate.key.pem \ -out intermediate/csr/intermediate.csr.pem \ -subj "${INTERMEDIATE_SUBJECT}" if [[ "$?" -ne 0 ]]; then log_error "Fail creating the intermediate CSR" exit 1 fi echo "Create the intermediate certificate" openssl ca -passin pass:"${pass}" -config openssl.cnf -extensions v3_intermediate_ca \ -days 3650 -notext -md sha256 \ -in intermediate/csr/intermediate.csr.pem \ -out intermediate/certs/intermediate.cert.pem if [[ "$?" -ne 0 ]]; then log_error "Fail creating the intermediate certificate" exit 1 fi chmod 444 intermediate/certs/intermediate.cert.pem openssl verify -CAfile certs/ca.cert.pem \ intermediate/certs/intermediate.cert.pem if [[ "$?" -ne 0 ]]; then log_error "Fail checking the intermediate certificate" exit 1 fi echo "Create the certificate chain file" cat intermediate/certs/intermediate.cert.pem \ certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem chmod 444 intermediate/certs/ca-chain.cert.pem echo "Create the server key" openssl genrsa -out intermediate/private/server.key.rsa 1024 openssl pkcs8 -topk8 -in intermediate/private/server.key.rsa \ -out intermediate/private/server.key -nocrypt echo "Create the server certificate signing request" openssl req -passin pass:"${pass}" -config intermediate/openssl.cnf -new -key intermediate/private/server.key \ -out intermediate/csr/server.csr -subj "/CN=${SERVER_COMMON_NAME}" if [[ "$?" -ne 0 ]]; then log_error "Fail creating the server signing request" exit 1 fi echo "Create the server certificate " openssl ca -passin pass:"${pass}" -config intermediate/openssl.cnf -in intermediate/csr/server.csr \ -out intermediate/certs/server.pem if [[ "$?" -ne 0 ]]; then log_error "Fail creating the server certificate" exit 1 fi echo "Create the client key" openssl genrsa -out intermediate/private/client.key.rsa 1024 openssl pkcs8 -topk8 -in intermediate/private/client.key.rsa \ -out intermediate/private/client.key -nocrypt echo "Create the client certificate signing request" openssl req -passin pass:"${pass}" -config intermediate/openssl.cnf -new -key intermediate/private/client.key \ -out intermediate/csr/client.csr -subj "/CN=${CLIENT_COMMON_NAME}" if [[ "$?" -ne 0 ]]; then log_error "Fail creating the client certificate signing request" exit 1 fi echo "Create the client certificate " openssl ca -verbose -passin pass:"${pass}" -config intermediate/openssl.cnf -in intermediate/csr/client.csr \ -out intermediate/certs/client.pem if [[ "$?" -ne 0 ]]; then log_error "Fail creating the client certificate" exit 1 fi