| package org.bouncycastle.asn1.x509; |
| |
| import java.util.Enumeration; |
| import java.util.NoSuchElementException; |
| |
| import org.bouncycastle.asn1.ASN1EncodableVector; |
| import org.bouncycastle.asn1.ASN1GeneralizedTime; |
| import org.bouncycastle.asn1.ASN1Integer; |
| import org.bouncycastle.asn1.ASN1Object; |
| import org.bouncycastle.asn1.ASN1Primitive; |
| import org.bouncycastle.asn1.ASN1Sequence; |
| import org.bouncycastle.asn1.ASN1TaggedObject; |
| import org.bouncycastle.asn1.ASN1UTCTime; |
| import org.bouncycastle.asn1.DERSequence; |
| import org.bouncycastle.asn1.DERTaggedObject; |
| import org.bouncycastle.asn1.x500.X500Name; |
| |
| /** |
| * 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 ASN1Object |
| { |
| public static class CRLEntry |
| extends ASN1Object |
| { |
| ASN1Sequence seq; |
| |
| Extensions crlEntryExtensions; |
| |
| private CRLEntry( |
| ASN1Sequence seq) |
| { |
| if (seq.size() < 2 || seq.size() > 3) |
| { |
| throw new IllegalArgumentException("Bad sequence size: " + seq.size()); |
| } |
| |
| this.seq = seq; |
| } |
| |
| public static CRLEntry getInstance(Object o) |
| { |
| if (o instanceof CRLEntry) |
| { |
| return ((CRLEntry)o); |
| } |
| else if (o != null) |
| { |
| return new CRLEntry(ASN1Sequence.getInstance(o)); |
| } |
| |
| return null; |
| } |
| |
| public ASN1Integer getUserCertificate() |
| { |
| return ASN1Integer.getInstance(seq.getObjectAt(0)); |
| } |
| |
| public Time getRevocationDate() |
| { |
| return Time.getInstance(seq.getObjectAt(1)); |
| } |
| |
| public Extensions getExtensions() |
| { |
| if (crlEntryExtensions == null && seq.size() == 3) |
| { |
| crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2)); |
| } |
| |
| return crlEntryExtensions; |
| } |
| |
| public ASN1Primitive toASN1Primitive() |
| { |
| return seq; |
| } |
| |
| public boolean hasExtensions() |
| { |
| return seq.size() == 3; |
| } |
| } |
| |
| private class RevokedCertificatesEnumeration |
| implements Enumeration |
| { |
| private final Enumeration en; |
| |
| RevokedCertificatesEnumeration(Enumeration en) |
| { |
| this.en = en; |
| } |
| |
| public boolean hasMoreElements() |
| { |
| return en.hasMoreElements(); |
| } |
| |
| public Object nextElement() |
| { |
| return CRLEntry.getInstance(en.nextElement()); |
| } |
| } |
| |
| private class EmptyEnumeration |
| implements Enumeration |
| { |
| public boolean hasMoreElements() |
| { |
| return false; |
| } |
| |
| public Object nextElement() |
| { |
| throw new NoSuchElementException("Empty Enumeration"); |
| } |
| } |
| |
| ASN1Integer version; |
| AlgorithmIdentifier signature; |
| X500Name issuer; |
| Time thisUpdate; |
| Time nextUpdate; |
| ASN1Sequence revokedCertificates; |
| Extensions 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 != null) |
| { |
| return new TBSCertList(ASN1Sequence.getInstance(obj)); |
| } |
| |
| return null; |
| } |
| |
| public TBSCertList( |
| ASN1Sequence seq) |
| { |
| if (seq.size() < 3 || seq.size() > 7) |
| { |
| throw new IllegalArgumentException("Bad sequence size: " + seq.size()); |
| } |
| |
| int seqPos = 0; |
| |
| if (seq.getObjectAt(seqPos) instanceof ASN1Integer) |
| { |
| version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++)); |
| } |
| else |
| { |
| version = null; // version is optional |
| } |
| |
| signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++)); |
| issuer = X500Name.getInstance(seq.getObjectAt(seqPos++)); |
| thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); |
| |
| if (seqPos < seq.size() |
| && (seq.getObjectAt(seqPos) instanceof ASN1UTCTime |
| || seq.getObjectAt(seqPos) instanceof ASN1GeneralizedTime |
| || seq.getObjectAt(seqPos) instanceof Time)) |
| { |
| nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++)); |
| } |
| |
| if (seqPos < seq.size() |
| && !(seq.getObjectAt(seqPos) instanceof ASN1TaggedObject)) |
| { |
| revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++)); |
| } |
| |
| if (seqPos < seq.size() |
| && seq.getObjectAt(seqPos) instanceof ASN1TaggedObject) |
| { |
| crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true)); |
| } |
| } |
| |
| public int getVersionNumber() |
| { |
| if (version == null) |
| { |
| return 1; |
| } |
| return version.getValue().intValue() + 1; |
| } |
| |
| public ASN1Integer getVersion() |
| { |
| return version; |
| } |
| |
| public AlgorithmIdentifier getSignature() |
| { |
| return signature; |
| } |
| |
| public X500Name getIssuer() |
| { |
| return issuer; |
| } |
| |
| public Time getThisUpdate() |
| { |
| return thisUpdate; |
| } |
| |
| public Time getNextUpdate() |
| { |
| return nextUpdate; |
| } |
| |
| public CRLEntry[] getRevokedCertificates() |
| { |
| if (revokedCertificates == null) |
| { |
| return new CRLEntry[0]; |
| } |
| |
| CRLEntry[] entries = new CRLEntry[revokedCertificates.size()]; |
| |
| for (int i = 0; i < entries.length; i++) |
| { |
| entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i)); |
| } |
| |
| return entries; |
| } |
| |
| public Enumeration getRevokedCertificateEnumeration() |
| { |
| if (revokedCertificates == null) |
| { |
| return new EmptyEnumeration(); |
| } |
| |
| return new RevokedCertificatesEnumeration(revokedCertificates.getObjects()); |
| } |
| |
| public Extensions getExtensions() |
| { |
| return crlExtensions; |
| } |
| |
| public ASN1Primitive toASN1Primitive() |
| { |
| ASN1EncodableVector v = new ASN1EncodableVector(); |
| |
| if (version != null) |
| { |
| v.add(version); |
| } |
| v.add(signature); |
| v.add(issuer); |
| |
| v.add(thisUpdate); |
| if (nextUpdate != null) |
| { |
| v.add(nextUpdate); |
| } |
| |
| // Add CRLEntries if they exist |
| if (revokedCertificates != null) |
| { |
| v.add(revokedCertificates); |
| } |
| |
| if (crlExtensions != null) |
| { |
| v.add(new DERTaggedObject(0, crlExtensions)); |
| } |
| |
| return new DERSequence(v); |
| } |
| } |