How to use certificate callback in SslStream.AuthenticateAsClient method?

前端 未结 3 1682
孤独总比滥情好
孤独总比滥情好 2021-01-14 18:47

My C#.NET SSL connect works when I import the certificate manually in IE (Tools/Internet Options/Content/Certificates), but how can I load the certificate by code? Here is m

3条回答
  •  鱼传尺愫
    2021-01-14 19:06

    To build upon owlstead's answer, here's how I use a single CA certificate and a custom chain in the verification callback to avoid Microsoft's store.

    I have not figured out how to use this chain (chain2 below) by default such that there's no need for the callback. That is, install it on the ssl socket and the connection will "just work". And I have not figured out how install it such that its passed into the callback. That is, I have to build the chain for each invocation of the callback. I think these are architectural defects in .Net, but I might be missing something obvious.

    The name of the function does not matter. Below, VerifyServerCertificate is the same callback as RemoteCertificateValidationCallback. You can also use it for the ServerCertificateValidationCallback in ServicePointManager.

    static bool VerifyServerCertificate(object sender, X509Certificate certificate,
        X509Chain chain, SslPolicyErrors sslPolicyErrors)
    {
        try
        {
            String CA_FILE = "ca-cert.der";
            X509Certificate2 ca = new X509Certificate2(CA_FILE);
    
            X509Chain chain2 = new X509Chain();
            chain2.ChainPolicy.ExtraStore.Add(ca);
    
            // Check all properties
            chain2.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
    
            // This setup does not have revocation information
            chain2.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
    
            // Build the chain
            chain2.Build(new X509Certificate2(certificate));
    
            // Are there any failures from building the chain?
            if (chain2.ChainStatus.Length == 0)
                return true;
    
            // If there is a status, verify the status is NoError
            bool result = chain2.ChainStatus[0].Status == X509ChainStatusFlags.NoError;
            Debug.Assert(result == true);
    
            return result;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    
        return false;
    }
    

提交回复
热议问题