--- old/src/jdk.snmp/share/classes/com/sun/jmx/snmp/BerDecoder.java 2014-10-15 14:04:22.000000000 +0200 +++ /dev/null 2014-10-15 14:04:22.000000000 +0200 @@ -1,757 +0,0 @@ -/* - * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - - -package com.sun.jmx.snmp; - - - - -/** - * The BerDecoder class is used for decoding - * BER-encoded data. - * - * A BerDecoder needs to be set up with the byte string containing - * the encoding. It maintains a current position in the byte string. - * - * Methods allows to fetch integer, string, OID, etc., from the current - * position. After a fetch the current position is moved forward. - * - * A fetch throws a BerException if the encoding is not of the - * expected type. - * - *

This API is a Sun Microsystems internal API and is subject - * to change without notice.

- * - * @since 1.5 - */ - -public class BerDecoder { - - /** - * Constructs a new decoder and attaches it to the specified byte string. - * - * @param b The byte string containing the encoded data. - */ - - public BerDecoder(byte b[]) { - bytes = b ; - reset() ; - } - - public void reset() { - next = 0 ; - stackTop = 0 ; - } - - /** - * Fetch an integer. - * - * @return The decoded integer. - * - * @exception BerException Current position does not point to an integer. - */ - - public int fetchInteger() throws BerException { - return fetchInteger(IntegerTag) ; - } - - - /** - * Fetch an integer with the specified tag. - * - * @param tag The expected tag. - * - * @return The decoded integer. - * - * @exception BerException Current position does not point to an integer - * or the tag is not the expected one. - */ - - public int fetchInteger(int tag) throws BerException { - int result = 0 ; - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - result = fetchIntegerValue() ; - } - catch(BerException e) { - next = backup ; - throw e ; - } - - return result ; - } - - - - /** - * Fetch an integer and return a long value. - * - * @return The decoded integer. - * - * @exception BerException Current position does not point to an integer. - */ - - public long fetchIntegerAsLong() throws BerException { - return fetchIntegerAsLong(IntegerTag) ; - } - - - /** - * Fetch an integer with the specified tag and return a long value. - * - * @param tag The expected tag. - * - * @return The decoded integer. - * - * @exception BerException Current position does not point to an integer - * or the tag is not the expected one. - */ - - public long fetchIntegerAsLong(int tag) throws BerException { - long result = 0 ; - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - result = fetchIntegerValueAsLong() ; - } - catch(BerException e) { - next = backup ; - throw e ; - } - - return result ; - } - - - - /** - * Fetch an octet string. - * - * @return The decoded string. - * - * @exception BerException Current position does not point to an octet string. - */ - - public byte[] fetchOctetString() throws BerException { - return fetchOctetString(OctetStringTag) ; - } - - - /** - * Fetch an octet string with a specified tag. - * - * @param tag The expected tag. - * - * @return The decoded string. - * - * @exception BerException Current position does not point to an octet string - * or the tag is not the expected one. - */ - - public byte[] fetchOctetString(int tag) throws BerException { - byte[] result = null ; - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - result = fetchStringValue() ; - } - catch(BerException e) { - next = backup ; - throw e ; - } - - return result ; - } - - - /** - * Fetch an object identifier. - * - * @return The decoded object identifier as an array of long. - */ - - public long[] fetchOid() throws BerException { - return fetchOid(OidTag) ; - } - - - /** - * Fetch an object identifier with a specified tag. - * - * @param tag The expected tag. - * - * @return The decoded object identifier as an array of long. - * - * @exception BerException Current position does not point to an oid - * or the tag is not the expected one. - */ - - public long[] fetchOid(int tag) throws BerException { - long[] result = null ; - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - result = fetchOidValue() ; - } - catch(BerException e) { - next = backup ; - throw e ; - } - - return result ; - } - - - /** - * Fetch a NULL value. - * - * @exception BerException Current position does not point to NULL value. - */ - - public void fetchNull() throws BerException { - fetchNull(NullTag) ; - } - - - /** - * Fetch a NULL value with a specified tag. - * - * @param tag The expected tag. - * - * @exception BerException Current position does not point to - * NULL value or the tag is not the expected one. - */ - - public void fetchNull(int tag) throws BerException { - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - final int length = fetchLength(); - if (length != 0) throw new BerException(); - } - catch(BerException e) { - next = backup ; - throw e ; - } - } - - - - /** - * Fetch an ANY value. In fact, this method does not decode anything - * it simply returns the next TLV as an array of bytes. - * - * @return The TLV as a byte array. - * - * @exception BerException The next TLV is really badly encoded... - */ - - public byte[] fetchAny() throws BerException { - byte[] result = null ; - final int backup = next ; - try { - final int tag = fetchTag() ; - final int contentLength = fetchLength() ; - if (contentLength < 0) throw new BerException() ; - final int tlvLength = next + contentLength - backup ; - if (contentLength > (bytes.length - next)) - throw new IndexOutOfBoundsException("Decoded length exceeds buffer"); - final byte[] data = new byte[tlvLength] ; - java.lang.System.arraycopy(bytes,backup,data,0,tlvLength); - // for (int i = 0 ; i < tlvLength ; i++) { - // data[i] = bytes[backup + i] ; - // } - next = next + contentLength ; - result = data; - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - // catch(Error e) { - // debug("fetchAny: Error decoding BER: " + e); - // throw e; - // } - - return result ; - } - - - /** - * Fetch an ANY value with a specific tag. - * - * @param tag The expected tag. - * - * @return The TLV as a byte array. - * - * @exception BerException The next TLV is really badly encoded... - */ - - public byte[] fetchAny(int tag) throws BerException { - if (getTag() != tag) { - throw new BerException() ; - } - return fetchAny() ; - } - - - - /** - * Fetch a sequence header. - * The decoder computes the end position of the sequence and push it - * on its stack. - * - * @exception BerException Current position does not point to a sequence header. - */ - - public void openSequence() throws BerException { - openSequence(SequenceTag) ; - } - - - /** - * Fetch a sequence header with a specific tag. - * - * @param tag The expected tag. - * - * @exception BerException Current position does not point to a sequence header - * or the tag is not the expected one. - */ - - public void openSequence(int tag) throws BerException { - final int backup = next ; - try { - if (fetchTag() != tag) { - throw new BerException() ; - } - final int l = fetchLength() ; - if (l < 0) throw new BerException(); - if (l > (bytes.length - next)) throw new BerException(); - stackBuf[stackTop++] = next + l ; - } - catch(BerException e) { - next = backup ; - throw e ; - } - } - - - /** - * Close a sequence. - * The decode pull the stack and verifies that the current position - * matches with the calculated end of the sequence. If not it throws - * an exception. - * - * @exception BerException The sequence is not expected to finish here. - */ - - public void closeSequence() throws BerException { - if (stackBuf[stackTop - 1] == next) { - stackTop-- ; - } - else { - throw new BerException() ; - } - } - - - /** - * Return true if the end of the current sequence is not reached. - * When this method returns false, closeSequence can (and must) be - * invoked. - * - * @return true if there is still some data in the sequence. - */ - - public boolean cannotCloseSequence() { - return (next < stackBuf[stackTop - 1]) ; - } - - - /** - * Get the tag of the data at the current position. - * Current position is unchanged. - * - * @return The next tag. - */ - - public int getTag() throws BerException { - int result = 0 ; - final int backup = next ; - try { - result = fetchTag() ; - } - finally { - next = backup ; - } - - return result ; - } - - - - public String toString() { - final StringBuffer result = new StringBuffer(bytes.length * 2) ; - for (int i = 0 ; i < bytes.length ; i++) { - final int b = (bytes[i] > 0) ? bytes[i] : bytes[i] + 256 ; - if (i == next) { - result.append("(") ; - } - result.append(Character.forDigit(b / 16, 16)) ; - result.append(Character.forDigit(b % 16, 16)) ; - if (i == next) { - result.append(")") ; - } - } - if (bytes.length == next) { - result.append("()") ; - } - - return new String(result) ; - } - - - // - // Some standard tags - // - public final static int BooleanTag = 1 ; - public final static int IntegerTag = 2 ; - public final static int OctetStringTag = 4 ; - public final static int NullTag = 5 ; - public final static int OidTag = 6 ; - public final static int SequenceTag = 0x30 ; - - - - - ////////////////////////// PRIVATE /////////////////////////////// - - - - /** - * Fetch a tag and move the current position forward. - * - * @return The tag - */ - - private final int fetchTag() throws BerException { - int result = 0 ; - final int backup = next ; - - try { - final byte b0 = bytes[next++] ; - result = (b0 >= 0) ? b0 : b0 + 256 ; - if ((result & 31) == 31) { - while ((bytes[next] & 128) != 0) { - result = result << 7 ; - result = result | (bytes[next++] & 127); - } - } - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - - return result ; - } - - - /** - * Fetch a length and move the current position forward. - * - * @return The length - */ - - private final int fetchLength() throws BerException { - int result = 0 ; - final int backup = next ; - - try { - final byte b0 = bytes[next++] ; - if (b0 >= 0) { - result = b0 ; - } - else { - for (int c = 128 + b0 ; c > 0 ; c--) { - final byte bX = bytes[next++] ; - result = result << 8 ; - result = result | ((bX >= 0) ? bX : bX+256) ; - } - } - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - - return result ; - } - - - /** - * Fetch an integer value and move the current position forward. - * - * @return The integer - */ - - private int fetchIntegerValue() throws BerException { - int result = 0 ; - final int backup = next ; - - try { - final int length = fetchLength() ; - if (length <= 0) throw new BerException() ; - if (length > (bytes.length - next)) throw - new IndexOutOfBoundsException("Decoded length exceeds buffer"); - final int end = next + length ; - result = bytes[next++] ; - while (next < end) { - final byte b = bytes[next++] ; - if (b < 0) { - result = (result << 8) | (256 + b) ; - } - else { - result = (result << 8) | b ; - } - } - } - catch(BerException e) { - next = backup ; - throw e ; - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - catch(ArithmeticException e) { - next = backup ; - throw new BerException() ; - } - return result ; - } - - - /** - * Fetch an integer value and return a long value. - * FIX ME: someday we could have only on fetchIntegerValue() which always - * returns a long value. - * - * @return The integer - */ - - private final long fetchIntegerValueAsLong() throws BerException { - long result = 0 ; - final int backup = next ; - - try { - final int length = fetchLength() ; - if (length <= 0) throw new BerException() ; - if (length > (bytes.length - next)) throw - new IndexOutOfBoundsException("Decoded length exceeds buffer"); - - final int end = next + length ; - result = bytes[next++] ; - while (next < end) { - final byte b = bytes[next++] ; - if (b < 0) { - result = (result << 8) | (256 + b) ; - } - else { - result = (result << 8) | b ; - } - } - } - catch(BerException e) { - next = backup ; - throw e ; - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - catch(ArithmeticException e) { - next = backup ; - throw new BerException() ; - } - return result ; - } - - - /** - * Fetch a byte string and move the current position forward. - * - * @return The byte string - */ - - private byte[] fetchStringValue() throws BerException { - byte[] result = null ; - final int backup = next ; - - try { - final int length = fetchLength() ; - if (length < 0) throw new BerException() ; - if (length > (bytes.length - next)) - throw new IndexOutOfBoundsException("Decoded length exceeds buffer"); - final byte data[] = new byte[length] ; - java.lang.System.arraycopy(bytes,next,data,0,length); - next += length; - // int i = 0 ; - // while (i < length) { - // result[i++] = bytes[next++] ; - // } - result = data; - } - catch(BerException e) { - next = backup ; - throw e ; - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - catch(ArithmeticException e) { - next = backup ; - throw new BerException() ; - } - // catch(Error e) { - // debug("fetchStringValue: Error decoding BER: " + e); - // throw e; - // } - - return result ; - } - - - - /** - * Fetch an oid and move the current position forward. - * - * @return The oid - */ - - private final long[] fetchOidValue() throws BerException { - long[] result = null ; - final int backup = next ; - - try { - final int length = fetchLength() ; - if (length <= 0) throw new BerException() ; - if (length > (bytes.length - next)) - throw new IndexOutOfBoundsException("Decoded length exceeds buffer"); - // Count how many bytes have their 8th bit to 0 - // -> this gives the number of components in the oid - int subidCount = 2 ; - for (int i = 1 ; i < length ; i++) { - if ((bytes[next + i] & 0x80) == 0) { - subidCount++ ; - } - } - final int datalen = subidCount; - final long[] data = new long[datalen]; - final byte b0 = bytes[next++] ; - - // bugId 4641746 - // The 8th bit of the first byte should always be set to 0 - if (b0 < 0) throw new BerException(); - - // bugId 4641746 - // The first sub Id cannot be greater than 2 - final long lb0 = b0 / 40 ; - if (lb0 > 2) throw new BerException(); - - final long lb1 = b0 % 40; - data[0] = lb0 ; - data[1] = lb1 ; - int i = 2 ; - while (i < datalen) { - long subid = 0 ; - byte b = bytes[next++] ; - while ((b & 0x80) != 0) { - subid = (subid << 7) | (b & 0x7f) ; - // bugId 4654674 - if (subid < 0) throw new BerException(); - b = bytes[next++] ; - } - subid = (subid << 7) | b ; - // bugId 4654674 - if (subid < 0) throw new BerException(); - data[i++] = subid ; - } - result = data; - } - catch(BerException e) { - next = backup ; - throw e ; - } - catch(IndexOutOfBoundsException e) { - next = backup ; - throw new BerException() ; - } - // catch(Error e) { - // debug("fetchOidValue: Error decoding BER: " + e); - // throw e; - // } - - return result ; - } - - // private static final void debug(String str) { - // System.out.println(str); - // } - - // - // This is the byte array containing the encoding. - // - private final byte bytes[]; - - // - // This is the current location. It is the next byte - // to be decoded. It's an index in bytes[]. - // - private int next = 0 ; - - // - // This is the stack where end of sequences are kept. - // A value is computed and pushed in it each time openSequence() - // is invoked. - // A value is pulled and checked each time closeSequence() is called. - // - private final int stackBuf[] = new int[200] ; - private int stackTop = 0 ; - -}