Open
Description
Is there an existing issue for this?
- I have searched the existing issues
Describe the bug
Kestrel HTTP3 endpoint validate server name for client certificate by default.
Expected Behavior
Default behavior for HTTP3 endpoint should match default behavior for HTTP2 endpoint, where server name is not validated for client certificates.
Steps To Reproduce
using System;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Https;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using var certificateServerLocalhost = X509CertificateLoader.LoadPkcs12(
Convert.FromBase64String(
"MIIDrwIBAzCCA2sGCSqGSIb3DQEHAaCCA1wEggNYMIIDVDCCAW0GCSqGSIb3DQEHAaCCAV4EggFaMIIBVjCCAVIGCyqGSIb3DQEM"
+ "CgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIad3vtjT4Dl0CAgfQBIGo6KjHd77pQmovty/084x1hiAASWOykB98Ae/UVnk2LpyP"
+ "fMa0CBf9ftYrZoRBxAVCxV69cji5ORmtAHeY4KnUC/YTpNtUSxQMwL+kzs1VVuAn97xlChlwT/Ja8I+nP/SZxqFkAubFSevVICtb"
+ "Ab/AQ2Fm2kc99Cxf3T3w1UXwztrEAia//16oW+lCoJgAWNsmRzDdSyr0DbHKyE0e5+lPYHHe1KI4btQsMXQwEwYJKoZIhvcNAQkV"
+ "MQYEBAEAAAAwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0"
+ "AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAd8GCSqGSIb3DQEHBqCCAdAwggHMAgEAMIIBxQYJKoZIhvcNAQcBMBwGCiqG"
+ "SIb3DQEMAQMwDgQI7CXlOm9fD2gCAgfQgIIBmFjiicG1YQPZbwMya27wyyhreSnznp/WLfycwsa2ssATFgRXssUw49gHs4ZDMqQO"
+ "5y57e4VJoJ4nAb3yQn9HuCqiwv0UJcFc2B70JuRWpWv/TAWgoLuPeeHtOCeBRvhuGW56xkNqiMk/aOQSuOYxKtXhwymY83kZ/g8T"
+ "3uNGRwOkqwzhfrN0vadkBBZmJJ2m7W8cDsWdfFhlFWhN6U9MQK0NnvCqCs9M/jrSfCe103pZb6GiXz6ybW+Ihk/5G5G85DFO2oI/"
+ "Jt++aOBegU+RuyIqsQAhbN13gX0roo5RF5TpQ94QMgxFo46i+Szg0osXggK+unEmCj4xLQ1bTreOaQaSW7RYb1sjm2JbkR66BB7Y"
+ "8YaLZZ79tbQfmzrXiorvOQKkPkDx9qGCRyMluD2kAZ6c5O0X14dc1Bo/RiBHXCpRlJP6tPD1RAF2qwCFtAT3x0/GJyVeAgSfsTvx"
+ "PU6Gv2gFNBtrhnxdhYVTEdDV2w8avJntBdGjO9FQRYhxHXx//RFYeY0CshPQ1lW8TYIxf96KqOWmSGm1TjA7MB8wBwYFKw4DAhoE"
+ "FBBrIxe8fGOgQiTnPTaTYR3QcUwzBBQVujtIjom0GFjf6v9B+43uzBgyLgICB9A="
),
null
);
using var certificateClient = X509CertificateLoader.LoadPkcs12(
Convert.FromBase64String(
"MIIDfwIBAzCCAzsGCSqGSIb3DQEHAaCCAywEggMoMIIDJDCCAW0GCSqGSIb3DQEHAaCCAV4EggFaMIIBVjCCAVIGCyqGSIb3DQEM"
+ "CgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQILlG/36k1fsECAgfQBIGoErtgM6e3Bml4MkwYRvULjwbzguW/VJyCbdk78PcVRVls"
+ "uWVMn6k28gubNFF1mjBw9rZzUD5LYF6mNzVbQMhKbaKDDgzqRf0Gp/rs7oE8s+3Mxa+AJHgdid8ir8FtPcKdQixARRsa/5xgTgS6"
+ "OygWxTDvgfNIToZAIwufEMVkZccm5AYxWsa1mBpU577BYhood7ndlhxf1y77/W+P/8cIrLv3YM7b61uWMXQwEwYJKoZIhvcNAQkV"
+ "MQYEBAEAAAAwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0"
+ "AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAa8GCSqGSIb3DQEHBqCCAaAwggGcAgEAMIIBlQYJKoZIhvcNAQcBMBwGCiqG"
+ "SIb3DQEMAQMwDgQIZj+k/x/0j9QCAgfQgIIBaD7nXwkkq8wWxJAWwqcWmZbpeeGyn2dFr/BgvhW09E6pPtkArJPpcOQjCR8vfMKu"
+ "RtyrkJXHCGhQm/1WhszAKJN7KkKECBWUt++a0h+YkPoaHYyQvy7oZKZ0udD3F3YNAplSB4E05BYF3d3w6PZXuMU/A8t1hLVaP+j6"
+ "2t0q324JvUVmTzQcJ8pOqocSGgUB9T0U5aWj2keJSDM6L4vz3Kkm8YCUEna/QBfp81vVbg6zYXF2BhmRD9Uc/7T9CjoC7aIpRoYT"
+ "Ey8CqxEaMrqq82+f4iSrKY+UmtxCtmVp8SCFcLqz9jTn7aUqwNn9SVRLMMmDSxXaEkRg8NFRPdnepkrF5h2EeIB4Gt+6BzWGbDOV"
+ "Yl8ioGYAS71GKKXNl4snh1woX5AQKVdaM/xohLPd8CiqYE4a8vSP1SSC/s3ttSVKfe3e/ONCV7WxshpYObQW2NAzNH/yi+OdLSY6"
+ "btoeRCkTiF8eulpwNjA7MB8wBwYFKw4DAhoEFL8/AatGW+KGBiEA4LplXG61rBNCBBR7tTmVo7NJZsX91Ysbc4PxyRznUwICB9A="
),
null
);
using var certificateClientLocalhost = X509CertificateLoader.LoadPkcs12(
Convert.FromBase64String(
"MIIDrwIBAzCCA2sGCSqGSIb3DQEHAaCCA1wEggNYMIIDVDCCAW0GCSqGSIb3DQEHAaCCAV4EggFaMIIBVjCCAVIGCyqGSIb3DQEM"
+ "CgECoIHMMIHJMBwGCiqGSIb3DQEMAQMwDgQIKi5n+9Fb2WwCAgfQBIGoEVZtJPlK2py4NO64buCWJiaZkGl1TTkXRUy4yvMTD5GQ"
+ "+v4Qmh3NXF7qtZoElQoA+UexWIyOgkNOdc0q8nPeTwlB9M6WAT8zLltc4u2YJRYABDyqxFHFVMrXyslj1TOogX55GTiXSaVO0D2m"
+ "sARHHI90Qjuf27sxMtBC+1VmpSBEhGZtMO14CHIpz5qRGyigTf/OC7xnpJ95poEKfUh4XdwCbijvot8lMXQwEwYJKoZIhvcNAQkV"
+ "MQYEBAEAAAAwXQYJKwYBBAGCNxEBMVAeTgBNAGkAYwByAG8AcwBvAGYAdAAgAFMAbwBmAHQAdwBhAHIAZQAgAEsAZQB5ACAAUwB0"
+ "AG8AcgBhAGcAZQAgAFAAcgBvAHYAaQBkAGUAcjCCAd8GCSqGSIb3DQEHBqCCAdAwggHMAgEAMIIBxQYJKoZIhvcNAQcBMBwGCiqG"
+ "SIb3DQEMAQMwDgQI3BQzuM21QesCAgfQgIIBmOSvMKdfwj/aVxsahOwtYAUGcpbYCT0SXXEfPy6iLblXBUWHx9Le8xKMpach2lgh"
+ "gcrJ3R2wT8vsREu4l4UT8cqJkl68B3OUhgPfuvso9iVfMgz/To+Sj5i0H4oMGq90cmdqO7bEp0ZOrRu/JNPRqZ1ghVDrnCQYOQ3m"
+ "3gApTnVQaHpDHSY+Nl3ZDy6DnBNZH4NHBqt8KqsKOWwVEtYFfb66Hi9WQBUP3wu8hiNxE+HuYOhdw00Gz1wneYn9xCKqgRKUyOKR"
+ "C0VG7MdWW7RqBK50DvFGGbQcb6ADCUdr8LqtuNqCklfoBd1NG2NOlYzdBQ93w0KMqV5Hd2SyFi+ZEOEjrwYuchk9AxolkVUNbUze"
+ "Y/O8+T30cR022jUi8YliugEhHm0l4huvyjN0M8mQF9dWcq4PxQ/7NUY9CXjXmp5ZLonbavk6iY5nytMaFUnhh3XtRYH6tJLQRZUV"
+ "4p0icUQhWh0g/aTnnSTzSXpOd5td6Mb0khwq+FfGAgrJWGp+LKYTPA6sag5lNpUMqqjYIosnJKQolBS6ADA7MB8wBwYFKw4DAhoE"
+ "FADCiRACrrpEnRFNC09caBMryMWwBBTHIA1DiU5Ni6bAxQ7YglL8CtieBwICB9A="
),
null
);
var builder = WebApplication.CreateEmptyBuilder(new());
builder.WebHost.UseKestrel();
builder
.Services.AddOptions<KestrelServerOptions>()
.Configure(kestrelOptions =>
{
kestrelOptions.ConfigureHttpsDefaults(httpsOptions =>
{
httpsOptions.ClientCertificateMode = ClientCertificateMode.RequireCertificate;
httpsOptions.ServerCertificate = certificateServerLocalhost;
httpsOptions.ClientCertificateValidation = (certificate, chain, errors) =>
{
Console.WriteLine($"{certificate.Subject} -> {errors}");
return true;
};
});
kestrelOptions.ListenLocalhost(
12345,
listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2 | HttpProtocols.Http3;
listenOptions.UseHttps();
}
);
});
builder.Services.AddRouting();
using var app = builder.Build();
app.MapGet("/", (HttpRequest request) => request.Protocol);
await app.StartAsync();
using (
HttpClient httpClient = new(
new SocketsHttpHandler()
{
SslOptions =
{
ClientCertificateContext = SslStreamCertificateContext.Create(
certificateClient,
null,
true
),
RemoteCertificateValidationCallback = (sender, certificate, chain, errors) => true,
},
}
)
)
{
Console.WriteLine(
await (
await httpClient.SendAsync(
new(HttpMethod.Get, "https://localhost:12345")
{
Version = new(2, 0),
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
}
)
).Content.ReadAsStringAsync()
);
Console.WriteLine(
await (
await httpClient.SendAsync(
new(HttpMethod.Get, "https://localhost:12345")
{
Version = new(3, 0),
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
}
)
).Content.ReadAsStringAsync()
);
}
using (
HttpClient httpClient = new(
new SocketsHttpHandler()
{
SslOptions =
{
ClientCertificateContext = SslStreamCertificateContext.Create(
certificateClientLocalhost,
null,
true
),
RemoteCertificateValidationCallback = (sender, certificate, chain, errors) => true,
},
}
)
)
{
Console.WriteLine(
await (
await httpClient.SendAsync(
new(HttpMethod.Get, "https://localhost:12345")
{
Version = new(2, 0),
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
}
)
).Content.ReadAsStringAsync()
);
Console.WriteLine(
await (
await httpClient.SendAsync(
new(HttpMethod.Get, "https://localhost:12345")
{
Version = new(3, 0),
VersionPolicy = HttpVersionPolicy.RequestVersionExact,
}
)
).Content.ReadAsStringAsync()
);
}
await app.StopAsync();
await app.WaitForShutdownAsync();
Output:
CN=Client -> RemoteCertificateChainErrors
HTTP/2
CN=Client -> RemoteCertificateNameMismatch, RemoteCertificateChainErrors
HTTP/3
CN=Client localhost -> RemoteCertificateChainErrors
HTTP/2
CN=Client localhost -> RemoteCertificateChainErrors
HTTP/3
Expected output:
CN=Client -> RemoteCertificateChainErrors
HTTP/2
CN=Client -> RemoteCertificateChainErrors
HTTP/3
CN=Client localhost -> RemoteCertificateChainErrors
HTTP/2
CN=Client localhost -> RemoteCertificateChainErrors
HTTP/3
Exceptions (if any)
No response
.NET Version
9.0.203
Anything else?
.NET SDK:
Version: 9.0.203
Commit: dc7acfa194
Workload version: 9.0.200-manifests.9df47798
MSBuild version: 17.13.20+a4ef1e90f
Runtime Environment:
OS Name: Windows
OS Version: 10.0.26100
OS Platform: Windows
RID: win-x64
Base Path: C:\Program Files\dotnet\sdk\9.0.203\
Host:
Version: 9.0.4
Architecture: x64
Commit: f57e6dc747
.NET SDKs installed:
9.0.203 [C:\Program Files\dotnet\sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 9.0.4 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]