X509Chain参数是如何在RemoteCertificateValidationCallback Delegate中
本文关键字:RemoteCertificateValidationCallback Delegate 参数 X509Chain | 更新日期: 2023-09-27 18:19:30
下面显示的RemoteCertificateValidationCallback
委派用于验证远程安全套接字层(SSL)证书。certificate
参数是远程服务器返回的最终实体服务器证书。我不确定的是chain
参数是如何构造的。它是根据远程服务器返回的证书列表(通常是服务器证书和中间CA证书)构建的,还是转到证书本地存储并尝试为certificate
参数中返回的最终实体服务器证书构建链?
// The following method is invoked by the RemoteCertificateValidationDelegate.
public static bool ValidateServerCertificate(
object sender,
X509Certificate certificate,
X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
...
}
更新
我怀疑它在使用X509Chain.Build(server_cert),但我想知道到底发生了什么。
这个人看到了类似的东西:c#从SSL流中检索证书与其他外部工具相比显示了不同的链结果a-certificate-from-an-ssl-stream-shows-different-chain-result
它是作为TLS握手的一部分从服务器接收的:
7.4.2.服务器证书
何时发送此消息:
只要同意,服务器必须发送证书消息-密钥交换方法使用证书进行身份验证(这包括本文件中定义的所有密钥交换方法DH_anon除外)。此消息将始终紧跟在服务器Hello消息。
此消息的含义:
此消息将服务器的证书链传递给客户端。
证书必须适用于协商的密码套件的密钥交换算法和任何协商的扩展。
此消息的结构:
opaque ASN.1Cert<1..2^24-1>; struct { ASN.1Cert certificate_list<0..2^24-1>; } Certificate;
certificate_list
这是一个证书序列(链)。发件人的证书必须排在列表的第一位。以下各项证书必须直接证明其前面的证书。因为证书验证要求分发根密钥独立地,指定根的自签名证书证书颁发机构可以从链中省略,在假设远端必须已经拥有它在任何情况下都要验证它。
好吧,根据X509Chain.BuildChain()
,它使用CAPI CertGetCertificateChain
,这意味着从本地证书存储中获取,从给定的证书中构建。您可以看到验证回调是如何在TransportSecurityHelpers.cs
中调用的。链构建在_SecureChannel.VerifyRemoteCertificate
:中
chain = new X509Chain();
chain.ChainPolicy.RevocationMode = m_CheckCertRevocation? X509RevocationMode.Online : X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
if (remoteCertificateStore != null)
chain.ChainPolicy.ExtraStore.AddRange(remoteCertificateStore);
if (!chain.Build(remoteCertificateEx) // Build failed on handle or on policy
&& chain.ChainContext == IntPtr.Zero) // Build failed to generate a valid handle
{
throw new CryptographicException(Marshal.GetLastWin32Error());
}
因此,看起来.Net从SSL上下文中获取服务器证书,并使用CAPI链构建函数构建链。