CMP Client Support
This page provides some code sample and other information required when creating a CMP client. These code sample are not maintained, and may not be in accordance with future versions of BouncyCastle.
HMAC protected (RA mode) certificate request (initial) message
// Just preparationsfinal BigInteger certReqId = BigInteger.valueOf(1);final byte[] senderNonce = "12345".getBytes();final byte[] transactionId = "23456".getBytes();KeyPairGenerator kpi = KeyPairGenerator.getInstance("RSA");kpi.initialize(1024);KeyPair keyPair = kpi.generateKeyPair();// Now on to the CMP CertificateRequestMessageBuilder msgbuilder = new CertificateRequestMessageBuilder(certReqId);X500Name issuerDN = new X500Name("CN=ManagementCA");X500Name subjectDN = new X500Name("CN=user");msgbuilder.setIssuer(issuerDN);msgbuilder.setSubject(subjectDN);final byte[] bytes = keyPair.getPublic().getEncoded();final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);final ASN1InputStream dIn = new ASN1InputStream(bIn);final SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject());dIn.close();msgbuilder.setPublicKey(keyInfo);GeneralName sender = new GeneralName(subjectDN);msgbuilder.setAuthInfoSender(sender);// RAVerified POPmsgbuilder.setProofOfPossessionRaVerified();CertificateRequestMessage msg = msgbuilder.build();org.bouncycastle.asn1.crmf.CertReqMessages msgs = new org.bouncycastle.asn1.crmf.CertReqMessages(msg.toASN1Structure());org.bouncycastle.asn1.cmp.PKIBody pkibody = new org.bouncycastle.asn1.cmp.PKIBody(org.bouncycastle.asn1.cmp.PKIBody.TYPE_INIT_REQ, msgs);// Message protection and final messageGeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime(new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);// Key Id used (required) by the recipient to do a lot of stuffpbuilder.setSenderKID("KeyID".getBytes());pbuilder.setBody(pkibody);JcePKMACValuesCalculator jcePkmacCalc = new JcePKMACValuesCalculator();final AlgorithmIdentifier digAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); // SHA1final AlgorithmIdentifier macAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.7")); // HMAC/SHA1jcePkmacCalc.setup(digAlg, macAlg);PKMACBuilder macbuilder = new PKMACBuilder(jcePkmacCalc);MacCalculator macCalculator = macbuilder.build("password".toCharArray());ProtectedPKIMessage message = pbuilder.build(macCalculator);HMAC protected (RA mode) revocation request message
// Just preparationsfinal byte[] senderNonce = "12345".getBytes();final byte[] transactionId = "23456".getBytes();BigInteger serNo = new BigInteger("aabbccdd");X500Name issuerDN = new X500Name("CN=ManagementCA");X500Name userDN = new X500Name("CN=user");// Cert template too tell which cert we want to revokeCertTemplateBuilder myCertTemplate = new CertTemplateBuilder();myCertTemplate.setIssuer(issuerDN);myCertTemplate.setSubject(userDN);myCertTemplate.setSerialNumber(new ASN1Integer(serNo));// Extension telling revocation reasonExtensionsGenerator extgen = new ExtensionsGenerator();CRLReason crlReason = CRLReason.lookup(CRLReason.cessationOfOperation);extgen.addExtension(Extension.reasonCode, false, crlReason); Extensions exts = extgen.generate();ASN1EncodableVector v = new ASN1EncodableVector();v.add(myCertTemplate.build());v.add(exts);ASN1Sequence seq = new DERSequence(v);RevDetails myRevDetails = RevDetails.getInstance(seq);RevReqContent myRevReqContent = new RevReqContent(myRevDetails);PKIBody myPKIBody = new PKIBody(PKIBody.TYPE_REVOCATION_REQ, myRevReqContent); // revocation request// Message protection and final messageGeneralName sender = new GeneralName(userDN);GeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime(new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);// Key Id used (required) by the recipient to do a lot of stuffpbuilder.setSenderKID("KeyId".getBytes());pbuilder.setBody(myPKIBody);JcePKMACValuesCalculator jcePkmacCalc = new JcePKMACValuesCalculator();final AlgorithmIdentifier digAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.3.14.3.2.26")); // SHA1final AlgorithmIdentifier macAlg = new AlgorithmIdentifier(new ASN1ObjectIdentifier("1.2.840.113549.2.7")); // HMAC/SHA1jcePkmacCalc.setup(digAlg, macAlg);PKMACBuilder macbuilder = new PKMACBuilder(jcePkmacCalc);MacCalculator macCalculator = macbuilder.build("password".toCharArray());ProtectedPKIMessage message = pbuilder.build(macCalculator);Signature protected (Client mode) message
CertificateRequestMessageBuilder msgbuilder = new CertificateRequestMessageBuilder(BigInteger.valueOf(certReqId));X509NameEntryConverter dnconverter = new X509DefaultEntryConverter();X500Name issuerDN = X500Name.getInstance(new X509Name("CN=ManagementCA").toASN1Object());X500Name subjectDN = X500Name.getInstance(new X509Name("CN=user", dnconverter).toASN1Object());msgbuilder.setIssuer(issuerDN);msgbuilder.setSubject(subjectDN);final byte[] bytes = keyPair.getPublic().getEncoded();final ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);final ASN1InputStream dIn = new ASN1InputStream(bIn);final SubjectPublicKeyInfo keyInfo = new SubjectPublicKeyInfo((ASN1Sequence)dIn.readObject());msgbuilder.setPublicKey(keyInfo);GeneralName sender = new GeneralName(subjectDN);msgbuilder.setAuthInfoSender(sender);Control control = new RegTokenControl("foo123");msgbuilder.addControl(control);Provider prov = Security.getProvider(BouncyCastleProvider.PROVIDER_NAME);ContentSigner popsigner = new JcaContentSignerBuilder("SHA256withRSA").setProvider(prov).build(keyPair.getPrivate());msgbuilder.setProofOfPossessionSigningKeySigner(popsigner);CertificateRequestMessage msg = msgbuilder.build();GeneralName recipient = new GeneralName(issuerDN);ProtectedPKIMessageBuilder pbuilder = new ProtectedPKIMessageBuilder(sender, recipient);pbuilder.setMessageTime(new Date());// senderNoncepbuilder.setSenderNonce(senderNonce);// TransactionIdpbuilder.setTransactionID(transactionId);org.bouncycastle.asn1.crmf.CertReqMessages msgs = new org.bouncycastle.asn1.crmf.CertReqMessages(msg.toASN1Structure());org.bouncycastle.asn1.cmp.PKIBody pkibody = new org.bouncycastle.asn1.cmp.PKIBody(org.bouncycastle.asn1.cmp.PKIBody.TYPE_INIT_REQ, msgs);pbuilder.setBody(pkibody);ContentSigner msgsigner = new JcaContentSignerBuilder("SHA1withRSA").setProvider(prov).build(keyPair.getPrivate());ProtectedPKIMessage message = pbuilder.build(msgsigner);Message with Multiple Signatures
Sample code for a signature protected NestedMessageContent message:
String subjectDN = "CN=bogusSubjectNested";final byte[] nonce = "sendernonce".getBytes();final byte[] transid = "trandis".getBytes();PKIMessage crmfMsg = createCrmfReq();//Signing crmfMsgKeyPair eeKeys = getAdminKeys();Certificate adminCert = getAdminCertificate();ByteArrayInputStream bIn = new ByteArrayInputStream(adminCert.getEncoded());ASN1InputStream dIn = new ASN1InputStream(bIn);ASN1Sequence extraAdminCertSeq = (ASN1Sequence)dIn.readObject();X509CertificateStructure extraCert = new X509CertificateStructure(ASN1Sequence.getInstance(extraAdminCertSeq));crmfMsg.addExtraCert(extraCert);final Signature sig = Signature.getInstance(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(eekeys.getPrivate());sig.update(crmfMsg.getProtectedBytes());byte[] eeSignature = sig.sign();crmfMsg.setProtection(new DERBitString(eeSignature));PKIHeader myPKIHeader = new PKIHeader(new DERInteger(2), new GeneralName(new X509Name(subjectDN)), new GeneralName(new X509Name(((X509Certificate)cacert).getSubjectDN().getName())));myPKIHeader.setMessageTime(new DERGeneralizedTime(new Date()));// senderNoncemyPKIHeader.setSenderNonce(new DEROctetString(nonce));// TransactionIdmyPKIHeader.setTransactionID(new DEROctetString(transid));PKIBody myPKIBody = new PKIBody(crmfMsg, 20); // NestedMessageContentPKIMessage myPKIMessage = new PKIMessage(myPKIHeader, myPKIBody);//Signing myPKIMessageKeyPair raKeys = getRAKeys();final Signature sig = Signature.getInstance(PKCSObjectIdentifiers.sha256WithRSAEncryption.getId(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(rakeys.getPrivate());sig.update(myPKIMessage.getProtectedBytes());byte[] eeSignature = sig.sign();myPKIMessage.setProtection(new DERBitString(eeSignature));final ByteArrayOutputStream bao = new ByteArrayOutputStream();final DEROutputStream out = new DEROutputStream(bao);out.writeObject(myPKIMessage);final byte[] ba = bao.toByteArray();// Send request and receive responsefinal byte[] resp = sendCmpHttp(ba, 200);