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