簡體   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