001 package org.apache.commons.ssl.asn1; 002 003 import java.io.IOException; 004 005 /** DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }. */ 006 public class DERNumericString 007 extends ASN1Object 008 implements DERString { 009 String string; 010 011 /** 012 * return a Numeric string from the passed in object 013 * 014 * @throws IllegalArgumentException if the object cannot be converted. 015 */ 016 public static DERNumericString getInstance( 017 Object obj) { 018 if (obj == null || obj instanceof DERNumericString) { 019 return (DERNumericString) obj; 020 } 021 022 if (obj instanceof ASN1OctetString) { 023 return new DERNumericString(((ASN1OctetString) obj).getOctets()); 024 } 025 026 if (obj instanceof ASN1TaggedObject) { 027 return getInstance(((ASN1TaggedObject) obj).getObject()); 028 } 029 030 throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName()); 031 } 032 033 /** 034 * return an Numeric String from a tagged object. 035 * 036 * @param obj the tagged object holding the object we want 037 * @param explicit true if the object is meant to be explicitly 038 * tagged false otherwise. 039 * @throws IllegalArgumentException if the tagged object cannot 040 * be converted. 041 */ 042 public static DERNumericString getInstance( 043 ASN1TaggedObject obj, 044 boolean explicit) { 045 return getInstance(obj.getObject()); 046 } 047 048 /** basic constructor - with bytes. */ 049 public DERNumericString( 050 byte[] string) { 051 char[] cs = new char[string.length]; 052 053 for (int i = 0; i != cs.length; i++) { 054 cs[i] = (char) (string[i] & 0xff); 055 } 056 057 this.string = new String(cs); 058 } 059 060 /** basic constructor - without validation.. */ 061 public DERNumericString( 062 String string) { 063 this(string, false); 064 } 065 066 /** 067 * Constructor with optional validation. 068 * 069 * @param string the base string to wrap. 070 * @param validate whether or not to check the string. 071 * @throws IllegalArgumentException if validate is true and the string 072 * contains characters that should not be in a NumericString. 073 */ 074 public DERNumericString( 075 String string, 076 boolean validate) { 077 if (validate && !isNumericString(string)) { 078 throw new IllegalArgumentException("string contains illegal characters"); 079 } 080 081 this.string = string; 082 } 083 084 public String getString() { 085 return string; 086 } 087 088 public String toString() { 089 return string; 090 } 091 092 public byte[] getOctets() { 093 char[] cs = string.toCharArray(); 094 byte[] bs = new byte[cs.length]; 095 096 for (int i = 0; i != cs.length; i++) { 097 bs[i] = (byte) cs[i]; 098 } 099 100 return bs; 101 } 102 103 void encode( 104 DEROutputStream out) 105 throws IOException { 106 out.writeEncoded(NUMERIC_STRING, this.getOctets()); 107 } 108 109 public int hashCode() { 110 return this.getString().hashCode(); 111 } 112 113 boolean asn1Equals( 114 DERObject o) { 115 if (!(o instanceof DERNumericString)) { 116 return false; 117 } 118 119 DERNumericString s = (DERNumericString) o; 120 121 return this.getString().equals(s.getString()); 122 } 123 124 /** 125 * Return true if the string can be represented as a NumericString ('0'..'9', ' ') 126 * 127 * @param str string to validate. 128 * @return true if numeric, fale otherwise. 129 */ 130 public static boolean isNumericString( 131 String str) { 132 for (int i = str.length() - 1; i >= 0; i--) { 133 char ch = str.charAt(i); 134 135 if (ch > 0x007f) { 136 return false; 137 } 138 139 if (('0' <= ch && ch <= '9') || ch == ' ') { 140 continue; 141 } 142 143 return false; 144 } 145 146 return true; 147 } 148 }