TBSCertList.java revision e6bf3e8dfa2804891a82075cb469b736321b4827
19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpackage org.bouncycastle.asn1.x509;
29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport java.util.Enumeration;
49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1EncodableVector;
69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Integer;
79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Object;
89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Primitive;
99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1Sequence;
109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.ASN1TaggedObject;
119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERGeneralizedTime;
129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERSequence;
139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERTaggedObject;
149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.DERUTCTime;
159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallimport org.bouncycastle.asn1.x500.X500Name;
169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/**
189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * PKIX RFC-2459 - TBSCertList object.
199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * <pre>
209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * TBSCertList  ::=  SEQUENCE  {
219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      version                 Version OPTIONAL,
229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *                                   -- if present, shall be v2
239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      signature               AlgorithmIdentifier,
249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      issuer                  Name,
259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      thisUpdate              Time,
269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      nextUpdate              Time OPTIONAL,
279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      revokedCertificates     SEQUENCE OF SEQUENCE  {
289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *           userCertificate         CertificateSerialNumber,
299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *           revocationDate          Time,
309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *           crlEntryExtensions      Extensions OPTIONAL
319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *                                         -- if present, shall be v2
329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *                                }  OPTIONAL,
339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *                                         -- if present, shall be v2
359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall *                                }
369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * </pre>
379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */
389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallpublic class TBSCertList
399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    extends ASN1Object
409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{
419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    public static class CRLEntry
429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        extends ASN1Object
439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall    {
449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        ASN1Sequence  seq;
459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        Extensions    crlEntryExtensions;
479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        private CRLEntry(
499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            ASN1Sequence  seq)
509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        {
519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            if (seq.size() < 2 || seq.size() > 3)
529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            {
539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                throw new IllegalArgumentException("Bad sequence size: " + seq.size());
549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            }
559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            this.seq = seq;
579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        public static CRLEntry getInstance(Object o)
609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        {
619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            if (o instanceof CRLEntry)
629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            {
639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                return ((CRLEntry)o);
649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            }
659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            else if (o != null)
669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            {
679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall                return new CRLEntry(ASN1Sequence.getInstance(o));
689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            }
699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall            return null;
719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        }
729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall
739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall        public ASN1Integer getUserCertificate()
74        {
75            return ASN1Integer.getInstance(seq.getObjectAt(0));
76        }
77
78        public Time getRevocationDate()
79        {
80            return Time.getInstance(seq.getObjectAt(1));
81        }
82
83        public Extensions getExtensions()
84        {
85            if (crlEntryExtensions == null && seq.size() == 3)
86            {
87                crlEntryExtensions = Extensions.getInstance(seq.getObjectAt(2));
88            }
89
90            return crlEntryExtensions;
91        }
92
93        public ASN1Primitive toASN1Primitive()
94        {
95            return seq;
96        }
97
98        public boolean hasExtensions()
99        {
100            return seq.size() == 3;
101        }
102    }
103
104    private class RevokedCertificatesEnumeration
105        implements Enumeration
106    {
107        private final Enumeration en;
108
109        RevokedCertificatesEnumeration(Enumeration en)
110        {
111            this.en = en;
112        }
113
114        public boolean hasMoreElements()
115        {
116            return en.hasMoreElements();
117        }
118
119        public Object nextElement()
120        {
121            return CRLEntry.getInstance(en.nextElement());
122        }
123    }
124
125    private class EmptyEnumeration
126        implements Enumeration
127    {
128        public boolean hasMoreElements()
129        {
130            return false;
131        }
132
133        public Object nextElement()
134        {
135            return null;   // TODO: check exception handling
136        }
137    }
138
139    ASN1Integer             version;
140    AlgorithmIdentifier     signature;
141    X500Name                issuer;
142    Time                    thisUpdate;
143    Time                    nextUpdate;
144    ASN1Sequence            revokedCertificates;
145    Extensions              crlExtensions;
146
147    public static TBSCertList getInstance(
148        ASN1TaggedObject obj,
149        boolean          explicit)
150    {
151        return getInstance(ASN1Sequence.getInstance(obj, explicit));
152    }
153
154    public static TBSCertList getInstance(
155        Object  obj)
156    {
157        if (obj instanceof TBSCertList)
158        {
159            return (TBSCertList)obj;
160        }
161        else if (obj != null)
162        {
163            return new TBSCertList(ASN1Sequence.getInstance(obj));
164        }
165
166        return null;
167    }
168
169    public TBSCertList(
170        ASN1Sequence  seq)
171    {
172        if (seq.size() < 3 || seq.size() > 7)
173        {
174            throw new IllegalArgumentException("Bad sequence size: " + seq.size());
175        }
176
177        int seqPos = 0;
178
179        if (seq.getObjectAt(seqPos) instanceof ASN1Integer)
180        {
181            version = ASN1Integer.getInstance(seq.getObjectAt(seqPos++));
182        }
183        else
184        {
185            version = null;  // version is optional
186        }
187
188        signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++));
189        issuer = X500Name.getInstance(seq.getObjectAt(seqPos++));
190        thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
191
192        if (seqPos < seq.size()
193            && (seq.getObjectAt(seqPos) instanceof DERUTCTime
194               || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime
195               || seq.getObjectAt(seqPos) instanceof Time))
196        {
197            nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
198        }
199
200        if (seqPos < seq.size()
201            && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject))
202        {
203            revokedCertificates = ASN1Sequence.getInstance(seq.getObjectAt(seqPos++));
204        }
205
206        if (seqPos < seq.size()
207            && seq.getObjectAt(seqPos) instanceof DERTaggedObject)
208        {
209            crlExtensions = Extensions.getInstance(ASN1Sequence.getInstance((ASN1TaggedObject)seq.getObjectAt(seqPos), true));
210        }
211    }
212
213    public int getVersionNumber()
214    {
215        if (version == null)
216        {
217            return 1;
218        }
219        return version.getValue().intValue() + 1;
220    }
221
222    public ASN1Integer getVersion()
223    {
224        return version;
225    }
226
227    public AlgorithmIdentifier getSignature()
228    {
229        return signature;
230    }
231
232    public X500Name getIssuer()
233    {
234        return issuer;
235    }
236
237    public Time getThisUpdate()
238    {
239        return thisUpdate;
240    }
241
242    public Time getNextUpdate()
243    {
244        return nextUpdate;
245    }
246
247    public CRLEntry[] getRevokedCertificates()
248    {
249        if (revokedCertificates == null)
250        {
251            return new CRLEntry[0];
252        }
253
254        CRLEntry[] entries = new CRLEntry[revokedCertificates.size()];
255
256        for (int i = 0; i < entries.length; i++)
257        {
258            entries[i] = CRLEntry.getInstance(revokedCertificates.getObjectAt(i));
259        }
260
261        return entries;
262    }
263
264    public Enumeration getRevokedCertificateEnumeration()
265    {
266        if (revokedCertificates == null)
267        {
268            return new EmptyEnumeration();
269        }
270
271        return new RevokedCertificatesEnumeration(revokedCertificates.getObjects());
272    }
273
274    public Extensions getExtensions()
275    {
276        return crlExtensions;
277    }
278
279    public ASN1Primitive toASN1Primitive()
280    {
281        ASN1EncodableVector v = new ASN1EncodableVector();
282
283        if (version != null)
284        {
285            v.add(version);
286        }
287        v.add(signature);
288        v.add(issuer);
289
290        v.add(thisUpdate);
291        if (nextUpdate != null)
292        {
293            v.add(nextUpdate);
294        }
295
296        // Add CRLEntries if they exist
297        if (revokedCertificates != null)
298        {
299            v.add(revokedCertificates);
300        }
301
302        if (crlExtensions != null)
303        {
304            v.add(new DERTaggedObject(0, crlExtensions));
305        }
306
307        return new DERSequence(v);
308    }
309}
310