blob: c7ce9ed3d984f5edef7214d965fc9c9d6e094351 [file] [log] [blame]
// 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);
}
}