1    
2    package org.bouncycastle.asn1.x509;
3    
4    import org.bouncycastle.asn1.*;
5    import org.bouncycastle.asn1.pkcs.*;
6    
7    /**
8     * PKIX RFC-2459
9     *
10    * <pre>
11    * TBSCertList  ::=  SEQUENCE  {
12    *      version                 Version OPTIONAL,
13    *                                   -- if present, shall be v2
14    *      signature               AlgorithmIdentifier,
15    *      issuer                  Name,
16    *      thisUpdate              Time,
17    *      nextUpdate              Time OPTIONAL,
18    *      revokedCertificates     SEQUENCE OF SEQUENCE  {
19    *           userCertificate         CertificateSerialNumber,
20    *           revocationDate          Time,
21    *           crlEntryExtensions      Extensions OPTIONAL
22    *                                         -- if present, shall be v2
23    *                                }  OPTIONAL,
24    *      crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
25    *                                         -- if present, shall be v2
26    *                                }
27    * </pre>
28    */
29   
30   public class TBSCertList
31       implements DEREncodable
32   {
33       public class CRLEntry
34           implements DEREncodable
35       {
36           DERConstructedSequence  seq;
37   
38           DERInteger          userCertificate;
39           Time                revocationDate;
40           X509Extensions      crlEntryExtensions;
41   
42           public CRLEntry(
43               DERConstructedSequence  seq)
44           {
45               this.seq = seq;
46   
47               userCertificate = (DERInteger)seq.getObjectAt(0);
48               revocationDate = Time.getInstance(seq.getObjectAt(1));
49               if (seq.getSize() == 3)
50               {
51                   crlEntryExtensions = X509Extensions.getInstance(seq.getObjectAt(2));
52               }
53           }
54   
55           public DERInteger getUserCertificate()
56           {
57               return userCertificate;
58           }
59   
60           public Time getRevocationDate()
61           {
62               return revocationDate;
63           }
64   
65           public X509Extensions getExtensions()
66           {
67               return crlEntryExtensions;
68           }
69   
70           public DERObject getDERObject()
71           {
72               return seq;
73           }
74       }
75   
76       ASN1Sequence     seq;
77   
78       DERInteger              version;
79       AlgorithmIdentifier     signature;
80       X509Name                issuer;
81       Time                    thisUpdate;
82       Time                    nextUpdate;
83       CRLEntry[]              revokedCertificates;
84       X509Extensions          crlExtensions;
85   
86       public static TBSCertList getInstance(
87           ASN1TaggedObject obj,
88           boolean          explicit)
89       {
90           return getInstance(ASN1Sequence.getInstance(obj, explicit));
91       }
92   
93       public static TBSCertList getInstance(
94           Object  obj)
95       {
96           if (obj instanceof TBSCertList)
97           {
98               return (TBSCertList)obj;
99           }
100          else if (obj instanceof ASN1Sequence)
101          {
102              return new TBSCertList((ASN1Sequence)obj);
103          }
104  
105          throw new IllegalArgumentException("unknown object in factory");
106      }
107  
108      public TBSCertList(
109          ASN1Sequence  seq)
110      {
111          int seqPos = 0;
112  
113          this.seq = seq;
114  
115          if (seq.getObjectAt(seqPos) instanceof DERInteger)
116          {
117              version = (DERInteger)seq.getObjectAt(seqPos++);
118          }
119          else
120          {
121              version = new DERInteger(0);
122          }
123  
124          signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqPos++));
125          issuer = X509Name.getInstance(seq.getObjectAt(seqPos++));
126          thisUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
127  
128          if (seqPos < seq.size()
129              && (seq.getObjectAt(seqPos) instanceof DERUTCTime
130                 || seq.getObjectAt(seqPos) instanceof DERGeneralizedTime
131                 || seq.getObjectAt(seqPos) instanceof Time))
132          {
133              nextUpdate = Time.getInstance(seq.getObjectAt(seqPos++));
134          }
135  
136          if (seqPos < seq.size()
137              && !(seq.getObjectAt(seqPos) instanceof DERTaggedObject))
138          {
139              DERConstructedSequence certs = (DERConstructedSequence)seq.getObjectAt(seqPos++);
140              revokedCertificates = new CRLEntry[certs.getSize()];
141  
142              for ( int i = 0; i < revokedCertificates.length; i++)
143              {
144                  revokedCertificates[i] = new CRLEntry((DERConstructedSequence)certs.getObjectAt(i));
145              }
146          }
147  
148          if (seqPos < seq.size()
149              && seq.getObjectAt(seqPos) instanceof DERTaggedObject)
150          {
151              crlExtensions = X509Extensions.getInstance(seq.getObjectAt(seqPos++));
152          }
153      }
154  
155      public int getVersion()
156      {
157          return version.getValue().intValue() + 1;
158      }
159  
160      public DERInteger getVersionNumber()
161      {
162          return version;
163      }
164  
165      public AlgorithmIdentifier getSignature()
166      {
167          return signature;
168      }
169  
170      public X509Name getIssuer()
171      {
172          return issuer;
173      }
174  
175      public Time getThisUpdate()
176      {
177          return thisUpdate;
178      }
179  
180      public Time getNextUpdate()
181      {
182          return nextUpdate;
183      }
184  
185      public CRLEntry[] getRevokedCertificates()
186      {
187          return revokedCertificates;
188      }
189  
190      public X509Extensions getExtensions()
191      {
192          return crlExtensions;
193      }
194  
195      public DERObject getDERObject()
196      {
197          return seq;
198      }
199  }
200