none
Validating an X509 Certificate

    Question

  • Hi,

    Could somebody help me on how to validate an X509 certificate? I know that there are 2 techniques to accomplish this, CRL's and OSCP, but I don't know how to use them in C#.NET.

    At the moment i got following code:

    Code Snippet

    X509Certificate2 CertToVerify = GetCertificate();

    X509Chain chain = new X509Chain();
    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EndCertificateOnly;
    chain.ChainPolicy.RevocationMode = X509RevocationMode.Offline; //  X509RevocationMode.Offline;
    chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 30);
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
    chain.Build(CertToVerify);

    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < chain.ChainStatus.Length; i++)
    {
        sb.AppendLine(chain.ChainStatus[i].Status.ToString() + " -> " + chain.ChainStatus[0].StatusInformation);

    }

    MessageBox.Show(sb.ToString(), "Status");


    When i run this code, i get errors like "UntrustedRoot -> Unknown Error", "UnknownRevocationStatus -> Unknown  Error" and "OfflineRevocation -> Unknown Error", so I conclude that some information regarding the certificate's status is missing.

    One option is to get it from local CRL files, another to go online and use the OCSP protocol. Can someone tell me how this is done using .NET?

    The X509Certificate2-object has a Verify()-method that can be used to validate a certificate, and returns a bool with the validation result. In some cases, when I get errors like those mentioned above using my code, I get "True" using that method. So could someone explain to me the difference between my code and the verify()-method?

    A last remark: When viewing the details of a certificate in Windows,  the certificate chain is evaluated and validated aswell (I guess this is the work of the windows CryptoAPI), so there must be some sort of CRL available on the system.

    If somebody has some experience in this domain, any help is more than welcome

    Thx in advance,
    Greetz


    Friday, February 15, 2008 1:36 PM

All replies

  • Your RevocationFlag, RevocationMode and VerficationFlags are difrent than what X509Certificate2.Verify() uses.

    Here is the code I use to validate a certificate.  These are the same settings used in X509Certificate2.Verify()

     

    Code Snippet

    bool chainIsValid = false;

    var chain = new X509Chain();

    chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;

    chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;

    chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 1, 0);

    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;

    chainIsValid = chain.Build(certificate);

     

     

    The advantage of using X509Chain over X509Certificate2.Verify() is you get access to the X509Chain.ChainStatus.

    Both X509Certificate2.Verify() & X509Chain.Build() use crypt32 CertVerifyCertificateChainPolicy() to verify the chain.
    Use Reflector to look at the code for both X509Certificate2.Verify() & X509Chain.Build()

     

    Later
    ES

    Tuesday, February 19, 2008 7:40 PM
  • Thx for the information! Using reflector was actually a very good hint I hadn't though about before.

    I have been trying out my code, your code and multiple combinations, using valid certificates, but I keep on getting following X509ChainStatusFlag: "RevocationStatusUnknown -> Unknown error." MSDN states following explanation for this flag:

    "Specifies that it is not possible to determine whether the certificate has been revoked. This can be due to the certificate revocation list (CRL) being offline or unavailable."

    Ok, now that is what I expected, but there is no info on how to find that CRL. Both X509RevocationMode.Online and Offline give the same result...

    Does anyone have an idea on how to find the appropriate CRL's or how to use OCSP while verifying a certificate?

    Grtz,
    Wednesday, February 27, 2008 2:22 PM