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
8db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    extends ASN1Object
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
10db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    private 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        }
256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        else if (obj instanceof byte[])
266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            try
286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                return ASN1Sequence.getInstance(ASN1Object.fromByteArray((byte[])obj));
306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            catch (IOException e)
326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
336e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                throw new IllegalArgumentException("failed to construct sequence from byte[]: " + e.getMessage());
346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
356e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
37c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return an ASN1 sequence from a tagged object. There is a special
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * case here, if an object appears to have been explicitly tagged on
43c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * reading but we were expecting it to be implicitly tagged in the
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * normal course of events it indicates that we lost the surrounding
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * sequence - so we need to add it back (this will happen if the tagged
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * object is a sequence that contains other sequences). If you are
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dealing with implicitly tagged sequences you really <b>should</b>
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * be using this method.
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly tagged,
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          false otherwise.
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          be converted.
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Sequence getInstance(
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!obj.isExplicit())
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("object implicit - explicit expected.");
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Sequence)obj.getObject();
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // constructed object which appears to be explicitly tagged
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // when it should be implicit means we have to add the
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // surrounding sequence.
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj.isExplicit())
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj instanceof BERTaggedObject)
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return new BERSequence(obj.getObject());
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                else
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return new DERSequence(obj.getObject());
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Sequence)
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return (ASN1Sequence)obj.getObject();
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
99db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public Enumeration getObjects()
100db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
101db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return seq.elements();
102db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public ASN1SequenceParser parser()
105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        final ASN1Sequence outer = this;
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
108c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return new ASN1SequenceParser()
109c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
110c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private final int max = size();
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
112c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private int index;
113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
114c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            public DEREncodable readObject() throws IOException
115c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
116c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (index == max)
117c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
118c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return null;
119c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
120c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
121c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                DEREncodable obj = getObjectAt(index++);
122c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Sequence)
123c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
124c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Sequence)obj).parser();
125c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
126c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Set)
127c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
128c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Set)obj).parser();
129c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
130c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return obj;
132c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
1346e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            public DERObject getLoadedObject()
1356e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
1366e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                return outer;
1376e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
1386e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
139c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            public DERObject getDERObject()
140c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return outer;
142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        };
144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
146db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
147db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the object at the sequence position indicated by index.
148db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
149db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @param index the sequence number (starting at zero) of the object
150db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the object at the sequence position indicated by index.
151db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
152db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public DEREncodable getObjectAt(
153db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int index)
154db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
155db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return (DEREncodable)seq.elementAt(index);
156db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
157db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
158db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
159db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the number of objects in this sequence.
160db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
161db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the number of objects in this sequence.
162db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
163db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int size()
164db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
165db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return seq.size();
166db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
167db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
168db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int hashCode()
169db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
170db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        Enumeration             e = this.getObjects();
171db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int                     hashCode = size();
172db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
173db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        while (e.hasMoreElements())
174db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
175db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            Object o = getNext(e);
176db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode *= 17;
177db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
178db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode ^= o.hashCode();
179db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
180db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
181db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return hashCode;
182db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
184c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERObject  o)
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof ASN1Sequence))
188b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
189b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
190b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
191b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Sequence   other = (ASN1Sequence)o;
193b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
194b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (this.size() != other.size())
195b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
196b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
197b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
198b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
199b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s1 = this.getObjects();
200b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s2 = other.getObjects();
201b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
202b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (s1.hasMoreElements())
203b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
2046e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            DEREncodable  obj1 = getNext(s1);
2056e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            DEREncodable  obj2 = getNext(s2);
2066e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2076e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            DERObject  o1 = obj1.getDERObject();
2086e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            DERObject  o2 = obj2.getDERObject();
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2106e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (o1 == o2 || o1.equals(o2))
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
212b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                continue;
213b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
214c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
215c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
216b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
217b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
218b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
219b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
220b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    private DEREncodable getNext(Enumeration e)
2226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        DEREncodable encObj = (DEREncodable)e.nextElement();
2246e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2256e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        // unfortunately null was allowed as a substitute for DER null
2266e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        if (encObj == null)
2276e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
2286e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            return DERNull.INSTANCE;
2296e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
2306e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2316e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return encObj;
2326e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2336e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
234db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    protected void addObject(
235db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        DEREncodable obj)
236db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
237db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        seq.addElement(obj);
238db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
239db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
240db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    abstract void encode(DEROutputStream out)
241db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        throws IOException;
242db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
243db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public String toString()
244db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
245db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom      return seq.toString();
246db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
247b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
248