Home | History | Annotate | Download | only in asn1
      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  * DER NumericString object - this is an ascii string of characters {0,1,2,3,4,5,6,7,8,9, }.
     10  */
     11 public class DERNumericString
     12     extends ASN1Primitive
     13     implements ASN1String
     14 {
     15     private final byte[]  string;
     16 
     17     /**
     18      * return a Numeric string from the passed in object
     19      *
     20      * @param obj a DERNumericString or an object that can be converted into one.
     21      * @exception IllegalArgumentException if the object cannot be converted.
     22      * @return a DERNumericString instance, or null
     23      */
     24     public static DERNumericString getInstance(
     25         Object  obj)
     26     {
     27         if (obj == null || obj instanceof DERNumericString)
     28         {
     29             return (DERNumericString)obj;
     30         }
     31 
     32         if (obj instanceof byte[])
     33         {
     34             try
     35             {
     36                 return (DERNumericString)fromByteArray((byte[])obj);
     37             }
     38             catch (Exception e)
     39             {
     40                 throw new IllegalArgumentException("encoding error in getInstance: " + e.toString());
     41             }
     42         }
     43 
     44         throw new IllegalArgumentException("illegal object in getInstance: " + obj.getClass().getName());
     45     }
     46 
     47     /**
     48      * return an Numeric String from a tagged object.
     49      *
     50      * @param obj the tagged object holding the object we want
     51      * @param explicit true if the object is meant to be explicitly
     52      *              tagged false otherwise.
     53      * @exception IllegalArgumentException if the tagged object cannot
     54      *               be converted.
     55      * @return a DERNumericString instance, or null.
     56      */
     57     public static DERNumericString getInstance(
     58         ASN1TaggedObject obj,
     59         boolean          explicit)
     60     {
     61         ASN1Primitive o = obj.getObject();
     62 
     63         if (explicit || o instanceof DERNumericString)
     64         {
     65             return getInstance(o);
     66         }
     67         else
     68         {
     69             return new DERNumericString(ASN1OctetString.getInstance(o).getOctets());
     70         }
     71     }
     72 
     73     /**
     74      * basic constructor - with bytes.
     75      */
     76     DERNumericString(
     77         byte[]   string)
     78     {
     79         this.string = string;
     80     }
     81 
     82     /**
     83      * basic constructor -  without validation..
     84      */
     85     public DERNumericString(
     86         String   string)
     87     {
     88         this(string, false);
     89     }
     90 
     91     /**
     92      * Constructor with optional validation.
     93      *
     94      * @param string the base string to wrap.
     95      * @param validate whether or not to check the string.
     96      * @throws IllegalArgumentException if validate is true and the string
     97      * contains characters that should not be in a NumericString.
     98      */
     99     public DERNumericString(
    100         String   string,
    101         boolean  validate)
    102     {
    103         if (validate && !isNumericString(string))
    104         {
    105             throw new IllegalArgumentException("string contains illegal characters");
    106         }
    107 
    108         this.string = Strings.toByteArray(string);
    109     }
    110 
    111     public String getString()
    112     {
    113         return Strings.fromByteArray(string);
    114     }
    115 
    116     public String toString()
    117     {
    118         return getString();
    119     }
    120 
    121     public byte[] getOctets()
    122     {
    123         return Arrays.clone(string);
    124     }
    125 
    126     boolean isConstructed()
    127     {
    128         return false;
    129     }
    130 
    131     int encodedLength()
    132     {
    133         return 1 + StreamUtil.calculateBodyLength(string.length) + string.length;
    134     }
    135 
    136     void encode(
    137         ASN1OutputStream out)
    138         throws IOException
    139     {
    140         out.writeEncoded(BERTags.NUMERIC_STRING, string);
    141     }
    142 
    143     public int hashCode()
    144     {
    145         return Arrays.hashCode(string);
    146     }
    147 
    148     boolean asn1Equals(
    149         ASN1Primitive o)
    150     {
    151         if (!(o instanceof DERNumericString))
    152         {
    153             return false;
    154         }
    155 
    156         DERNumericString  s = (DERNumericString)o;
    157 
    158         return Arrays.areEqual(string, s.string);
    159     }
    160 
    161     /**
    162      * Return true if the string can be represented as a NumericString ('0'..'9', ' ')
    163      *
    164      * @param str string to validate.
    165      * @return true if numeric, fale otherwise.
    166      */
    167     public static boolean isNumericString(
    168         String  str)
    169     {
    170         for (int i = str.length() - 1; i >= 0; i--)
    171         {
    172             char    ch = str.charAt(i);
    173 
    174             if (ch > 0x007f)
    175             {
    176                 return false;
    177             }
    178 
    179             if (('0' <= ch && ch <= '9') || ch == ' ')
    180             {
    181                 continue;
    182             }
    183 
    184             return false;
    185         }
    186 
    187         return true;
    188     }
    189 }
    190