blob: c7ce9ed3d984f5edef7214d965fc9c9d6e094351 [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.*;
6import java.util.*;
7import org.xbill.DNS.utils.*;
8
9/**
10 * Transaction Signature - this record is automatically generated by the
11 * resolver. TSIG records provide transaction security between the
12 * sender and receiver of a message, using a shared key.
13 * @see Resolver
14 * @see TSIG
15 *
16 * @author Brian Wellington
17 */
18
19public class TSIGRecord extends Record {
20
21private static final long serialVersionUID = -88820909016649306L;
22
23private Name alg;
24private Date timeSigned;
25private int fudge;
26private byte [] signature;
27private int originalID;
28private int error;
29private byte [] other;
30
31TSIGRecord() {}
32
33Record
34getObject() {
35 return new TSIGRecord();
36}
37
38/**
39 * Creates a TSIG Record from the given data. This is normally called by
40 * the TSIG class
41 * @param alg The shared key's algorithm
42 * @param timeSigned The time that this record was generated
43 * @param fudge The fudge factor for time - if the time that the message is
44 * received is not in the range [now - fudge, now + fudge], the signature
45 * fails
46 * @param signature The signature
47 * @param originalID The message ID at the time of its generation
48 * @param error The extended error field. Should be 0 in queries.
49 * @param other The other data field. Currently used only in BADTIME
50 * responses.
51 * @see TSIG
52 */
53public
54TSIGRecord(Name name, int dclass, long ttl, Name alg, Date timeSigned,
55 int fudge, byte [] signature, int originalID, int error,
56 byte other[])
57{
58 super(name, Type.TSIG, dclass, ttl);
59 this.alg = checkName("alg", alg);
60 this.timeSigned = timeSigned;
61 this.fudge = checkU16("fudge", fudge);
62 this.signature = signature;
63 this.originalID = checkU16("originalID", originalID);
64 this.error = checkU16("error", error);
65 this.other = other;
66}
67
68void
69rrFromWire(DNSInput in) throws IOException {
70 alg = new Name(in);
71
72 long timeHigh = in.readU16();
73 long timeLow = in.readU32();
74 long time = (timeHigh << 32) + timeLow;
75 timeSigned = new Date(time * 1000);
76 fudge = in.readU16();
77
78 int sigLen = in.readU16();
79 signature = in.readByteArray(sigLen);
80
81 originalID = in.readU16();
82 error = in.readU16();
83
84 int otherLen = in.readU16();
85 if (otherLen > 0)
86 other = in.readByteArray(otherLen);
87 else
88 other = null;
89}
90
91void
92rdataFromString(Tokenizer st, Name origin) throws IOException {
93 throw st.exception("no text format defined for TSIG");
94}
95
96/** Converts rdata to a String */
97String
98rrToString() {
99 StringBuffer sb = new StringBuffer();
100 sb.append(alg);
101 sb.append(" ");
102 if (Options.check("multiline"))
103 sb.append("(\n\t");
104
105 sb.append (timeSigned.getTime() / 1000);
106 sb.append (" ");
107 sb.append (fudge);
108 sb.append (" ");
109 sb.append (signature.length);
110 if (Options.check("multiline")) {
111 sb.append ("\n");
112 sb.append (base64.formatString(signature, 64, "\t", false));
113 } else {
114 sb.append (" ");
115 sb.append (base64.toString(signature));
116 }
117 sb.append (" ");
118 sb.append (Rcode.TSIGstring(error));
119 sb.append (" ");
120 if (other == null)
121 sb.append (0);
122 else {
123 sb.append (other.length);
124 if (Options.check("multiline"))
125 sb.append("\n\n\n\t");
126 else
127 sb.append(" ");
128 if (error == Rcode.BADTIME) {
129 if (other.length != 6) {
130 sb.append("<invalid BADTIME other data>");
131 } else {
132 long time = ((long)(other[0] & 0xFF) << 40) +
133 ((long)(other[1] & 0xFF) << 32) +
134 ((other[2] & 0xFF) << 24) +
135 ((other[3] & 0xFF) << 16) +
136 ((other[4] & 0xFF) << 8) +
137 ((other[5] & 0xFF) );
138 sb.append("<server time: ");
139 sb.append(new Date(time * 1000));
140 sb.append(">");
141 }
142 } else {
143 sb.append("<");
144 sb.append(base64.toString(other));
145 sb.append(">");
146 }
147 }
148 if (Options.check("multiline"))
149 sb.append(" )");
150 return sb.toString();
151}
152
153/** Returns the shared key's algorithm */
154public Name
155getAlgorithm() {
156 return alg;
157}
158
159/** Returns the time that this record was generated */
160public Date
161getTimeSigned() {
162 return timeSigned;
163}
164
165/** Returns the time fudge factor */
166public int
167getFudge() {
168 return fudge;
169}
170
171/** Returns the signature */
172public byte []
173getSignature() {
174 return signature;
175}
176
177/** Returns the original message ID */
178public int
179getOriginalID() {
180 return originalID;
181}
182
183/** Returns the extended error */
184public int
185getError() {
186 return error;
187}
188
189/** Returns the other data */
190public byte []
191getOther() {
192 return other;
193}
194
195void
196rrToWire(DNSOutput out, Compression c, boolean canonical) {
197 alg.toWire(out, null, canonical);
198
199 long time = timeSigned.getTime() / 1000;
200 int timeHigh = (int) (time >> 32);
201 long timeLow = (time & 0xFFFFFFFFL);
202 out.writeU16(timeHigh);
203 out.writeU32(timeLow);
204 out.writeU16(fudge);
205
206 out.writeU16(signature.length);
207 out.writeByteArray(signature);
208
209 out.writeU16(originalID);
210 out.writeU16(error);
211
212 if (other != null) {
213 out.writeU16(other.length);
214 out.writeByteArray(other);
215 }
216 else
217 out.writeU16(0);
218}
219
220}