Home | History | Annotate | Download | only in x509
      1 package org.bouncycastle.asn1.x509;
      2 
      3 import java.io.IOException;
      4 
      5 import org.bouncycastle.asn1.ASN1InputStream;
      6 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
      7 import org.bouncycastle.asn1.ASN1Primitive;
      8 import org.bouncycastle.asn1.DERPrintableString;
      9 import org.bouncycastle.util.Strings;
     10 
     11 /**
     12  * It turns out that the number of standard ways the fields in a DN should be
     13  * encoded into their ASN.1 counterparts is rapidly approaching the
     14  * number of machines on the internet. By default the X509Name class
     15  * will produce UTF8Strings in line with the current recommendations (RFC 3280).
     16  * <p>
     17  * An example of an encoder look like below:
     18  * <pre>
     19  * public class X509DirEntryConverter
     20  *     extends X509NameEntryConverter
     21  * {
     22  *     public ASN1Primitive getConvertedValue(
     23  *         ASN1ObjectIdentifier  oid,
     24  *         String               value)
     25  *     {
     26  *         if (str.length() != 0 &amp;&amp; str.charAt(0) == '#')
     27  *         {
     28  *             return convertHexEncoded(str, 1);
     29  *         }
     30  *         if (oid.equals(EmailAddress))
     31  *         {
     32  *             return new DERIA5String(str);
     33  *         }
     34  *         else if (canBePrintable(str))
     35  *         {
     36  *             return new DERPrintableString(str);
     37  *         }
     38  *         else if (canBeUTF8(str))
     39  *         {
     40  *             return new DERUTF8String(str);
     41  *         }
     42  *         else
     43  *         {
     44  *             return new DERBMPString(str);
     45  *         }
     46  *     }
     47  * }
     48  * </pre>
     49  */
     50 public abstract class X509NameEntryConverter
     51 {
     52     /**
     53      * Convert an inline encoded hex string rendition of an ASN.1
     54      * object back into its corresponding ASN.1 object.
     55      *
     56      * @param str the hex encoded object
     57      * @param off the index at which the encoding starts
     58      * @return the decoded object
     59      */
     60     protected ASN1Primitive convertHexEncoded(
     61         String  str,
     62         int     off)
     63         throws IOException
     64     {
     65         str = Strings.toLowerCase(str);
     66         byte[] data = new byte[(str.length() - off) / 2];
     67         for (int index = 0; index != data.length; index++)
     68         {
     69             char left = str.charAt((index * 2) + off);
     70             char right = str.charAt((index * 2) + off + 1);
     71 
     72             if (left < 'a')
     73             {
     74                 data[index] = (byte)((left - '0') << 4);
     75             }
     76             else
     77             {
     78                 data[index] = (byte)((left - 'a' + 10) << 4);
     79             }
     80             if (right < 'a')
     81             {
     82                 data[index] |= (byte)(right - '0');
     83             }
     84             else
     85             {
     86                 data[index] |= (byte)(right - 'a' + 10);
     87             }
     88         }
     89 
     90         ASN1InputStream aIn = new ASN1InputStream(data);
     91 
     92         return aIn.readObject();
     93     }
     94 
     95     /**
     96      * return true if the passed in String can be represented without
     97      * loss as a PrintableString, false otherwise.
     98      */
     99     protected boolean canBePrintable(
    100         String  str)
    101     {
    102         return DERPrintableString.isPrintableString(str);
    103     }
    104 
    105     /**
    106      * Convert the passed in String value into the appropriate ASN.1
    107      * encoded object.
    108      *
    109      * @param oid the oid associated with the value in the DN.
    110      * @param value the value of the particular DN component.
    111      * @return the ASN.1 equivalent for the value.
    112      */
    113     public abstract ASN1Primitive getConvertedValue(ASN1ObjectIdentifier oid, String value);
    114 }
    115