It is only my hunch that this is happening due to the difference between 
OpenSSL and BoringSSL. I build gRPC with OpenSSL, since other dependencies 
of my application require it. Prefixing BoringSSL symbols, although seems 
possible, is apparently not recommended. The Python package grpcio is 
apparently always built with BoringSSL. Unfortunately I am not involved 
enough to figure out if setting certain environment variables for my C++ 
application would make them behave in a similar way. I would really 
appreciate some input.
On Friday, 17 June 2022 at 20:22:33 UTC+2 Subhamoy Sengupta wrote:

> I am trying to do mTLS with a server using gRPC 1.46.0/OpenSSL 3.0.3 on 
> Linux/C++
>
> Below is a snippet of how I prepare `SSLChannelCredentials`:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials() {  
> std::ifstream root_cert_path(GetRootCertPath());  std::string 
> root_cert(std::istreambuf_iterator<char>{root_cert_path}, {});  
> std::ifstream client_key_path(GetClientKeyPath());  std::string 
> client_key(std::istreambuf_iterator<char>{client_key_path}, {});  
> std::ifstream client_cert_path(GetClientCertPath());  std::string 
> client_cert(std::istreambuf_iterator<char>{client_cert_path}, {});  
> grpc::SslCredentialsOptions cred_opts;  cred_opts.pem_root_certs = 
> root_cert;  cred_opts.pem_private_key = client_key;  
> cred_opts.pem_cert_chain = client_cert;  return 
> grpc::SslCredentials(cred_opts);}*
> And this fails with the following debug log:
>
>
>
>
>
>
>
>
>
>
>
> *I0617 10:21:51.992245501     409 socket_utils_common_posix.cc:353] 
> TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be used 
> thereafterI0617 10:21:54.979146083     407 ssl_transport_security.cc:226]   
>    HANDSHAKE START -      before SSL initialization  - PINIT I0617 
> 10:21:54.979203105     407 ssl_transport_security.cc:226]                 
> LOOP -      before SSL initialization  - PINIT I0617 10:21:54.979849401     
> 407 ssl_transport_security.cc:226]                 LOOP -   SSLv3/TLS write 
> client hello  -  TWCHI0617 10:21:59.975724008     409 
> ssl_transport_security.cc:226]                 LOOP -   SSLv3/TLS write 
> client hello  -  TWCHI0617 10:21:59.975958355     409 
> ssl_transport_security.cc:226]                 LOOP -    SSLv3/TLS read 
> server hello  -  TRSHI0617 10:21:59.975972388     409 
> ssl_transport_security.cc:226]                 LOOP - TLSv1.3 read 
> encrypted extensi  -  TREEI0617 10:21:59.976032247     409 
> ssl_transport_security.cc:226]                 LOOP - SSLv3/TLS read server 
> certific  -  TRCRE0617 10:21:59.976188482     409 
> ssl_transport_security.cc:1495] Handshake failed with fatal error 
> SSL_ERROR_SSL: error:1416F086:SSL 
> routines:tls_process_server_certificate:certificate verify failed.D0617 
> 10:21:59.976230069     409 security_handshaker.cc:181] Security handshake 
> failed: {"created":"@1655461319.976196203","description":"Handshake 
> failed","file":"/grpc/src/core/lib/security/transport/security_handshaker.cc","file_line":377,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}I0617
>  
> 10:21:59.976453245     409 subchannel.cc:948]          subchannel 
> 0x619000064a80 {address=ipv6:[2a05:d014:c4b:3500:bb49:5b5c:47c:5191]:443, 
> args=grpc.client_channel_factory=0x602000001cb0, 
> grpc.default_authority=backend_url:443, 
> grpc.http2.max_pings_without_data=0, grpc.http2_scheme=https, 
> grpc.internal.channel_credentials=0x606000005b40, 
> grpc.internal.security_connector=0x60d000023280, 
> grpc.internal.subchannel_pool=0x607000009b70, 
> grpc.keepalive_permit_without_calls=1, grpc.keepalive_time_ms=86400000, 
> grpc.keepalive_timeout_ms=86400000, 
> grpc.primary_user_agent=grpc-c++/1.46.0, 
> grpc.resource_quota=0x60400000fa90, 
> grpc.server_uri=dns:///backend_url:443}: connect failed: 
> {"created":"@1655461319.976196203","description":"Handshake 
> failed","file":"/grpc/src/core/lib/security/transport/security_handshaker.cc","file_line":377,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}*
>
> This is really surprising, because I thought the prefix SSL in 
> SSLChannelCredentials is only for historical purposes and it does not 
> actually try to use SSLv3 any more.
>
> To double check, I used the Python bindings to put together a simple 
> example:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *def certs():    path = "certificate_file_path"    with open(path + 
> "ca.crt") as fd:        ca = fd.read()    with open(path + "client.crt") as 
> fd:        crt = fd.read()    with open(path + "client.key") as fd:        
> key = fd.read()    return {        "root_certificates": ca.encode("utf8"),  
>       "private_key": key.encode("utf8"),        "certificate_chain": 
> crt.encode("utf8"),    }async def main() -> None:    credentials = 
> grpc.ssl_channel_credentials(**certs())    async with 
> grpc.aio.secure_channel(        "server_url:port", credentials    ) as 
> channel:        stub = xxxxx(channel)        await stream(stub)*
>
> And surely enough, this works like a charm with the following debug log:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *D0617 12:25:37.611607359    5824 certificate_provider_registry.cc:33] 
> registering certificate provider factory for "file_watcher"D0617 
> 12:25:37.611612059    5824 lb_policy_registry.cc:42]   registering LB 
> policy factory for "cds_experimental"D0617 12:25:37.611812743    5824 
> lb_policy_registry.cc:42]   registering LB policy factory for 
> "xds_cluster_impl_experimental"D0617 12:25:37.611817173    5824 
> lb_policy_registry.cc:42]   registering LB policy factory for 
> "xds_cluster_resolver_experimental"D0617 12:25:37.611824862    5824 
> lb_policy_registry.cc:42]   registering LB policy factory for 
> "xds_cluster_manager_experimental"E0617 12:25:37.611829462    5824 
> trace.cc:66]                Unknown trace var: 'transport_security'I0617 
> 12:25:37.664472925    5825 ssl_transport_security.cc:226]      HANDSHAKE 
> START -       TLS client start_connect  - !!!!!!I0617 12:25:37.664616500   
>  5825 ssl_transport_security.cc:226]                 LOOP -    TLS client 
> enter_early_data  - !!!!!!I0617 12:25:37.664622010    5825 
> ssl_transport_security.cc:226]                 LOOP -   TLS client 
> read_server_hello  - !!!!!!I0617 12:25:37.694303510    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_hello_retr  - !!!!!!I0617 12:25:37.694320800    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_server_hel  - !!!!!!I0617 12:25:37.694401058    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_encrypted_  - !!!!!!I0617 12:25:37.694410227    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_certificat  - !!!!!!I0617 12:25:37.694434267    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_server_cer  - !!!!!!I0617 12:25:37.694463286    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_server_cer  - !!!!!!I0617 12:25:37.694742638    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> read_server_fin  - !!!!!!I0617 12:25:37.694764417    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> send_end_of_ear  - !!!!!!I0617 12:25:37.694769907    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> send_client_enc  - !!!!!!I0617 12:25:37.694773247    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> send_client_cer  - !!!!!!I0617 12:25:37.694779987    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> send_client_cer  - !!!!!!I0617 12:25:37.695587273    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS 1.3 client 
> complete_second  - !!!!!!I0617 12:25:37.695603763    5828 
> ssl_transport_security.cc:226]                 LOOP -            TLS 1.3 
> client done  - !!!!!!I0617 12:25:37.695607223    5828 
> ssl_transport_security.cc:226]                 LOOP - TLS client 
> finish_client_hands  - !!!!!!I0617 12:25:37.695614203    5828 
> ssl_transport_security.cc:226]                 LOOP -                TLS 
> client done  - !!!!!!I0617 12:25:37.695616983    5828 
> ssl_transport_security.cc:226]       HANDSHAKE DONE -                TLS 
> client done  - !!!!!!*
>
> So, the python bindings try nothing but TLS 1.3, which is exactly what I 
> expected.
>
> I figured, perhaps the SSL in SSLChannelCredentials in C++ is taken 
> literally by the gRPC team and I am supposed to use the experimental 
> TLSCredentials. So I tried something like this:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials() {  
> std::ifstream root_cert_path(GetRootCertPath());  std::string 
> root_cert(std::istreambuf_iterator<char>{root_cert_path}, {});  
> std::ifstream client_key_path(GetClientKeyPath());  std::string 
> client_key(std::istreambuf_iterator<char>{client_key_path}, {});  
> std::ifstream client_cert_path(GetClientCertPath());  std::string 
> client_cert(std::istreambuf_iterator<char>{client_cert_path}, {});  
> std::vector<grpc::experimental::IdentityKeyCertPair> keypairs = 
> {{client_key, client_cert}};  auto certificate_provider = 
> std::make_shared<grpc::experimental::StaticDataCertificateProvider>(root_cert,
>  
> keypairs);  grpc::experimental::TlsChannelCredentialsOptions cred_opts;  
> cred_opts.set_certificate_provider(certificate_provider);  cred_opts.  
> cred_opts.set_verify_server_certs(true);  return 
> grpc::experimental::TlsCredentials(cred_opts);}*
>
> And at least this tries to do TLS 1.3, but fails with the following 
> message:
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> *I0617 19:26:21.349515081   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.360184162   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.360424123   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.360607314   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.360816715   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.361017545   81267 ssl_utils.cc:422]           No root 
> certificates specified; use ones stored in system default locations 
> insteadI0617 19:26:21.361262535   81267 socket_utils_common_posix.cc:353] 
> TCP_USER_TIMEOUT is available. TCP_USER_TIMEOUT will be used 
> thereafterI0617 19:26:24.348350517   81265 ssl_transport_security.cc:226]   
>    HANDSHAKE START -      before SSL initialization  - PINITI0617 
> 19:26:24.348468056   81265 ssl_transport_security.cc:226]                 
> LOOP -      before SSL initialization  - PINITI0617 19:26:24.348747673   
> 81265 ssl_transport_security.cc:226]                 LOOP -   SSLv3/TLS 
> write client hello  -  TWCHI0617 19:26:29.347766352   81267 
> ssl_transport_security.cc:226]                 LOOP -   SSLv3/TLS write 
> client hello  -  TWCHI0617 19:26:29.348116633   81267 
> ssl_transport_security.cc:226]                 LOOP -    SSLv3/TLS read 
> server hello  -  TRSHI0617 19:26:29.348155419   81267 
> ssl_transport_security.cc:226]                 LOOP - TLSv1.3 read 
> encrypted extensi  -  TREEI0617 19:26:29.348220587   81267 
> ssl_transport_security.cc:226]                 LOOP - SSLv3/TLS read server 
> certific  -  TRCRE0617 19:26:29.348505470   81267 
> ssl_transport_security.cc:1495] Handshake failed with fatal error 
> SSL_ERROR_SSL: error:1416F086:SSL 
> routines:tls_process_server_certificate:certificate verify failed.D0617 
> 19:26:29.348590787   81267 security_handshaker.cc:181] Security handshake 
> failed: {"created":"@1655486789.348516884","description":"Handshake 
> failed","file":"/home/ssengupta/git/grpc/src/core/lib/security/transport/security_handshaker.cc","file_line":377,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}I0617
>  
> 19:26:29.348826737   81267 subchannel.cc:948]          subchannel 
> 0x619000065480 {address=ipv6:[2a05:d014:c4b:3500:bb49:5b5c:47c:5191]:443, 
> args=grpc.client_channel_factory=0x602000001cb0, 
> grpc.default_authority=backend_url:443, 
> grpc.http2.max_pings_without_data=0, grpc.http2_scheme=https, 
> grpc.internal.channel_credentials=0x60300001e010, 
> grpc.internal.security_connector=0x613000040700, 
> grpc.internal.subchannel_pool=0x6070000099b0, 
> grpc.keepalive_permit_without_calls=1, grpc.keepalive_time_ms=86400000, 
> grpc.keepalive_timeout_ms=86400000, 
> grpc.primary_user_agent=grpc-c++/1.46.0-dev, 
> grpc.resource_quota=0x60400000fa90, 
> grpc.server_uri=dns:///backend_url:443}: connect failed: 
> {"created":"@1655486789.348516884","description":"Handshake 
> failed","file":"/home/ssengupta/git/grpc/src/core/lib/security/transport/security_handshaker.cc","file_line":377,"tsi_code":10,"tsi_error":"TSI_PROTOCOL_FAILURE"}*
> I am confused now what I should do. What is the preferred method to use 
> TLS with a gRPC client for C++?
>

-- 
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/3fab404d-7098-4624-892e-530326d4b494n%40googlegroups.com.

Reply via email to