1 11 12 package org.eclipse.osgi.internal.verifier; 13 14 import java.math.BigInteger ; 15 16 20 public class BERProcessor { 21 24 byte buffer[]; 25 29 int offset; 30 33 int lastOffset; 34 38 int contentOffset; 39 42 int contentLength; 43 46 int endOffset; 47 50 int classOfTag; 51 static final int UNIVERSAL_TAGCLASS = 0; 52 static final int APPLICATION_TAGCLASS = 1; 53 static final int CONTEXTSPECIFIC_TAGCLASS = 2; 54 static final int PRIVATE_TAGCLASS = 3; 55 56 static final byte BOOLTAG = 1; 57 static final byte INTTAG = 2; 58 static final byte OIDTAG = 6; 59 static final byte SEQTAG = 16; 60 static final byte SETTAG = 17; 61 static final byte NULLTAG = 5; 62 63 66 static final String tagNames[] = {"<null>", "boolean", "int", "bitstring", "octetstring", "null", "objid", "objdesc", "external", "real", "enum", "pdv", "utf8", "relobjid", "resv", "resv", "sequence", "set", "char string"}; 68 71 public boolean constructed; 72 76 public byte tag; 77 78 86 public BERProcessor(byte buffer[], int offset, int len) { 87 this.buffer = buffer; 88 this.offset = offset; 89 lastOffset = len + offset; 90 processStructure(); 91 } 92 93 99 public void processStructure() { 100 if (offset == -1) 102 return; 103 endOffset = offset; 104 classOfTag = (buffer[offset] & 0xff) >> 6; 106 constructed = (buffer[offset] & 0x20) != 0; 108 byte tagNumber = (byte) (buffer[offset] & 0x1f); 110 if (tagNumber < 32) { 111 tag = tagNumber; 112 endOffset = offset + 1; 113 } else { 114 throw new IllegalArgumentException ("Can't handle tags > 32"); } 116 if ((buffer[endOffset] & 0x80) == 0) { 117 contentLength = buffer[endOffset]; 119 endOffset++; 120 } else { 121 int octetCount = buffer[endOffset] & 0x7f; 123 if (octetCount > 3) 124 throw new ArrayIndexOutOfBoundsException ("ContentLength octet count too large: " + octetCount); contentLength = 0; 126 endOffset++; 127 for (int i = 0; i < octetCount; i++) { 128 contentLength <<= 8; 129 contentLength |= buffer[endOffset] & 0xff; 130 endOffset++; 131 } 132 if (octetCount == 0) 134 contentLength = -1; 135 } 136 contentOffset = endOffset; 137 if (contentLength != -1) 138 endOffset += contentLength; 139 if (endOffset > lastOffset) 140 throw new ArrayIndexOutOfBoundsException (endOffset + " > " + lastOffset); } 142 143 148 public String toString() { 149 StringBuffer sb = new StringBuffer (); 150 switch (classOfTag) { 151 case UNIVERSAL_TAGCLASS : 152 sb.append('U'); 153 break; 154 case APPLICATION_TAGCLASS : 155 sb.append('A'); 156 break; 157 case CONTEXTSPECIFIC_TAGCLASS : 158 sb.append('C'); 159 break; 160 case PRIVATE_TAGCLASS : 161 sb.append('P'); 162 break; 163 } 164 sb.append(constructed ? 'C' : 'P'); 165 sb.append(" tag=" + tag); if (tag < tagNames.length) { 167 sb.append("(" + tagNames[tag] + ")"); } 169 sb.append(" len="); sb.append(contentLength); 171 switch (tag) { 172 case INTTAG : 173 sb.append(" value=" + getIntValue()); break; 175 case OIDTAG : 176 sb.append(" value="); int oid[] = getObjId(); 178 for (int i = 0; i < oid.length; i++) { 179 if (i > 0) 180 sb.append('.'); 181 sb.append(oid[i]); 182 } 183 } 184 if (tag == 12 || (tag >= 18 && tag <= 22) || (tag >= 25 && tag <= 30)) { 185 sb.append(" value="); sb.append(getString()); 187 } 188 return sb.toString(); 189 } 190 191 194 public BERProcessor stepInto() { 195 return new BERProcessor(buffer, contentOffset, contentLength); 196 } 197 198 public void stepOver() { 199 offset = endOffset; 200 if (endOffset >= lastOffset) { 201 offset = -1; 202 return; 203 } 204 processStructure(); 205 } 206 207 public boolean endOfSequence() { 208 return offset == -1; 209 } 210 211 215 public String getString() { 216 return new String (buffer, contentOffset, contentLength); 217 } 218 219 223 public BigInteger getIntValue() { 224 return new BigInteger (getBytes()); 225 } 226 227 231 public int[] getObjId() { 232 int count = 0; 234 for (int i = 0; i < contentLength; i++) { 235 if ((buffer[contentOffset + i] & 0x80) == 0) 237 count++; 238 } 239 count++; int oid[] = new int[count]; 241 int index = 0; 242 int currentValue = 0; 243 for (int i = 0; i < contentLength; i++) { 244 currentValue <<= 7; 245 currentValue |= buffer[contentOffset + i] & 0x7f; 246 if ((buffer[contentOffset + i] & 0x80) == 0) { 248 if (index == 0) { 249 oid[index++] = currentValue / 40; 251 oid[index++] = currentValue % 40; 252 } else { 253 oid[index++] = currentValue; 254 } 255 currentValue = 0; 256 } 257 } 258 return oid; 259 } 260 261 265 public byte[] getBytes() { 266 byte v[] = new byte[contentLength]; 267 System.arraycopy(buffer, contentOffset, v, 0, contentLength); 268 return v; 269 } 270 271 } 272 | Popular Tags |