blob: aa482357286f76fa3faa4ec78c2cd62f53e32630 [file] [log] [blame]
package org.bouncycastle.cert.crmf;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Integer;
import org.bouncycastle.asn1.ASN1Null;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.DERNull;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.crmf.AttributeTypeAndValue;
import org.bouncycastle.asn1.crmf.CertReqMsg;
import org.bouncycastle.asn1.crmf.CertRequest;
import org.bouncycastle.asn1.crmf.CertTemplate;
import org.bouncycastle.asn1.crmf.CertTemplateBuilder;
import org.bouncycastle.asn1.crmf.OptionalValidity;
import org.bouncycastle.asn1.crmf.POPOPrivKey;
import org.bouncycastle.asn1.crmf.ProofOfPossession;
import org.bouncycastle.asn1.crmf.SubsequentMessage;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.ExtensionsGenerator;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x509.Time;
import org.bouncycastle.cert.CertIOException;
import org.bouncycastle.operator.ContentSigner;
public class CertificateRequestMessageBuilder
{
private final BigInteger certReqId;
private ExtensionsGenerator extGenerator;
private CertTemplateBuilder templateBuilder;
private List controls;
private ContentSigner popSigner;
private PKMACBuilder pkmacBuilder;
private char[] password;
private GeneralName sender;
private POPOPrivKey popoPrivKey;
private ASN1Null popRaVerified;
public CertificateRequestMessageBuilder(BigInteger certReqId)
{
this.certReqId = certReqId;
this.extGenerator = new ExtensionsGenerator();
this.templateBuilder = new CertTemplateBuilder();
this.controls = new ArrayList();
}
public CertificateRequestMessageBuilder setPublicKey(SubjectPublicKeyInfo publicKey)
{
if (publicKey != null)
{
templateBuilder.setPublicKey(publicKey);
}
return this;
}
public CertificateRequestMessageBuilder setIssuer(X500Name issuer)
{
if (issuer != null)
{
templateBuilder.setIssuer(issuer);
}
return this;
}
public CertificateRequestMessageBuilder setSubject(X500Name subject)
{
if (subject != null)
{
templateBuilder.setSubject(subject);
}
return this;
}
public CertificateRequestMessageBuilder setSerialNumber(BigInteger serialNumber)
{
if (serialNumber != null)
{
templateBuilder.setSerialNumber(new ASN1Integer(serialNumber));
}
return this;
}
/**
* Request a validity period for the certificate. Either, but not both, of the date parameters may be null.
*
* @param notBeforeDate not before date for certificate requested.
* @param notAfterDate not after date for the certificate requested.
*
* @return the current builder.
*/
public CertificateRequestMessageBuilder setValidity(Date notBeforeDate, Date notAfterDate)
{
templateBuilder.setValidity(new OptionalValidity(createTime(notBeforeDate), createTime(notAfterDate)));
return this;
}
private Time createTime(Date date)
{
if (date != null)
{
return new Time(date);
}
return null;
}
public CertificateRequestMessageBuilder addExtension(
ASN1ObjectIdentifier oid,
boolean critical,
ASN1Encodable value)
throws CertIOException
{
CRMFUtil.addExtension(extGenerator, oid, critical, value);
return this;
}
public CertificateRequestMessageBuilder addExtension(
ASN1ObjectIdentifier oid,
boolean critical,
byte[] value)
{
extGenerator.addExtension(oid, critical, value);
return this;
}
public CertificateRequestMessageBuilder addControl(Control control)
{
controls.add(control);
return this;
}
public CertificateRequestMessageBuilder setProofOfPossessionSigningKeySigner(ContentSigner popSigner)
{
if (popoPrivKey != null || popRaVerified != null)
{
throw new IllegalStateException("only one proof of possession allowed");
}
this.popSigner = popSigner;
return this;
}
public CertificateRequestMessageBuilder setProofOfPossessionSubsequentMessage(SubsequentMessage msg)
{
if (popSigner != null || popRaVerified != null)
{
throw new IllegalStateException("only one proof of possession allowed");
}
this.popoPrivKey = new POPOPrivKey(msg);
return this;
}
public CertificateRequestMessageBuilder setProofOfPossessionRaVerified()
{
if (popSigner != null || popoPrivKey != null)
{
throw new IllegalStateException("only one proof of possession allowed");
}
this.popRaVerified = DERNull.INSTANCE;
return this;
}
public CertificateRequestMessageBuilder setAuthInfoPKMAC(PKMACBuilder pkmacBuilder, char[] password)
{
this.pkmacBuilder = pkmacBuilder;
this.password = password;
return this;
}
public CertificateRequestMessageBuilder setAuthInfoSender(X500Name sender)
{
return setAuthInfoSender(new GeneralName(sender));
}
public CertificateRequestMessageBuilder setAuthInfoSender(GeneralName sender)
{
this.sender = sender;
return this;
}
public CertificateRequestMessage build()
throws CRMFException
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(certReqId));
if (!extGenerator.isEmpty())
{
templateBuilder.setExtensions(extGenerator.generate());
}
v.add(templateBuilder.build());
if (!controls.isEmpty())
{
ASN1EncodableVector controlV = new ASN1EncodableVector();
for (Iterator it = controls.iterator(); it.hasNext();)
{
Control control = (Control)it.next();
controlV.add(new AttributeTypeAndValue(control.getType(), control.getValue()));
}
v.add(new DERSequence(controlV));
}
CertRequest request = CertRequest.getInstance(new DERSequence(v));
v = new ASN1EncodableVector();
v.add(request);
if (popSigner != null)
{
CertTemplate template = request.getCertTemplate();
if (template.getSubject() == null || template.getPublicKey() == null)
{
SubjectPublicKeyInfo pubKeyInfo = request.getCertTemplate().getPublicKey();
ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(pubKeyInfo);
if (sender != null)
{
builder.setSender(sender);
}
else
{
PKMACValueGenerator pkmacGenerator = new PKMACValueGenerator(pkmacBuilder);
builder.setPublicKeyMac(pkmacGenerator, password);
}
v.add(new ProofOfPossession(builder.build(popSigner)));
}
else
{
ProofOfPossessionSigningKeyBuilder builder = new ProofOfPossessionSigningKeyBuilder(request);
v.add(new ProofOfPossession(builder.build(popSigner)));
}
}
else if (popoPrivKey != null)
{
v.add(new ProofOfPossession(ProofOfPossession.TYPE_KEY_ENCIPHERMENT, popoPrivKey));
}
else if (popRaVerified != null)
{
v.add(new ProofOfPossession());
}
return new CertificateRequestMessage(CertReqMsg.getInstance(new DERSequence(v)));
}
}