How to connect Grpc (NuGet >2.33) client (.NET Framework) with Grpc.Asp.NetCore (NuGet >2.31) server (.NET 5.0) using HTTPS and my own certificate?
Asked Answered
T

1

2

Exception message:

Grpc.Core.RpcException: 'Status(StatusCode="Unavailable", Detail="failed to connect to all addresses", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1606657072.668000000","description":"Failed to pick subchannel","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\client_channel.cc","file_line":4166,"referenced_errors":[{"created":"@1606657072.668000000","description":"failed to connect to all addresses","file":"T:\src\github\grpc\workspace_csharp_ext_windows_x86\src\core\ext\filters\client_channel\lb_policy\pick_first\pick_first.cc","file_line":398,"grpc_status":14}]}")'

I've created an example on GitHub which you can easily tweak, play with, and answer this question if you succeed to solve the problem.

grpc_certifier_example

...

I've figured out that the problem is in my own certificates and I am unable to create my own that work, tried numerous combinations.

I've used this example to generate my certificates: How to enable server side SSL for gRPC?

and tested it on this example: https://github.com/angelagyang/GRPCProtobufExample

Timbre answered 29/11, 2020 at 5:58 Comment(7)
Does this answer your question? How to connect Grpc (netstandard 2.0) with Grpc.Asp.NetCore server (.NET 5.0) using HTTPS and my own certificate?Leavis
No, it has no answer that works for this case.Timbre
Do you intend to use client authentication (mTLS) or not? (your question title only mentions a single certificate)Leavis
For starters, I need any solution that uses HTTPS, the simplest one at first, and then build on it. I need this example to use HTTPS successfully.Hakim
My goal is to have an application that has a secret with which it can connect to my service. I don't want that secret to be computed by users' intervention because it needs to work before any users' intervention and on any PC without installing anything prior to that device and I also want to be able to use my own certs not trusted by CA, I don't need that. It's a software update service, software update solution similar to click-once...Hakim
Anyone with the application should be able to use it without any configuration. Identity is my application and the secret it holds inside its code. If the connection is secure I don't see the difference between an app providing some cert as a secret or a password. Correct me if I am wrong. I also want to be able not to use CA trusted SSL certificate because I don't want to have to buy one. Download the app and run it, with minimal intervention from the user.Hakim
I will also need a service for the report generation and the client app will send the user name and password to that service so that it can determine if the user has the right to that report. I don't want to hand out any certificates to the clients because it needs to be highly dynamic and flexible, I just need a secure connection so that no one can read that user name and password from the channel.Hakim
H
1

The problem is in the certificate and its CN=. CN=%COMPUTERNAME% must be server DNS or IP, in my case, it had to be localhost and the server needs to have a certificate with the key (pfx). The main problem is that it throws the exception with no relevant explanation.

Client:

                //THIS IS YOUR CLIENT'S CERTIFICATE AND IT'S KEY
                var keyCertPair = new KeyCertificatePair(File.ReadAllText($"{rootDir}/samplecert.pem.txt"), File.ReadAllText($"{rootDir}/samplecert.key.txt"));
                //GetRootCertificates() GETS THE CA CERTIFICATE, NOT THE CLIENT CERTIFICATE NOR SERVER CERTIFICATE
                var channelCreds = new SslCredentials(GetRootCertificates(), keyCertPair);
                //YOU DON'T EVEN NEED TO PROVIDE KeyCertificatePair, IT WORKS WITH JUST A CA ROOT
                var channelCreds = new SslCredentials(GetRootCertificates());

Server:

                //LoadSSLCertificate() GETS THE SERVER CERTIFICATE
                var sslCertificate = LoadSSLCertificate(); 
                o.ListenAnyIP(5001, listenOptions =>
                {
                    listenOptions.UseHttps(sslCertificate, httpsOptions =>
                    {
                        httpsOptions.SslProtocols = SslProtocols.Tls12;
                        httpsOptions.ClientCertificateMode = ClientCertificateMode.NoCertificate;
                        httpsOptions.ClientCertificateValidation = (certificate, chain, errors) =>
                        {
                            return true;
                            //return certificate.Thumbprint.Equals(_clientThumbprint, StringComparison.OrdinalIgnoreCase);
                        };
                    });
                });

Certificates creation:

@echo off
REM set OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.cfg   

echo Generate CA key:
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096

echo Generate CA certificate:
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=MyRootCA"

echo Generate server key:
openssl genrsa -passout pass:1111 -des3 -out server.key 4096

echo Generate server signing request:
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%COMPUTERNAME%"

echo Self-sign server certificate:
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

echo Remove passphrase from server key:
openssl rsa -passin pass:1111 -in server.key -out server.key

echo Generate client key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096

echo Generate client signing request:
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%CLIENT-COMPUTERNAME%"

echo Self-sign client certificate:
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

echo Remove passphrase from client key:
openssl rsa -passin pass:1111 -in client.key -out client.key

echo Create server.pfx file:
openssl pkcs12 -export -passout pass:1111 -out server.pfx -inkey server.key -in server.crt
Hakim answered 1/12, 2020 at 7:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.