RemoteCertificateValidationCallback
代理(如下所示)用于验证远程安全套接字层(SSL)证书。 certificate
参数是远程服务器返回的最终实体服务器证书。我不确定的是chain
参数的构造方式。它是从远程服务器返回的证书列表(通常是服务器证书和中间CA证书)构建的,还是转到证书本地存储,并尝试为{{}中返回的最终实体服务器证书构建链。 1}}参数?
certificate
更新
我怀疑它是否使用X509Chain.Build(server_cert),但想知道实际发生了什么。
此人看到了类似的内容:c# Retrieving a Certificate from an SSL stream shows different chain results vs other external tools 一个证书从 - 一个-SSL-流节目-不同链结果
答案 0 :(得分:2)
它是作为TLS handshake:
的一部分从服务器收到的7.4.2。服务器证书
发送此消息时:
服务器必须在约定的情况下发送证书消息 密钥交换方法使用证书进行身份验证 (这包括本文档中定义的所有密钥交换方法 除了DH_anon)。此消息将始终紧随其后 ServerHello消息。
此消息的含义:
此消息将服务器的证书链传达给客户端。
证书必须适用于协商密码 套件的密钥交换算法和任何协商扩展。
此消息的结构:
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链构建函数构建链。