1    package org.bouncycastle.asn1.x509;
2    
3    import org.bouncycastle.asn1.*;
4    import org.bouncycastle.asn1.pkcs.*;
5    
6    /**
7     * <pre>
8     * TBSCertificate ::= SEQUENCE {
9     *      version          [ 0 ]  Version DEFAULT v1(0),
10    *      serialNumber            CertificateSerialNumber,
11    *      signature               AlgorithmIdentifier,
12    *      issuer                  Name,
13    *      validity                Validity,
14    *      subject                 Name,
15    *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
16    *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
17    *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
18    *      extensions        [ 3 ] Extensions OPTIONAL
19    *      }
20    * </pre>
21    * <p>
22    * Note: issuerUniqueID and subjectUniqueID are both deprecated by the IETF. This class
23    * will parse them, but you really shouldn't be creating new ones.
24    */
25   public class TBSCertificateStructure
26       implements DEREncodable, X509ObjectIdentifiers, PKCSObjectIdentifiers
27   {
28       ASN1Sequence            seq;
29   
30       DERInteger              version;
31       DERInteger              serialNumber;
32       AlgorithmIdentifier     signature;
33       X509Name                issuer;
34       TimeTime                startDate, endDate;
35       X509Name                subject;
36       SubjectPublicKeyInfo    subjectPublicKeyInfo;
37       DERBitString            issuerUniqueId;
38       DERBitString            subjectUniqueId;
39       X509Extensions          extensions;
40   
41       public static TBSCertificateStructure getInstance(
42           ASN1TaggedObject obj,
43           boolean          explicit)
44       {
45           return getInstance(ASN1Sequence.getInstance(obj, explicit));
46       }
47   
48       public static TBSCertificateStructure getInstance(
49           Object  obj)
50       {
51           if (obj instanceof TBSCertificateStructure)
52           {
53               return (TBSCertificateStructure)obj;
54           }
55           else if (obj instanceof ASN1Sequence)
56           {
57               return new TBSCertificateStructure((ASN1Sequence)obj);
58           }
59   
60           throw new IllegalArgumentException("unknown object in factory");
61       }
62   
63       public TBSCertificateStructure(
64           ASN1Sequence  seq)
65       {
66           int         seqStart = 0;
67   
68           this.seq = seq;
69   
70           //
71           // some certficates don't include a version number - we assume v1
72           //
73           if (seq.getObjectAt(0) instanceof DERTaggedObject)
74           {
75               version = DERInteger.getInstance(seq.getObjectAt(0));
76           }
77           else
78           {
79               seqStart = -1;          // field 0 is missing!
80               version = new DERInteger(0);
81           }
82   
83           serialNumber = DERInteger.getInstance(seq.getObjectAt(seqStart + 1));
84   
85           signature = AlgorithmIdentifier.getInstance(seq.getObjectAt(seqStart + 2));
86           issuer = X509Name.getInstance(seq.getObjectAt(seqStart + 3));
87   
88           //
89           // before and after dates
90           //
91           ASN1Sequence  dates = (ASN1Sequence)seq.getObjectAt(seqStart + 4);
92   
93           startDate = Time.getInstance(dates.getObjectAt(0));
94           endDate = Time.getInstance(dates.getObjectAt(1));
95   
96           subject = X509Name.getInstance(seq.getObjectAt(seqStart + 5));
97   
98           //
99           // public key info.
100          //
101          subjectPublicKeyInfo = SubjectPublicKeyInfo.getInstance(seq.getObjectAt(seqStart + 6));
102  
103          for (int extras = seq.size() - (seqStart + 6) - 1; extras > 0; extras--)
104          {
105              DERTaggedObject extra = (DERTaggedObject)seq.getObjectAt(seqStart + 6 + extras);
106  
107              switch (extra.getTagNo())
108              {
109              case 1:
110                  issuerUniqueId = DERBitString.getInstance(extra);
111                  break;
112              case 2:
113                  subjectUniqueId = DERBitString.getInstance(extra);
114                  break;
115              case 3:
116                  extensions = X509Extensions.getInstance(extra);
117              }
118          }
119      }
120  
121      public int getVersion()
122      {
123          return version.getValue().intValue() + 1;
124      }
125  
126      public DERInteger getVersionNumber()
127      {
128          return version;
129      }
130  
131      public DERInteger getSerialNumber()
132      {
133          return serialNumber;
134      }
135  
136      public AlgorithmIdentifier getSignature()
137      {
138          return signature;
139      }
140  
141      public X509Name getIssuer()
142      {
143          return issuer;
144      }
145  
146      public Time getStartDate()
147      {
148          return startDate;
149      }
150  
151      public Time getEndDate()
152      {
153          return endDate;
154      }
155  
156      public X509Name getSubject()
157      {
158          return subject;
159      }
160  
161      public SubjectPublicKeyInfo getSubjectPublicKeyInfo()
162      {
163          return subjectPublicKeyInfo;
164      }
165  
166      public DERBitString getIssuerUniqueId()
167      {
168          return issuerUniqueId;
169      }
170  
171      public DERBitString getSubjectUniqueId()
172      {
173          return subjectUniqueId;
174      }
175  
176      public X509Extensions getExtensions()
177      {
178          return extensions;
179      }
180  
181      public DERObject getDERObject()
182      {
183          return seq;
184      }
185  }
186