001package org.apache.commons.ssl.org.bouncycastle.asn1.tsp;
002
003import java.util.Enumeration;
004
005import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Boolean;
006import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1EncodableVector;
007import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1GeneralizedTime;
008import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Integer;
009import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Object;
010import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1ObjectIdentifier;
011import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Primitive;
012import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1Sequence;
013import org.apache.commons.ssl.org.bouncycastle.asn1.ASN1TaggedObject;
014import org.apache.commons.ssl.org.bouncycastle.asn1.DERSequence;
015import org.apache.commons.ssl.org.bouncycastle.asn1.DERTaggedObject;
016import org.apache.commons.ssl.org.bouncycastle.asn1.x509.Extensions;
017import org.apache.commons.ssl.org.bouncycastle.asn1.x509.GeneralName;
018
019public class TSTInfo
020    extends ASN1Object
021{
022    private ASN1Integer version;
023    private ASN1ObjectIdentifier tsaPolicyId;
024    private MessageImprint messageImprint;
025    private ASN1Integer serialNumber;
026    private ASN1GeneralizedTime genTime;
027    private Accuracy accuracy;
028    private ASN1Boolean ordering;
029    private ASN1Integer nonce;
030    private GeneralName tsa;
031    private Extensions extensions;
032
033    public static TSTInfo getInstance(Object o)
034    {
035        if (o instanceof TSTInfo)
036        {
037            return (TSTInfo)o;
038        }
039        else if (o != null)
040        {
041            return new TSTInfo(ASN1Sequence.getInstance(o));
042        }
043
044        return null;
045    }
046
047    private TSTInfo(ASN1Sequence seq)
048    {
049        Enumeration e = seq.getObjects();
050
051        // version
052        version = ASN1Integer.getInstance(e.nextElement());
053
054        // tsaPolicy
055        tsaPolicyId = ASN1ObjectIdentifier.getInstance(e.nextElement());
056
057        // messageImprint
058        messageImprint = MessageImprint.getInstance(e.nextElement());
059
060        // serialNumber
061        serialNumber = ASN1Integer.getInstance(e.nextElement());
062
063        // genTime
064        genTime = ASN1GeneralizedTime.getInstance(e.nextElement());
065
066        // default for ordering
067        ordering = ASN1Boolean.getInstance(false);
068        
069        while (e.hasMoreElements())
070        {
071            ASN1Object o = (ASN1Object) e.nextElement();
072
073            if (o instanceof ASN1TaggedObject)
074            {
075                DERTaggedObject tagged = (DERTaggedObject) o;
076
077                switch (tagged.getTagNo())
078                {
079                case 0:
080                    tsa = GeneralName.getInstance(tagged, true);
081                    break;
082                case 1:
083                    extensions = Extensions.getInstance(tagged, false);
084                    break;
085                default:
086                    throw new IllegalArgumentException("Unknown tag value " + tagged.getTagNo());
087                }
088            }
089            else if (o instanceof ASN1Sequence || o instanceof Accuracy)
090            {
091                accuracy = Accuracy.getInstance(o);
092            }
093            else if (o instanceof ASN1Boolean)
094            {
095                ordering = ASN1Boolean.getInstance(o);
096            }
097            else if (o instanceof ASN1Integer)
098            {
099                nonce = ASN1Integer.getInstance(o);
100            }
101
102        }
103    }
104
105    public TSTInfo(ASN1ObjectIdentifier tsaPolicyId, MessageImprint messageImprint,
106            ASN1Integer serialNumber, ASN1GeneralizedTime genTime,
107            Accuracy accuracy, ASN1Boolean ordering, ASN1Integer nonce,
108            GeneralName tsa, Extensions extensions)
109    {
110        version = new ASN1Integer(1);
111        this.tsaPolicyId = tsaPolicyId;
112        this.messageImprint = messageImprint;
113        this.serialNumber = serialNumber;
114        this.genTime = genTime;
115
116        this.accuracy = accuracy;
117        this.ordering = ordering;
118        this.nonce = nonce;
119        this.tsa = tsa;
120        this.extensions = extensions;
121    }
122
123    public ASN1Integer getVersion()
124    {
125        return version;
126    }
127
128    public MessageImprint getMessageImprint()
129    {
130        return messageImprint;
131    }
132
133    public ASN1ObjectIdentifier getPolicy()
134    {
135        return tsaPolicyId;
136    }
137
138    public ASN1Integer getSerialNumber()
139    {
140        return serialNumber;
141    }
142
143    public Accuracy getAccuracy()
144    {
145        return accuracy;
146    }
147
148    public ASN1GeneralizedTime getGenTime()
149    {
150        return genTime;
151    }
152
153    public ASN1Boolean getOrdering()
154    {
155        return ordering;
156    }
157
158    public ASN1Integer getNonce()
159    {
160        return nonce;
161    }
162
163    public GeneralName getTsa()
164    {
165        return tsa;
166    }
167
168    public Extensions getExtensions()
169    {
170        return extensions;
171    }
172
173    /**
174     * <pre>
175     * 
176     *     TSTInfo ::= SEQUENCE  {
177     *        version                      INTEGER  { v1(1) },
178     *        policy                       TSAPolicyId,
179     *        messageImprint               MessageImprint,
180     *          -- MUST have the same value as the similar field in
181     *          -- TimeStampReq
182     *        serialNumber                 INTEGER,
183     *         -- Time-Stamping users MUST be ready to accommodate integers
184     *         -- up to 160 bits.
185     *        genTime                      GeneralizedTime,
186     *        accuracy                     Accuracy                 OPTIONAL,
187     *        ordering                     BOOLEAN             DEFAULT FALSE,
188     *        nonce                        INTEGER                  OPTIONAL,
189     *          -- MUST be present if the similar field was present
190     *          -- in TimeStampReq.  In that case it MUST have the same value.
191     *        tsa                          [0] GeneralName          OPTIONAL,
192     *        extensions                   [1] IMPLICIT Extensions   OPTIONAL  }
193     * 
194     * </pre>
195     */
196    public ASN1Primitive toASN1Primitive()
197    {
198        ASN1EncodableVector seq = new ASN1EncodableVector();
199        seq.add(version);
200
201        seq.add(tsaPolicyId);
202        seq.add(messageImprint);
203        seq.add(serialNumber);
204        seq.add(genTime);
205
206        if (accuracy != null)
207        {
208            seq.add(accuracy);
209        }
210        
211        if (ordering != null && ordering.isTrue())
212        {
213            seq.add(ordering);
214        }
215        
216        if (nonce != null)
217        {
218            seq.add(nonce);
219        }
220        
221        if (tsa != null)
222        {
223            seq.add(new DERTaggedObject(true, 0, tsa));
224        }
225        
226        if (extensions != null)
227        {
228            seq.add(new DERTaggedObject(false, 1, extensions));
229        }
230
231        return new DERSequence(seq);
232    }
233}