Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to accept self-signed certificates in Grpc.Core?

Tags:

c#

.net

ssl

grpc

Scenario: I have a client implemented in C# that shoud connect to a server using gRPC using SSL for an encrypted Connection. However, the certificate used by the server may or may not be self-signed.

In the docs, I have only seen that I can set up a channel credential either insecure (no SSL at all) or secure by using custom root certificates (or using the public root CAs which will not validate a self-signed cert), which effectively means I would have to make sure that I install the self-signed server certificate as root. Basically, how do I do that programmatically?

var channelCredentials = new SslCredentials(rootAsPem); 
// FIXME: specify that channelCredentials can accept self-signed certificates or fetch certificates?
var channel = new Channel("myservice.example.com", channelCredentials);
var client = new Greeter.GreeterClient(channel);

What I would like to implement is to ask the user like "hey, the server that you configured uses a self-signed certificate, are you OK with that?" and if so, install the certificate as a root certificate in the PEM.

My main Questions now are:

  1. How do I even get the server certificate? All I currently get is an exception.
  2. Is it possible to avoid having to install the server certificate as a root certificate?
like image 249
Georg Avatar asked Mar 26 '19 19:03

Georg


2 Answers

var httpClientHandler = new HttpClientHandler();
// Return `true` to allow certificates that are untrusted/invalid
httpClientHandler.ServerCertificateCustomValidationCallback = 
    HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;
var httpClient = new HttpClient(httpClientHandler);
var channel = GrpcChannel.ForAddress("https://localhost:5001",
    new GrpcChannelOptions { HttpClient = httpClient });
var client = new Greet.GreeterClient(channel);

https://docs.microsoft.com/en-us/aspnet/core/grpc/troubleshoot?view=aspnetcore-3.0

like image 52
Gasha Avatar answered Oct 17 '22 15:10

Gasha


I had a similar problem and finally found a solution to establish HTTPs connection between

  • .NET Framework 4.7.2 client (WPF app) and
  • ASP .NET Core 3.1 gRPC Server (Console).

They key to a solution was to first download the server certificate using a regular HttpClient and a Get on the the gRPC target server. Through the HttpClientHandler with its ServerCertifacteCustomValidationCallback, you are able to get the X509 Certificate of the server and check if it is a self-signed certificate to prompt the user for confirmation of a probably unsafe connection. If it is confirmend, you can export the certificate to a PEM formatted string and than use it in the constructor of SslCredentials. There is another important thing: the certificate has to contain the DNS name or the IP of the URL through which you are contacting the server, because the client performs a check on this. You can see a detailed error by enabling gRPC client debugging:

See my more detailed answer here:

https://stackoverflow.com/a/63565090/378415

like image 22
JanW Avatar answered Oct 17 '22 16:10

JanW