I'm trying to connect to a gRPC server using TLS (gRPC version 1.76.0) on Windows. However, I'm getting the following errors in the console:
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1770816303.480934 5684 ssl_transport_security.cc:886] Could not load any root certificate.
E0000 00:00:1770816303.481355 5684 ssl_transport_security.cc:1466] Could not load root certificates.
E0000 00:00:1770816303.488018 5684 ssl_transport_security.cc:886] Could not load any root certificate.
E0000 00:00:1770816303.488263 5684 ssl_transport_security.cc:2576] Cannot load server root certificates.
E0000 00:00:1770816303.488506 5684 ssl_credentials.cc:212] Handshaker factory creation failed with TSI_INVALID_ARGUMENT
The error appears to indicate that gRPC requires root certificates to be installed. However, according to this GitHub issue, the gRPC library now loads certificates automatically:
https://github.com/grpc/grpc/issues/25533
However, I continue to receive this error. I tried installing the certificates manually as shown in the code below, after which the number of errors decreased, and I get the following output
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
E0000 00:00:1770816360.263513 19664 ssl_transport_security.cc:886] Could not load any root certificate.
E0000 00:00:1770816360.263836 19664 ssl_transport_security.cc:2576] Cannot load server root certificates.
E0000 00:00:1770816360.264067 19664 ssl_credentials.cc:212] Handshaker factory creation failed with TSI_INVALID_ARGUMENT
As you can see, the problem with loading root certificates still persists. What could be the problem?
Here's my code:
#include
#include
std::string utf8Encode(const std::wstring& wstr)
{
if (wstr.empty())
return std::string();
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(),
NULL, 0, NULL, NULL);
std::string strTo(sizeNeeded, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(),
&strTo[0], sizeNeeded, NULL, NULL);
return strTo;
}
using namespace grpc;
SslCredentialsOptions getSslOptions()
{
// Fetch root certificate as required on Windows (s. issue 25533).
SslCredentialsOptions result;
// Open root certificate store.
HANDLE hRootCertStore = CertOpenSystemStoreW(NULL, L"ROOT");
if (!hRootCertStore)
return result;
// Get all root certificates.
PCCERT_CONTEXT pCert = NULL;
while ((pCert = CertEnumCertificatesInStore(hRootCertStore, pCert)) != NULL)
{
// Append this certificate in PEM formatted data.
DWORD size = 0;
CryptBinaryToStringW(pCert->pbCertEncoded, pCert->cbCertEncoded,
CRYPT_STRING_BASE64HEADER, NULL, &size);
std::vector pem(size);
CryptBinaryToStringW(pCert->pbCertEncoded, pCert->cbCertEncoded,
CRYPT_STRING_BASE64HEADER, pem.data(), &size);
result.pem_root_certs += utf8Encode(pem.data());
}
CertCloseStore(hRootCertStore, 0);
return result;
}
int main()
{
std::cout << "gRPC version: " << grpc::Version() << std::endl;
grpc::SslCredentialsOptions ssl_opts = getSslOptions();
auto channel = grpc::CreateChannel("grpcb.in:9001", grpc::SslCredentials(ssl_opts));
return 0;
}