1package org.bouncycastle.asn1.x509;
2
3import org.bouncycastle.asn1.ASN1EncodableVector;
4import org.bouncycastle.asn1.ASN1Integer;
5import org.bouncycastle.asn1.ASN1UTCTime;
6import org.bouncycastle.asn1.DERBitString;
7import org.bouncycastle.asn1.DERSequence;
8import org.bouncycastle.asn1.DERTaggedObject;
9import org.bouncycastle.asn1.x500.X500Name;
10
11/**
12 * Generator for Version 3 TBSCertificateStructures.
13 * <pre>
14 * TBSCertificate ::= SEQUENCE {
15 *      version          [ 0 ]  Version DEFAULT v1(0),
16 *      serialNumber            CertificateSerialNumber,
17 *      signature               AlgorithmIdentifier,
18 *      issuer                  Name,
19 *      validity                Validity,
20 *      subject                 Name,
21 *      subjectPublicKeyInfo    SubjectPublicKeyInfo,
22 *      issuerUniqueID    [ 1 ] IMPLICIT UniqueIdentifier OPTIONAL,
23 *      subjectUniqueID   [ 2 ] IMPLICIT UniqueIdentifier OPTIONAL,
24 *      extensions        [ 3 ] Extensions OPTIONAL
25 *      }
26 * </pre>
27 *
28 */
29public class V3TBSCertificateGenerator
30{
31    DERTaggedObject         version = new DERTaggedObject(true, 0, new ASN1Integer(2));
32
33    ASN1Integer              serialNumber;
34    AlgorithmIdentifier     signature;
35    X500Name                issuer;
36    Time                    startDate, endDate;
37    X500Name                subject;
38    SubjectPublicKeyInfo    subjectPublicKeyInfo;
39    Extensions              extensions;
40
41    private boolean altNamePresentAndCritical;
42    private DERBitString issuerUniqueID;
43    private DERBitString subjectUniqueID;
44
45    public V3TBSCertificateGenerator()
46    {
47    }
48
49    public void setSerialNumber(
50        ASN1Integer  serialNumber)
51    {
52        this.serialNumber = serialNumber;
53    }
54
55    public void setSignature(
56        AlgorithmIdentifier    signature)
57    {
58        this.signature = signature;
59    }
60
61        /**
62     * @deprecated use X500Name method
63     */
64    public void setIssuer(
65        X509Name    issuer)
66    {
67        this.issuer = X500Name.getInstance(issuer);
68    }
69
70    public void setIssuer(
71        X500Name issuer)
72    {
73        this.issuer = issuer;
74    }
75
76    public void setStartDate(
77        ASN1UTCTime startDate)
78    {
79        this.startDate = new Time(startDate);
80    }
81
82    public void setStartDate(
83        Time startDate)
84    {
85        this.startDate = startDate;
86    }
87
88    public void setEndDate(
89        ASN1UTCTime endDate)
90    {
91        this.endDate = new Time(endDate);
92    }
93
94    public void setEndDate(
95        Time endDate)
96    {
97        this.endDate = endDate;
98    }
99
100        /**
101     * @deprecated use X500Name method
102     */
103    public void setSubject(
104        X509Name    subject)
105    {
106        this.subject = X500Name.getInstance(subject.toASN1Primitive());
107    }
108
109    public void setSubject(
110        X500Name subject)
111    {
112        this.subject = subject;
113    }
114
115    public void setIssuerUniqueID(
116        DERBitString uniqueID)
117    {
118        this.issuerUniqueID = uniqueID;
119    }
120
121    public void setSubjectUniqueID(
122        DERBitString uniqueID)
123    {
124        this.subjectUniqueID = uniqueID;
125    }
126
127    public void setSubjectPublicKeyInfo(
128        SubjectPublicKeyInfo    pubKeyInfo)
129    {
130        this.subjectPublicKeyInfo = pubKeyInfo;
131    }
132
133    /**
134     * @deprecated use method taking Extensions
135     * @param extensions
136     */
137    public void setExtensions(
138        X509Extensions    extensions)
139    {
140        setExtensions(Extensions.getInstance(extensions));
141    }
142
143    public void setExtensions(
144        Extensions    extensions)
145    {
146        this.extensions = extensions;
147        if (extensions != null)
148        {
149            Extension altName = extensions.getExtension(Extension.subjectAlternativeName);
150
151            if (altName != null && altName.isCritical())
152            {
153                altNamePresentAndCritical = true;
154            }
155        }
156    }
157
158    public TBSCertificate generateTBSCertificate()
159    {
160        if ((serialNumber == null) || (signature == null)
161            || (issuer == null) || (startDate == null) || (endDate == null)
162            || (subject == null && !altNamePresentAndCritical) || (subjectPublicKeyInfo == null))
163        {
164            throw new IllegalStateException("not all mandatory fields set in V3 TBScertificate generator");
165        }
166
167        ASN1EncodableVector  v = new ASN1EncodableVector();
168
169        v.add(version);
170        v.add(serialNumber);
171        v.add(signature);
172        v.add(issuer);
173
174        //
175        // before and after dates
176        //
177        ASN1EncodableVector  validity = new ASN1EncodableVector();
178
179        validity.add(startDate);
180        validity.add(endDate);
181
182        v.add(new DERSequence(validity));
183
184        if (subject != null)
185        {
186            v.add(subject);
187        }
188        else
189        {
190            v.add(new DERSequence());
191        }
192
193        v.add(subjectPublicKeyInfo);
194
195        if (issuerUniqueID != null)
196        {
197            v.add(new DERTaggedObject(false, 1, issuerUniqueID));
198        }
199
200        if (subjectUniqueID != null)
201        {
202            v.add(new DERTaggedObject(false, 2, subjectUniqueID));
203        }
204
205        if (extensions != null)
206        {
207            v.add(new DERTaggedObject(true, 3, extensions));
208        }
209
210        return TBSCertificate.getInstance(new DERSequence(v));
211    }
212}
213