/*
 * Copyright 1996-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.security.util;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigInteger;
import java.util.Date;
import sun.util.calendar.CalendarDate;
import sun.util.calendar.CalendarSystem;

/**
 * DER input buffer ... this is the main abstraction in the DER library
 * which actively works with the "untyped byte stream" abstraction.  It
 * does so with impunity, since it's not intended to be exposed to
 * anyone who could violate the "typed value stream" DER model and hence
 * corrupt the input stream of DER values.
 *
 * @author David Brownell
 */
class DerInputBuffer extends ByteArrayInputStream implements Cloneable {

    DerInputBuffer(byte[] buf) { super(buf); }

    DerInputBuffer(byte[] buf, int offset, int len) {
        super(buf, offset, len);
    }

    DerInputBuffer dup() {
        try {
            DerInputBuffer retval = (DerInputBuffer)clone();

            retval.mark(Integer.MAX_VALUE);
            return retval;
        } catch (CloneNotSupportedException e) {
            throw new IllegalArgumentException(e.toString());
        }
    }

    byte[] toByteArray() {
        int     len = available();
        if (len <= 0)
            return null;
        byte[]  retval = new byte[len];

        System.arraycopy(buf, pos, retval, 0, len);
        return retval;
    }

    int peek() throws IOException {
        if (pos >= count)
            throw new IOException("out of data");
        else
            return buf[pos];
    }

    /**
     * Compares this DerInputBuffer for equality with the specified
     * object.
     */
    public boolean equals(Object other) {
        if (other instanceof DerInputBuffer)
            return equals((DerInputBuffer)other);
        else
            return false;
    }

    boolean equals(DerInputBuffer other) {
        if (this == other)
            return true;

        int max = this.available();
        if (other.available() != max)
            return false;
        for (int i = 0; i < max; i++) {
            if (this.buf[this.pos + i] != other.buf[other.pos + i]) {
                return false;
            }
        }
        return true;
    }

    /**
     * Returns a hashcode for this DerInputBuffer.
     *
     * @return a hashcode for this DerInputBuffer.
     */
    public int hashCode() {
        int retval = 0;

        int len = available();
        int p = pos;

        for (int i = 0; i < len; i++)
            retval += buf[p + i] * i;
        return retval;
    }

    void truncate(int len) throws IOException {
        if (len > available())
            throw new IOException("insufficient data");
        count = pos + len;
    }

    /**
     * Returns the integer which takes up the specified number
     * of bytes in this buffer as a BigInteger.
     * @param len the number of bytes to use.
     * @param makePositive whether to always return a positive value,
     *   irrespective of actual encoding
     * @return the integer as a BigInteger.
     */
    BigInteger getBigInteger(int len, boolean makePositive) throws IOException {
        if (len > available())
            throw new IOException("short read of integer");

        if (len == 0) {
            throw new IOException("Invalid encoding: zero length Int value");
        }

        byte[] bytes = new byte[len];

        System.arraycopy(buf, pos, bytes, 0, len);
        skip(len);

        if (makePositive) {
            return new BigInteger(1, bytes);
        } else {
            return new BigInteger(bytes);
        }
    }

    /**
     * Returns the integer which takes up the specified number
     * of bytes in this buffer.
     * @throws IOException if the result is not within the valid
     * range for integer, i.e. between Integer.MIN_VALUE and
     * Integer.MAX_VALUE.
     * @param len the number of bytes to use.
     * @return the integer.
     */
    public int getInteger(int len) throws IOException {

        BigInteger result = getBigInteger(len, false);
        if (result.compareTo(BigInteger.valueOf(Integer.MIN_VALUE)) < 0) {
            throw new IOException("Integer below minimum valid value");
        }
        if (result.compareTo(BigInteger.valueOf(Integer.MAX_VALUE)) > 0) {
            throw new IOException("Integer exceeds maximum valid value");
        }
        return result.intValue();
    }

    /**
     * Returns the bit string which takes up the specified
     * number of bytes in this buffer.
     */
    public byte[] getBitString(int len) throws IOException {
        if (len > available())
            throw new IOException("short read of bit string");

        if (len == 0) {
            throw new IOException("Invalid encoding: zero length bit string");
        }

        int numOfPadBits = buf[pos];
        if ((numOfPadBits < 0) || (numOfPadBits > 7)) {
            throw new IOException("Invalid number of padding bits");
        }
        // minus the first byte which indicates the number of padding bits
        byte[] retval = new byte[len - 1];
        System.arraycopy(buf, pos + 1, retval, 0, len - 1);
        if (numOfPadBits != 0) {
            // get rid of the padding bits
            retval[len - 2] &= (0xff << numOfPadBits);
        }
        skip(len);
        return retval;
    }

    /**
     * Returns the bit string which takes up the rest of this buffer.
     */
    byte[] getBitString() throws IOException {
        return getBitString(available());
    }

    /**
     * Returns the bit string which takes up the rest of this buffer.
     * The bit string need not be byte-aligned.
     */
    BitArray getUnalignedBitString() throws IOException {
        if (pos >= count)
            return null;
        /*
         * Just copy the data into an aligned, padded octet buffer,
         * and consume the rest of the buffer.
         */
        int len = available();
        int unusedBits = buf[pos] & 0xff;
        if (unusedBits > 7 ) {
            throw new IOException("Invalid value for unused bits: " + unusedBits);
        }
        byte[] bits = new byte[len - 1];
        // number of valid bits
        int length = (bits.length == 0) ? 0 : bits.length * 8 - unusedBits;

        System.arraycopy(buf, pos + 1, bits, 0, len - 1);

        BitArray bitArray = new BitArray(length, bits);
        pos = count;
        return bitArray;
    }

    /**
     * Returns the UTC Time value that takes up the specified number
     * of bytes in this buffer.
     * @param len the number of bytes to use
     */
    public Date getUTCTime(int len) throws IOException {
        if (len > available())
            throw new IOException("short read of DER UTC Time");

        if (len < 11 || len > 17)
            throw new IOException("DER UTC Time length error");

        return getTime(len, false);
    }

    /**
     * Returns the Generalized Time value that takes up the specified
     * number of bytes in this buffer.
     * @param len the number of bytes to use
     */
    public Date getGeneralizedTime(int len) throws IOException {
        if (len > available())
            throw new IOException("short read of DER Generalized Time");

        if (len < 13 || len > 23)
            throw new IOException("DER Generalized Time length error");

        return getTime(len, true);

    }

    /**
     * Private helper routine to extract time from the der value.
     * @param len the number of bytes to use
     * @param generalized true if Generalized Time is to be read, false
     * if UTC Time is to be read.
     */
    private Date getTime(int len, boolean generalized) throws IOException {

        /*
         * UTC time encoded as ASCII chars:
         *       YYMMDDhhmmZ
         *       YYMMDDhhmmssZ
         *       YYMMDDhhmm+hhmm
         *       YYMMDDhhmm-hhmm
         *       YYMMDDhhmmss+hhmm
         *       YYMMDDhhmmss-hhmm
         * UTC Time is broken in storing only two digits of year.
         * If YY < 50, we assume 20YY;
         * if YY >= 50, we assume 19YY, as per RFC 3280.
         *
         * Generalized time has a four-digit year and allows any
         * precision specified in ISO 8601. However, for our purposes,
         * we will only allow the same format as UTC time, except that
         * fractional seconds (millisecond precision) are supported.
         */

        int year, month, day, hour, minute, second, millis;
        String type = null;

        if (generalized) {
            type = "Generalized";
            year = 1000 * Character.digit((char)buf[pos++], 10);
            year += 100 * Character.digit((char)buf[pos++], 10);
            year += 10 * Character.digit((char)buf[pos++], 10);
            year += Character.digit((char)buf[pos++], 10);
            len -= 2; // For the two extra YY
        } else {
            type = "UTC";
            year = 10 * Character.digit((char)buf[pos++], 10);
            year += Character.digit((char)buf[pos++], 10);

            if (year < 50)              // origin 2000
                year += 2000;
            else
                year += 1900;   // origin 1900
        }

        month = 10 * Character.digit((char)buf[pos++], 10);
        month += Character.digit((char)buf[pos++], 10);

        day = 10 * Character.digit((char)buf[pos++], 10);
        day += Character.digit((char)buf[pos++], 10);

        hour = 10 * Character.digit((char)buf[pos++], 10);
        hour += Character.digit((char)buf[pos++], 10);

        minute = 10 * Character.digit((char)buf[pos++], 10);
        minute += Character.digit((char)buf[pos++], 10);

        len -= 10; // YYMMDDhhmm

        /*
         * We allow for non-encoded seconds, even though the
         * IETF-PKIX specification says that the seconds should
         * always be encoded even if it is zero.
         */

        millis = 0;
        if (len > 2 && len < 12) {
            second = 10 * Character.digit((char)buf[pos++], 10);
            second += Character.digit((char)buf[pos++], 10);
            len -= 2;
            // handle fractional seconds (if present)
            if (buf[pos] == '.' || buf[pos] == ',') {
                len --;
                pos++;
                // handle upto milisecond precision only
                int precision = 0;
                int peek = pos;
                while (buf[peek] != 'Z' &&
                       buf[peek] != '+' &&
                       buf[peek] != '-') {
                    peek++;
                    precision++;
                }
                switch (precision) {
                case 3:
                    millis += 100 * Character.digit((char)buf[pos++], 10);
                    millis += 10 * Character.digit((char)buf[pos++], 10);
                    millis += Character.digit((char)buf[pos++], 10);
                    break;
                case 2:
                    millis += 100 * Character.digit((char)buf[pos++], 10);
                    millis += 10 * Character.digit((char)buf[pos++], 10);
                    break;
                case 1:
                    millis += 100 * Character.digit((char)buf[pos++], 10);
                    break;
                default:
                        throw new IOException("Parse " + type +
                            " time, unsupported precision for seconds value");
                }
                len -= precision;
            }
        } else
            second = 0;

        if (month == 0 || day == 0
            || month > 12 || day > 31
            || hour >= 24 || minute >= 60 || second >= 60)
            throw new IOException("Parse " + type + " time, invalid format");

        /*
         * Generalized time can theoretically allow any precision,
         * but we're not supporting that.
         */
        CalendarSystem gcal = CalendarSystem.getGregorianCalendar();
        CalendarDate date = gcal.newCalendarDate(null); // no time zone
        date.setDate(year, month, day);
        date.setTimeOfDay(hour, minute, second, millis);
        long time = gcal.getTime(date);

        /*
         * Finally, "Z" or "+hhmm" or "-hhmm" ... offsets change hhmm
         */
        if (! (len == 1 || len == 5))
            throw new IOException("Parse " + type + " time, invalid offset");

        int hr, min;

        switch (buf[pos++]) {
        case '+':
            hr = 10 * Character.digit((char)buf[pos++], 10);
            hr += Character.digit((char)buf[pos++], 10);
            min = 10 * Character.digit((char)buf[pos++], 10);
            min += Character.digit((char)buf[pos++], 10);

            if (hr >= 24 || min >= 60)
                throw new IOException("Parse " + type + " time, +hhmm");

            time -= ((hr * 60) + min) * 60 * 1000;
            break;

        case '-':
            hr = 10 * Character.digit((char)buf[pos++], 10);
            hr += Character.digit((char)buf[pos++], 10);
            min = 10 * Character.digit((char)buf[pos++], 10);
            min += Character.digit((char)buf[pos++], 10);

            if (hr >= 24 || min >= 60)
                throw new IOException("Parse " + type + " time, -hhmm");

            time += ((hr * 60) + min) * 60 * 1000;
            break;

        case 'Z':
            break;

        default:
            throw new IOException("Parse " + type + " time, garbage offset");
        }
        return new Date(time);
    }
}
