[英]How to trust a self-signed certificate with System.Net.Quic?
我正在使用.Net 7 preview 7 和新的 System.Net.Quic 库进行一些测试。 我有以下客户端代码:
public static class Program
{
public static async Task Main(string[] args)
{
var serverCert = LoadCert();
var x509policy = new X509ChainPolicy();
// None of the following x509policy lines seem to have any effect
x509policy.TrustMode = X509ChainTrustMode.CustomRootTrust;
x509policy.CustomTrustStore.Add(serverCert);
x509policy.ExtraStore.Add(serverCert);
x509policy.VerificationFlags
= X509VerificationFlags.AllowUnknownCertificateAuthority;
var sslAuthOptions = new SslClientAuthenticationOptions
{
AllowRenegotiation = true,
ApplicationProtocols = new() { SslApplicationProtocol.Http3 },
EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
EncryptionPolicy = EncryptionPolicy.RequireEncryption,
CertificateChainPolicy = x509policy,
RemoteCertificateValidationCallback = ProcessCertificate,
};
var conectionOptions = new QuicClientConnectionOptions
{
ClientAuthenticationOptions = sslAuthOptions,
RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, 15001),
};
var conn = await QuicConnection.ConnectAsync(conectionOptions);
Console.WriteLine(conn.RemoteEndPoint);
// more code here that verifies that data transfer works
}
private static X509Certificate2 LoadCert()
{
var directory = Path
.GetDirectoryName(typeof(Program).Assembly.Location)
?? throw new ArgumentNullException("Assembly.Location");
using var rawCertificate = X509Certificate2
.CreateFromPemFile(Path.Combine(directory, "certificate.pem"));
return new X509Certificate2(
rawCertificate.Export(X509ContentType.Pkcs12));
}
private static bool ProcessCertificate(
object sender,
X509Certificate? certificate,
X509Chain? chain,
SslPolicyErrors sslPolicyErrors)
{
if (chain?.ChainStatus?.Length > 0)
{
var errs = string.Join(
Environment.NewLine,
chain!.ChainStatus
.Select(x => $"[{x.Status}] {x.StatusInformation}"));
Console.WriteLine(errs);
}
return true;
}
}
certifcate.pem
是一个自签名的,由我生成的证书。 上面的代码有效,这意味着我可以连接到服务器(也是我编写的)。 但是ProcessCertificate
回调会打印以下错误:
[UntrustedRoot] A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.
请注意,如果没有如上所述设置RemoteCertificateValidationCallback
,客户端将无法建立连接。
为什么我会收到此错误? 我将证书添加到X509ChainPolicy
。 我已经手动验证了服务器返回的是完全相同的证书。 我在这里做错了什么? System.Net.Quic
是否可能不尊重X509ChainPolicy
并且我必须在RemoteCertificateValidationCallback
中手动进行证书验证?
我可能可以通过将证书添加到系统范围的受信任存储来使其工作。 我仍然想知道如何在没有它的情况下做到这一点。
编辑:我已经验证了chain.ChainPolicy
中的x509policy
我刚刚创建和设置的RemoteCertificateValidationCallback
不同。 是System.Net.Quic
错误还是我错过了什么?
好的,在挖掘和阅读源代码后,我发现了这个提交:
https://github.com/dotnet/runtime/commit/1f0582e1ee1e6bf05df41aa4cf0d246584c280c8
它为 Quic 添加了X509ChainPolicy
支持。 该更改是最近发生的(2022 年 8 月 4 日),尚未出现在 .Net 7 预览版 7 中(尽管它已于 2022 年 8 月 7 日发布)。 我想我们将不得不等待下一个版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.