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