1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
6c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * ASN.1 TaggedObject - in ASN.1 notation this is any object preceded by
7c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * a [n] where n is some number - these are assumed to follow the construction
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * rules (as with sequences).
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic abstract class ASN1TaggedObject
114c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    extends ASN1Primitive
12c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    implements ASN1TaggedObjectParser
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    int             tagNo;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    boolean         empty = false;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    boolean         explicit = true;
174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Encodable obj = null;
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    static public ASN1TaggedObject getInstance(
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1TaggedObject)obj.getObject();
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("implicitly tagged tagged object");
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    static public ASN1TaggedObject getInstance(
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object obj)
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof ASN1TaggedObject)
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return (ASN1TaggedObject)obj;
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
384c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else if (obj instanceof byte[])
394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
404c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            try
414c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
424c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                return ASN1TaggedObject.getInstance(fromByteArray((byte[])obj));
434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
444c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            catch (IOException e)
454c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
464c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                throw new IllegalArgumentException("failed to construct tagged object from byte[]: " + e.getMessage());
474c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
484c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
50c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new IllegalArgumentException("unknown object in getInstance: " + obj.getClass().getName());
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Create a tagged object with the style given by the value of explicit.
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * If the object implements ASN1Choice the tag style will always be changed
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * to explicit in accordance with the ASN.1 encoding rules.
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </p>
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is explicitly tagged.
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param tagNo the tag number for this object.
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public ASN1TaggedObject(
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean         explicit,
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int             tagNo,
664c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Encodable   obj)
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1Choice)
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.explicit = true;
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.explicit = explicit;
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.tagNo = tagNo;
784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
794c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        if (this.explicit)
804c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.obj = obj;
824c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
834c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        else
844c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        {
854c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            ASN1Primitive prim = obj.toASN1Primitive();
864c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
874c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (prim instanceof ASN1Set)
884c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            {
894c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom                ASN1Set s = null;
904c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            }
914c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            this.obj = obj;
934c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        }
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
974c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        ASN1Primitive o)
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (!(o instanceof ASN1TaggedObject))
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject other = (ASN1TaggedObject)o;
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if(obj == null)
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
113c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (other.obj != null)
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return false;
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            if (!(obj.toASN1Primitive().equals(other.obj.toASN1Primitive())))
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return false;
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int hashCode()
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int code = tagNo;
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
133c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // TODO: actually this is wrong - the problem is that a re-encoded
134c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // object may end up with a different hashCode due to implicit
135c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // tagging. As implicit tagging is ambiguous if a sequence is involved
136c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // it seems the only correct method for both equals and hashCode is to
137c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        // compare the encodings...
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj != null)
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            code ^= obj.hashCode();
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return code;
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getTagNo()
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return tagNo;
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return whether or not the object may be explicitly tagged.
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Note: if the object has been read from an input stream, the only
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * time you can be sure if isExplicit is returning the true state of
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * affairs is if it returns false. An implicitly tagged object may appear
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * to be explicitly tagged, so you need to understand the context under
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * which the reading was done as well, see getObject below.
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isExplicit()
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return explicit;
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isEmpty()
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return empty;
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return whatever was following the tag.
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Note: tagged objects are generally context dependent if you're
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * trying to extract a tagged object you should be going via the
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * appropriate getInstance method.
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
1774c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive getObject()
178b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
179b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj != null)
180b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
1814c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom            return obj.toASN1Primitive();
182b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
183b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
184b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
185b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
186b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Return the object held in this tagged object as a parser assuming it has
189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * the type of the passed in tag. If the object doesn't have a parser
190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * associated with it, the base object is returned.
191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
1924c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Encodable getObjectParser(
193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        int     tag,
194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean isExplicit)
195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        switch (tag)
197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
1984c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        case BERTags.SET:
199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return ASN1Set.getInstance(this, isExplicit).parser();
2004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        case BERTags.SEQUENCE:
201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return ASN1Sequence.getInstance(this, isExplicit).parser();
2024c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        case BERTags.OCTET_STRING:
203c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return ASN1OctetString.getInstance(this, isExplicit).parser();
204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (isExplicit)
207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return getObject();
209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        throw new RuntimeException("implicit tagging not implemented for tag: " + tag);
212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
2144c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    public ASN1Primitive getLoadedObject()
2156e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    {
2164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return this.toASN1Primitive();
2176e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom    }
2184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2194c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDERObject()
2204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new DERTaggedObject(explicit, tagNo, obj);
2224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2244c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    ASN1Primitive toDLObject()
2254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    {
2264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom        return new DLTaggedObject(explicit, tagNo, obj);
2274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    }
2284c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom
2294c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom    abstract void encode(ASN1OutputStream out)
230b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException;
231b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
232b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
233b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
234b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "[" + tagNo + "]" + obj;
235b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
236b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
237