1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.asn1; 2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallamimport java.io.IOException; 4b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 54c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.util.Arrays; 64c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstromimport org.bouncycastle.util.Strings; 74c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom 8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/** 9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * DER PrintableString object. 10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic class DERPrintableString 124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom extends ASN1Primitive 134c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom implements ASN1String 14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{ 15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // BEGIN android-changed 164c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom private final byte[] string; 17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam // END android-changed 18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a printable string from the passed in object. 21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the object cannot be converted. 23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERPrintableString getInstance( 25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam Object obj) 26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (obj == null || obj instanceof DERPrintableString) 28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return (DERPrintableString)obj; 30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 3270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom if (obj instanceof byte[]) 3370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 3470c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom try 3570c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 3670c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom return (DERPrintableString)fromByteArray((byte[])obj); 3770c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 3870c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom catch (Exception e) 3970c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom { 4070c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); 4170c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 4270c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom } 4370c8287138e69a98c2f950036f9f703ee37228c8Brian Carlstrom 44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * return a Printable String from a tagged object. 49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * 50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param obj the tagged object holding the object we want 51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @param explicit true if the object is meant to be explicitly 52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * tagged false otherwise. 53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * @exception IllegalArgumentException if the tagged object cannot 54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * be converted. 55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public static DERPrintableString getInstance( 57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam ASN1TaggedObject obj, 58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam boolean explicit) 59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 604c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o = obj.getObject(); 616e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom 626e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom if (explicit || o instanceof DERPrintableString) 636e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 646e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return getInstance(o); 656e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 666e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom else 676e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom { 686e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom return new DERPrintableString(ASN1OctetString.getInstance(o).getOctets()); 696e736056d64d0e33b26cf9f7c4e351b496241fdeBrian Carlstrom } 70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * basic constructor - byte encoded string. 74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 754c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom DERPrintableString( 76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam byte[] string) 77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 784c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.string = string; 79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam /** 82c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * basic constructor - this does not validate the string 83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */ 84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public DERPrintableString( 85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam String string) 86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 87c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom this(string, false); 88c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 89c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 90c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 91c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * Constructor with optional validation. 92c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 93c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param string the base string to wrap. 94c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @param validate whether or not to check the string. 95c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @throws IllegalArgumentException if validate is true and the string 96c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * contains characters that should not be in a PrintableString. 97c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 98c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public DERPrintableString( 99c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String string, 100c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean validate) 101c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 102c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (validate && !isPrintableString(string)) 103c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 104c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom throw new IllegalArgumentException("string contains illegal characters"); 105c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 106c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 1074c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom this.string = Strings.toByteArray(string); 108b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 110b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String getString() 111b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1124c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return Strings.fromByteArray(string); 113b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 114b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 115b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public byte[] getOctets() 116b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1174c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return Arrays.clone(string); 1184c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 119b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1204c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom boolean isConstructed() 1214c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1224c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return false; 1234c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom } 124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1254c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom int encodedLength() 1264c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom { 1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; 128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 130b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam void encode( 1314c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1OutputStream out) 132b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam throws IOException 133b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1344c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom out.writeEncoded(BERTags.PRINTABLE_STRING, string); 135b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 136b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 137b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public int hashCode() 138b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1394c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return Arrays.hashCode(string); 140b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 141b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom boolean asn1Equals( 1434c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom ASN1Primitive o) 144b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 145b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam if (!(o instanceof DERPrintableString)) 146b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 147b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam return false; 148b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 149b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam DERPrintableString s = (DERPrintableString)o; 151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 1524c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return Arrays.areEqual(string, s.string); 153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam 155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam public String toString() 156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam { 1574c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom return getString(); 158c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 159c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 160c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom /** 161c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * return true if the passed in String can be represented without 162c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * loss as a PrintableString, false otherwise. 163c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * 164c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom * @return true if in printable set, false otherwise. 165c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom */ 166c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom public static boolean isPrintableString( 167c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom String str) 168c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 169c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom for (int i = str.length() - 1; i >= 0; i--) 170c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 171c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom char ch = str.charAt(i); 172c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 173c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if (ch > 0x007f) 174c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 175c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return false; 176c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 177c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 178c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ('a' <= ch && ch <= 'z') 179c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 180c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 181c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 182c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 183c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ('A' <= ch && ch <= 'Z') 184c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 185c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 186c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 187c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 188c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom if ('0' <= ch && ch <= '9') 189c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 190c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 191c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 192c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 193c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom switch (ch) 194c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom { 195c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case ' ': 196c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '\'': 197c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '(': 198c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case ')': 199c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '+': 200c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '-': 201c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '.': 202c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case ':': 203c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '=': 204c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '?': 205c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case '/': 206c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom case ',': 207c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom continue; 208c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 209c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 210c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return false; 211c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom } 212c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom 213c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom return true; 214b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam } 215b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam} 216