Home | History | Annotate | Download | only in asn1
      1 package org.bouncycastle.asn1;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.io.EOFException;
      5 import java.io.IOException;
      6 import java.io.InputStream;
      7 import java.util.Vector;
      8 
      9 /**
     10  * @deprecated use ASN1InputStream
     11  */
     12 public class BERInputStream
     13     extends DERInputStream
     14 {
     15     private DERObject END_OF_STREAM = new DERObject()
     16     {
     17                                         void encode(
     18                                             DEROutputStream out)
     19                                         throws IOException
     20                                         {
     21                                             throw new IOException("Eeek!");
     22                                         }
     23                                         public int hashCode()
     24                                         {
     25                                             return 0;
     26                                         }
     27                                         public boolean equals(
     28                                             Object o)
     29                                         {
     30                                             return o == this;
     31                                         }
     32                                     };
     33     public BERInputStream(
     34         InputStream is)
     35     {
     36         super(is);
     37     }
     38 
     39     /**
     40      * read a string of bytes representing an indefinite length object.
     41      */
     42     private byte[] readIndefiniteLengthFully()
     43         throws IOException
     44     {
     45         ByteArrayOutputStream   bOut = new ByteArrayOutputStream();
     46         int                     b, b1;
     47 
     48         b1 = read();
     49 
     50         while ((b = read()) >= 0)
     51         {
     52             if (b1 == 0 && b == 0)
     53             {
     54                 break;
     55             }
     56 
     57             bOut.write(b1);
     58             b1 = b;
     59         }
     60 
     61         return bOut.toByteArray();
     62     }
     63 
     64     private BERConstructedOctetString buildConstructedOctetString()
     65         throws IOException
     66     {
     67         Vector               octs = new Vector();
     68 
     69         for (;;)
     70         {
     71             DERObject        o = readObject();
     72 
     73             if (o == END_OF_STREAM)
     74             {
     75                 break;
     76             }
     77 
     78             octs.addElement(o);
     79         }
     80 
     81         return new BERConstructedOctetString(octs);
     82     }
     83 
     84     public DERObject readObject()
     85         throws IOException
     86     {
     87         int tag = read();
     88         if (tag == -1)
     89         {
     90             throw new EOFException();
     91         }
     92 
     93         int     length = readLength();
     94 
     95         if (length < 0)    // indefinite length method
     96         {
     97             switch (tag)
     98             {
     99             case NULL:
    100                 return null;
    101             case SEQUENCE | CONSTRUCTED:
    102                 BERConstructedSequence  seq = new BERConstructedSequence();
    103 
    104                 for (;;)
    105                 {
    106                     DERObject   obj = readObject();
    107 
    108                     if (obj == END_OF_STREAM)
    109                     {
    110                         break;
    111                     }
    112 
    113                     seq.addObject(obj);
    114                 }
    115                 return seq;
    116             case OCTET_STRING | CONSTRUCTED:
    117                 return buildConstructedOctetString();
    118             case SET | CONSTRUCTED:
    119                 ASN1EncodableVector  v = new ASN1EncodableVector();
    120 
    121                 for (;;)
    122                 {
    123                     DERObject   obj = readObject();
    124 
    125                     if (obj == END_OF_STREAM)
    126                     {
    127                         break;
    128                     }
    129 
    130                     v.add(obj);
    131                 }
    132                 return new BERSet(v);
    133             default:
    134                 //
    135                 // with tagged object tag number is bottom 5 bits
    136                 //
    137                 if ((tag & TAGGED) != 0)
    138                 {
    139                     if ((tag & 0x1f) == 0x1f)
    140                     {
    141                         throw new IOException("unsupported high tag encountered");
    142                     }
    143 
    144                     //
    145                     // simple type - implicit... return an octet string
    146                     //
    147                     if ((tag & CONSTRUCTED) == 0)
    148                     {
    149                         byte[]  bytes = readIndefiniteLengthFully();
    150 
    151                         return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes));
    152                     }
    153 
    154                     //
    155                     // either constructed or explicitly tagged
    156                     //
    157                     DERObject        dObj = readObject();
    158 
    159                     if (dObj == END_OF_STREAM)     // empty tag!
    160                     {
    161                         return new DERTaggedObject(tag & 0x1f);
    162                     }
    163 
    164                     DERObject       next = readObject();
    165 
    166                     //
    167                     // explicitly tagged (probably!) - if it isn't we'd have to
    168                     // tell from the context
    169                     //
    170                     if (next == END_OF_STREAM)
    171                     {
    172                         return new BERTaggedObject(tag & 0x1f, dObj);
    173                     }
    174 
    175                     //
    176                     // another implicit object, we'll create a sequence...
    177                     //
    178                     seq = new BERConstructedSequence();
    179 
    180                     seq.addObject(dObj);
    181 
    182                     do
    183                     {
    184                         seq.addObject(next);
    185                         next = readObject();
    186                     }
    187                     while (next != END_OF_STREAM);
    188 
    189                     return new BERTaggedObject(false, tag & 0x1f, seq);
    190                 }
    191 
    192                 throw new IOException("unknown BER object encountered");
    193             }
    194         }
    195         else
    196         {
    197             if (tag == 0 && length == 0)    // end of contents marker.
    198             {
    199                 return END_OF_STREAM;
    200             }
    201 
    202             byte[]  bytes = new byte[length];
    203 
    204             readFully(bytes);
    205 
    206             return buildObject(tag, bytes);
    207         }
    208     }
    209 }
    210