derinputstream.java

来自「This is a resource based on j2me embedde」· Java 代码 · 共 583 行 · 第 1/2 页

JAVA
583
字号
/* * * * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program 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. * * This program 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 at /legal/license.txt). * * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */package com.sun.midp.pki;import java.io.InputStream;import java.io.IOException;import java.util.Date;import java.util.Vector;import java.io.DataInputStream;/** * A DER input stream, used for parsing ASN.1 DER-encoded data such as * that found in X.509 certificates.  DER is a subset of BER/1, which has * the advantage that it allows only a single encoding of primitive data. * (High level data such as dates still support many encodings.)  That is, * it uses the "Definite" Encoding Rules (DER) not the "Basic" ones (BER). * * <P>Note that, like BER/1, DER streams are streams of explicitly * tagged data values.  Accordingly, this programming interface does * not expose any variant of the java.io.InputStream interface, since * that kind of input stream holds untagged data values and using that * I/O model could prevent correct parsing of the DER data. * * <P>At this time, this class supports only a subset of the types of DER * data encodings which are defined.  That subset is sufficient for parsing * most X.509 certificates. */public class DerInputStream {    /*     * This version only supports fully buffered DER.  This is easy to     * work with, though if large objects are manipulated DER becomes     * awkward to deal with.  That's where BER is useful, since BER     * handles streaming data relatively well.     */    DerInputBuffer      buffer;    /** The DER tag of the value; one of the tag_ constants. */    public byte         tag;    /**     * Create a DER input stream from a data buffer.  The buffer is not     * copied, it is shared.  Accordingly, the buffer should be treated     * as read-only.     *     * @param data the buffer from which to create the string (CONSUMED)     */    public DerInputStream(byte[] data) throws IOException {        init(data, 0, data.length);    }    /**     * Create a DER input stream from part of a data buffer.     * The buffer is not copied, it is shared.  Accordingly, the     * buffer should be treated as read-only.     *     * @param data the buffer from which to create the string (CONSUMED)     * @param offset the first index of <em>data</em> which will     *          be read as DER input in the new stream     * @param len how long a chunk of the buffer to use,     *          starting at "offset"     */    public DerInputStream(byte[] data, int offset, int len) throws IOException {        init(data, offset, len);    }    /*     * private helper routine     */    private void init(byte[] data, int offset, int len) throws IOException {        if ((offset+2 > data.length) || (offset+len > data.length)) {            throw new IOException("Encoding bytes too short");        }        // check for indefinite length encoding        if (DerIndefLenConverter.isIndefinite(data[offset+1])) {            byte[] inData = new byte[len];            System.arraycopy(data, offset, inData, 0, len);            DerIndefLenConverter derIn = new DerIndefLenConverter();            buffer = new DerInputBuffer(derIn.convert(inData));        } else {            buffer = new DerInputBuffer(data, offset, len);        }        buffer.mark(Integer.MAX_VALUE);    }    DerInputStream(DerInputBuffer buf) {        buffer = buf;        buffer.mark(Integer.MAX_VALUE);    }    /**     * Creates a new DER input stream from part of this input stream.     *     * @param len how long a chunk of the current input stream to use,     *          starting at the current position.     * @param do_skip true if the existing data in the input stream should     *          be skipped.  If this value is false, the next data read     *          on this stream and the newly created stream will be the     *          same.     */    public DerInputStream subStream(int len, boolean do_skip)            throws IOException {        DerInputBuffer  newbuf = buffer.dup();        newbuf.truncate(len);        if (do_skip) {            buffer.skip(len);        }        return new DerInputStream(newbuf);    }    /**     * Return what has been written to this DerInputStream     * as a byte array. Useful for debugging.     */    public byte[] toByteArray() {        return buffer.toByteArray();    }    /*     * PRIMITIVES -- these are "universal" ASN.1 simple types.     *     *  INTEGER, ENUMERATED, BIT STRING, OCTET STRING, NULL     *  OBJECT IDENTIFIER, SEQUENCE (OF), SET (OF)     *  UTF8String, PrintableString, T61String, IA5String, UTCTime,     *  GeneralizedTime, BMPString.     * Note: UniversalString not supported till encoder is available.     */    /**     * Get an integer from the input stream as an integer.     *     * @return the integer held in this DER input stream.     */    public int getInteger() throws IOException {        if (buffer.read() != DerValue.tag_Integer) {            throw new IOException("DER input, Integer tag error");        }        return buffer.getInteger(getLength(buffer));    }    /**     * Get a integer from the input stream as a BigInteger object.     *     * @return the integer held in this DER input stream.     */    public BigInteger getBigInteger() throws IOException {        if (buffer.read() != DerValue.tag_Integer) {            throw new IOException("DER input, Integer tag error");        }        return buffer.getBigInteger(getLength(buffer), false);    }    /**     * Returns an ASN.1 INTEGER value as a positive BigInteger.     * This is just to deal with implementations that incorrectly encode     * some values as negative.     *     * @return the integer held in this DER value as a BigInteger.     */    public BigInteger getPositiveBigInteger() throws IOException {        if (buffer.read() != DerValue.tag_Integer) {            throw new IOException("DER input, Integer tag error");        }        return buffer.getBigInteger(getLength(buffer), true);    }        /**     * Get an enumerated from the input stream.     *     * @return the integer held in this DER input stream.     */    public int getEnumerated() throws IOException {        if (buffer.read() != DerValue.tag_Enumerated) {            throw new IOException("DER input, Enumerated tag error");        }        return buffer.getInteger(getLength(buffer));    }    /**     * Get a bit string from the input stream. Padded bits (if any)     * will be stripped off before the bit string is returned.     */    public byte[] getBitString() throws IOException {        if (buffer.read() != DerValue.tag_BitString) {            throw new IOException("DER input not an bit string");        }        return buffer.getBitString(getLength(buffer));    }    /**     * Returns an ASN.1 OCTET STRING from the input stream.     */    public byte[] getOctetString() throws IOException {        if (buffer.read() != DerValue.tag_OctetString) {            throw new IOException("DER input not an octet string");        }        int length = getLength(buffer);        byte[] retval = new byte[length];        if ((length != 0) && (buffer.read(retval) != length)) {            throw new IOException("short read of DER octet string");        }        return retval;    }    /**     * Returns the asked number of bytes from the input stream.     */    public void getBytes(byte[] val) throws IOException {        if ((val.length != 0) && (buffer.read(val) != val.length)) {            throw new IOException("short read of DER octet string");        }    }    /**     * Reads an encoded null value from the input stream.     */    public void getNull() throws IOException {        if (buffer.read() != DerValue.tag_Null || buffer.read() != 0) {            throw new IOException("getNull, bad data");        }    }    /**     * Reads an X.200 style Object Identifier from the stream.     */    public ObjectIdentifier getOID() throws IOException {        return new ObjectIdentifier(this);    }    /**     * Return a sequence of encoded entities.  ASN.1 sequences are     * ordered, and they are often used, like a "struct" in C or C++,     * to group data values.  They may have optional or context     * specific values.     *     * @param startLen guess about how long the sequence will be     *          (used to initialize an auto-growing data structure)     * @return array of the values in the sequence     */    public DerValue[] getSequence(int startLen) throws IOException {        tag = (byte)buffer.read();        if (tag != DerValue.tag_Sequence) {            throw new IOException("Sequence tag error");        }        return readVector(startLen);    }    /**     * Return a set of encoded entities.  ASN.1 sets are unordered,     * though DER may specify an order for some kinds of sets (such     * as the attributes in an X.500 relative distinguished name)     * to facilitate binary comparisons of encoded values.     *     * @param startLen guess about how large the set will be     *          (used to initialize an auto-growing data structure)     * @return array of the values in the sequence     */    public DerValue[] getSet(int startLen) throws IOException {        tag = (byte)buffer.read();        if (tag != DerValue.tag_Set) {            throw new IOException("Set tag error");        }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?