1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
5db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstromimport java.util.Vector;
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic abstract class ASN1Sequence
84c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Primitive
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected Vector seq = new Vector();
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return an ASN1Sequence from the given object.
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the object we want converted.
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the object cannot be converted.
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Sequence getInstance(
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof ASN1Sequence)
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Sequence)obj;
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1SequenceParser)
264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ASN1Sequence.getInstance(((ASN1SequenceParser)obj).toASN1Primitive());
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        else if (obj instanceof byte[])
306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            try
326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return ASN1Sequence.getInstance(fromByteArray((byte[])obj));
346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
356e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            catch (IOException e)
366e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
376e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
396e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1Encodable)
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (primitive instanceof ASN1Sequence)
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return (ASN1Sequence)primitive;
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return an ASN1 sequence from a tagged object. There is a special
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * case here, if an object appears to have been explicitly tagged on
56c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * reading but we were expecting it to be implicitly tagged in the
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * normal course of events it indicates that we lost the surrounding
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * sequence - so we need to add it back (this will happen if the tagged
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * object is a sequence that contains other sequences). If you are
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dealing with implicitly tagged sequences you really <b>should</b>
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * be using this method.
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly tagged,
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          false otherwise.
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          be converted.
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Sequence getInstance(
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!obj.isExplicit())
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("object implicit - explicit expected.");
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ASN1Sequence.getInstance(obj.getObject().toASN1Primitive());
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // constructed object which appears to be explicitly tagged
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // when it should be implicit means we have to add the
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // surrounding sequence.
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj.isExplicit())
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj instanceof BERTaggedObject)
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return new BERSequence(obj.getObject());
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return new DLSequence(obj.getObject());
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Sequence)
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return (ASN1Sequence)obj.getObject();
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create an empty sequence
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Sequence()
1164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing one object
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Sequence(
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable obj)
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        seq.addElement(obj);
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Sequence(
1324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1EncodableVector v)
1334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != v.size(); i++)
1354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            seq.addElement(v.get(i));
1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Sequence(
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable[]   array)
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != array.length; i++)
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            seq.addElement(array[i]);
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable[] toArray()
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable[] values = new ASN1Encodable[this.size()];
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != this.size(); i++)
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            values[i] = this.getObjectAt(i);
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return values;
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
164db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public Enumeration getObjects()
165db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
166db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return seq.elements();
167db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
169c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public ASN1SequenceParser parser()
170c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
171c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        final ASN1Sequence outer = this;
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return new ASN1SequenceParser()
174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private final int max = size();
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private int index;
178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
1794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Encodable readObject() throws IOException
180c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
181c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (index == max)
182c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
183c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return null;
184c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
1864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1Encodable obj = getObjectAt(index++);
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Sequence)
188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Sequence)obj).parser();
190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Set)
192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Set)obj).parser();
194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return obj;
197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
1994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive getLoadedObject()
2006e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
2016e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                return outer;
2026e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
2036e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive toASN1Primitive()
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return outer;
207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        };
209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
211db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
212db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the object at the sequence position indicated by index.
213db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
214db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @param index the sequence number (starting at zero) of the object
215db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the object at the sequence position indicated by index.
216db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
2174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable getObjectAt(
218db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int index)
219db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return (ASN1Encodable)seq.elementAt(index);
221db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
222db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
223db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
224db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the number of objects in this sequence.
225db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
226db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the number of objects in this sequence.
227db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
228db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int size()
229db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
230db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return seq.size();
231db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
232db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
233db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int hashCode()
234db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
235db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        Enumeration             e = this.getObjects();
236db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int                     hashCode = size();
237db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
238db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        while (e.hasMoreElements())
239db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
240db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            Object o = getNext(e);
241db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode *= 17;
242db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
243db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode ^= o.hashCode();
244db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
245db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
246db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return hashCode;
247db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
248b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
2504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o)
251b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
252c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof ASN1Sequence))
253b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
254b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
255b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
256b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
257c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Sequence   other = (ASN1Sequence)o;
258b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
259b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (this.size() != other.size())
260b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
261b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
262b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
263b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
264b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s1 = this.getObjects();
265b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s2 = other.getObjects();
266b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
267b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (s1.hasMoreElements())
268b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
2694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj1 = getNext(s1);
2704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj2 = getNext(s2);
2716e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o1 = obj1.toASN1Primitive();
2734c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o2 = obj2.toASN1Primitive();
274b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2756e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (o1 == o2 || o1.equals(o2))
276b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
277b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                continue;
278b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
279c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
280c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
281b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
282b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
283b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
284b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
285b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1Encodable getNext(Enumeration e)
2876e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
2896e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2906e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return encObj;
2916e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2926e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDERObject()
294db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Sequence derSeq = new DERSequence();
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        derSeq.seq = this.seq;
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return derSeq;
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDLObject()
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Sequence dlSeq = new DLSequence();
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        dlSeq.seq = this.seq;
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return dlSeq;
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean isConstructed()
3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return true;
314db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
315db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
3164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    abstract void encode(ASN1OutputStream out)
317db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        throws IOException;
318db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
319db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public String toString()
320db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
3214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return seq.toString();
322db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
323b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
324