繁体   English   中英

如何使用 System.Net.Quic 信任自签名证书?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM