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