1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.ByteArrayOutputStream;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport java.io.IOException;
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.util.Enumeration;
6db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstromimport java.util.Vector;
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamabstract public class ASN1Set
94c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Primitive
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private Vector set = new Vector();
124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private boolean isSorted = false;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return an ASN1Set from the given object.
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the object we want converted.
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the object cannot be converted.
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Set getInstance(
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof ASN1Set)
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Set)obj;
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1SetParser)
284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof byte[])
324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            try
344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
354c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            catch (IOException e)
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof ASN1Encodable)
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (primitive instanceof ASN1Set)
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return (ASN1Set)primitive;
494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
52c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Return an ASN1 set from a tagged object. There is a special
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * case here, if an object appears to have been explicitly tagged on
58c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * reading but we were expecting it to be implicitly tagged in the
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * normal course of events it indicates that we lost the surrounding
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * set - so we need to add it back (this will happen if the tagged
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * object is a sequence that contains other sequences). If you are
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * dealing with implicitly tagged sets you really <b>should</b>
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * be using this method.
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly tagged
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          false otherwise.
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *          be converted.
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static ASN1Set getInstance(
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (!obj.isExplicit())
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                throw new IllegalArgumentException("object implicit - explicit expected.");
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1Set)obj.getObject();
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // constructed object which appears to be explicitly tagged
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            // and it's really implicit means we have to add the
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            // surrounding set.
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            //
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if (obj.isExplicit())
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                if (obj instanceof BERTaggedObject)
944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return new BERSet(obj.getObject());
964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                else
984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                {
994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    return new DLSet(obj.getObject());
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                }
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            else
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Set)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    return (ASN1Set)obj.getObject();
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                //
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // in this case the parser returns a sequence, convert it
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                // into a set.
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                //
1134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1EncodableVector v = new ASN1EncodableVector();
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                if (obj.getObject() instanceof ASN1Sequence)
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                {
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    ASN1Sequence s = (ASN1Sequence)obj.getObject();
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    if (obj instanceof BERTaggedObject)
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    {
1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        return new BERSet(s.toArray());
1244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    }
1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    else
1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    {
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        return new DLSet(s.toArray());
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                    }
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                }
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
1364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set()
1374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing one object
1424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable obj)
1454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        set.addElement(obj);
1474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1494c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1504c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1514c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1534c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1EncodableVector v,
1544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        boolean                  doSort)
1554c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
1564c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != v.size(); i++)
1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1584c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            set.addElement(v.get(i));
1594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1614c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (doSort)
1624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1634c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.sort();
1644c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1654c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
1664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1674c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    /**
1684c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * create a sequence containing a vector of objects.
1694c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     */
1704c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    protected ASN1Set(
1714c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable[]   array,
1724c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        boolean doSort)
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
1744c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        for (int i = 0; i != array.length; i++)
1754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1764c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            set.addElement(array[i]);
1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
1784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
1794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (doSort)
1804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
1814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.sort();
1824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
185db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public Enumeration getObjects()
186db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
187db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return set.elements();
188db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
189db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
190db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
191db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the object at the set position indicated by index.
192db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
193db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @param index the set number (starting at zero) of the object
194db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the object at the set position indicated by index.
195db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
1964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable getObjectAt(
197db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int index)
198db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
1994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return (ASN1Encodable)set.elementAt(index);
200db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
201db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
202db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
203db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return the number of objects in this set.
204db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     *
205db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * @return the number of objects in this set.
206db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
207db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int size()
208db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
209db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return set.size();
210db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
211b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
2126e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    public ASN1Encodable[] toArray()
2136e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2146e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        ASN1Encodable[] values = new ASN1Encodable[this.size()];
2156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2166e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        for (int i = 0; i != this.size(); i++)
2176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
2184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            values[i] = this.getObjectAt(i);
2196e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
2206e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2216e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return values;
2226e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2236e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
224c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public ASN1SetParser parser()
225b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
226c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        final ASN1Set outer = this;
227c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
228c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return new ASN1SetParser()
229b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
230c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private final int max = size();
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
232c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            private int index;
233c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Encodable readObject() throws IOException
235c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
236c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (index == max)
237c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
238c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return null;
239c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
240c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1Encodable obj = getObjectAt(index++);
242c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Sequence)
243c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
244c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Sequence)obj).parser();
245c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
246c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                if (obj instanceof ASN1Set)
247c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                {
248c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                    return ((ASN1Set)obj).parser();
249c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                }
250c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
251c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return obj;
252c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
253c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive getLoadedObject()
2556e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            {
2566e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom                return outer;
2576e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            }
2586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
2594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            public ASN1Primitive toASN1Primitive()
260c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
261c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return outer;
262c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
263c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        };
264c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
265c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
266db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public int hashCode()
267db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
268db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        Enumeration             e = this.getObjects();
269db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int                     hashCode = size();
270db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
271db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        while (e.hasMoreElements())
272db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
273db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            Object o = getNext(e);
274db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode *= 17;
275db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
276db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            hashCode ^= o.hashCode();
277db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
278db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
279db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return hashCode;
280db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
281c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDERObject()
2834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (isSorted)
2854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Set derSet = new DERSet();
2874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.set = this.set;
2894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return derSet;
2914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
2924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
2934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
2944c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            Vector v = new Vector();
2954c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2964c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            for (int i = 0; i != set.size(); i++)
2974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
2984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                v.addElement(set.elementAt(i));
2994c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
3004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3014c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Set derSet = new DERSet();
3024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3034c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.set = v;
3044c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3054c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            derSet.sort();
3064c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return derSet;
3084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
3094c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDLObject()
3124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
3134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Set derSet = new DLSet();
3144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3154c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        derSet.set = this.set;
3164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
3174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return derSet;
3184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
3194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
320c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
3214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o)
322c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
323c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (!(o instanceof ASN1Set))
324b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
325b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
326b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
327b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
328c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1Set   other = (ASN1Set)o;
329b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
330b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (this.size() != other.size())
331b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
332b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
333b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
334b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
335b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s1 = this.getObjects();
336b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Enumeration s2 = other.getObjects();
337b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
338b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        while (s1.hasMoreElements())
339b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
3404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj1 = getNext(s1);
3414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Encodable obj2 = getNext(s2);
3426e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o1 = obj1.toASN1Primitive();
3444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive o2 = obj2.toASN1Primitive();
345c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
3466e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            if (o1 == o2 || o1.equals(o2))
347b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
348c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
349b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
350c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
351c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
352b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
353b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
354b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
355b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
356b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    private ASN1Encodable getNext(Enumeration e)
3586e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
3594c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
3606e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        // unfortunately null was allowed as a substitute for DER null
3626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        if (encObj == null)
3636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        {
3646e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom            return DERNull.INSTANCE;
3656e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        }
3666e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
3676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom        return encObj;
3686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
3696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom
370db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    /**
371db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     * return true if a <= b (arrays are assumed padded with zeros).
372db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom     */
373db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    private boolean lessThanOrEqual(
374db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom         byte[] a,
375db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom         byte[] b)
376db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
377db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        int len = Math.min(a.length, b.length);
378db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        for (int i = 0; i != len; ++i)
379db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
380db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            if (a[i] != b[i])
381db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            {
382db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                return (a[i] & 0xff) < (b[i] & 0xff);
383db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            }
384db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
385db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        return len == a.length;
386db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
387b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
388c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    private byte[] getEncoded(
3894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable obj)
390c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
391c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
392c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        ASN1OutputStream        aOut = new ASN1OutputStream(bOut);
393c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
394c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        try
395c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
396c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            aOut.writeObject(obj);
397c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
398c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        catch (IOException e)
399c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
400c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new IllegalArgumentException("cannot encode object added to SET");
401c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
402c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
403c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return bOut.toByteArray();
404c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
405c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
406db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    protected void sort()
407db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4084c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (!isSorted)
409db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        {
4104c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            isSorted = true;
4114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (set.size() > 1)
412db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            {
4134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                boolean    swapped = true;
4144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                int        lastSwap = set.size() - 1;
415db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                while (swapped)
417db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                {
4184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    int    index = 0;
4194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    int    swapIndex = 0;
4204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    byte[] a = getEncoded((ASN1Encodable)set.elementAt(0));
421db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    swapped = false;
4234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    while (index != lastSwap)
425db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                    {
4264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        byte[] b = getEncoded((ASN1Encodable)set.elementAt(index + 1));
427db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        if (lessThanOrEqual(a, b))
4294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        {
4304c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            a = b;
4314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        }
4324c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        else
4334c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        {
4344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            Object  o = set.elementAt(index);
435db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4364c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            set.setElementAt(set.elementAt(index + 1), index);
4374c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            set.setElementAt(o, index + 1);
4384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            swapped = true;
4404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                            swapIndex = index;
4414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        }
4424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
4434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                        index++;
444db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                    }
445db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                    lastSwap = swapIndex;
447db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom                }
448db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            }
449db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom        }
450db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
451db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    boolean isConstructed()
453db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4544c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return true;
455db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
456db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
4574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    abstract void encode(ASN1OutputStream out)
458db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom            throws IOException;
459db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom
460db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    public String toString()
461db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    {
4624c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return set.toString();
463db9f6e2562dff550a3c62aeb7c96e72fc40d1a06Brian Carlstrom    }
464b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
465