-
Notifications
You must be signed in to change notification settings - Fork 10.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default SSL credentials don't work on Win32/OsX. #25167
Comments
Is this commit fixing your problem? Try 1.35.0 release |
@nicolasnoble where is default root.pem installed in the system for Mac and windows? |
I am not sure about Mac but on Windows you need to go through the specific API. You need to open the "ROOT" certificate store and I assume the first certificate will be the "root" one. |
From the error message, it seems on Windows, the client is not able to read the root certificate from the default root path. Would you be able to manually read the certificate byte data from that "specific API", and then put it into grpc client? You can set the root certificates from grpc::SslCredentialsOptions on the client side as well. |
@zackgalbreath did you install grpc to your system? That is If |
@ZhenLian, I appreciate you looking into this issue. Yes, I can definitely read the root certificate on the application level or I can even generate a certificate on the fly. I see that there are experimental features in the latest version that allow me to plug in my own certificate provider but I simply did not have enough time to look into it yet. |
Sounds good! I will close this for now, but feel free to reopen it if you have anything else that you want to bring up :) |
@zbordas-kollective Is is possible to share the code snippet to populate |
The root certificate we currently use is Cloudflare Inc ECC CA-3 Certificate `
|
Thanks for the incredibly fast reply! So I seem to have another issue as my setup of those credentials is pretty similar. Instead of an "UNAVAILABLE - empty update" I now get "UNAVAILABLE - failed to connect to all addresses" despite it still working in the C# grpc client... 🤔 |
Alright, I solved it, I thought I only had to provide the first root certificate as someone mentioned above, but I had to iterate through the whole root certificate store. Here a complete example for anyone needing this: #include <Windows.h>
#include <wincrypt.h>
string utf8Encode(const wstring& wstr)
{
if (wstr.empty())
return string();
int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
string strTo(sizeNeeded, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], sizeNeeded, NULL, NULL);
return strTo;
}
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);
vector<WCHAR> 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;
} To clarify, the code above is public domain, use it in any way you want. |
Thanks for your solution! |
Updated in my comment, may wanna remove the code in your reply so people don't see the old thing twice |
spent 4 hours last night trying to figure out why my C++ gRPC client wouldnt work with cloudflare dispite nodejs/postman and other languages working just fine. Glad to have found this, it solved my problem. 💀 🙏 |
I am trying to build and run the code snippet from https://grpc.github.io/docs/guides/auth.html
`// Create a default SSL ChannelCredentials object.
auto channel_creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
// Create a channel using the credentials created in the previous step.
auto channel = grpc::CreateChannel("some.endpoint.com:443", channel_creds);
// Create a stub on the channel.
std::unique_ptrGreeter::Stub stub(Greeter::NewStub(channel));
// Make actual RPC calls on the stub.
grpc::Status s = stub->sayHello(&context, *request, response);`
The endpoint I'm trying to reach is a TLS secured gRPC service with no gRPC server certificates.
What version of gRPC and what language are you using?
Tried 1.27, 1.32 and 1.34 with C++, none seems to be working, only Linux works.
What operating system (Linux, Windows,...) and version?
Windows, OsX and Linux, only Linux works, Windows and OsX fails.
What runtime / compiler are you using (e.g. python version or version of gcc)
MSDEV 2017 and 2019, Clang 11.0 on OsX. GCC 7.5 on Linux which works.
What did you do?
I was trying to run the example from the documentation page, trying to create a secure channel with server side certificate only.
What did you expect to see?
I expected the channel to establish a connection and connect. Tried to same code in Java and .NET and it works without issues:
Channel channel = new Channel("some.endpoint.com:443", new SslCredentials()); var client = new MyGrpcClient(channel);
What did you see instead?
Received an error and the connection was not established:
E0114 10:45:32.025000000 2336 ssl_utils.cc:565] load_file: {"created":"@1610649932.024000000","description":"Failed to load file","file":"c:\.conan\46f65c\1\source_subfolder\src\core\lib\iomgr\load_file.cc","file_line":72,"filename":"/usr/share/grpc/roots.pem","referenced_errors":[{"created":"@1610649932.024000000","description":"No such file or directory","errno":2,"file":"c:\.conan\46f65c\1\source_subfolder\src\core\lib\iomgr\load_file.cc","file_line":45,"os_error":"No such file or directory","syscall":"fopen"}]} E0114 10:45:32.052000000 2336 ssl_security_connector.cc:413] Could not get default pem root certs. E0114 10:45:32.057000000 2336 secure_channel_create.cc:107] Failed to create secure subchannel for secure name 'some.endpoint.com:443' E0114 10:45:32.065000000 2336 secure_channel_create.cc:49] Failed to create channel args during subchannel creation.
Anything else we should know about your project / environment?
Tried both Conan packages and hand-built gRPC. I made sure the grpc++_unsecure & grpc_unsecure libraries are NOT added to the link dependencies.
I also tried to add self signed certificates (not the server's) and it still failed to authenticate and connect. I am not sure why it works on Linux and not on Windows or OsX.
The text was updated successfully, but these errors were encountered: