org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of bcpkix-jdk15to18 Show documentation
Show all versions of bcpkix-jdk15to18 Show documentation
The Bouncy Castle Java APIs for CMS, PKCS, EAC, TSP, CMP, CRMF, OCSP, and certificate generation. This jar contains APIs for JDK 1.5 to JDK 1.8. The APIs can be used in conjunction with a JCE/JCA provider such as the one provided with the Bouncy Castle Cryptography APIs.
package org.bouncycastle.pkcs;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERBitString;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.pkcs.Attribute;
import org.bouncycastle.asn1.pkcs.CertificationRequest;
import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.operator.ContentSigner;
/**
* A class for creating PKCS#10 Certification requests.
*
* CertificationRequest ::= SEQUENCE {
* certificationRequestInfo CertificationRequestInfo,
* signatureAlgorithm AlgorithmIdentifier{{ SignatureAlgorithms }},
* signature BIT STRING
* }
*
* CertificationRequestInfo ::= SEQUENCE {
* version INTEGER { v1(0) } (v1,...),
* subject Name,
* subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }},
* attributes [0] Attributes{{ CRIAttributes }}
* }
*
* Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }}
*
* Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE {
* type ATTRIBUTE.&id({IOSet}),
* values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{\@type})
* }
*
*/
public class PKCS10CertificationRequestBuilder
{
private SubjectPublicKeyInfo publicKeyInfo;
private X500Name subject;
private List attributes = new ArrayList();
private boolean leaveOffEmpty = false;
public PKCS10CertificationRequestBuilder(PKCS10CertificationRequestBuilder original)
{
this.publicKeyInfo = original.publicKeyInfo;
this.subject = original.subject;
this.leaveOffEmpty = original.leaveOffEmpty;
this.attributes = new ArrayList(original.attributes);
}
/**
* Basic constructor.
*
* @param subject the X.500 Name defining the certificate subject this request is for.
* @param publicKeyInfo the info structure for the public key to be associated with this subject.
*/
public PKCS10CertificationRequestBuilder(X500Name subject, SubjectPublicKeyInfo publicKeyInfo)
{
this.subject = subject;
this.publicKeyInfo = publicKeyInfo;
}
/**
* Set an attribute to the certification request we are building.
* Removed existing attributes with the same attrType.
*
* @param attrType the OID giving the type of the attribute.
* @param attrValue the ASN.1 structure that forms the value of the attribute.
* @return this builder object.
*/
public PKCS10CertificationRequestBuilder setAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue)
{
// Remove existing copies of the attribute.
for (Iterator it = attributes.iterator(); it.hasNext(); )
{
if (((Attribute)it.next()).getAttrType().equals(attrType))
{
throw new IllegalStateException("Attribute " + attrType.toString() + " is already set");
}
}
addAttribute(attrType, attrValue);
return this;
}
/**
* Add an attribute with multiple values to the certification request we are building.
* Removed existing attributes with the same attrType.
*
* @param attrType the OID giving the type of the attribute.
* @param attrValue the ASN.1 structure that forms the value of the attribute.
* @return this builder object.
*/
public PKCS10CertificationRequestBuilder setAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable[] attrValue)
{
// Remove existing copies of the attribute.
for (Iterator it = attributes.iterator(); it.hasNext(); )
{
if (((Attribute)it.next()).getAttrType().equals(attrType))
{
throw new IllegalStateException("Attribute " + attrType.toString() + " is already set");
}
}
addAttribute(attrType, attrValue);
return this;
}
/**
* Add an attribute to the certification request we are building.
*
* @param attrType the OID giving the type of the attribute.
* @param attrValue the ASN.1 structure that forms the value of the attribute.
* @return this builder object.
*/
public PKCS10CertificationRequestBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable attrValue)
{
attributes.add(new Attribute(attrType, new DERSet(attrValue)));
return this;
}
/**
* Add an attribute with multiple values to the certification request we are building.
*
* @param attrType the OID giving the type of the attribute.
* @param attrValues an array of ASN.1 structures that form the value of the attribute.
* @return this builder object.
*/
public PKCS10CertificationRequestBuilder addAttribute(ASN1ObjectIdentifier attrType, ASN1Encodable[] attrValues)
{
attributes.add(new Attribute(attrType, new DERSet(attrValues)));
return this;
}
/**
* The attributes field in PKCS10 should encoded to an empty tagged set if there are
* no attributes. Some CAs will reject requests with the attribute field present.
*
* @param leaveOffEmpty true if empty attributes should be left out of the encoding false otherwise.
* @return this builder object.
*/
public PKCS10CertificationRequestBuilder setLeaveOffEmptyAttributes(boolean leaveOffEmpty)
{
this.leaveOffEmpty = leaveOffEmpty;
return this;
}
/**
* Generate an PKCS#10 request based on the past in signer.
*
* @param signer the content signer to be used to generate the signature validating the certificate.
* @return a holder containing the resulting PKCS#10 certification request.
*/
public PKCS10CertificationRequest build(
ContentSigner signer)
{
CertificationRequestInfo info;
if (attributes.isEmpty())
{
if (leaveOffEmpty)
{
info = new CertificationRequestInfo(subject, publicKeyInfo, null);
}
else
{
info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet());
}
}
else
{
ASN1EncodableVector v = new ASN1EncodableVector();
for (Iterator it = attributes.iterator(); it.hasNext(); )
{
v.add(Attribute.getInstance(it.next()));
}
info = new CertificationRequestInfo(subject, publicKeyInfo, new DERSet(v));
}
try
{
OutputStream sOut = signer.getOutputStream();
sOut.write(info.getEncoded(ASN1Encoding.DER));
sOut.close();
return new PKCS10CertificationRequest(new CertificationRequest(info, signer.getAlgorithmIdentifier(), new DERBitString(signer.getSignature())));
}
catch (IOException e)
{
throw new IllegalStateException("cannot produce certification request signature");
}
}
}