如何在RemoteCertificateValidationCallback委托中构建X509Chain参数?

时间:2014-08-26 11:41:31

标签: c# .net

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-流节目-不同链结果

1 个答案:

答案 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链构建函数构建链。