/*
 * 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.
 */

/*
 *
 *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
 *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
 */

package sun.security.krb5.internal;

import sun.security.util.*;
import sun.security.krb5.Asn1Exception;
import java.util.Vector;
import java.io.IOException;
import sun.security.krb5.internal.ccache.CCacheOutputStream;

/**
 * In RFC4120, the ASN.1 AuthorizationData is defined as:
 *
 * AuthorizationData            ::= SEQUENCE OF SEQUENCE {
 *              ad-type         [0] Int32,
 *              ad-data         [1] OCTET STRING
 * }
 *
 * Here, two classes are used to implement it and they can be represented as follows:
 *
 * AuthorizationData ::= SEQUENCE OF AuthorizationDataEntry
 * AuthorizationDataEntry ::= SEQUENCE {
 *              ad-type[0]  Int32,
 *              ad-data[1]  OCTET STRING
 * }
 */
public class AuthorizationData implements Cloneable {
        private AuthorizationDataEntry[] entry = null;

        private AuthorizationData() {
        }

        public AuthorizationData(
                AuthorizationDataEntry[] new_entries
        ) throws IOException {
                if (new_entries != null) {
                   entry = new AuthorizationDataEntry[new_entries.length];
                   for (int i = 0; i < new_entries.length; i++) {
                        if (new_entries[i] == null) {
                           throw new IOException("Cannot create an AuthorizationData");
                        } else {
                           entry[i] = (AuthorizationDataEntry)new_entries[i].clone();
                        }
                   }
                }
        }

        public AuthorizationData(
                AuthorizationDataEntry new_entry
        ) {
                entry = new AuthorizationDataEntry[1];
                entry[0] = new_entry;
        }

        public Object clone() {
                AuthorizationData new_authorizationData =
                        new AuthorizationData();
                if (entry != null) {
                        new_authorizationData.entry =
                                new AuthorizationDataEntry[entry.length];
                        for (int i = 0; i < entry.length; i++)
                                new_authorizationData.entry[i] =
                                        (AuthorizationDataEntry)entry[i].clone();
                }
                return new_authorizationData;
        }

        /**
         * Constructs a new <code>AuthorizationData,</code> instance.
         * @param der a single DER-encoded value.
         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
         * @exception IOException if an I/O error occurs while reading encoded data.
         */
        public AuthorizationData(DerValue der) throws Asn1Exception, IOException {
                Vector<AuthorizationDataEntry> v =
                    new Vector<AuthorizationDataEntry> ();
                if (der.getTag() != DerValue.tag_Sequence) {
                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
                }
                while (der.getData().available() > 0) {
                        v.addElement(new AuthorizationDataEntry(der.getData().getDerValue()));
                }
                if (v.size() > 0) {
                        entry = new AuthorizationDataEntry[v.size()];
                        v.copyInto(entry);
                }
        }

        /**
         * Encodes an <code>AuthorizationData</code> object.
         * @return byte array of encoded <code>AuthorizationData</code> object.
         * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
         * @exception IOException if an I/O error occurs while reading encoded data.
         */
        public byte[] asn1Encode() throws Asn1Exception, IOException {
                DerOutputStream bytes = new DerOutputStream();
                DerValue der[] = new DerValue[entry.length];
                for (int i = 0; i < entry.length; i++) {
                        der[i] = new DerValue(entry[i].asn1Encode());
                }
                bytes.putSequence(der);
                return bytes.toByteArray();
        }

    /**
     * Parse (unmarshal) an <code>AuthorizationData</code> object from a DER input stream.
     * This form of parsing might be used when expanding a value which is part of
     * a constructed sequence and uses explicitly tagged type.
     *
     * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
     * @exception IOException if an I/O error occurs while reading encoded data.
     * @param data the Der input stream value, which contains one or more marshaled value.
     * @param explicitTag tag number.
     * @param optional indicates if this data field is optional
     * @return an instance of AuthorizationData.
     *
     */
        public static AuthorizationData parse(DerInputStream data, byte explicitTag, boolean optional) throws Asn1Exception, IOException{
                if ((optional) && (((byte)data.peekByte() & (byte)0x1F) != explicitTag)) {
                        return null;
                }
                DerValue der = data.getDerValue();
                if (explicitTag != (der.getTag() & (byte)0x1F))  {
                        throw new Asn1Exception(Krb5.ASN1_BAD_ID);
                }
                else {
                        DerValue subDer = der.getData().getDerValue();
                        return new AuthorizationData(subDer);
                }
        }

        /**
         * Writes <code>AuthorizationData</code> data fields to a output stream.
         *
         * @param cos a <code>CCacheOutputStream</code> to be written to.
         * @exception IOException if an I/O exception occurs.
         */
        public void writeAuth(CCacheOutputStream cos) throws IOException {
                for (int i = 0; i < entry.length; i++) {
                        entry[i].writeEntry(cos);
                }
        }

    public String toString() {
        String retVal = "AuthorizationData:\n";
        for (int i = 0; i < entry.length; i++) {
            retVal += entry[i].toString();
        }
        return retVal;
    }
}
