1 package org.bouncycastle.asn1; 2 3 import java.io.ByteArrayOutputStream; 4 import java.io.IOException; 5 6 import org.bouncycastle.util.Arrays; 7 8 /** 9 * DER UniversalString object. 10 */ 11 public class DERUniversalString 12 extends ASN1Primitive 13 implements ASN1String 14 { 15 private static final char[] table = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; 16 private byte[] string; 17 18 /** 19 * return a Universal String from the passed in object. 20 * 21 * @exception IllegalArgumentException if the object cannot be converted. 22 */ 23 public static DERUniversalString getInstance( 24 Object obj) 25 { 26 if (obj == null || obj instanceof DERUniversalString) 27 { 28 return (DERUniversalString)obj; 29 } 30 31 if (obj instanceof byte[]) 32 { 33 try 34 { 35 return (DERUniversalString)fromByteArray((byte[])obj); 36 } 37 catch (Exception e) 38 { 39 throw new IllegalArgumentException("encoding error getInstance: " + e.toString()); 40 } 41 } 42 43 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 44 } 45 46 /** 47 * return a Universal String from a tagged object. 48 * 49 * @param obj the tagged object holding the object we want 50 * @param explicit true if the object is meant to be explicitly 51 * tagged false otherwise. 52 * @exception IllegalArgumentException if the tagged object cannot 53 * be converted. 54 */ 55 public static DERUniversalString getInstance( 56 ASN1TaggedObject obj, 57 boolean explicit) 58 { 59 ASN1Primitive o = obj.getObject(); 60 61 if (explicit || o instanceof DERUniversalString) 62 { 63 return getInstance(o); 64 } 65 else 66 { 67 return new DERUniversalString(((ASN1OctetString)o).getOctets()); 68 } 69 } 70 71 /** 72 * basic constructor - byte encoded string. 73 */ 74 public DERUniversalString( 75 byte[] string) 76 { 77 this.string = string; 78 } 79 80 public String getString() 81 { 82 StringBuffer buf = new StringBuffer("#"); 83 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 84 ASN1OutputStream aOut = new ASN1OutputStream(bOut); 85 86 try 87 { 88 aOut.writeObject(this); 89 } 90 catch (IOException e) 91 { 92 throw new RuntimeException("internal error encoding BitString"); 93 } 94 95 byte[] string = bOut.toByteArray(); 96 97 for (int i = 0; i != string.length; i++) 98 { 99 buf.append(table[(string[i] >>> 4) & 0xf]); 100 buf.append(table[string[i] & 0xf]); 101 } 102 103 return buf.toString(); 104 } 105 106 public String toString() 107 { 108 return getString(); 109 } 110 111 public byte[] getOctets() 112 { 113 return string; 114 } 115 116 boolean isConstructed() 117 { 118 return false; 119 } 120 121 int encodedLength() 122 { 123 return 1 + StreamUtil.calculateBodyLength(string.length) + string.length; 124 } 125 126 void encode( 127 ASN1OutputStream out) 128 throws IOException 129 { 130 out.writeEncoded(BERTags.UNIVERSAL_STRING, this.getOctets()); 131 } 132 133 boolean asn1Equals( 134 ASN1Primitive o) 135 { 136 if (!(o instanceof DERUniversalString)) 137 { 138 return false; 139 } 140 141 return Arrays.areEqual(string, ((DERUniversalString)o).string); 142 } 143 144 public int hashCode() 145 { 146 return Arrays.hashCode(string); 147 } 148 } 149