derinputstream.java

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

JAVA
584
字号
/* * @(#)DerInputStream.java	1.54 06/10/10 * * Copyright  1990-2008 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 sun.security.util;import java.io.InputStream;import java.io.IOException;import java.io.EOFException;import java.util.Date;import java.util.Vector;import java.math.BigInteger;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. * * @version 1.47 * * @author David Brownell * @author Amit Kapoor * @author Hemma Prafullchandra */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));    }    /**      * 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));    }    /**     * Get a bit string from the input stream.  The bit string need     * not be byte-aligned.     */    public BitArray getUnalignedBitString() throws IOException {	if (buffer.read() != DerValue.tag_BitString)	    throw new IOException("DER input not a bit string");	int length = getLength(buffer) - 1;	/*	 * First byte = number of excess bits in the last octet of the	 * representation.	 */	int validBits = length*8 - buffer.read();	byte[] repn = new byte[length];	if ((length != 0) && (buffer.read(repn) != length))	    throw new IOException("short read of DER bit string");	return new BitArray(validBits, repn);    }    /**     * 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

⌨️ 快捷键说明

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