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