// Copyright 1997 The Open Group Research Institute.  All rights reserved.

package krb4.lib;

import java.io.*;
import krb4.lib.crypto.*;

public class Krb4Authenticator {
	public String cname;
	public String cinst;
	public String crealm;
	public int checksum;
	public long timestamp_5ms;
	public long timestamp;

	public Krb4Authenticator(
		String new_cname,
		String new_cinst,
		String new_crealm,
		int new_checksum,
		long new_timestamp_5ms,
		long new_timestamp
	) {
		cname = new_cname;
		cinst = new_cinst;
		crealm = new_crealm;
		checksum = new_checksum;
		timestamp_5ms = new_timestamp_5ms;
		timestamp = new_timestamp;
	}

	public Krb4Authenticator(
		String new_cname,
		String new_cinst,
		String new_crealm,
		int new_checksum
	) {
		cname = new_cname;
		cinst = new_cinst;
		crealm = new_crealm;
		checksum = new_checksum;
		timestamp = new java.util.Date().getTime();
		timestamp_5ms = timestamp % 1000L;
	}

	public byte[] encode(byte[] key) throws Krb4Exception, IOException {
		ByteArrayOutputStream o = new ByteArrayOutputStream();
		o.write(Krb4Encode.toBytes(cname));
		o.write(Krb4Encode.toBytes(cinst));
		o.write(Krb4Encode.toBytes(crealm));
		o.write(Krb4Encode.toBytes(checksum));
		o.write((byte)(timestamp_5ms / 5L));
		o.write(Krb4Encode.toBytes((int)(timestamp / 1000L)));
		byte[] authenticatorBytes = o.toByteArray();
		byte[] encAuthenticator = new byte[authenticatorBytes.length +
			(authenticatorBytes.length % 8 != 0 ? 8 - authenticatorBytes.length % 8 : 0)];
		long[] key_sched = new long[16];
		des.des_set_key(key, key_sched);
		byte[] ivec = new byte[key.length];
		System.arraycopy(key, 0, ivec, 0, key.length);
		des.pcbc_encrypt(authenticatorBytes, encAuthenticator,
			key_sched, ivec, true);
		return encAuthenticator;
	}

	public Krb4Authenticator(byte[] data, boolean littleEndian)
		throws Krb4Exception {
		Krb4Encode ref = new Krb4Encode(data);
		ref.setByteOrder(littleEndian);
		cname = ref.getString();
		cinst = ref.getString();
		crealm = ref.getString();
		checksum = ref.getInt();
		timestamp_5ms = (long)ref.getUnsignedByte() * 5L;
		timestamp = (long)ref.getInt() * 1000L;
	}
}
