package org.bouncycastle.asn1.x509; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1TaggedObject; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; /** * PKIX RFC-2459 - TBSCertList object. * <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> */ public class TBSCertList extends ASN1Encodable { public class CRLEntry extends ASN1Encodable { ASN1Sequence seq; DERInteger userCertificate; Time revocationDate; X509Extensions crlEntryExtensions; public CRLEntry( ASN1Sequence seq) { if (seq.size() < 2 || seq.size() > 3) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } this.seq = seq; userCertificate = DERInteger.getInstance(seq.getObjectAt(0)); revocationDate = Time.getInstance(seq.getObjectAt(1)); if (seq.size() == 3) { crlEntryExtensions = X509Extensions.getInstance(seq.getObjectAt(2)); } } public DERInteger getUserCertificate() { return userCertificate; } public Time getRevocationDate() { return revocationDate; } public X509Extensions getExtensions() { return crlEntryExtensions; } public DERObject toASN1Object() { return seq; } } ASN1Sequence seq; DERInteger version; AlgorithmIdentifier signature; X509Name issuer; Time thisUpdate; Time nextUpdate; CRLEntry[] revokedCertificates; X509Extensions crlExtensions; public static TBSCertList getInstance( ASN1TaggedObject obj, boolean explicit) { return getInstance(ASN1Sequence.getInstance(obj, explicit)); } public static TBSCertList getInstance( Object obj) { if (obj instanceof TBSCertList) { return (TBSCertList)obj; } else if (obj instanceof ASN1Sequence) { return new TBSCertList((ASN1Sequence)obj); } throw new IllegalArgumentException("unknown object in factory"); } public TBSCertList( ASN1Sequence seq) { if (seq.size() < 3 || seq.size() > 7) { throw new IllegalArgumentException("Bad sequence size: " + seq.size()); } int seqPos = 0; this.seq = seq; if (seq.getObjectAt(seqPos) instanceof DERInteger) { version = DERInteger.getInstance(seq.getObjectAt(seqPos++)); } else { version = new DERInteger(0); } signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++)); issuer = X509Name.getInstance(seq.getObjectAt(seqPos++)); thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); if (seqPos < seq.size() && (seq.getObjectAt(seqPos) instanceof DERUTCTime || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime || seq.getObjectAt(seqPos) instanceof Time)) { nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); } if (seqPos < seq.size() && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject)) { ASN1Sequence certs = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++)); revokedCertificates = new CRLEntry[certs.size()]; for (int i = 0; i < revokedCertificates.length; i++) { revokedCertificates[i] = new CRLEntry(ASN1Sequence.getInstance(certs.getObjectAt(i))); } } if (seqPos < seq.size() && seq.getObjectAt(seqPos) instanceof DERTaggedObject) { crlExtensions = X509Extensions.getInstance(seq.getObjectAt(seqPos++)); } } public int getVersion() { return version.getValue().intValue() + 1; } public DERInteger getVersionNumber() { return version; } public AlgorithmIdentifier getSignature() { return signature; } public X509Name getIssuer() { return issuer; } public Time getThisUpdate() { return thisUpdate; } public Time getNextUpdate() { return nextUpdate; } public CRLEntry[] getRevokedCertificates() { return revokedCertificates; } public X509Extensions getExtensions() { return crlExtensions; } public DERObject toASN1Object() { return seq; } }