Using PKCS10 Certificate Request, any example code (provided Bouncy Castle working code)

+1 vote
asked Mar 11, 2014 by hlogmans (220 points)
edited Nov 10, 2014

Hi all,

after browsing for hours to fix my PKI needs, I did implement most code with Rebex. But I have one last part of Bouncy Castle code that I want to rewrite. I have been searching and trying, but without luck.

This is the code:

        //Requested Certificate Name and things
        X509Name name = new X509Name(String.Format("C={0}, O={1}, L={2}, OU={3},{4} CN={5}",
             Landcode, // C
            Organisatienaam + " (" + Organisatiecode() + ")", // O
            Vestingsplaats + " " + Vestigingsadres + " (" + Vestigingscode() + ")", // L
            ForEncryption ? EncryptieCertSignature : HandtekeningCertSignature, //OU
            String.IsNullOrEmpty(Afdeling) ? "" : "OU=" + Afdeling + ", ", // 2e OU optioneel
            Organisatienaam // CN
            ));


        //Key generation 2048bits
        var rkpg = new RsaKeyPairGenerator();
        rkpg.Init(new KeyGenerationParameters(new SecureRandom(), 2048));
        AsymmetricCipherKeyPair ackp = rkpg.GenerateKeyPair(); //BAPI.EncryptionKey;
        //if (!ForEncryption) ackp = BAPI.SignKey;

        //Key Usage Extension
        var ku = new KeyUsage(ForEncryption ? KeyUsage.KeyEncipherment : KeyUsage.DigitalSignature);
        var extgen = new Org.BouncyCastle.Asn1.X509.X509ExtensionsGenerator();
        extgen.AddExtension(X509Extensions.KeyUsage, true, ku);
        var attribute = new AttributeX509(PkcsObjectIdentifiers.Pkcs9AtExtensionRequest, new DerSet(extgen.Generate()));

        //PKCS #10 Certificate Signing Request
        Pkcs10CertificationRequest csr = new Pkcs10CertificationRequest("SHA1WITHRSA", name, ackp.Public, new DerSet(attribute), ackp.Private); //new DerSet(new DerOctetString(ku))

        var bytedata = csr.GetDerEncoded();

I found a class CertificateRequest, but I cannot set the properties (the are probably based on the provided object in the constructor). I also found :

         var keypair = SshPrivateKey.Generate(SshHostKeyAlgorithm.RSA, 2048);

But I have no clue how to glue everything together.

I have to generate a keypair (RSA, 2048 bits). I have to generate a PKCS#10 request with KeyUsage KeyEncipherment (and for a second certificate DigitalSignature). This request has te be formatted as DER to be sent as attachment to the CA.

I hope someone can help me, thanks in advance.

1 Answer

0 votes
answered Mar 11, 2014 by Lukas Pokorny (100,710 points)
edited Jul 10, 2014
 
Best answer

Update: The new functionality is already present in the current release.

Actually, the CertificationRequest class in the current release only supports parsing existing requests and not creating new ones.

However, this is part of the functionality we plan to enhance and document in one of the upcoming releases (along with actual certificate issuing, which is already supported in the current release), so if you would like to give it a try, get a pre-release build that already supports what you need.

With the new build release 2014 R2 or later, the following code should do the trick:

//Requested Certificate Name and things
var name = new DistinguishedName(String.Format("C={0}, O={1}, L={2}, OU={3},{4} CN={5}",
    Landcode, // C
    Organisatienaam + " (" + Organisatiecode() + ")", // O
    Vestingsplaats + " " + Vestigingsadres + " (" + Vestigingscode() + ")", // L
    ForEncryption ? EncryptieCertSignature : HandtekeningCertSignature, //OU
    String.IsNullOrEmpty(Afdeling) ? "" : "OU=" + Afdeling + ", ", // 2e OU optioneel
    Organisatienaam // CN
    ));

//Key generation 2048bits
PrivateKeyInfo privateKey = PrivateKeyInfo.Generate(KeyAlgorithm.RSA, 2048);
PublicKeyInfo publicKey = privateKey.GetPublicKey();

//PKCS #10 Certificate Request
var csr = new CertificationRequest(name, publicKey);

//Key Usage Extension
csr.CertificateExtensions.Add(CertificateExtension.KeyUsage(ForEncryption ? KeyUses.KeyEncipherment : KeyUses.DigitalSignature));

//Sign the request
csr.Sign(privateKey, SignatureHashAlgorithm.SHA1);

var bytedata = csr.Encode();

(Please let me know if you already purchased a Rebex product to get a non-trial version of the DLLs.)

commented Mar 12, 2014 by hlogmans (220 points)
edited Mar 12, 2014

Thanks, Lukas. This works and the request has been confirmed by the CSR test facilities. You might even know that I built this using SecureBlackBox, Chilkat and BouncyCastle, and this is by far the most straightforward and readable code. Thanks for your help, your tool does do the job well (the current state of documentation is something you have to work on, but I know this is a lot of work)

commented Mar 27, 2014 by hlogmans (220 points)
edited Jul 10, 2014

Hi Lukas,

I purchased the product an hour ago, but in the provided download these options are not included yet. Can I get an update to the registered binaries where this is included?

commented Mar 27, 2014 by Lukas Pokorny (100,710 points)
edited Mar 27, 2014

Hi, thanks for your purchase! I just sent the link to your e-mail addresses.

commented Mar 27, 2014 by hlogmans (220 points)
edited Mar 27, 2014

Thanks, received it. Super service!

commented Jul 10, 2014 by Lukas Pokorny (100,710 points)
edited Jul 10, 2014

Update: The new functionality has been released as part of 2014 R2 release.

...