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 + -
显示快捷键?