/**
 * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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 in the LICENSE file that
 * accompanied this code).
 *
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.util;

import java.io.*;
import java.math.BigInteger;
import java.util.Date;

/**
 * Represents a single DER-encoded value.  DER encoding rules are a subset
 * of the "Basic" Encoding Rules (BER), but they only support a single way
 * ("Definite" encoding) to encode any given value.
 *
 * <P>All DER-encoded data are triples <em>{type, length, data}</em>.  This
 * class represents such tagged values as they have been read (or constructed),
 * and provides structured access to the encoded 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, and working with selected additional formats
 * (such as PKCS #10 certificate requests, and some kinds of PKCS #7 data).
 *
 * A note with respect to T61/Teletex strings: From RFC 1617, section 4.1.3
 * and RFC 5280, section 8, we assume that this kind of string will contain
 * ISO-8859-1 characters only.
 *
 *
 * @author David Brownell
 * @author Amit Kapoor
 * @author Hemma Prafullchandra
 */
public class DerValue {
    /** The tag class types */
    public static final byte TAG_UNIVERSAL = (byte)0x000;
    public static final byte TAG_APPLICATION = (byte)0x040;
    public static final byte TAG_CONTEXT = (byte)0x080;
    public static final byte TAG_PRIVATE = (byte)0x0c0;

    /** The DER tag of the value; one of the tag_ constants. */
    public byte                 tag;

    protected DerInputBuffer    buffer;

    /**
     * The DER-encoded data of the value, never null
     */
    public final DerInputStream data;

    private int                 length;

    /*
     * The type starts at the first byte of the encoding, and
     * is one of these tag_* values.  That may be all the type
     * data that is needed.
     */

    /*
     * These tags are the "universal" tags ... they mean the same
     * in all contexts.  (Mask with 0x1f -- five bits.)
     */

    /** Tag value indicating an ASN.1 "BOOLEAN" value. */
    public static final byte    tag_Boolean = 0x01;

    /** Tag value indicating an ASN.1 "INTEGER" value. */
    public static final byte    tag_Integer = 0x02;

    /** Tag value indicating an ASN.1 "BIT STRING" value. */
    public static final byte    tag_BitString = 0x03;

    /** Tag value indicating an ASN.1 "OCTET STRING" value. */
    public static final byte    tag_OctetString = 0x04;

    /** Tag value indicating an ASN.1 "NULL" value. */
    public static final byte    tag_Null = 0x05;

    /** Tag value indicating an ASN.1 "OBJECT IDENTIFIER" value. */
    public static final byte    tag_ObjectId = 0x06;

    /** Tag value including an ASN.1 "ENUMERATED" value */
    public static final byte    tag_Enumerated = 0x0A;

    /** Tag value indicating an ASN.1 "UTF8String" value. */
    public static final byte    tag_UTF8String = 0x0C;

    /** Tag value including a "printable" string */
    public static final byte    tag_PrintableString = 0x13;

    /** Tag value including a "teletype" string */
    public static final byte    tag_T61String = 0x14;

    /** Tag value including an ASCII string */
    public static final byte    tag_IA5String = 0x16;

    /** Tag value indicating an ASN.1 "UTCTime" value. */
    public static final byte    tag_UtcTime = 0x17;

    /** Tag value indicating an ASN.1 "GeneralizedTime" value. */
    public static final byte    tag_GeneralizedTime = 0x18;

    /** Tag value indicating an ASN.1 "GenerallString" value. */
    public static final byte    tag_GeneralString = 0x1B;

    /** Tag value indicating an ASN.1 "UniversalString" value. */
    public static final byte    tag_UniversalString = 0x1C;

    /** Tag value indicating an ASN.1 "BMPString" value. */
    public static final byte    tag_BMPString = 0x1E;

    // CONSTRUCTED seq/set

    /**
     * Tag value indicating an ASN.1
     * "SEQUENCE" (zero to N elements, order is significant).
     */
    public static final byte    tag_Sequence = 0x30;

    /**
     * Tag value indicating an ASN.1
     * "SEQUENCE OF" (one to N elements, order is significant).
     */
    public static final byte    tag_SequenceOf = 0x30;

    /**
     * Tag value indicating an ASN.1
     * "SET" (zero to N members, order does not matter).
     */
    public static final byte    tag_Set = 0x31;

    /**
     * Tag value indicating an ASN.1
     * "SET OF" (one to N members, order does not matter).
     */
    public static final byte    tag_SetOf = 0x31;

    /*
     * These values are the high order bits for the other kinds of tags.
     */

    /**
     * Returns true if the tag class is UNIVERSAL.
     */
    public boolean isUniversal()      { return ((tag & 0x0c0) == 0x000); }

    /**
     * Returns true if the tag class is APPLICATION.
     */
    public boolean isApplication()    { return ((tag & 0x0c0) == 0x040); }

    /**
     * Returns true iff the CONTEXT SPECIFIC bit is set in the type tag.
     * This is associated with the ASN.1 "DEFINED BY" syntax.
     */
    public boolean isContextSpecific() { return ((tag & 0x0c0) == 0x080); }

    /**
     * Returns true iff the CONTEXT SPECIFIC TAG matches the passed tag.
     */
    public boolean isContextSpecific(byte cntxtTag) {
        if (!isContextSpecific()) {
            return false;
        }
        return ((tag & 0x01f) == cntxtTag);
    }

    boolean isPrivate()        { return ((tag & 0x0c0) == 0x0c0); }

    /** Returns true iff the CONSTRUCTED bit is set in the type tag. */
    public boolean isConstructed()    { return ((tag & 0x020) == 0x020); }

    /**
     * Returns true iff the CONSTRUCTED TAG matches the passed tag.
     */
    public boolean isConstructed(byte constructedTag) {
        if (!isConstructed()) {
            return false;
        }
        return ((tag & 0x01f) == constructedTag);
    }

    /**
     * Creates a PrintableString or UTF8string DER value from a string
     */
    public DerValue(String value) throws IOException {
        boolean isPrintableString = true;
        for (int i = 0; i < value.length(); i++) {
            if (!isPrintableStringChar(value.charAt(i))) {
                isPrintableString = false;
                break;
            }
        }

        data = init(isPrintableString ? tag_PrintableString : tag_UTF8String, value);
    }

    /**
     * Creates a string type DER value from a String object
     * @param stringTag the tag for the DER value to create
     * @param value the String object to use for the DER value
     */
    public DerValue(byte stringTag, String value) throws IOException {
        data = init(stringTag, value);
    }

    // Creates a DerValue from a tag and some DER-encoded data w/ additional
    // arg to control whether DER checks are enforced.
    DerValue(byte tag, byte[] data, boolean allowBER) {
        this.tag = tag;
        buffer = new DerInputBuffer(data.clone(), allowBER);
        length = data.length;
        this.data = new DerInputStream(buffer);
        this.data.mark(Integer.MAX_VALUE);
    }

    /**
     * Creates a DerValue from a tag and some DER-encoded data.
     *
     * @param tag the DER type tag
     * @param data the DER-encoded data
     */
    public DerValue(byte tag, byte[] data) {
        this(tag, data, true);
    }

    /*
     * package private
     */
    DerValue(DerInputBuffer in) throws IOException {

        // XXX must also parse BER-encoded constructed
        // values such as sequences, sets...
        tag = (byte)in.read();
        byte lenByte = (byte)in.read();
        length = DerInputStream.getLength(lenByte, in);
        if (length == -1) {  // indefinite length encoding found
            DerInputBuffer inbuf = in.dup();
            inbuf = new DerInputBuffer(
                    DerIndefLenConverter.convertStream(inbuf, lenByte, tag),
                    in.allowBER);
            if (tag != inbuf.read())
                throw new IOException
                        ("Indefinite length encoding not supported");
            length = DerInputStream.getDefiniteLength(inbuf);
            buffer = inbuf.dup();
            buffer.truncate(length);
            data = new DerInputStream(buffer);
            // indefinite form is encoded by sending a length field with a
            // length of 0. - i.e. [1000|0000].
            // the object is ended by sending two zero bytes.
            in.skip(length + 2);
        } else {

            buffer = in.dup();
            buffer.truncate(length);
            data = new DerInputStream(buffer);

            in.skip(length);
        }
    }

    // Get an ASN.1/DER encoded datum from a buffer w/ additional
    // arg to control whether DER checks are enforced.
    DerValue(byte[] buf, boolean allowBER) throws IOException {
        data = init(true, new ByteArrayInputStream(buf), allowBER);
    }

    /**
     * Get an ASN.1/DER encoded datum from a buffer.  The
     * entire buffer must hold exactly one datum, including
     * its tag and length.
     *
     * @param buf buffer holding a single DER-encoded datum.
     */
    public DerValue(byte[] buf) throws IOException {
        this(buf, true);
    }

    // Get an ASN.1/DER encoded datum from part of a buffer w/ additional
    // arg to control whether DER checks are enforced.
    DerValue(byte[] buf, int offset, int len, boolean allowBER)
        throws IOException {
        data = init(true, new ByteArrayInputStream(buf, offset, len), allowBER);
    }

    /**
     * Wraps a byte array as a single DerValue.
     *
     * Attention: no cloning is made.
     *
     * @param buf the byte array containing the DER-encoded datum
     * @returns a new DerValue
     */
    public static DerValue wrap(byte[] buf)
            throws IOException {
        return wrap(buf, 0, buf.length);
    }

    /**
     * Wraps a byte array as a single DerValue.
     *
     * Attention: no cloning is made.
     *
     * @param buf the byte array containing the DER-encoded datum
     * @param offset where the encoded datum starts inside {@code buf}
     * @param len length of bytes to parse inside {@code buf}
     * @returns a new DerValue
     */
    public static DerValue wrap(byte[] buf, int offset, int len)
            throws IOException {
        return new DerValue(buf, offset, len);
    }

    /**
     * Get an ASN.1/DER encoded datum from part of a buffer.
     * That part of the buffer must hold exactly one datum, including
     * its tag and length.
     *
     * @param buf the buffer
     * @param offset start point of the single DER-encoded dataum
     * @param len how many bytes are in the encoded datum
     */
    public DerValue(byte[] buf, int offset, int len) throws IOException {
        this(buf, offset, len, true);
    }

    // Get an ASN1/DER encoded datum from an input stream w/ additional
    // arg to control whether DER checks are enforced.
    DerValue(InputStream in, boolean allowBER) throws IOException {
        data = init(false, in, allowBER);
    }

    /**
     * Get an ASN1/DER encoded datum from an input stream.  The
     * stream may have additional data following the encoded datum.
     * In case of indefinite length encoded datum, the input stream
     * must hold only one datum.
     *
     * @param in the input stream holding a single DER datum,
     *  which may be followed by additional data
     */
    public DerValue(InputStream in) throws IOException {
        this(in, true);
    }

    private DerInputStream init(byte stringTag, String value)
        throws IOException {
        String enc = null;

        tag = stringTag;

        switch (stringTag) {
        case tag_PrintableString:
        case tag_IA5String:
        case tag_GeneralString:
            enc = "ASCII";
            break;
        case tag_T61String:
            enc = "ISO-8859-1";
            break;
        case tag_BMPString:
            enc = "UnicodeBigUnmarked";
            break;
        case tag_UTF8String:
            enc = "UTF8";
            break;
            // TBD: Need encoder for UniversalString before it can
            // be handled.
        default:
            throw new IllegalArgumentException("Unsupported DER string type");
        }

        byte[] buf = value.getBytes(enc);
        length = buf.length;
        buffer = new DerInputBuffer(buf, true);
        DerInputStream result = new DerInputStream(buffer);
        result.mark(Integer.MAX_VALUE);
        return result;
    }

    /*
     * helper routine
     */
    private DerInputStream init(boolean fullyBuffered, InputStream in,
        boolean allowBER) throws IOException {

        tag = (byte)in.read();
        byte lenByte = (byte)in.read();
        length = DerInputStream.getLength(lenByte, in);
        if (length == -1) { // indefinite length encoding found
            in = new ByteArrayInputStream(
                    DerIndefLenConverter.convertStream(in, lenByte, tag));
            if (tag != in.read())
                throw new IOException
                        ("Indefinite length encoding not supported");
            length = DerInputStream.getDefiniteLength(in);
        }

        if (fullyBuffered && in.available() != length)
            throw new IOException("extra data given to DerValue constructor");

        byte[] bytes = IOUtils.readExactlyNBytes(in, length);

        buffer = new DerInputBuffer(bytes, allowBER);
        return new DerInputStream(buffer);
    }

    /**
     * Encode an ASN1/DER encoded datum onto a DER output stream.
     */
    public void encode(DerOutputStream out)
    throws IOException {
        out.write(tag);
        out.putLength(length);
        // XXX yeech, excess copies ... DerInputBuffer.write(OutStream)
        if (length > 0) {
            byte[] value = new byte[length];
            // always synchronized on data
            synchronized (data) {
                buffer.reset();
                if (buffer.read(value) != length) {
                    throw new IOException("short DER value read (encode)");
                }
                out.write(value);
            }
        }
    }

    public final DerInputStream getData() {
        return data;
    }

    public final byte getTag() {
        return tag;
    }

    /**
     * Returns an ASN.1 BOOLEAN
     *
     * @return the boolean held in this DER value
     */
    public boolean getBoolean() throws IOException {
        if (tag != tag_Boolean) {
            throw new IOException("DerValue.getBoolean, not a BOOLEAN " + tag);
        }
        if (length != 1) {
            throw new IOException("DerValue.getBoolean, invalid length "
                                        + length);
        }
        if (buffer.read() != 0) {
            return true;
        }
        return false;
    }

    /**
     * Returns an ASN.1 OBJECT IDENTIFIER.
     *
     * @return the OID held in this DER value
     */
    public ObjectIdentifier getOID() throws IOException {
        if (tag != tag_ObjectId)
            throw new IOException("DerValue.getOID, not an OID " + tag);
        return new ObjectIdentifier(buffer);
    }

    private byte[] append(byte[] a, byte[] b) {
        if (a == null)
            return b;

        byte[] ret = new byte[a.length + b.length];
        System.arraycopy(a, 0, ret, 0, a.length);
        System.arraycopy(b, 0, ret, a.length, b.length);

        return ret;
    }

    /**
     * Returns an ASN.1 OCTET STRING
     *
     * @return the octet string held in this DER value
     */
    public byte[] getOctetString() throws IOException {

        if (tag != tag_OctetString && !isConstructed(tag_OctetString)) {
            throw new IOException(
                "DerValue.getOctetString, not an Octet String: " + tag);
        }
        // Note: do not attempt to call buffer.read(bytes) at all. There's a
        // known bug that it returns -1 instead of 0.
        if (length == 0) {
            return new byte[0];
        }

        // Only allocate the array if there are enough bytes available.
        // This only works for ByteArrayInputStream.
        // The assignment below ensures that buffer has the required type.
        ByteArrayInputStream arrayInput = buffer;
        if (arrayInput.available() < length) {
            throw new IOException("short read on DerValue buffer");
        }
        byte[] bytes = new byte[length];
        arrayInput.read(bytes);

        if (isConstructed()) {
            DerInputStream in = new DerInputStream(bytes, 0, bytes.length,
                buffer.allowBER);
            bytes = null;
            while (in.available() != 0) {
                bytes = append(bytes, in.getOctetString());
            }
        }
        return bytes;
    }

    /**
     * Returns an ASN.1 INTEGER value as an integer.
     *
     * @return the integer held in this DER value.
     */
    public int getInteger() throws IOException {
        if (tag != tag_Integer) {
            throw new IOException("DerValue.getInteger, not an int " + tag);
        }
        return buffer.getInteger(data.available());
    }

    /**
     * Returns an ASN.1 INTEGER value as a BigInteger.
     *
     * @return the integer held in this DER value as a BigInteger.
     */
    public BigInteger getBigInteger() throws IOException {
        if (tag != tag_Integer)
            throw new IOException("DerValue.getBigInteger, not an int " + tag);
        return buffer.getBigInteger(data.available(), false);
    }

    /**
     * Returns an ASN.1 INTEGER value as a positive BigInteger.
     * This is just to deal with implementations that incorrectly encode
     * some values as negative.
     *
     * @return the integer held in this DER value as a BigInteger.
     */
    public BigInteger getPositiveBigInteger() throws IOException {
        if (tag != tag_Integer)
            throw new IOException("DerValue.getBigInteger, not an int " + tag);
        return buffer.getBigInteger(data.available(), true);
    }

    /**
     * Returns an ASN.1 ENUMERATED value.
     *
     * @return the integer held in this DER value.
     */
    public int getEnumerated() throws IOException {
        if (tag != tag_Enumerated) {
            throw new IOException("DerValue.getEnumerated, incorrect tag: "
                                  + tag);
        }
        return buffer.getInteger(data.available());
    }

    /**
     * Returns an ASN.1 BIT STRING value.  The bit string must be byte-aligned.
     *
     * @return the bit string held in this value
     */
    public byte[] getBitString() throws IOException {
        if (tag != tag_BitString)
            throw new IOException(
                "DerValue.getBitString, not a bit string " + tag);

        return buffer.getBitString();
    }

    /**
     * Returns an ASN.1 BIT STRING value that need not be byte-aligned.
     *
     * @return a BitArray representing the bit string held in this value
     */
    public BitArray getUnalignedBitString() throws IOException {
        if (tag != tag_BitString)
            throw new IOException(
                "DerValue.getBitString, not a bit string " + tag);

        return buffer.getUnalignedBitString();
    }

    /**
     * Returns the name component as a Java string, regardless of its
     * encoding restrictions (ASCII, T61, Printable, IA5, BMP, UTF8).
     */
    // TBD: Need encoder for UniversalString before it can be handled.
    public String getAsString() throws IOException {
        if (tag == tag_UTF8String)
            return getUTF8String();
        else if (tag == tag_PrintableString)
            return getPrintableString();
        else if (tag == tag_T61String)
            return getT61String();
        else if (tag == tag_IA5String)
            return getIA5String();
        /*
          else if (tag == tag_UniversalString)
          return getUniversalString();
        */
        else if (tag == tag_BMPString)
            return getBMPString();
        else if (tag == tag_GeneralString)
            return getGeneralString();
        else
            return null;
    }

    /**
     * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
     * based on the parameter.  The bit string must be byte-aligned.
     *
     * @param tagImplicit if true, the tag is assumed implicit.
     * @return the bit string held in this value
     */
    public byte[] getBitString(boolean tagImplicit) throws IOException {
        if (!tagImplicit) {
            if (tag != tag_BitString)
                throw new IOException("DerValue.getBitString, not a bit string "
                                       + tag);
            }
        return buffer.getBitString();
    }

    /**
     * Returns an ASN.1 BIT STRING value, with the tag assumed implicit
     * based on the parameter.  The bit string need not be byte-aligned.
     *
     * @param tagImplicit if true, the tag is assumed implicit.
     * @return the bit string held in this value
     */
    public BitArray getUnalignedBitString(boolean tagImplicit)
    throws IOException {
        if (!tagImplicit) {
            if (tag != tag_BitString)
                throw new IOException("DerValue.getBitString, not a bit string "
                                       + tag);
            }
        return buffer.getUnalignedBitString();
    }

    /**
     * Helper routine to return all the bytes contained in the
     * DerInputStream associated with this object.
     */
    public byte[] getDataBytes() throws IOException {
        byte[] retVal = new byte[length];
        synchronized (data) {
            data.reset();
            data.getBytes(retVal);
        }
        return retVal;
    }

    /**
     * Returns an ASN.1 STRING value
     *
     * @return the printable string held in this value
     */
    public String getPrintableString()
    throws IOException {
        if (tag != tag_PrintableString)
            throw new IOException(
                "DerValue.getPrintableString, not a string " + tag);

        return new String(getDataBytes(), "ASCII");
    }

    /**
     * Returns an ASN.1 T61 (Teletype) STRING value
     *
     * @return the teletype string held in this value
     */
    public String getT61String() throws IOException {
        if (tag != tag_T61String)
            throw new IOException(
                "DerValue.getT61String, not T61 " + tag);

        return new String(getDataBytes(), "ISO-8859-1");
    }

    /**
     * Returns an ASN.1 IA5 (ASCII) STRING value
     *
     * @return the ASCII string held in this value
     */
    public String getIA5String() throws IOException {
        if (tag != tag_IA5String)
            throw new IOException(
                "DerValue.getIA5String, not IA5 " + tag);

        return new String(getDataBytes(), "ASCII");
    }

    /**
     * Returns the ASN.1 BMP (Unicode) STRING value as a Java string.
     *
     * @return a string corresponding to the encoded BMPString held in
     * this value
     */
    public String getBMPString() throws IOException {
        if (tag != tag_BMPString)
            throw new IOException(
                "DerValue.getBMPString, not BMP " + tag);

        // BMPString is the same as Unicode in big endian, unmarked
        // format.
        return new String(getDataBytes(), "UnicodeBigUnmarked");
    }

    /**
     * Returns the ASN.1 UTF-8 STRING value as a Java String.
     *
     * @return a string corresponding to the encoded UTF8String held in
     * this value
     */
    public String getUTF8String() throws IOException {
        if (tag != tag_UTF8String)
            throw new IOException(
                "DerValue.getUTF8String, not UTF-8 " + tag);

        return new String(getDataBytes(), "UTF8");
    }

    /**
     * Returns the ASN.1 GENERAL STRING value as a Java String.
     *
     * @return a string corresponding to the encoded GeneralString held in
     * this value
     */
    public String getGeneralString() throws IOException {
        if (tag != tag_GeneralString)
            throw new IOException(
                "DerValue.getGeneralString, not GeneralString " + tag);

        return new String(getDataBytes(), "ASCII");
    }

    /**
     * Returns a Date if the DerValue is UtcTime.
     *
     * @return the Date held in this DER value
     */
    public Date getUTCTime() throws IOException {
        if (tag != tag_UtcTime) {
            throw new IOException("DerValue.getUTCTime, not a UtcTime: " + tag);
        }
        return buffer.getUTCTime(data.available());
    }

    /**
     * Returns a Date if the DerValue is GeneralizedTime.
     *
     * @return the Date held in this DER value
     */
    public Date getGeneralizedTime() throws IOException {
        if (tag != tag_GeneralizedTime) {
            throw new IOException(
                "DerValue.getGeneralizedTime, not a GeneralizedTime: " + tag);
        }
        return buffer.getGeneralizedTime(data.available());
    }

    /**
     * Bitwise equality comparison.  DER encoded values have a single
     * encoding, so that bitwise equality of the encoded values is an
     * efficient way to establish equivalence of the unencoded values.
     *
     * @param o the object being compared with this one
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof DerValue)) {
            return false;
        }
        DerValue other = (DerValue) o;
        if (tag != other.tag) {
            return false;
        }
        if (data == other.data) {
            return true;
        }

        // make sure the order of lock is always consistent to avoid a deadlock
        return (System.identityHashCode(this.data)
                > System.identityHashCode(other.data)) ?
                doEquals(this, other):
                doEquals(other, this);
    }

    /**
     * Helper for public method equals()
     */
    private static boolean doEquals(DerValue d1, DerValue d2) {
        synchronized (d1.data) {
            synchronized (d2.data) {
                d1.data.reset();
                d2.data.reset();
                return d1.buffer.equals(d2.buffer);
            }
        }
    }

    /**
     * Returns a printable representation of the value.
     *
     * @return printable representation of the value
     */
    @Override
    public String toString() {
        try {

            String str = getAsString();
            if (str != null)
                return "\"" + str + "\"";
            if (tag == tag_Null)
                return "[DerValue, null]";
            if (tag == tag_ObjectId)
                return "OID." + getOID();

            // integers
            else
                return "[DerValue, tag = " + tag
                        + ", length = " + length + "]";
        } catch (IOException e) {
            throw new IllegalArgumentException("misformatted DER value");
        }
    }

    /**
     * Returns a DER-encoded value, such that if it's passed to the
     * DerValue constructor, a value equivalent to "this" is returned.
     *
     * @return DER-encoded value, including tag and length.
     */
    public byte[] toByteArray() throws IOException {
        DerOutputStream out = new DerOutputStream();

        encode(out);
        data.reset();
        return out.toByteArray();
    }

    /**
     * For "set" and "sequence" types, this function may be used
     * to return a DER stream of the members of the set or sequence.
     * This operation is not supported for primitive types such as
     * integers or bit strings.
     */
    public DerInputStream toDerInputStream() throws IOException {
        if (tag == tag_Sequence || tag == tag_Set)
            return new DerInputStream(buffer);
        throw new IOException("toDerInputStream rejects tag type " + tag);
    }

    /**
     * Get the length of the encoded value.
     */
    public int length() {
        return length;
    }

    /**
     * Determine if a character is one of the permissible characters for
     * PrintableString:
     * A-Z, a-z, 0-9, space, apostrophe (39), left and right parentheses,
     * plus sign, comma, hyphen, period, slash, colon, equals sign,
     * and question mark.
     *
     * Characters that are *not* allowed in PrintableString include
     * exclamation point, quotation mark, number sign, dollar sign,
     * percent sign, ampersand, asterisk, semicolon, less than sign,
     * greater than sign, at sign, left and right square brackets,
     * backslash, circumflex (94), underscore, back quote (96),
     * left and right curly brackets, vertical line, tilde,
     * and the control codes (0-31 and 127).
     *
     * This list is based on X.680 (the ASN.1 spec).
     */
    public static boolean isPrintableStringChar(char ch) {
        if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') ||
            (ch >= '0' && ch <= '9')) {
            return true;
        } else {
            switch (ch) {
                case ' ':       /* space */
                case '\'':      /* apostrophe */
                case '(':       /* left paren */
                case ')':       /* right paren */
                case '+':       /* plus */
                case ',':       /* comma */
                case '-':       /* hyphen */
                case '.':       /* period */
                case '/':       /* slash */
                case ':':       /* colon */
                case '=':       /* equals */
                case '?':       /* question mark */
                    return true;
                default:
                    return false;
            }
        }
    }

    /**
     * Create the tag of the attribute.
     *
     * @param tagClass the tag class type, one of UNIVERSAL, CONTEXT,
     *               APPLICATION or PRIVATE
     * @param form if true, the value is constructed, otherwise it
     * is primitive.
     * @param val the tag value
     */
    public static byte createTag(byte tagClass, boolean form, byte val) {
        byte tag = (byte)(tagClass | val);
        if (form) {
            tag |= (byte)0x20;
        }
        return (tag);
    }

    /**
     * Set the tag of the attribute. Commonly used to reset the
     * tag value used for IMPLICIT encodings.
     *
     * @param tag the tag value
     */
    public void resetTag(byte tag) {
        this.tag = tag;
    }

    /**
     * Returns a hashcode for this DerValue.
     *
     * @return a hashcode for this DerValue.
     */
    @Override
    public int hashCode() {
        return toString().hashCode();
    }
}
