ASN1TaggedObject.java revision b61a96e7ef1a78acf013bbf08fe537e5b5f129ca
1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * ASN.1 TaggedObject - in ASN.1 nottation this is any object proceeded by
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * a [n] where n is some number - these are assume to follow the construction
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * rules (as with sequences).
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic abstract class ASN1TaggedObject
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    extends DERObject
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    int             tagNo;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    boolean         empty = false;
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    boolean         explicit = true;
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    DEREncodable    obj = null;
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    static public ASN1TaggedObject getInstance(
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject    obj,
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean             explicit)
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (explicit)
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (ASN1TaggedObject)obj.getObject();
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("implicitly tagged tagged object");
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    static public ASN1TaggedObject getInstance(
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object obj)
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof ASN1TaggedObject)
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return (ASN1TaggedObject)obj;
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("unknown object in getInstance");
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Create a tagged object in the explicit style.
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param tagNo the tag number for this object.
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public ASN1TaggedObject(
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int             tagNo,
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DEREncodable    obj)
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.explicit = true;
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.tagNo = tagNo;
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.obj = obj;
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Create a tagged object with the style given by the value of explicit.
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * If the object implements ASN1Choice the tag style will always be changed
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * to explicit in accordance with the ASN.1 encoding rules.
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * </p>
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is explicitly tagged.
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param tagNo the tag number for this object.
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object.
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public ASN1TaggedObject(
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean         explicit,
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int             tagNo,
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DEREncodable    obj)
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1Choice)
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.explicit = true;
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            this.explicit = explicit;
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.tagNo = tagNo;
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.obj = obj;
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean equals(
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object o)
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (!(o instanceof ASN1TaggedObject))
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject other = (ASN1TaggedObject)o;
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if(obj == null)
100b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if(other.obj != null)
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return false;
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            if(!(obj.equals(other.obj)))
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                return false;
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return true;
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int hashCode()
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int code = tagNo;
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj != null)
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            code ^= obj.hashCode();
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return code;
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getTagNo()
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return tagNo;
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return whether or not the object may be explicitly tagged.
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Note: if the object has been read from an input stream, the only
138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * time you can be sure if isExplicit is returning the true state of
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * affairs is if it returns false. An implicitly tagged object may appear
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * to be explicitly tagged, so you need to understand the context under
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * which the reading was done as well, see getObject below.
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isExplicit()
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return explicit;
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public boolean isEmpty()
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return empty;
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return whatever was following the tag.
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * <p>
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * Note: tagged objects are generally context dependent if you're
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * trying to extract a tagged object you should be going via the
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * appropriate getInstance method.
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERObject getObject()
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj != null)
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return obj.getDERObject();
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return null;
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    abstract void encode(DEROutputStream  out)
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException;
172b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
173b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
174b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
175b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return "[" + tagNo + "]" + obj;
176b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
177b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
178