diff options
Diffstat (limited to 'libraries/spongycastle/core/src/main/java/org/spongycastle/asn1/x509/TBSCertList.java')
-rw-r--r-- | libraries/spongycastle/core/src/main/java/org/spongycastle/asn1/x509/TBSCertList.java | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/libraries/spongycastle/core/src/main/java/org/spongycastle/asn1/x509/TBSCertList.java b/libraries/spongycastle/core/src/main/java/org/spongycastle/asn1/x509/TBSCertList.java new file mode 100644 index 000000000..e21c0bd94 --- /dev/null +++ b/libraries/spongycastle/core/src/main/java/org/spongycastle/asn1/x509/TBSCertList.java @@ -0,0 +1,309 @@ +package org.spongycastle.asn1.x509; + +import java.util.Enumeration; + +import org.spongycastle.asn1.ASN1EncodableVector; +import org.spongycastle.asn1.ASN1Integer; +import org.spongycastle.asn1.ASN1Object; +import org.spongycastle.asn1.ASN1Primitive; +import org.spongycastle.asn1.ASN1Sequence; +import org.spongycastle.asn1.ASN1TaggedObject; +import org.spongycastle.asn1.DERGeneralizedTime; +import org.spongycastle.asn1.DERSequence; +import org.spongycastle.asn1.DERTaggedObject; +import org.spongycastle.asn1.DERUTCTime; +import org.spongycastle.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() + { + return null; // TODO: check exception handling + } + } + + 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 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)) + { + revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++)); + } + + if (seqPos < seq.size() + && seq.getObjectAt(seqPos) instanceof DERTaggedObject) + { + 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); + } +} |