1package org.bouncycastle.asn1.ocsp;
2
3import org.bouncycastle.asn1.ASN1EncodableVector;
4import org.bouncycastle.asn1.ASN1Sequence;
5import org.bouncycastle.asn1.ASN1TaggedObject;
6import org.bouncycastle.asn1.ASN1Encodable;
7import org.bouncycastle.asn1.DERGeneralizedTime;
8import org.bouncycastle.asn1.DERInteger;
9import org.bouncycastle.asn1.DERObject;
10import org.bouncycastle.asn1.DERSequence;
11import org.bouncycastle.asn1.DERTaggedObject;
12import org.bouncycastle.asn1.x509.X509Extensions;
13
14public class ResponseData
15    extends ASN1Encodable
16{
17    private static final DERInteger V1 = new DERInteger(0);
18
19    private boolean             versionPresent;
20
21    private DERInteger          version;
22    private ResponderID         responderID;
23    private DERGeneralizedTime  producedAt;
24    private ASN1Sequence        responses;
25    private X509Extensions      responseExtensions;
26
27    public ResponseData(
28        DERInteger          version,
29        ResponderID         responderID,
30        DERGeneralizedTime  producedAt,
31        ASN1Sequence        responses,
32        X509Extensions      responseExtensions)
33    {
34        this.version = version;
35        this.responderID = responderID;
36        this.producedAt = producedAt;
37        this.responses = responses;
38        this.responseExtensions = responseExtensions;
39    }
40
41    public ResponseData(
42        ResponderID         responderID,
43        DERGeneralizedTime  producedAt,
44        ASN1Sequence        responses,
45        X509Extensions      responseExtensions)
46    {
47        this(V1, responderID, producedAt, responses, responseExtensions);
48    }
49
50    public ResponseData(
51        ASN1Sequence    seq)
52    {
53        int index = 0;
54
55        if (seq.getObjectAt(0) instanceof ASN1TaggedObject)
56        {
57            ASN1TaggedObject    o = (ASN1TaggedObject)seq.getObjectAt(0);
58
59            if (o.getTagNo() == 0)
60            {
61                this.versionPresent = true;
62                this.version = DERInteger.getInstance(
63                                (ASN1TaggedObject)seq.getObjectAt(0), true);
64                index++;
65            }
66            else
67            {
68                this.version = V1;
69            }
70        }
71        else
72        {
73            this.version = V1;
74        }
75
76        this.responderID = ResponderID.getInstance(seq.getObjectAt(index++));
77        this.producedAt = (DERGeneralizedTime)seq.getObjectAt(index++);
78        this.responses = (ASN1Sequence)seq.getObjectAt(index++);
79
80        if (seq.size() > index)
81        {
82            this.responseExtensions = X509Extensions.getInstance(
83                                (ASN1TaggedObject)seq.getObjectAt(index), true);
84        }
85    }
86
87    public static ResponseData getInstance(
88        ASN1TaggedObject obj,
89        boolean          explicit)
90    {
91        return getInstance(ASN1Sequence.getInstance(obj, explicit));
92    }
93
94    public static ResponseData getInstance(
95        Object  obj)
96    {
97        if (obj == null || obj instanceof ResponseData)
98        {
99            return (ResponseData)obj;
100        }
101        else if (obj instanceof ASN1Sequence)
102        {
103            return new ResponseData((ASN1Sequence)obj);
104        }
105
106        throw new IllegalArgumentException("unknown object in factory");
107    }
108
109    public DERInteger getVersion()
110    {
111        return version;
112    }
113
114    public ResponderID getResponderID()
115    {
116        return responderID;
117    }
118
119    public DERGeneralizedTime getProducedAt()
120    {
121        return producedAt;
122    }
123
124    public ASN1Sequence getResponses()
125    {
126        return responses;
127    }
128
129    public X509Extensions getResponseExtensions()
130    {
131        return responseExtensions;
132    }
133
134    /**
135     * Produce an object suitable for an ASN1OutputStream.
136     * <pre>
137     * ResponseData ::= SEQUENCE {
138     *     version              [0] EXPLICIT Version DEFAULT v1,
139     *     responderID              ResponderID,
140     *     producedAt               GeneralizedTime,
141     *     responses                SEQUENCE OF SingleResponse,
142     *     responseExtensions   [1] EXPLICIT Extensions OPTIONAL }
143     * </pre>
144     */
145    public DERObject toASN1Object()
146    {
147        ASN1EncodableVector v = new ASN1EncodableVector();
148
149        if (versionPresent || !version.equals(V1))
150        {
151            v.add(new DERTaggedObject(true, 0, version));
152        }
153
154        v.add(responderID);
155        v.add(producedAt);
156        v.add(responses);
157        if (responseExtensions != null)
158        {
159            v.add(new DERTaggedObject(true, 1, responseExtensions));
160        }
161
162        return new DERSequence(v);
163    }
164}
165