Generated signed X.509 client certificate is invalid (no certificate chain to its CA)

Posted by Genady on Stack Overflow See other posts from Stack Overflow or by Genady
Published on 2011-01-11T16:02:58Z Indexed on 2011/01/14 1:54 UTC
Read the original article Hit count: 780

Filed under:
|
|

I use Bouncy Castle for generation of X.509 client certificates and sing them using a known CA.

First I read the CA certificate from the certificate store, generate the client certificate, sign it using the CA. Validation of the certificate is failed doe to the following issue

A certificate chain could not be built to a trusted root authority.

As I understand this is due to the certificate not being related to the CA.

Here is a code sample:

public static X509Certificate2 GenerateCertificate(X509Certificate2 caCert, string certSubjectName)
{
    // Generate Certificate

    var cerKp = kpgen.GenerateKeyPair();

    var certName = new X509Name(true,certSubjectName); // subjectName = user
    var serialNo = BigInteger.ProbablePrime(120, new Random());

    X509V3CertificateGenerator gen2 = new X509V3CertificateGenerator();
    gen2.SetSerialNumber(serialNo);
    gen2.SetSubjectDN(certName);
    gen2.SetIssuerDN(new X509Name(true,caCert.Subject));
    gen2.SetNotAfter(DateTime.Now.AddDays(100));
    gen2.SetNotBefore(DateTime.Now.Subtract(new TimeSpan(7, 0, 0, 0)));
    gen2.SetSignatureAlgorithm("SHA1WithRSA");
    gen2.SetPublicKey(cerKp.Public);


    AsymmetricCipherKeyPair akp = DotNetUtilities.GetKeyPair(caCert.PrivateKey);
    Org.BouncyCastle.X509.X509Certificate newCert = gen2.Generate(caKp.Private);

    // used for getting a private key
    X509Certificate2 userCert = ConvertToWindows(newCert,cerKp);

    if (caCert22.Verify()) // works well for CA 
    {
        if (userCert.Verify()) // fails for client certificate 
        {
            return userCert;
        }
    }
    return null;

}



private static X509Certificate2 ConvertToWindows(Org.BouncyCastle.X509.X509Certificate newCert, AsymmetricCipherKeyPair kp)
{
    string tempStorePwd = "abcd1234";
    var tempStoreFile = new FileInfo(Path.GetTempFileName());

    try
    {
        // store key 
        {
            var newStore = new Pkcs12Store();

            var certEntry = new X509CertificateEntry(newCert);

            newStore.SetCertificateEntry(
                newCert.SubjectDN.ToString(),
                certEntry
                );

            newStore.SetKeyEntry(
                newCert.SubjectDN.ToString(),
                new AsymmetricKeyEntry(kp.Private),
                new[] { certEntry }
                );
            using (var s = tempStoreFile.Create())
            {
                newStore.Save(
                    s,
                    tempStorePwd.ToCharArray(),
                    new SecureRandom(new CryptoApiRandomGenerator())
                    );
            }
        }

        // reload key 
        return new X509Certificate2(tempStoreFile.FullName, tempStorePwd);
    }
    finally
    {
        tempStoreFile.Delete();
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about x509certificate