1 package org.bouncycastle.asn1; 2 3 import java.io.IOException; 4 5 import org.bouncycastle.util.Arrays; 6 import org.bouncycastle.util.Strings; 7 8 /** 9 * ASN.1 VisibleString object encoding ISO 646 (ASCII) character code points 32 to 126. 10 * <p> 11 * Explicit character set escape sequences are not allowed. 12 * </p> 13 */ 14 public abstract class ASN1VisibleString 15 extends ASN1Primitive 16 implements ASN1String 17 { 18 static final ASN1UniversalType TYPE = new ASN1UniversalType(ASN1VisibleString.class, BERTags.VISIBLE_STRING) 19 { 20 ASN1Primitive fromImplicitPrimitive(DEROctetString octetString) 21 { 22 return createPrimitive(octetString.getOctets()); 23 } 24 }; 25 26 /** 27 * Return a Visible String from the passed in object. 28 * 29 * @param obj an ASN1VisibleString or an object that can be converted into one. 30 * @exception IllegalArgumentException if the object cannot be converted. 31 * @return an ASN1VisibleString instance, or null 32 */ getInstance( Object obj)33 public static ASN1VisibleString getInstance( 34 Object obj) 35 { 36 if (obj == null || obj instanceof ASN1VisibleString) 37 { 38 return (ASN1VisibleString)obj; 39 } 40 if (obj instanceof ASN1Encodable) 41 { 42 ASN1Primitive primitive = ((ASN1Encodable)obj).toASN1Primitive(); 43 if (primitive instanceof ASN1VisibleString) 44 { 45 return (ASN1VisibleString)primitive; 46 } 47 } 48 if (obj instanceof byte[]) 49 { 50 try 51 { 52 return (ASN1VisibleString)TYPE.fromByteArray((byte[])obj); 53 } 54 catch (Exception e) 55 { 56 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString()); 57 } 58 } 59 60 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 61 } 62 63 /** 64 * Return a Visible String from a tagged object. 65 * 66 * @param taggedObject the tagged object holding the object we want 67 * @param explicit true if the object is meant to be explicitly 68 * tagged false otherwise. 69 * @exception IllegalArgumentException if the tagged object cannot 70 * be converted. 71 * @return an ASN1VisibleString instance, or null 72 */ getInstance(ASN1TaggedObject taggedObject, boolean explicit)73 public static ASN1VisibleString getInstance(ASN1TaggedObject taggedObject, boolean explicit) 74 { 75 return (ASN1VisibleString)TYPE.getContextInstance(taggedObject, explicit); 76 } 77 78 final byte[] contents; 79 ASN1VisibleString(String string)80 ASN1VisibleString(String string) 81 { 82 this.contents = Strings.toByteArray(string); 83 } 84 ASN1VisibleString(byte[] contents, boolean clone)85 ASN1VisibleString(byte[] contents, boolean clone) 86 { 87 this.contents = clone ? Arrays.clone(contents) : contents; 88 } 89 getString()90 public final String getString() 91 { 92 return Strings.fromByteArray(contents); 93 } 94 toString()95 public String toString() 96 { 97 return getString(); 98 } 99 getOctets()100 public final byte[] getOctets() 101 { 102 return Arrays.clone(contents); 103 } 104 encodeConstructed()105 final boolean encodeConstructed() 106 { 107 return false; 108 } 109 encodedLength(boolean withTag)110 final int encodedLength(boolean withTag) 111 { 112 return ASN1OutputStream.getLengthOfEncodingDL(withTag, contents.length); 113 } 114 encode(ASN1OutputStream out, boolean withTag)115 final void encode(ASN1OutputStream out, boolean withTag) throws IOException 116 { 117 out.writeEncodingDL(withTag, BERTags.VISIBLE_STRING, contents); 118 } 119 asn1Equals(ASN1Primitive other)120 final boolean asn1Equals(ASN1Primitive other) 121 { 122 if (!(other instanceof ASN1VisibleString)) 123 { 124 return false; 125 } 126 127 ASN1VisibleString that = (ASN1VisibleString)other; 128 129 return Arrays.areEqual(this.contents, that.contents); 130 } 131 hashCode()132 public final int hashCode() 133 { 134 return Arrays.hashCode(contents); 135 } 136 createPrimitive(byte[] contents)137 static ASN1VisibleString createPrimitive(byte[] contents) 138 { 139 return new DERVisibleString(contents, false); 140 } 141 } 142