Home | History | Annotate | Download | only in asn1
      1 package org.bouncycastle.asn1;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.io.IOException;
      5 import java.util.Enumeration;
      6 import java.util.Vector;
      7 
      8 public class BERConstructedOctetString
      9     extends DEROctetString
     10 {
     11     /**
     12      * convert a vector of octet strings into a single byte string
     13      */
     14     static private byte[] toBytes(
     15         Vector  octs)
     16     {
     17         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
     18 
     19         for (int i = 0; i != octs.size(); i++)
     20         {
     21             try
     22             {
     23                 DEROctetString  o = (DEROctetString)octs.elementAt(i);
     24 
     25                 bOut.write(o.getOctets());
     26             }
     27             catch (ClassCastException e)
     28             {
     29                 throw new IllegalArgumentException(octs.elementAt(i).getClass().getName() + " found in input should only contain DEROctetString");
     30             }
     31             catch (IOException e)
     32             {
     33                 throw new IllegalArgumentException("exception converting octets " + e.toString());
     34             }
     35         }
     36 
     37         return bOut.toByteArray();
     38     }
     39 
     40     private Vector  octs;
     41 
     42     /**
     43      * @param string the octets making up the octet string.
     44      */
     45     public BERConstructedOctetString(
     46         byte[]  string)
     47     {
     48         super(string);
     49     }
     50 
     51     public BERConstructedOctetString(
     52         Vector  octs)
     53     {
     54         super(toBytes(octs));
     55 
     56         this.octs = octs;
     57     }
     58 
     59     public BERConstructedOctetString(
     60         DERObject  obj)
     61     {
     62         super(obj);
     63     }
     64 
     65     public BERConstructedOctetString(
     66         DEREncodable  obj)
     67     {
     68         super(obj.getDERObject());
     69     }
     70 
     71     public byte[] getOctets()
     72     {
     73         return string;
     74     }
     75 
     76     /**
     77      * return the DER octets that make up this string.
     78      */
     79     public Enumeration getObjects()
     80     {
     81         if (octs == null)
     82         {
     83             return generateOcts().elements();
     84         }
     85 
     86         return octs.elements();
     87     }
     88 
     89     private Vector generateOcts()
     90     {
     91         int     start = 0;
     92         int     end = 0;
     93         Vector  vec = new Vector();
     94 
     95         while ((end + 1) < string.length)
     96         {
     97             if (string[end] == 0 && string[end + 1] == 0)
     98             {
     99                 byte[]  nStr = new byte[end - start + 1];
    100 
    101                 System.arraycopy(string, start, nStr, 0, nStr.length);
    102 
    103                 vec.addElement(new DEROctetString(nStr));
    104                 start = end + 1;
    105             }
    106             end++;
    107         }
    108 
    109         byte[]  nStr = new byte[string.length - start];
    110 
    111         System.arraycopy(string, start, nStr, 0, nStr.length);
    112 
    113         vec.addElement(new DEROctetString(nStr));
    114 
    115         return vec;
    116     }
    117 
    118     public void encode(
    119         DEROutputStream out)
    120         throws IOException
    121     {
    122         if (out instanceof ASN1OutputStream || out instanceof BEROutputStream)
    123         {
    124             out.write(CONSTRUCTED | OCTET_STRING);
    125 
    126             out.write(0x80);
    127 
    128             //
    129             // write out the octet array
    130             //
    131             if (octs != null)
    132             {
    133                 for (int i = 0; i != octs.size(); i++)
    134                 {
    135                     out.writeObject(octs.elementAt(i));
    136                 }
    137             }
    138             else
    139             {
    140                 int     start = 0;
    141                 int     end = 0;
    142 
    143                 while ((end + 1) < string.length)
    144                 {
    145                     if (string[end] == 0 && string[end + 1] == 0)
    146                     {
    147                         byte[]  nStr = new byte[end - start + 1];
    148 
    149                         System.arraycopy(string, start, nStr, 0, nStr.length);
    150 
    151                         out.writeObject(new DEROctetString(nStr));
    152                         start = end + 1;
    153                     }
    154                     end++;
    155                 }
    156 
    157                 byte[]  nStr = new byte[string.length - start];
    158 
    159                 System.arraycopy(string, start, nStr, 0, nStr.length);
    160 
    161                 out.writeObject(new DEROctetString(nStr));
    162             }
    163 
    164             out.write(0x00);
    165             out.write(0x00);
    166         }
    167         else
    168         {
    169             super.encode(out);
    170         }
    171     }
    172 }
    173