package org.bouncycastle.asn1.x509;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DEROutputStream;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.DERUTCTime;
/**
* Generator for Version 2 TBSCertList structures.
* <pre>
* TBSCertList ::= SEQUENCE {
* version Version OPTIONAL,
* -- if present, shall be v2
* signature AlgorithmIdentifier,
* issuer Name,
* thisUpdate Time,
* nextUpdate Time OPTIONAL,
* revokedCertificates SEQUENCE OF SEQUENCE {
* userCertificate CertificateSerialNumber,
* revocationDate Time,
* crlEntryExtensions Extensions OPTIONAL
* -- if present, shall be v2
* } OPTIONAL,
* crlExtensions [0] EXPLICIT Extensions OPTIONAL
* -- if present, shall be v2
* }
* </pre>
*
* <b>Note: This class may be subject to change</b>
*/
public class V2TBSCertListGenerator
{
DERInteger version = new DERInteger(1);
AlgorithmIdentifier signature;
X509Name issuer;
Time thisUpdate, nextUpdate=null;
X509Extensions extensions=null;
private Vector crlentries=null;
public V2TBSCertListGenerator()
{
}
public void setSignature(
AlgorithmIdentifier signature)
{
this.signature = signature;
}
public void setIssuer(
X509Name issuer)
{
this.issuer = issuer;
}
public void setThisUpdate(
DERUTCTime thisUpdate)
{
this.thisUpdate = new Time(thisUpdate);
}
public void setNextUpdate(
DERUTCTime nextUpdate)
{
this.nextUpdate = new Time(nextUpdate);
}
public void setThisUpdate(
Time thisUpdate)
{
this.thisUpdate = thisUpdate;
}
public void setNextUpdate(
Time nextUpdate)
{
this.nextUpdate = nextUpdate;
}
public void addCRLEntry(
ASN1Sequence crlEntry)
{
if (crlentries == null)
crlentries = new Vector();
crlentries.addElement(crlEntry);
}
public void addCRLEntry(DERInteger userCertificate, DERUTCTime revocationDate, int reason)
{
addCRLEntry(userCertificate, new Time(revocationDate), reason);
}
public void addCRLEntry(DERInteger userCertificate, Time revocationDate, int reason)
{
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(userCertificate);
v.add(revocationDate);
if (reason != 0)
{
CRLReason rf = new CRLReason(reason);
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
try
{
dOut.writeObject(rf);
}
catch (IOException e)
{
throw new IllegalArgumentException("error encoding value: " + e);
}
byte[] value = bOut.toByteArray();
ASN1EncodableVector v1 = new ASN1EncodableVector();
v1.add(X509Extensions.ReasonCode);
v1.add(new DEROctetString(value));
X509Extensions ex = new X509Extensions(new DERSequence(
new DERSequence(v1)));
v.add(ex);
}
if (crlentries == null)
{
crlentries = new Vector();
}
crlentries.addElement(new DERSequence(v));
}
public void setExtensions(
X509Extensions extensions)
{
this.extensions = extensions;
}
public TBSCertList generateTBSCertList()
{
if ((signature == null) || (issuer == null) || (thisUpdate == null))
{
throw new IllegalStateException("Not all mandatory fields set in V2 TBSCertList generator.");
}
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(version);
v.add(signature);
v.add(issuer);
v.add(thisUpdate);
if (nextUpdate != null)
{
v.add(nextUpdate);
}
// Add CRLEntries if they exist
if (crlentries != null)
{
ASN1EncodableVector certs = new ASN1EncodableVector();
Enumeration it = crlentries.elements();
while( it.hasMoreElements() )
{
certs.add((ASN1Sequence)it.nextElement());
}
v.add(new DERSequence(certs));
}
if (extensions != null)
{
v.add(new DERTaggedObject(0, extensions));
}
return new TBSCertList(new DERSequence(v));
}
}