View Javadoc

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