⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 derdecoder.java

📁 JAVA的加密库之一
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	/**
	 * Decodes a UTCTime from the input stream.
	 *
	 * @param obj the element to decode.
	 * @return the concrete value of this ASN.1 type.
	 * @exception TagMismatchException if the element in the stream has a
	 * different tag to the designated one.
	 * @exception DerObjectTooLargeException if the DER value of the length part
	 * exceeds 32-bit.
	 * @exception DerInvalidLengthException if a mismatch between the expected
	 * and parsed size of the element's encoding is detected.
	 * @exception EOFException if the end-of-stream was encountered while
	 * decoding the element.
	 * @exception IOException if any other I/O related exception has occured.
	 */
	public Date decodeUTCTime(IType obj) throws IOException {
		cat.debug("==> decodeUTCTime()");

		Tag tag = obj.tag();
		byte[] buffer = readRaw(tag, Tag.UTC_TIME);
		Date result = toDate(buffer);

		cat.debug("<== decodeUTCTime() --> "+result);
		return result;
	}

	/**
	 * Decodes a GeneralizedTime from the input stream.
	 *
	 * @param obj the element to decode.
	 * @return the concrete value of this ASN.1 type.
	 * @exception TagMismatchException if the element in the stream has a
	 * different tag to the designated one.
	 * @exception DerObjectTooLargeException if the DER value of the length part
	 * exceeds 32-bit.
	 * @exception DerInvalidLengthException if a mismatch between the expected
	 * and parsed size of the element's encoding is detected.
	 * @exception EOFException if the end-of-stream was encountered while
	 * decoding the element.
	 * @exception IOException if any other I/O related exception has occured.
	 */
	public Date decodeGeneralizedTime(IType obj) throws IOException {
		cat.debug("==> decodeGeneralizedTime()");

		Tag tag = obj.tag();
		byte[] buffer = readRaw(tag, Tag.GENERALIZED_TIME);
		Date result = toFullDate(buffer);

		cat.debug("<== decodeGeneralizedTime() --> "+result);
		return result;
	}

   /**
    * Decodes a compound type (SEQUENCE/SET [OF]) from the input stream.
    *
    * @param obj the compound element to decode.
    * @return a Decoder that parses the input stream according to the same
    * encoding rules as this one.
    * @exception TagMismatchException if the element in the stream has a
    * different tag to the designated one.
    * @exception DerObjectTooLargeException if the DER value of the length part
    * exceeds 32-bit.
    * @exception DerLengthMismatchException if a mismatch between the expected
    * (parsed) and actual (read) size of the element's encoding is detected.
    * @exception EOFException if the end-of-stream was encountered while
    * decoding the element.
    * @exception IOException if any other I/O related exception has occured.
    */
   public ASNReader decodeStructure(IType obj) throws IOException {
		cat.debug("==> decodeStructure()");

		Tag tag = obj.tag();
		byte[] buffer = readRaw(tag, Tag.SEQUENCE);
		DerDecoder result = new DerDecoder(buffer);

		cat.debug("<== decodeStructure() --> "+result);
		return result;
	}

   // InputStream methods implementation
   // .......................................................................

	/**
	 * Reads the next byte of data from the underlying input stream. The value
	 * byte is returned as an <tt>int</tt> in the range <tt>0</tt> to <tt>255</tt>.
	 * Contrary to the normal <tt>java.io.InputStream</tt> contract, if no
	 * byte is available because the end of the stream has been reached, this
	 * method throws a <tt>java.io.EOFException</tt>. This method blocks until
	 * input data is available, the end of the stream is detected, or another
	 * exception is thrown.
     *
     * @return the next byte of data.
     * @exception java.io.EOFException the end-of-stream was detected.
     * @exception java.io.IOException if an I/O error occurs.
     */
	public int read() throws IOException {
		int result = in.read();
		if (result == -1)
			throw new EOFException();

		return (result & 0xFF);
	}

	/**
	 * Closes the underlying input stream and releases any system resources
	 * associated with it.
	 *
	 * @exception java.io.IOException if an I/O error occurs.
	 */
	public void close() throws IOException {
		if (in != null) {
			try {
				in.close();
			} catch (IOException ignored) {
				cat.warn("I/O exception while closing the stream: "+ignored.getMessage());
			}
			in = null;
		}
	}

	/**
	 * Marks the current position in the underlying input stream. A subsequent
	 * call to the <tt>reset()</tt> method repositions that stream at the last
	 * marked position so that subsequent reads re-read the same byte(s).<p>
	 *
	 * The <tt>readlimit</tt> arguments tells the underlying input stream to
	 * allow that many bytes to be read before the mark position gets
	 * invalidated.<p>
	 *
	 * The general contract of <tt>mark()</tt> is that, if the method
	 * <tt>markSupported()</tt> returns <tt>true</tt>, the stream somehow
	 * remembers all the bytes read after the call to <tt>mark()</tt> and
	 * stands ready to supply those same bytes again if and whenever the method
	 * <tt>reset()</tt> is called. However, the stream is not required to
	 * remember any data at all if more than <tt>readlimit</tt> bytes are read
	 * from the stream before <tt>reset()</tt> is called.
	 *
	 * @param readlimit the maximum limit of bytes that can be read before the
	 * mark position becomes invalid.
	 */
	public void mark(int readlimit) {
		in.mark(readlimit);
	}

	/**
	 * Repositions the underlying stream to the position at the time the
	 * <tt>mark()</tt> method was last called on that input stream.
	 *
	 * The general contract of <tt>reset()</tt> is:
	 * <ul>
	 * <li>If the method <tt>markSupported()</tt> returns <tt>true</tt>, then:
	 *		<ul>
	 *		<li>If the method <tt>mark()</tt> has not been called since the
	 *		stream was created, or the number of bytes read from the stream
	 *		since <tt>mark()</tt> was last called is larger than the argument
	 *		to <tt>mark()</tt> at that last call, then an <tt>IOException</tt>
	 *		might be thrown.</li>
	 *		<li>If such an <tt>IOException</tt> is not thrown, then the stream
	 *		is reset to a state such that all the bytes read since the most
	 *		recent call to <tt>mark()</tt> (or since the start of the file, if
	 *		<tt>mark()</tt> has not been called) will be resupplied to subsequent
	 *		callers of the <tt>read()</tt> method, followed by any bytes that
	 *		otherwise would have been the next input data as of the time of the
	 *		call to <tt>reset()</tt>.</li>
	 *		</ul>
	 * </li>
	 * <li>If the method <tt>markSupported()</tt> returns <tt>false</tt>, then:
	 *		<ul>
	 *		<li>The call to <tt>reset()</tt> may throw an <tt>IOException</tt>.
	 *		Specifically if <tt>markpos</tt> is <tt>-1</tt> (no mark has been
	 *		set or the mark has been invalidated), an <tt>IOException</tt> is
	 *		thrown</li>
	 *		<li>If an <tt>IOException</tt> is not thrown, then the stream is
	 *		reset to a fixed state that depends on the particular type of the
	 *		underlying input stream and how it was created. Specifically
	 *		<tt>pos</tt> is set equal to <tt>markpos</tt>. The bytes that will
	 *		be supplied to subsequent callers of the <tt>read()</tt> method
	 *		depend on the particular type of the input stream.</li>
	 *		</ul>
	 * </li>
	 * </ul>
	 *
	 * @exception IOException if the underlying stream has not been marked or
	 * if the mark has been invalidated.
     */
	public void reset() throws IOException {
		in.reset();
	}

	/**
	 * Tests if the underlying input stream supports the <tt>mark()</tt> and
	 * <tt>reset()</tt> methods.
	 *
	 * @return true if the underlying input stream supports the <tt>mark()</tt>
	 * and <tt>reset()</tt> method; false otherwise.
	 */
	public boolean markSupported() {
		return in.markSupported();
	}

	// Other instance methods
	// ........................................................................

	private byte[] readRaw(Tag tag, int universalValue) throws IOException {
		byte[] buffer = readBytes(tag);

		// buffer may contain a TLV of a UNIVERSAL class and a universalValue
		// value, or just the value bytes of the type's instance depending on
		// (a) if the tag is explicit or implicit, and (b) if it is explicit,
		// whether the tag's context is UNIVERSAL or not.
		byte[] result;
		if (tag.isExplicit() && !tag.isUniversal()) { // it's a TLV
			DerDecoder local = new DerDecoder(buffer);
			result = local.readBytes(new Tag(universalValue));
		} else
			result = buffer;

		return result;
   }

	private byte[] readBytes(Tag tag) throws IOException  {
		int length = readTL(tag);
		byte[] result = new byte[length];
		int actualLength = read(result);
		if (actualLength == -1)
			throw new EOFException();

		if (actualLength != length)
			throw new DerLengthMismatchException(actualLength, length);

		return result;
	}

	// Tag-related methods
	// ........................................................................

	private int readTL(Tag tag) throws IOException {
		if (!isExpectedTag(tag))
			throw new TagMismatchException(String.valueOf(tag));

		int result = readLength();
		return result;
	}

	private boolean isExpectedTag(Tag tag) throws IOException {
		Tag result = getExpectedTag(tag.getClazz(), tag.getValue());
		return (result != null);
	}

	private Tag getExpectedTag(int xClass, int xValue)
	throws IOException {
		int tClass = -1;
		int tValue = -1;
		Tag result = null;
		try {
			cat.debug("==> getExpectedTag("+xClass+", "+xValue+")");

			int c = read();
			tClass = c & 0xC0;
			boolean tConstructed = (c & 0x20) != 0;
			tValue = c & 0x1F;
			if (tValue == 0x1F) { // multiple bytes for tag number
				tValue = 0;
				do {
					c = read();
					tValue += c & 0x3F;
				} while ((c & 0x80) != 0);
			}

			result = new Tag(tClass, tValue, true, tConstructed);
			cat.info("Checking for Tag's ["+xClass+" "+xValue+"] found: "+result);
		} finally {
			if (!eval(tClass, xClass, tValue, xValue))
				result = null;
		}

		cat.debug("<== getExpectedTag() --> "+result+" ["+tClass+", "+tValue+"]");
		return result;
	}

	private Tag readTag() throws IOException {
		cat.debug("==> readTag()");

		Tag result = null;
		int c = read();
		int tClass = c & 0xC0;
		boolean tConstructed = (c & 0x20) != 0;
   	int tValue = c & 0x1F;
		if (tValue == 0x1F) { // multiple bytes for tag number
			c = read();
		   tValue = c & 0x3F;
			while ((c & 0x80) != 0) {
				c = read();
				tValue += c & 0x3F;
			}
		}

		result = new Tag(tClass, tValue, true, tConstructed);

		cat.debug("<== readTag() --> "+result);
		return result;
	}

   // Length-related methods
   // .......................................................................

	private int readLength() throws IOException {
		int result;
		int limit = read();
		if ((limit & 0x80) == 0)
			result = limit;
		else {
			limit &= 0x7F;
			if (limit > 4)
				throw new DerObjectTooLargeException();

			result = 0;
			while (limit-- > 0)
				result = (result << 8) | (read() & 0xFF);
		}

		cat.info("Element length = "+result);
		return result;
	}
}


⌨️ 快捷键说明

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