// Copyright 1997 The Open Group Research Institute.  All rights reserved.

package krb5.lib;

import krb5.lib.asn1.*;
import java.util.Vector;

/**
 * KRB credential information
 */
public class KrbCredInfo {

	/**
	 * Key
	 */
	public EncryptionKey key;

	/**
	 * Realm
	 */
	public Realm prealm; //optional

	/**
	 * Name
	 */
	public PrincipalName pname; //optional

	/**
	 * Ticket flags
	 */
	public TicketFlags flags; //optional

	/**
	 * Authentication time
	 */
	public KerberosTime authtime; //optional

	/**
	 * Start time
	 */
	public KerberosTime starttime; //optional

	/**
	 * End time
	 */
	public KerberosTime endtime; //optional

	/**
	 * Renew till 
	 */
	public KerberosTime renewTill; //optional

	/**
	 * Realm
	 */
	public Realm srealm; //optional

	/**
	 * Name
	 */
	public PrincipalName sname; //optional

	/**
	 * Address
	 */
	public HostAddresses caddr; //optional

	/**
	 * Class constructor
	 *
	 * @param new_key is of type EncryptionKey
	 * @param new_prealm is of type Realm
	 * @param new_pname is of type PrincipalName
	 * @param new_flags is of type TicketFlags
	 * @param new_authtime is of type KerberosTime
	 * @param new_starttime is of type KerberosTime
	 * @param new_endtime is of type KerberosTime
	 * @param new_renewTill is of type KerberosTime
	 * @param new_srealm is of type Realm
	 * @param new_sname is of type PrincipalName
	 * @param new_caddr is of type HostAddresses
	 * @see krb5.lib.EncryptionKey
	 * @see krb5.lib.Realm
	 * @see krb5.lib.PrincipalName
	 * @see krb5.lib.TicketFlags
	 * @see krb5.lib.KerberosTime
	 * @see krb5.lib.PrincipalName
	 * @see krb5.lib.HostAddresses
	 */
	public KrbCredInfo(
		EncryptionKey new_key,
		Realm new_prealm,
		PrincipalName new_pname,
		TicketFlags new_flags,
		KerberosTime new_authtime,
		KerberosTime new_starttime,
		KerberosTime new_endtime,
		KerberosTime new_renewTill,
		Realm new_srealm,
		PrincipalName new_sname,
		HostAddresses new_caddr
	) {
		key = new_key;
		prealm = new_prealm;
		pname = new_pname;
		flags = new_flags;
		authtime = new_authtime;
		starttime = new_starttime;
		endtime = new_endtime;
		renewTill = new_renewTill;
		srealm = new_srealm;
		sname = new_sname;
		caddr = new_caddr;
	}

	/**
	 * Class constructor
	 *
	 * @param ref is of type EncodeRef
	 * @exception Asn1Exception an exception
	 * @exception BitStringException an exception
	 * @exception RealmException an exception
	 * @see krb5.lib.asn1.EncodeRef
	 * @see krb5.lib.Asn1Exception
	 * @see krb5.lib.BitStringException
	 * @see krb5.lib.RealmException
	 */
	public KrbCredInfo(EncodeRef ref)
		throws Asn1Exception, BitStringException, RealmException {
		EncodeRef subRef = decode.Sequence(ref);

		if (decode.Tag(subRef) == 0) {
			key = new EncryptionKey(subRef.startOfData());
			subRef.next();
		}
		else
			throw new Asn1Exception(Krb5.ASN1_BAD_ID);

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 1) {
			prealm = new Realm(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 2) {
			pname = new PrincipalName(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 3) {
			flags = new TicketFlags(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 4) {
			authtime = new KerberosTime(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 5) {
			starttime = new KerberosTime(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 6) {
			endtime = new KerberosTime(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 7) {
			renewTill = new KerberosTime(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 8) {
			srealm = new Realm(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 9) {
			sname = new PrincipalName(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence() && decode.Tag(subRef) == 10) {
			caddr = new HostAddresses(subRef.startOfData());
			subRef.next();
		}

		if (subRef.isMoreInSequence())
			throw new Asn1Exception(Krb5.ASN1_BAD_ID);
	}

	/**
	 * Encodes the object in asn1
	 *
	 * @return byte[] is a result
	 * @exception Asn1Exception an exception
	 * @exception BitStringException an exception
	 * @see krb5.lib.Asn1Exception
	 * @see krb5.lib.BitStringException
	 */
	public byte[] asn1Encode() throws Asn1Exception,
		BitStringException {
		Vector tempKrbCredInfo = new Vector();

		tempKrbCredInfo.addElement(
			encode.prependExplicitTag(0, key.asn1Encode()));

		if (prealm != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(1, prealm.asn1Encode()));

		if (pname != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(2, pname.asn1Encode()));

		if (flags != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(3, flags.asn1Encode()));

		if (authtime != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(4, authtime.asn1Encode()));

		if (starttime != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(5, starttime.asn1Encode()));

		if (endtime != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(6, endtime.asn1Encode()));

		if (renewTill != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(7, renewTill.asn1Encode()));

		if (srealm != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(8, srealm.asn1Encode()));

		if (sname != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(9, sname.asn1Encode()));

		if (caddr != null)
			tempKrbCredInfo.addElement(
				encode.prependExplicitTag(10, caddr.asn1Encode()));

		byte[][] krb_cred_info = new byte[tempKrbCredInfo.size()][];
		for (int i = 0; i < tempKrbCredInfo.size(); i++)
			krb_cred_info[i] = (byte[])(tempKrbCredInfo.elementAt(i));

		return encode.Sequence(krb_cred_info);
	}

}