/*
 * Copyright (c) 2003, 2004, 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.timestamp;

import java.io.IOException;
import java.math.BigInteger;
import sun.security.pkcs.PKCS7;
import sun.security.pkcs.PKCS9Attribute;
import sun.security.pkcs.PKCS9Attributes;
import sun.security.pkcs.ParsingException;
import sun.security.pkcs.SignerInfo;
import sun.security.util.DerValue;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;

/**
 * This class provides the response corresponding to a timestamp request,
 * as defined in
 * <a href="http://www.ietf.org/rfc/rfc3161.txt">RFC 3161</a>.
 *
 * The TimeStampResp ASN.1 type has the following definition:
 * <pre>
 *
 *     TimeStampResp ::= SEQUENCE {
 *         status            PKIStatusInfo,
 *         timeStampToken    TimeStampToken OPTIONAL ]
 *
 *     PKIStatusInfo ::= SEQUENCE {
 *         status        PKIStatus,
 *         statusString  PKIFreeText OPTIONAL,
 *         failInfo      PKIFailureInfo OPTIONAL }
 *
 *     PKIStatus ::= INTEGER {
 *         granted                (0),
 *           -- when the PKIStatus contains the value zero a TimeStampToken, as
 *           -- requested, is present.
 *         grantedWithMods        (1),
 *           -- when the PKIStatus contains the value one a TimeStampToken,
 *           -- with modifications, is present.
 *         rejection              (2),
 *         waiting                (3),
 *         revocationWarning      (4),
 *           -- this message contains a warning that a revocation is
 *           -- imminent
 *         revocationNotification (5)
 *           -- notification that a revocation has occurred }
 *
 *     PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String
 *           -- text encoded as UTF-8 String (note:  each UTF8String SHOULD
 *           -- include an RFC 1766 language tag to indicate the language
 *           -- of the contained text)
 *
 *     PKIFailureInfo ::= BIT STRING {
 *         badAlg              (0),
 *           -- unrecognized or unsupported Algorithm Identifier
 *         badRequest          (2),
 *           -- transaction not permitted or supported
 *         badDataFormat       (5),
 *           -- the data submitted has the wrong format
 *         timeNotAvailable    (14),
 *           -- the TSA's time source is not available
 *         unacceptedPolicy    (15),
 *           -- the requested TSA policy is not supported by the TSA
 *         unacceptedExtension (16),
 *           -- the requested extension is not supported by the TSA
 *         addInfoNotAvailable (17)
 *           -- the additional information requested could not be understood
 *           -- or is not available
 *         systemFailure       (25)
 *           -- the request cannot be handled due to system failure }
 *
 *     TimeStampToken ::= ContentInfo
 *         -- contentType is id-signedData
 *         -- content is SignedData
 *         -- eContentType within SignedData is id-ct-TSTInfo
 *         -- eContent within SignedData is TSTInfo
 *
 * </pre>
 *
 * @since 1.5
 * @author Vincent Ryan
 * @see Timestamper
 */

public class TSResponse {

    // Status codes (from RFC 3161)

    /**
     * The requested timestamp was granted.
     */
    public static final int GRANTED = 0;

    /**
     * The requested timestamp was granted with some modifications.
     */
    public static final int GRANTED_WITH_MODS = 1;

    /**
     * The requested timestamp was not granted.
     */
    public static final int REJECTION = 2;

    /**
     * The requested timestamp has not yet been processed.
     */
    public static final int WAITING = 3;

    /**
     * A warning that a certificate revocation is imminent.
     */
    public static final int REVOCATION_WARNING = 4;

    /**
     * Notification that a certificate revocation has occurred.
     */
    public static final int REVOCATION_NOTIFICATION = 5;

    // Failure codes (from RFC 3161)

    /**
     * Unrecognized or unsupported algorithm identifier.
     */
    public static final int BAD_ALG = 0;

    /**
     * The requested transaction is not permitted or supported.
     */
    public static final int BAD_REQUEST = 2;

    /**
     * The data submitted has the wrong format.
     */
    public static final int BAD_DATA_FORMAT = 5;

    /**
     * The TSA's time source is not available.
     */
    public static final int TIME_NOT_AVAILABLE = 14;

    /**
     * The requested TSA policy is not supported by the TSA.
     */
    public static final int UNACCEPTED_POLICY = 15;

    /**
     * The requested extension is not supported by the TSA.
     */
    public static final int UNACCEPTED_EXTENSION = 16;

    /**
     * The additional information requested could not be understood or is not
     * available.
     */
    public static final int ADD_INFO_NOT_AVAILABLE = 17;

    /**
     * The request cannot be handled due to system failure.
     */
    public static final int SYSTEM_FAILURE = 25;

    private static final boolean DEBUG = false;

    private int status;

    private String[] statusString = null;

    private int failureInfo = -1;

    private byte[] encodedTsToken = null;

    private PKCS7 tsToken = null;

    /**
     * Constructs an object to store the response to a timestamp request.
     *
     * @param status A buffer containing the ASN.1 BER encoded response.
     * @throws IOException The exception is thrown if a problem is encountered
     *         parsing the timestamp response.
     */
    TSResponse(byte[] tsReply) throws IOException {
        parse(tsReply);
    }

    /**
     * Retrieve the status code returned by the TSA.
     */
    public int getStatusCode() {
        return status;
    }

    /**
     * Retrieve the status messages returned by the TSA.
     *
     * @return If null then no status messages were received.
     */
    public String[] getStatusMessages() {
        return statusString;
    }

    /**
     * Retrieve the failure code returned by the TSA.
     *
     * @return If -1 then no failure code was received.
     */
    public int getFailureCode() {
        return failureInfo;
    }

    public String getStatusCodeAsText() {

        switch (status)  {
        case GRANTED:
            return "the timestamp request was granted.";

        case GRANTED_WITH_MODS:
            return
                "the timestamp request was granted with some modifications.";

        case REJECTION:
            return "the timestamp request was rejected.";

        case WAITING:
            return "the timestamp request has not yet been processed.";

        case REVOCATION_WARNING:
            return "warning: a certificate revocation is imminent.";

        case REVOCATION_NOTIFICATION:
            return "notification: a certificate revocation has occurred.";

        default:
            return ("unknown status code " + status + ".");
        }
    }

    public String getFailureCodeAsText() {

        if (failureInfo == -1) {
            return null;
        }

        switch (failureInfo)  {

        case BAD_ALG:
            return "Unrecognized or unsupported alrorithm identifier.";

        case BAD_REQUEST:
            return "The requested transaction is not permitted or supported.";

        case BAD_DATA_FORMAT:
            return "The data submitted has the wrong format.";

        case TIME_NOT_AVAILABLE:
            return "The TSA's time source is not available.";

        case UNACCEPTED_POLICY:
            return "The requested TSA policy is not supported by the TSA.";

        case UNACCEPTED_EXTENSION:
            return "The requested extension is not supported by the TSA.";

        case ADD_INFO_NOT_AVAILABLE:
            return "The additional information requested could not be " +
                "understood or is not available.";

        case SYSTEM_FAILURE:
            return "The request cannot be handled due to system failure.";

        default:
            return ("unknown status code " + status);
        }
    }

    /**
     * Retrieve the timestamp token returned by the TSA.
     *
     * @return If null then no token was received.
     */
    public PKCS7 getToken() {
        return tsToken;
    }

    /**
     * Retrieve the ASN.1 BER encoded timestamp token returned by the TSA.
     *
     * @return If null then no token was received.
     */
    public byte[] getEncodedToken() {
        return encodedTsToken;
    }

    /*
     * Parses the timestamp response.
     *
     * @param status A buffer containing the ASN.1 BER encoded response.
     * @throws IOException The exception is thrown if a problem is encountered
     *         parsing the timestamp response.
     */
    private void parse(byte[] tsReply) throws IOException {
        // Decode TimeStampResp

        DerValue derValue = new DerValue(tsReply);
        if (derValue.tag != DerValue.tag_Sequence) {
            throw new IOException("Bad encoding for timestamp response");
        }

        // Parse status

        DerValue status = derValue.data.getDerValue();
        // Parse status
        this.status = status.data.getInteger();
        if (DEBUG) {
            System.out.println("timestamp response: status=" + this.status);
        }
        // Parse statusString, if present
        if (status.data.available() > 0) {
            DerValue[] strings = status.data.getSequence(1);
            statusString = new String[strings.length];
            for (int i = 0; i < strings.length; i++) {
                statusString[i] = strings[i].data.getUTF8String();
            }
        }
        // Parse failInfo, if present
        if (status.data.available() > 0) {
            byte[] failInfo = status.data.getBitString();
            int failureInfo = (new Byte(failInfo[0])).intValue();
            if (failureInfo < 0 || failureInfo > 25 || failInfo.length != 1) {
                throw new IOException("Bad encoding for timestamp response: " +
                    "unrecognized value for the failInfo element");
            }
            this.failureInfo = failureInfo;
        }

        // Parse timeStampToken, if present
        if (derValue.data.available() > 0) {
            DerValue timestampToken = derValue.data.getDerValue();
            encodedTsToken = timestampToken.toByteArray();
            tsToken = new PKCS7(encodedTsToken);
        }

        // Check the format of the timestamp response
        if (this.status == 0 || this.status == 1) {
            if (tsToken == null) {
                throw new TimestampException(
                    "Bad encoding for timestamp response: " +
                    "expected a timeStampToken element to be present");
            }
        } else if (tsToken != null) {
            throw new TimestampException(
                "Bad encoding for timestamp response: " +
                "expected no timeStampToken element to be present");
        }
    }

final static class TimestampException extends IOException {
    TimestampException(String message) {
        super(message);
    }
}
}
