001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.geronimo.util.asn1; 019 020 import java.io.ByteArrayOutputStream; 021 import java.io.EOFException; 022 import java.io.IOException; 023 import java.io.InputStream; 024 import java.util.Vector; 025 026 /** 027 * @deprecated use ASN1InputStream 028 */ 029 public class BERInputStream 030 extends DERInputStream 031 { 032 private DERObject END_OF_STREAM = new DERObject() { 033 void encode( 034 DEROutputStream out) 035 throws IOException 036 { 037 throw new IOException("Eeek!"); 038 } 039 public int hashCode() 040 { 041 return 0; 042 } 043 public boolean equals( 044 Object o) 045 { 046 return o == this; 047 } 048 }; 049 public BERInputStream( 050 InputStream is) 051 { 052 super(is); 053 } 054 055 /** 056 * read a string of bytes representing an indefinite length object. 057 */ 058 private byte[] readIndefiniteLengthFully() 059 throws IOException 060 { 061 ByteArrayOutputStream bOut = new ByteArrayOutputStream(); 062 int b, b1; 063 064 b1 = read(); 065 066 while ((b = read()) >= 0) 067 { 068 if (b1 == 0 && b == 0) 069 { 070 break; 071 } 072 073 bOut.write(b1); 074 b1 = b; 075 } 076 077 return bOut.toByteArray(); 078 } 079 080 private BERConstructedOctetString buildConstructedOctetString() 081 throws IOException 082 { 083 Vector octs = new Vector(); 084 085 for (;;) 086 { 087 DERObject o = readObject(); 088 089 if (o == END_OF_STREAM) 090 { 091 break; 092 } 093 094 octs.addElement(o); 095 } 096 097 return new BERConstructedOctetString(octs); 098 } 099 100 public DERObject readObject() 101 throws IOException 102 { 103 int tag = read(); 104 if (tag == -1) 105 { 106 throw new EOFException(); 107 } 108 109 int length = readLength(); 110 111 if (length < 0) // indefinite length method 112 { 113 switch (tag) 114 { 115 case NULL: 116 return null; 117 case SEQUENCE | CONSTRUCTED: 118 BERConstructedSequence seq = new BERConstructedSequence(); 119 120 for (;;) 121 { 122 DERObject obj = readObject(); 123 124 if (obj == END_OF_STREAM) 125 { 126 break; 127 } 128 129 seq.addObject(obj); 130 } 131 return seq; 132 case OCTET_STRING | CONSTRUCTED: 133 return buildConstructedOctetString(); 134 case SET | CONSTRUCTED: 135 ASN1EncodableVector v = new ASN1EncodableVector(); 136 137 for (;;) 138 { 139 DERObject obj = readObject(); 140 141 if (obj == END_OF_STREAM) 142 { 143 break; 144 } 145 146 v.add(obj); 147 } 148 return new BERSet(v); 149 default: 150 // 151 // with tagged object tag number is bottom 5 bits 152 // 153 if ((tag & TAGGED) != 0) 154 { 155 if ((tag & 0x1f) == 0x1f) 156 { 157 throw new IOException("unsupported high tag encountered"); 158 } 159 160 // 161 // simple type - implicit... return an octet string 162 // 163 if ((tag & CONSTRUCTED) == 0) 164 { 165 byte[] bytes = readIndefiniteLengthFully(); 166 167 return new BERTaggedObject(false, tag & 0x1f, new DEROctetString(bytes)); 168 } 169 170 // 171 // either constructed or explicitly tagged 172 // 173 DERObject dObj = readObject(); 174 175 if (dObj == END_OF_STREAM) // empty tag! 176 { 177 return new DERTaggedObject(tag & 0x1f); 178 } 179 180 DERObject next = readObject(); 181 182 // 183 // explicitly tagged (probably!) - if it isn't we'd have to 184 // tell from the context 185 // 186 if (next == END_OF_STREAM) 187 { 188 return new BERTaggedObject(tag & 0x1f, dObj); 189 } 190 191 // 192 // another implicit object, we'll create a sequence... 193 // 194 seq = new BERConstructedSequence(); 195 196 seq.addObject(dObj); 197 198 do 199 { 200 seq.addObject(next); 201 next = readObject(); 202 } 203 while (next != END_OF_STREAM); 204 205 return new BERTaggedObject(false, tag & 0x1f, seq); 206 } 207 208 throw new IOException("unknown BER object encountered"); 209 } 210 } 211 else 212 { 213 if (tag == 0 && length == 0) // end of contents marker. 214 { 215 return END_OF_STREAM; 216 } 217 218 byte[] bytes = new byte[length]; 219 220 readFully(bytes); 221 222 return buildObject(tag, bytes); 223 } 224 } 225 }