title: C# - Verify client certificate signed by proper root
body: <p>I know there are a lot of questions on this argument but I'm stuck into this for several days now so here I am.
  I've got a root certificate and a client certificate. I need to replicate in a C# web API project what the command <code>openssl verify -CAfile ca.pem client.pem</code> does.</p>
  
  <p>This is what i know for now (hope it's actually true):</p>
  
  <ul>
  <li><code>Verify()</code> method actually validate that the certificate is signed by an authority. It's like a format control. It doesn't matter which autority signed the certificate. </li>
  <li><code>X509 Chain</code> is the way to go. Add your ca certificate inside an extra store because i'm not going to install the certificate into Windows. Then build passing the client certificate. Let's the magic happens! Unfortunately I've got some problems with the configuration. </li>
  </ul>
  
  <p>Let me be more clear with an example</p>
  
  <pre><code>private bool VerifyCertificate(X509Certificate2 client)
  {
      X509Chain chain = new X509Chain();
      var stringCert = WebConfigurationManager.AppSettings["CACertificate"];
      var byteCert = Encoding.ASCII.GetBytes(stringCert);
      var authority = new X509Certificate2(byteCert);
  
      chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
      chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage;
  
      chain.ChainPolicy.ExtraStore.Add(authority);
  
      // Do the preliminary validation.
      if (!chain.Build(client))
          return false;
  
      return true;
  }
  </code></pre>
  
  <p>With this example the program returns <code>false</code>. The build is not passed. I'm sure the problem is with the <code>ChainPolicy properties</code> so i tried a different configuration</p>
  
  <pre><code>chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
  chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
  chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
  chain.ChainPolicy.VerificationTime = DateTime.Now;
  chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
  </code></pre>
  
  <p>But this one is not going to verify <strong>anything</strong>, in fact using my ca cert the method returns <code>true</code> and using another ca certificate (which i didn't use to signed my client certificate) the method also returns <code>true</code>.</p>
  
  <p>I Searched for an OpenSSL wrapper for C# and i found it but unfortunately is based on old libraries and the repo isn't manteined anymore. Also, i would achieve my goal using just .net framework if possible.</p>
  
  <p>So guys, fast recap. I want to check that only the certificate that is firmed by my ca certificate can pass the validation, all the others must be stopped.</p>
  
  <p>Thanks in advance for any help</p>