derencoder.java

来自「JAVA的加密库之一」· Java 代码 · 共 525 行 · 第 1/2 页

JAVA
525
字号
/* $Id: DerEncoder.java,v 1.4 2001/06/02 02:46:40 raif Exp $
 *
 * Copyright (C) 1997-2001 The Cryptix Foundation Limited. All rights reserved.
 *
 * Use, modification, copying and distribution of this software is subject to
 * the terms and conditions of the Cryptix General Licence. You should have
 * received a copy of the Cryptix General Licence along with this library; if
 * not, you can download a copy from http://www.cryptix.org/
 */
package cryptix.asn1.encoding;

import cryptix.asn1.io.*;
import cryptix.asn1.lang.*;

import org.apache.log4j.Category;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.TimeZone;

/**
 * A class to encode ASN.1 specifications according to the Distinguished
 * Encoding Rules.<p>
 *
 * @version $Revision: 1.4 $
 * @author  Raif S. Naffah, Axelle Apvrille
 */
public class DerEncoder extends ASNWriter implements Cloneable {

	// Constants and vars
	// .......................................................................

	static Category cat = Category.getInstance(DerEncoder.class.getName());

    /** The underlying output stream. */
	BufferedOutputStream out;

	// Constructor(s)
	// .......................................................................

    /** Trivial constructor for use by Factory. */
	public DerEncoder() {
   		super();
	}

	// Class method(s)
	// .......................................................................

	// Cloneable interface implementation
	// .......................................................................

	public Object clone() {
		return new DerEncoder();
	}

	// ASNWriter abstract methods implementation
	// .......................................................................

	/**
	 * Initialises this instance to encode to the designated output stream.
	 *
	 * @param os the designated output stream.
	 * @exception IllegalStateException if this instance is already initialised
	 * with an output stream. Caller should close the previous stream before
	 * invoking this method again.
	 */
	public void open(OutputStream os) {
		if (out != null)
      		throw new IllegalStateException();

		this.out = os instanceof BufferedOutputStream
      		? (BufferedOutputStream) os
            : new BufferedOutputStream(os, 10240);
	}

	public void encodeAny(IType obj, Object val) throws IOException {
		cat.debug("==> encodeAny()");

		if (val instanceof Boolean)
			this.encodeBoolean(obj, (Boolean) val);
		else if (val instanceof BigInteger)
			this.encodeInteger(obj, (BigInteger) val);
		else if (val instanceof String)
			this.encodeString(Tag.UNIVERSAL_STRING, obj, (String) val);
		else if (val instanceof Date)
			this.encodeUTCTime(obj, (Date) val);
		else if (val instanceof IType)
			((IType) val).encode(this);
		else
			this.encodeOctetString(obj, (byte[]) val);

//		synchronized (out) {
//			write(obj);
//			flush();
//		}

		cat.debug("<== encodeAny()");
	}

	public void encodeObjectIdentifier(IType obj, String val)
	throws IOException {
		cat.debug("==> encodeObjectIdentifier()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");
		cat.info("   val=\""+val+"\"");

		// convert oid components substrings into ints
		StringTokenizer st = new StringTokenizer(val, ".");
		int[] component = new int[st.countTokens()];
		int i;
		for (i = 0; i < component.length; i++)
			component[i] = Integer.parseInt(st.nextToken());

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		encodeSubIdentifier(baos, component[0] * 40 + component[1]); // first 2 are special
		for (i = 2; i < component.length; i++)
		    encodeSubIdentifier(baos, component[i]);

		byte[] ba = baos.toByteArray();
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(Tag.OBJECT_IDENTIFIER, ba);

		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeObjectIdentifier()");
	}

	public void encodeNull(IType obj) throws IOException {
		cat.debug("==> encodeNull()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");

		byte[] ba = new byte[0];
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(Tag.NULL, ba);
		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeNull()");
	}

	public void encodeBoolean(IType obj, Boolean val) throws IOException {
		cat.debug("==> encodeBoolean()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");
		cat.info("   val="+String.valueOf(val));

		byte[] ba = new byte[] { (byte)(val.booleanValue() ? 0x01 : 0x00) };
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(Tag.BOOLEAN, ba);
		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeBoolean()");
	}

	public void encodeInteger(IType obj, BigInteger val) throws IOException {
		cat.debug("==> encodeInteger()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");
		cat.info("   val="+String.valueOf(val));

		byte[] ba = val.toByteArray();
		if ((ba[0] & 0x80) != 0)
			throw new IllegalArgumentException("Illegal internal encoding");
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(Tag.INTEGER, ba);
		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeInteger()");
	}

	public void encodeString(int tagValue, IType obj, String val)
	throws IOException {
		cat.debug("==> encodeString("+tagValue+")");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");
		cat.info("   val="+String.valueOf(val));

      if (tag == null)
         tag = new Tag(tagValue, false); // implicit tag

		byte[] ba = val.getBytes("UTF8");
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(tagValue, ba);
		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeString()");
	}

	public void encodeBitString(IType obj, byte[] val) throws IOException {
		cat.debug("==> encodeBitString()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");

		byte[] ba = new byte[val.length+1];
		System.arraycopy(val, 0, ba, 1, val.length);
		if (tag.isExplicit() && !tag.isUniversal())
			ba = toTLV(Tag.BIT_STRING, ba);
		synchronized (out) {
			encode(tag);
			encode(ba.length); // write the length
			write(ba); // and finally the object's data
			flush();
		}

		cat.debug("<== encodeBitString()");
	}

	public void encodeOctetString(IType obj, byte[] val) throws IOException {
		cat.debug("==> encodeOctetString()");

		Tag tag = obj.tag();
		cat.info("   tag=\""+tag+"\"");

		if (tag.isExplicit() && !tag.isUniversal())
			val = toTLV(Tag.OCTET_STRING, val);
		synchronized (out) {
			encode(tag);
			encode(val.length); // write the length
			write(val); // and finally the object's data
			flush();
		}

⌨️ 快捷键说明

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