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