deroutputstream.java

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

JAVA
525
字号
/* * * * 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.ByteArrayOutputStream;import java.io.OutputStream;import java.io.IOException;import java.util.Date;import java.util.TimeZone;import java.util.Calendar;/** * Output stream marshaling DER-encoded data.  This is eventually provided * in the form of a byte array; there is no advance limit on the size of * that byte array. * * <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 * generating most X.509 certificates. */public class DerOutputStream extends ByteArrayOutputStream {    /**     * Construct an DER output stream.     *     * @param size how large a buffer to preallocate.     */    public DerOutputStream(int size) { super(size); }    /**     * Construct an DER output stream.     */    public DerOutputStream() { }    /**     * Writes tagged, pre-marshaled data.  This calcuates and encodes     * the length, so that the output data is the standard triple of     * { tag, length, data } used by all DER values.     *     * @param tag the DER value tag for the data, such as     *          <em>DerValue.tag_Sequence</em>     * @param buf buffered data, which must be DER-encoded     */    public void write(byte tag, byte[] buf) throws IOException {        write(tag);        putLength(buf.length);        write(buf, 0, buf.length);    }    /**     * Writes tagged data using buffer-to-buffer copy.  As above,     * this writes a standard DER record.  This is often used when     * efficiently encapsulating values in sequences.     *     * @param tag the DER value tag for the data, such as     *          <em>DerValue.tag_Sequence</em>     * @param out buffered data     */    public void write(byte tag, DerOutputStream out) throws IOException {        write(tag);        putLength(out.count);        write(out.buf, 0, out.count);    }    /**     * Writes implicitly tagged data using buffer-to-buffer copy.  As above,     * this writes a standard DER record.  This is often used when     * efficiently encapsulating implicitly tagged values.     *     * @param tag the DER value of the context-specific tag that replaces     * original tag of the value in the output, such as in     * <pre>     *          <em> <field> [N] IMPLICIT <type></em>     * </pre>     * For example, <em>FooLength [1] IMPLICIT INTEGER</em>, with value=4;     * would be encoded as "81 01 04"  whereas in explicit     * tagging it would be encoded as "A1 03 02 01 04".     * Notice that the tag is A1 and not 81, this is because with     * explicit tagging the form is always constructed.     * @param value original value being implicitly tagged     */    public void writeImplicit(byte tag, DerOutputStream value)    throws IOException {        write(tag);        write(value.buf, 1, value.count-1);    }    /**     * Marshals pre-encoded DER value onto the output stream.     */    public void putDerValue(DerValue val) throws IOException {        val.encode(this);    }    /*     * PRIMITIVES -- these are "universal" ASN.1 simple types.     *     *  BOOLEAN, INTEGER, BIT STRING, OCTET STRING, NULL     *  OBJECT IDENTIFIER, SEQUENCE(OF), SET(OF)     *  PrintableString, T61String, IA5String, UTCTime     */    /**     * Marshals a DER boolean on the output stream.     */    public void putBoolean(boolean val) throws IOException {        write(DerValue.tag_Boolean);        putLength(1);        if (val) {            write(0xff);        } else {            write(0);        }    }    /**     * Marshals a DER enumerated on the output stream.     * @param i the enumerated value.     */    public void putEnumerated(int i) throws IOException {        write(DerValue.tag_Enumerated);        putIntegerContents(i);    }       /**     * Marshals a DER integer on the output stream.     *     * @param i the integer in the form of a BigInteger.     */    public void putInteger(BigInteger i) throws IOException {        write(DerValue.tag_Integer);        byte[] buf = i.toByteArray(); // least number of bytes        putLength(buf.length);        write(buf, 0, buf.length);    }        /**     * Marshals a DER integer on the output stream.     * @param i the integer in the form of an Integer.     */    public void putInteger(Integer i) throws IOException {        putInteger(i.intValue());    }    /**     * Marshals a DER integer on the output stream.     * @param i the integer.     */    public void putInteger(int i) throws IOException {        write(DerValue.tag_Integer);        putIntegerContents(i);    }    private void putIntegerContents(int i) throws IOException {        byte[] bytes = new byte[4];        int start = 0;        // Obtain the four bytes of the int        bytes[3] = (byte) (i & 0xff);        bytes[2] = (byte)((i & 0xff00) >>> 8);        bytes[1] = (byte)((i & 0xff0000) >>> 16);        bytes[0] = (byte)((i & 0xff000000) >>> 24);        // Reduce them to the least number of bytes needed to        // represent this int        if (bytes[0] == 0xff) {            // Eliminate redundant 0xff            for (int j = 0; j < 3; j++) {                if ((bytes[j] == 0xff) &&                    ((bytes[j+1] & 0x80) == 0x80))                    start++;                else                    break;             }         } else if (bytes[0] == 0x00) {             // Eliminate redundant 0x00            for (int j = 0; j < 3; j++) {                if ((bytes[j] == 0x00) &&                    ((bytes[j+1] & 0x80) == 0))                    start++;                else                    break;            }        }        putLength(4 - start);        for (int k = start; k < 4; k++)            write(bytes[k]);    }    /**     * Marshals a DER bit string on the output stream. The bit     * string must be byte-aligned.     *     * @param bits the bit string, MSB first     */    public void putBitString(byte[] bits) throws IOException {        write(DerValue.tag_BitString);        putLength(bits.length + 1);        write(0);               // all of last octet is used        write(bits);    }    /**     * Marshals a DER bit string on the output stream.     * The bit strings need not be byte-aligned.     *     * @param ba the bit string, MSB first     */    public void putUnalignedBitString(BitArray ba) throws IOException {        byte[] bits = ba.toByteArray();        write(DerValue.tag_BitString);        putLength(bits.length + 1);        write(bits.length*8 - ba.length()); // excess bits in last octet        write(bits);    }    /**     * Marshals a truncated DER bit string on the output stream.     * The bit strings need not be byte-aligned.     *     * @param ba the bit string, MSB first     */    public void putTruncatedUnalignedBitString(BitArray ba) throws IOException {        putUnalignedBitString(ba.truncate());    }    /**     * DER-encodes an ASN.1 OCTET STRING value on the output stream.     *

⌨️ 快捷键说明

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