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