116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.asn1;
216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.io.IOException;
416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.util.Enumeration;
5bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giroimport java.util.Iterator;
616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.util.Vector;
716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
8bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giroimport org.bouncycastle.util.Arrays;
9bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro
1053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro/**
1153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * ASN.1 <code>SET</code> and <code>SET OF</code> constructs.
1253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
1353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Note: This does not know which syntax the set is!
1453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * (The difference: ordering of SET elements or not ordering.)
1553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
1653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * DER form is always definite form length fields, while
1753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * BER support uses indefinite form.
1853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
1953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The CER form support does not exist.
2053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
2153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <hr>
2253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h2>X.690</h2>
2353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h3>8: Basic encoding rules</h3>
2453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>8.11 Encoding of a set value </h4>
2553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.11.1</b> The encoding of a set value shall be constructed
2653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
2753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.11.2</b> The contents octets shall consist of the complete
2853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * encoding of a data value from each of the types listed in the
2953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * ASN.1 definition of the set type, in an order chosen by the sender,
3053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * unless the type was referenced with the keyword
3153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
3253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
3353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.11.3</b> The encoding of a data value may, but need not,
3453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * be present for a type which was referenced with the keyword
3553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>OPTIONAL</b> or the keyword <b>DEFAULT</b>.
3653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <blockquote>
3753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * NOTE &mdash; The order of data values in a set value is not significant,
3853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * and places no constraints on the order during transfer
3953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * </blockquote>
4053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>8.12 Encoding of a set-of value</h4>
4153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.12.1</b> The encoding of a set-of value shall be constructed.
4253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
4353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.12.2</b> The text of 8.10.2 applies:
4453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <i>The contents octets shall consist of zero,
4553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * one or more complete encodings of data values from the type listed in
4653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * the ASN.1 definition.</i>
4753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
4853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <b>8.12.3</b> The order of data values need not be preserved by
4953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * the encoding and subsequent decoding.
5053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro *
5153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h3>9: Canonical encoding rules</h3>
5253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>9.1 Length forms</h4>
53bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * If the encoding is constructed, it shall employ the indefinite-length form.
5453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * If the encoding is primitive, it shall include the fewest length octets necessary.
5553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * [Contrast with 8.1.3.2 b).]
5653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>9.3 Set components</h4>
5753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The encodings of the component values of a set value shall
5853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * appear in an order determined by their tags as specified
5953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
6053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * Additionally, for the purposes of determining the order in which
6153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * components are encoded when one or more component is an untagged
6253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * choice type, each untagged choice type is ordered as though it
6353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * has a tag equal to that of the smallest tag in that choice type
6453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * or any untagged choice types nested within.
6553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro *
6653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h3>10: Distinguished encoding rules</h3>
6753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>10.1 Length forms</h4>
6853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The definite form of length encoding shall be used,
6953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * encoded in the minimum number of octets.
7053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * [Contrast with 8.1.3.2 b).]
7153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>10.3 Set components</h4>
7253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The encodings of the component values of a set value shall appear
7353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * in an order determined by their tags as specified
7453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * in 8.6 of ITU-T Rec. X.680 | ISO/IEC 8824-1.
7553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <blockquote>
7653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * NOTE &mdash; Where a component of the set is an untagged choice type,
7753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * the location of that component in the ordering will depend on
7853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * the tag of the choice component being encoded.
7953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * </blockquote>
8053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro *
8153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h3>11: Restrictions on BER employed by both CER and DER</h3>
8253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>11.5 Set and sequence components with default value </h4>
8353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The encoding of a set value or sequence value shall not include
8453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * an encoding for any component value which is equal to
8553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * its default value.
8653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <h4>11.6 Set-of components </h4>
8753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <p>
8853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * The encodings of the component values of a set-of value
8953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * shall appear in ascending order, the encodings being compared
9053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * as octet strings with the shorter components being padded at
9153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * their trailing end with 0-octets.
9253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * <blockquote>
9353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * NOTE &mdash; The padding octets are for comparison purposes only
9453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * and do not appear in the encodings.
9553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro * </blockquote>
9653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro */
9753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giropublic abstract class ASN1Set
9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    extends ASN1Primitive
99bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    implements org.bouncycastle.util.Iterable<ASN1Encodable>
10016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{
10116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private Vector set = new Vector();
10216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private boolean isSorted = false;
10316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
10416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
10516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * return an ASN1Set from the given object.
10616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *
10716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @param obj the object we want converted.
10816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @exception IllegalArgumentException if the object cannot be converted.
10953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * @return an ASN1Set instance, or null.
11016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
11116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public static ASN1Set getInstance(
11216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        Object  obj)
11316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
11416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (obj == null || obj instanceof ASN1Set)
11516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
11616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return (ASN1Set)obj;
11716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
11816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (obj instanceof ASN1SetParser)
11916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
12016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return ASN1Set.getInstance(((ASN1SetParser)obj).toASN1Primitive());
12116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
12216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (obj instanceof byte[])
12316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
12416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            try
12516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
12616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return ASN1Set.getInstance(ASN1Primitive.fromByteArray((byte[])obj));
12716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
12816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            catch (IOException e)
12916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
13016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                throw new IllegalArgumentException("failed to construct set from byte[]: " + e.getMessage());
13116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
13216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
13316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else if (obj instanceof ASN1Encodable)
13416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
13516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive();
13616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
13716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (primitive instanceof ASN1Set)
13816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
13916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return (ASN1Set)primitive;
14016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
14116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
14216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
14316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
14416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
14516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
14616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
14716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * Return an ASN1 set from a tagged object. There is a special
14816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * case here, if an object appears to have been explicitly tagged on
14916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * reading but we were expecting it to be implicitly tagged in the
15016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * normal course of events it indicates that we lost the surrounding
15116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * set - so we need to add it back (this will happen if the tagged
15216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * object is a sequence that contains other sequences). If you are
15316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * dealing with implicitly tagged sets you really <b>should</b>
15416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * be using this method.
15516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *
15616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @param obj the tagged object.
15716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @param explicit true if the object is meant to be explicitly tagged
15816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *          false otherwise.
15916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @exception IllegalArgumentException if the tagged object cannot
16016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *          be converted.
16153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * @return an ASN1Set instance.
16216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
16316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public static ASN1Set getInstance(
16416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1TaggedObject    obj,
16516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        boolean             explicit)
16616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
16716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (explicit)
16816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
16916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (!obj.isExplicit())
17016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
17116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                throw new IllegalArgumentException("object implicit - explicit expected.");
17216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
17316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
17416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return (ASN1Set)obj.getObject();
17516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
17616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else
17716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
17816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            //
17916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            // constructed object which appears to be explicitly tagged
18016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            // and it's really implicit means we have to add the
18116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            // surrounding set.
18216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            //
18316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (obj.isExplicit())
18416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
18516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (obj instanceof BERTaggedObject)
18616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
18716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return new BERSet(obj.getObject());
18816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
18916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                else
19016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
19116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return new DLSet(obj.getObject());
19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
19316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            else
19516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
19616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (obj.getObject() instanceof ASN1Set)
19716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
19816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return (ASN1Set)obj.getObject();
19916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
20016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
20116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                //
20216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                // in this case the parser returns a sequence, convert it
20316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                // into a set.
20416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                //
20516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (obj.getObject() instanceof ASN1Sequence)
20616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
20716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    ASN1Sequence s = (ASN1Sequence)obj.getObject();
20816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
20916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    if (obj instanceof BERTaggedObject)
21016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    {
21116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        return new BERSet(s.toArray());
21216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    }
21316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    else
21416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    {
21516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        return new DLSet(s.toArray());
21616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    }
21716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
21816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
21916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
22016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
22116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
22216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
22316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
22416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    protected ASN1Set()
22516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
22616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
22716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
22816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
22916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * create a sequence containing one object
23053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * @param obj object to be added to the SET.
23116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
23216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    protected ASN1Set(
23316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Encodable obj)
23416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
23516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        set.addElement(obj);
23616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
23716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
23816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
23916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * create a sequence containing a vector of objects.
24053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * @param v a vector of objects to make up the SET.
24153b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * @param doSort true if should be sorted DER style, false otherwise.
24216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
24316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    protected ASN1Set(
24416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1EncodableVector v,
24516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        boolean                  doSort)
24616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
24716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        for (int i = 0; i != v.size(); i++)
24816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
24916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            set.addElement(v.get(i));
25016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
25116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
25216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (doSort)
25316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
25416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            this.sort();
25516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
25616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
25716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
258bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    /*
25916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * create a sequence containing a vector of objects.
26016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
26116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    protected ASN1Set(
26216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Encodable[]   array,
26316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        boolean doSort)
26416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
26516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        for (int i = 0; i != array.length; i++)
26616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
26716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            set.addElement(array[i]);
26816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
26916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
27016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (doSort)
27116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
27216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            this.sort();
27316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
27416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
27516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
27616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public Enumeration getObjects()
27716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
27816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return set.elements();
27916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
28016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
28116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
28216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * return the object at the set position indicated by index.
28316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *
28416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @param index the set number (starting at zero) of the object
28516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @return the object at the set position indicated by index.
28616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
28716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public ASN1Encodable getObjectAt(
28816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        int index)
28916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
29016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return (ASN1Encodable)set.elementAt(index);
29116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
29216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
29316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
29416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * return the number of objects in this set.
29516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     *
29616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * @return the number of objects in this set.
29716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
29816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public int size()
29916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
30016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return set.size();
30116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
30216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
30316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public ASN1Encodable[] toArray()
30416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
30516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Encodable[] values = new ASN1Encodable[this.size()];
30616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
30716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        for (int i = 0; i != this.size(); i++)
30816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
30916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            values[i] = this.getObjectAt(i);
31016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
31116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
31216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return values;
31316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
31416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
31516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public ASN1SetParser parser()
31616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
31716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        final ASN1Set outer = this;
31816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
31916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return new ASN1SetParser()
32016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
32116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            private final int max = size();
32216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
32316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            private int index;
32416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
32516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            public ASN1Encodable readObject() throws IOException
32616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
32716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (index == max)
32816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
32916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return null;
33016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
33116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
33216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                ASN1Encodable obj = getObjectAt(index++);
33316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (obj instanceof ASN1Sequence)
33416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
33516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return ((ASN1Sequence)obj).parser();
33616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
33716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                if (obj instanceof ASN1Set)
33816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
33916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    return ((ASN1Set)obj).parser();
34016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
34116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
34216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return obj;
34316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
34416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
34516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            public ASN1Primitive getLoadedObject()
34616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
34716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return outer;
34816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
34916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
35016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            public ASN1Primitive toASN1Primitive()
35116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
35216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return outer;
35316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
35416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        };
35516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
35616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
35716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public int hashCode()
35816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
35916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        Enumeration             e = this.getObjects();
36016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        int                     hashCode = size();
36116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
36216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        while (e.hasMoreElements())
36316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
36416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            Object o = getNext(e);
36516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            hashCode *= 17;
36616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
36716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            hashCode ^= o.hashCode();
36816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
36916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
37016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return hashCode;
37116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
37216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
37353b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    /**
37453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * Change current SET object to be encoded as {@link DERSet}.
37553b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * This is part of Distinguished Encoding Rules form serialization.
37653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     */
37716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    ASN1Primitive toDERObject()
37816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
37916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (isSorted)
38016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
38116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Set derSet = new DERSet();
38216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
38316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            derSet.set = this.set;
38416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
38516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return derSet;
38616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
38716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        else
38816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
38916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            Vector v = new Vector();
39016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
39116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            for (int i = 0; i != set.size(); i++)
39216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
39316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                v.addElement(set.elementAt(i));
39416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
39516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
39616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Set derSet = new DERSet();
39716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
39816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            derSet.set = v;
39916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
40016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            derSet.sort();
40116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
40216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return derSet;
40316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
40416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
40516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
40653b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    /**
40753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * Change current SET object to be encoded as {@link DLSet}.
40853b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     * This is part of Direct Length form serialization.
40953b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro     */
41016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    ASN1Primitive toDLObject()
41116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
41216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Set derSet = new DLSet();
41316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
41416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        derSet.set = this.set;
41516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
41616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return derSet;
41716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
41816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
41916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    boolean asn1Equals(
42016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Primitive o)
42116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
42216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (!(o instanceof ASN1Set))
42316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
42416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return false;
42516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
42616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
42716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Set   other = (ASN1Set)o;
42816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
42916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (this.size() != other.size())
43016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
43116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return false;
43216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
43316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
43416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        Enumeration s1 = this.getObjects();
43516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        Enumeration s2 = other.getObjects();
43616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
43716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        while (s1.hasMoreElements())
43816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
43916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Encodable obj1 = getNext(s1);
44016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Encodable obj2 = getNext(s2);
44116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
44216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Primitive o1 = obj1.toASN1Primitive();
44316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            ASN1Primitive o2 = obj2.toASN1Primitive();
44416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
44516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (o1 == o2 || o1.equals(o2))
44616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
44716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                continue;
44816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
44916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
45016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return false;
45116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
45216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
45316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return true;
45416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
45516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
45616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private ASN1Encodable getNext(Enumeration e)
45716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
45816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Encodable encObj = (ASN1Encodable)e.nextElement();
45916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
46016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        // unfortunately null was allowed as a substitute for DER null
46116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (encObj == null)
46216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
46316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            return DERNull.INSTANCE;
46416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
46516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
46616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return encObj;
46716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
46816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
46916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    /**
47016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     * return true if a <= b (arrays are assumed padded with zeros).
47116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro     */
47216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    private boolean lessThanOrEqual(
47316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro         byte[] a,
47416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro         byte[] b)
47516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
47616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        int len = Math.min(a.length, b.length);
47716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        for (int i = 0; i != len; ++i)
47816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
47916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (a[i] != b[i])
48016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
48116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                return (a[i] & 0xff) < (b[i] & 0xff);
48216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
48316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
48416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return len == a.length;
48516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
48616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
48753b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro    private byte[] getDEREncoded(
48816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        ASN1Encodable obj)
48916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
49016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        try
49116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
49253b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro            return obj.toASN1Primitive().getEncoded(ASN1Encoding.DER);
49316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
49416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        catch (IOException e)
49516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
49616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            throw new IllegalArgumentException("cannot encode object added to SET");
49716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
49816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
49916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
50016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    protected void sort()
50116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
50216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        if (!isSorted)
50316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        {
50416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            isSorted = true;
50516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            if (set.size() > 1)
50616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            {
50716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                boolean    swapped = true;
50816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                int        lastSwap = set.size() - 1;
50916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
51016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                while (swapped)
51116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                {
51216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    int    index = 0;
51316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    int    swapIndex = 0;
51453b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                    byte[] a = getDEREncoded((ASN1Encodable)set.elementAt(0));
51516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
51616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    swapped = false;
51716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
51816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    while (index != lastSwap)
51916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    {
52053b61f9fe9d58034fcc7021137e92460f91b70ceSergio Giro                        byte[] b = getDEREncoded((ASN1Encodable)set.elementAt(index + 1));
52116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
52216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        if (lessThanOrEqual(a, b))
52316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        {
52416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            a = b;
52516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        }
52616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        else
52716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        {
52816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            Object  o = set.elementAt(index);
52916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
53016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            set.setElementAt(set.elementAt(index + 1), index);
53116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            set.setElementAt(o, index + 1);
53216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
53316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            swapped = true;
53416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                            swapIndex = index;
53516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        }
53616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
53716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                        index++;
53816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    }
53916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
54016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                    lastSwap = swapIndex;
54116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro                }
54216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            }
54316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        }
54416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
54516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
54616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    boolean isConstructed()
54716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
54816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return true;
54916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
55016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
55116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    abstract void encode(ASN1OutputStream out)
55216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro            throws IOException;
55316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro
55416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    public String toString()
55516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    {
55616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro        return set.toString();
55716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro    }
558bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro
559bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    public Iterator<ASN1Encodable> iterator()
560bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    {
561bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro        return new Arrays.Iterator<ASN1Encodable>(toArray());
562bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro    }
56316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro}
564