runtime: Received an unexpected EOF or 0 bytes from the transport stream
I am trying to use a WPF application that use gRPC to connect to a service that is hosted in an ASP Core application.
The ASP Core has this code:
using GestorOrdenadores.Service.Server.Host.AspCore.Services;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Security.Cryptography.X509Certificates;
var builder = WebApplication.CreateBuilder(args);
builder.WebHost.ConfigureKestrel((context, options) =>
{
string miStrCertificado = File.ReadAllText("certificados/client.crt");
string miStrKey = File.ReadAllText("certificados/client.key");
X509Certificate2 miCertficadoX509 = X509Certificate2.CreateFromPem(miStrCertificado, miStrKey);
options.ListenAnyIP(5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps(miCertficadoX509);
});
});
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<GreeterService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
app.Run();
This is the code in the code in my WPF application:
HttpClientHandler miHttpHandler = new HttpClientHandler();
miHttpHandler.SslProtocols = System.Security.Authentication.SslProtocols.Tls12;
miHttpHandler.ClientCertificates.Add(cert);
HttpClient httpClient = new(miHttpHandler);
var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
HttpClient = httpClient
});
var miCliente = new Greeter.GreeterClient(channel);
HelloRequest miRequest = new HelloRequest()
{
Name = "MiNombre"
};
return (await miCliente.SayHelloAsync(miRequest)).Message;
By the moment, I am running the service and the client in the same machine.
But I get the error: Received an unexpected EOF or 0 bytes from the transport stream.
This is the complete error message:
{"Status(StatusCode=\"Unavailable\", Detail=\"Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. IOException: Received an unexpected EOF or 0 bytes from the transport stream.\", DebugException=\"System.Net.Http.HttpRequestException: The SSL connection could not be established, see inner exception.\r\n
---> System.IO.IOException: Received an unexpected EOF or 0 bytes from the transport stream.\r\n
at System.Net.Security.SslStream.<FillHandshakeBufferAsync>g__InternalFillHandshakeBufferAsync|189_0[TIOAdapter](TIOAdapter adap, ValueTask`1 task, Int32 minSize)\r\n
at System.Net.Security.SslStream.ReceiveBlobAsync[TIOAdapter](TIOAdapter adapter)\r\n
at System.Net.Security.SslStream.ForceAuthenticationAsync[TIOAdapter](TIOAdapter adapter, Boolean receiveFirst, Byte[] reAuthenticationData, Boolean isApm)\r\n
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)\r\n
--- End of inner exception stack trace ---\r\n
at System.Net.Http.ConnectHelper.EstablishSslConnectionAsync(SslClientAuthenticationOptions sslOptions, HttpRequestMessage request, Boolean async, Stream stream, CancellationToken cancellationToken)\r\n
at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)\r\n
at System.Net.Http.HttpConnectionPool.AddHttp2ConnectionAsync(HttpRequestMessage request)\r\n
at System.Threading.Tasks.TaskCompletionSourceWithCancellation`1.WaitWithCancellationAsync(CancellationToken cancellationToken)\r\n
at System.Net.Http.HttpConnectionPool.GetHttp2ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)\r\n
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)\r\n
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)\r\n
at System.Net.Http.HttpClient.<SendAsync>g__Core|83_0(HttpRequestMessage request, HttpCompletionOption completionOption, CancellationTokenSource cts, Boolean disposeCts, CancellationTokenSource pendingRequestsCts, CancellationToken originalCancellationToken)\r\n
at Grpc.Net.Client.Internal.GrpcCall`2.RunCall(HttpRequestMessage request, Nullable`1 timeout)\")"}
This is the script that I use to create the certficates with OpenSsl:
set path=.\OpenSsl
set OPENSSL_CONF=.\openssl.cfg
# Generate valid CA
openssl genrsa -passout pass:1234 -des3 -out ca.key 4096
openssl req -passin pass:1234 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Test/CN=Root CA"
# Generate valid Server Key/Cert
openssl genrsa -passout pass:1234 -des3 -out server.key 4096
openssl req -passin pass:1234 -new -key server.key -out server.csr -subj "/CN=localhost" -config openssl.cfg
openssl x509 -req -passin pass:1234 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
# Remove passphrase from the Server Key
openssl rsa -passin pass:1234 -in server.key -out server.key
# Generate valid Client Key/Cert
openssl genrsa -passout pass:1234 -des3 -out client.key 4096
openssl req -passin pass:1234 -new -key client.key -out client.csr -subj "/C=SP/ST=Spain/L=Valdepenias/O=Test/OU=Client/CN=Client"
openssl x509 -passin pass:1234 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
# Remove passphrase from Client Key
openssl rsa -passin pass:1234 -in client.key -out client.key
pause
Really I don’t know if the problem is that I didn’t create the certificates correctly, perhaps because of a wrong CN or another data, or perhaps because I don’t configure correctly the service or the client.
Thanks.
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 30 (13 by maintainers)
@simonrozsival Done - #75536 - Feel free to edit as needed.
To can trust in the self signed certificate, in android I am using the network_security_config.xml with this code:
Her I set the IP of the first computer, and it could explain why it works. I will try adding the IP of the second computer to see if it solves the problem.