// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)

package org.xbill.DNS;

import java.io.*;
import java.util.*;
import org.xbill.DNS.utils.*;

/**
 * Transaction Signature - this record is automatically generated by the
 * resolver.  TSIG records provide transaction security between the
 * sender and receiver of a message, using a shared key.
 * @see Resolver
 * @see TSIG
 *
 * @author Brian Wellington
 */

public class TSIGRecord extends Record {

private static final long serialVersionUID = -88820909016649306L;

private Name alg;
private Date timeSigned;
private int fudge;
private byte [] signature;
private int originalID;
private int error;
private byte [] other;

TSIGRecord() {} 

Record
getObject() {
	return new TSIGRecord();
}

/**
 * Creates a TSIG Record from the given data.  This is normally called by
 * the TSIG class
 * @param alg The shared key's algorithm
 * @param timeSigned The time that this record was generated
 * @param fudge The fudge factor for time - if the time that the message is
 * received is not in the range [now - fudge, now + fudge], the signature
 * fails
 * @param signature The signature
 * @param originalID The message ID at the time of its generation
 * @param error The extended error field.  Should be 0 in queries.
 * @param other The other data field.  Currently used only in BADTIME
 * responses.
 * @see TSIG
 */
public
TSIGRecord(Name name, int dclass, long ttl, Name alg, Date timeSigned,
	   int fudge, byte [] signature, int originalID, int error,
	   byte other[])
{
	super(name, Type.TSIG, dclass, ttl);
	this.alg = checkName("alg", alg);
	this.timeSigned = timeSigned;
	this.fudge = checkU16("fudge", fudge);
	this.signature = signature;
	this.originalID = checkU16("originalID", originalID);
	this.error = checkU16("error", error);
	this.other = other;
}

void
rrFromWire(DNSInput in) throws IOException {
	alg = new Name(in);

	long timeHigh = in.readU16();
	long timeLow = in.readU32();
	long time = (timeHigh << 32) + timeLow;
	timeSigned = new Date(time * 1000);
	fudge = in.readU16();

	int sigLen = in.readU16();
	signature = in.readByteArray(sigLen);

	originalID = in.readU16();
	error = in.readU16();

	int otherLen = in.readU16();
	if (otherLen > 0)
		other = in.readByteArray(otherLen);
	else
		other = null;
}

void
rdataFromString(Tokenizer st, Name origin) throws IOException {
	throw st.exception("no text format defined for TSIG");
}

/** Converts rdata to a String */
String
rrToString() {
	StringBuffer sb = new StringBuffer();
	sb.append(alg);
	sb.append(" ");
	if (Options.check("multiline"))
		sb.append("(\n\t");

	sb.append (timeSigned.getTime() / 1000);
	sb.append (" ");
	sb.append (fudge);
	sb.append (" ");
	sb.append (signature.length);
	if (Options.check("multiline")) {
		sb.append ("\n");
		sb.append (base64.formatString(signature, 64, "\t", false));
	} else {
		sb.append (" ");
		sb.append (base64.toString(signature));
	}
	sb.append (" ");
	sb.append (Rcode.TSIGstring(error));
	sb.append (" ");
	if (other == null)
		sb.append (0);
	else {
		sb.append (other.length);
		if (Options.check("multiline"))
			sb.append("\n\n\n\t");
		else
			sb.append(" ");
		if (error == Rcode.BADTIME) {
			if (other.length != 6) {
				sb.append("<invalid BADTIME other data>");
			} else {
				long time = ((long)(other[0] & 0xFF) << 40) +
					    ((long)(other[1] & 0xFF) << 32) +
					    ((other[2] & 0xFF) << 24) +
					    ((other[3] & 0xFF) << 16) +
					    ((other[4] & 0xFF) << 8) +
					    ((other[5] & 0xFF)     );
				sb.append("<server time: ");
				sb.append(new Date(time * 1000));
				sb.append(">");
			}
		} else {
			sb.append("<");
			sb.append(base64.toString(other));
			sb.append(">");
		}
	}
	if (Options.check("multiline"))
		sb.append(" )");
	return sb.toString();
}

/** Returns the shared key's algorithm */
public Name
getAlgorithm() {
	return alg;
}

/** Returns the time that this record was generated */
public Date
getTimeSigned() {
	return timeSigned;
}

/** Returns the time fudge factor */
public int
getFudge() {
	return fudge;
}

/** Returns the signature */
public byte []
getSignature() {
	return signature;
}

/** Returns the original message ID */
public int
getOriginalID() {
	return originalID;
}

/** Returns the extended error */
public int
getError() {
	return error;
}

/** Returns the other data */
public byte []
getOther() {
	return other;
}

void
rrToWire(DNSOutput out, Compression c, boolean canonical) {
	alg.toWire(out, null, canonical);

	long time = timeSigned.getTime() / 1000;
	int timeHigh = (int) (time >> 32);
	long timeLow = (time & 0xFFFFFFFFL);
	out.writeU16(timeHigh);
	out.writeU32(timeLow);
	out.writeU16(fudge);

	out.writeU16(signature.length);
	out.writeByteArray(signature);

	out.writeU16(originalID);
	out.writeU16(error);

	if (other != null) {
		out.writeU16(other.length);
		out.writeByteArray(other);
	}
	else
		out.writeU16(0);
}

}
