1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException;
4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * DER PrintableString object.
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERPrintableString
9c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    extends ASN1Object
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    implements DERString
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    // BEGIN android-changed
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    private final String string;
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    // END android-changed
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return a printable string from the passed in object.
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the object cannot be converted.
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static DERPrintableString getInstance(
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        Object  obj)
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj == null || obj instanceof DERPrintableString)
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return (DERPrintableString)obj;
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1OctetString)
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return new DERPrintableString(((ASN1OctetString)obj).getOctets());
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (obj instanceof ASN1TaggedObject)
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return getInstance(((ASN1TaggedObject)obj).getObject());
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return a Printable String from a tagged object.
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param obj the tagged object holding the object we want
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param explicit true if the object is meant to be explicitly
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *              tagged false otherwise.
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @exception IllegalArgumentException if the tagged object cannot
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *               be converted.
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static DERPrintableString getInstance(
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        ASN1TaggedObject obj,
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        boolean          explicit)
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return getInstance(obj.getObject());
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * basic constructor - byte encoded string.
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERPrintableString(
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]   string)
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        char[]  cs = new char[string.length];
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != cs.length; i++)
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            cs[i] = (char)(string[i] & 0xff);
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // BEGIN android-changed
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.string = new String(cs).intern();
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // END android-changed
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
77c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * basic constructor - this does not validate the string
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public DERPrintableString(
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        String   string)
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        this(string, false);
83c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
84c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
85c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
86c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * Constructor with optional validation.
87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     *
88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param string the base string to wrap.
89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param validate whether or not to check the string.
90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @throws IllegalArgumentException if validate is true and the string
91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * contains characters that should not be in a PrintableString.
92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public DERPrintableString(
94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String   string,
95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        boolean  validate)
96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        if (validate && !isPrintableString(string))
98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            throw new IllegalArgumentException("string contains illegal characters");
100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // BEGIN android-changed
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.string = string.intern();
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        // END android-changed
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
106b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
107b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String getString()
108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return string;
110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
112b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getOctets()
113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        char[]  cs = string.toCharArray();
115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  bs = new byte[cs.length];
116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
117b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        for (int i = 0; i != cs.length; i++)
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            bs[i] = (byte)cs[i];
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return bs;
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
125b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    void encode(
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DEROutputStream  out)
127b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        throws IOException
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        out.writeEncoded(PRINTABLE_STRING, this.getOctets());
130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
131b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int hashCode()
133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
134b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return this.getString().hashCode();
135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
137c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    boolean asn1Equals(
138c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        DERObject  o)
139b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (!(o instanceof DERPrintableString))
141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
142b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return false;
143b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        DERPrintableString  s = (DERPrintableString)o;
146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return this.getString().equals(s.getString());
148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public String toString()
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
152c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return string;
153c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
154c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
155c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
156c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * return true if the passed in String can be represented without
157c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * loss as a PrintableString, false otherwise.
158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     *
159c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return true if in printable set, false otherwise.
160c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public static boolean isPrintableString(
162c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        String  str)
163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
164c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        for (int i = str.length() - 1; i >= 0; i--)
165c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        {
166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            char    ch = str.charAt(i);
167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
168c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if (ch > 0x007f)
169c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
170c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                return false;
171c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
172c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if ('a' <= ch && ch <= 'z')
174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
176c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if ('A' <= ch && ch <= 'Z')
179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
180c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
181c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
182c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
183c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            if ('0' <= ch && ch <= '9')
184c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            switch (ch)
189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            {
190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case ' ':
191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '\'':
192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '(':
193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case ')':
194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '+':
195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '-':
196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '.':
197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case ':':
198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '=':
199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '?':
200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case '/':
201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            case ',':
202c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom                continue;
203c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            }
204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom            return false;
206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        }
207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        return true;
209b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
210b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
211