1 // Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3 package org.xbill.DNS;
4
5 import java.io.*;
6 import java.util.*;
7 import org.xbill.DNS.utils.*;
8
9 /**
10 * Transaction Key - used to compute and/or securely transport a shared
11 * secret to be used with TSIG.
12 * @see TSIG
13 *
14 * @author Brian Wellington
15 */
16
17 public class TKEYRecord extends Record {
18
19 private static final long serialVersionUID = 8828458121926391756L;
20
21 private Name alg;
22 private Date timeInception;
23 private Date timeExpire;
24 private int mode, error;
25 private byte [] key;
26 private byte [] other;
27
28 /** The key is assigned by the server (unimplemented) */
29 public static final int SERVERASSIGNED = 1;
30
31 /** The key is computed using a Diffie-Hellman key exchange */
32 public static final int DIFFIEHELLMAN = 2;
33
34 /** The key is computed using GSS_API (unimplemented) */
35 public static final int GSSAPI = 3;
36
37 /** The key is assigned by the resolver (unimplemented) */
38 public static final int RESOLVERASSIGNED = 4;
39
40 /** The key should be deleted */
41 public static final int DELETE = 5;
42
TKEYRecord()43 TKEYRecord() {}
44
45 Record
getObject()46 getObject() {
47 return new TKEYRecord();
48 }
49
50 /**
51 * Creates a TKEY Record from the given data.
52 * @param alg The shared key's algorithm
53 * @param timeInception The beginning of the validity period of the shared
54 * secret or keying material
55 * @param timeExpire The end of the validity period of the shared
56 * secret or keying material
57 * @param mode The mode of key agreement
58 * @param error The extended error field. Should be 0 in queries
59 * @param key The shared secret
60 * @param other The other data field. Currently unused
61 * responses.
62 */
63 public
TKEYRecord(Name name, int dclass, long ttl, Name alg, Date timeInception, Date timeExpire, int mode, int error, byte [] key, byte other[])64 TKEYRecord(Name name, int dclass, long ttl, Name alg,
65 Date timeInception, Date timeExpire, int mode, int error,
66 byte [] key, byte other[])
67 {
68 super(name, Type.TKEY, dclass, ttl);
69 this.alg = checkName("alg", alg);
70 this.timeInception = timeInception;
71 this.timeExpire = timeExpire;
72 this.mode = checkU16("mode", mode);
73 this.error = checkU16("error", error);
74 this.key = key;
75 this.other = other;
76 }
77
78 void
rrFromWire(DNSInput in)79 rrFromWire(DNSInput in) throws IOException {
80 alg = new Name(in);
81 timeInception = new Date(1000 * in.readU32());
82 timeExpire = new Date(1000 * in.readU32());
83 mode = in.readU16();
84 error = in.readU16();
85
86 int keylen = in.readU16();
87 if (keylen > 0)
88 key = in.readByteArray(keylen);
89 else
90 key = null;
91
92 int otherlen = in.readU16();
93 if (otherlen > 0)
94 other = in.readByteArray(otherlen);
95 else
96 other = null;
97 }
98
99 void
rdataFromString(Tokenizer st, Name origin)100 rdataFromString(Tokenizer st, Name origin) throws IOException {
101 throw st.exception("no text format defined for TKEY");
102 }
103
104 protected String
modeString()105 modeString() {
106 switch (mode) {
107 case SERVERASSIGNED: return "SERVERASSIGNED";
108 case DIFFIEHELLMAN: return "DIFFIEHELLMAN";
109 case GSSAPI: return "GSSAPI";
110 case RESOLVERASSIGNED: return "RESOLVERASSIGNED";
111 case DELETE: return "DELETE";
112 default: return Integer.toString(mode);
113 }
114 }
115
116 /** Converts rdata to a String */
117 String
rrToString()118 rrToString() {
119 StringBuffer sb = new StringBuffer();
120 sb.append(alg);
121 sb.append(" ");
122 if (Options.check("multiline"))
123 sb.append("(\n\t");
124 sb.append(FormattedTime.format(timeInception));
125 sb.append(" ");
126 sb.append(FormattedTime.format(timeExpire));
127 sb.append(" ");
128 sb.append(modeString());
129 sb.append(" ");
130 sb.append(Rcode.TSIGstring(error));
131 if (Options.check("multiline")) {
132 sb.append("\n");
133 if (key != null) {
134 sb.append(base64.formatString(key, 64, "\t", false));
135 sb.append("\n");
136 }
137 if (other != null)
138 sb.append(base64.formatString(other, 64, "\t", false));
139 sb.append(" )");
140 } else {
141 sb.append(" ");
142 if (key != null) {
143 sb.append(base64.toString(key));
144 sb.append(" ");
145 }
146 if (other != null)
147 sb.append(base64.toString(other));
148 }
149 return sb.toString();
150 }
151
152 /** Returns the shared key's algorithm */
153 public Name
getAlgorithm()154 getAlgorithm() {
155 return alg;
156 }
157
158 /**
159 * Returns the beginning of the validity period of the shared secret or
160 * keying material
161 */
162 public Date
getTimeInception()163 getTimeInception() {
164 return timeInception;
165 }
166
167 /**
168 * Returns the end of the validity period of the shared secret or
169 * keying material
170 */
171 public Date
getTimeExpire()172 getTimeExpire() {
173 return timeExpire;
174 }
175
176 /** Returns the key agreement mode */
177 public int
getMode()178 getMode() {
179 return mode;
180 }
181
182 /** Returns the extended error */
183 public int
getError()184 getError() {
185 return error;
186 }
187
188 /** Returns the shared secret or keying material */
189 public byte []
getKey()190 getKey() {
191 return key;
192 }
193
194 /** Returns the other data */
195 public byte []
getOther()196 getOther() {
197 return other;
198 }
199
200 void
rrToWire(DNSOutput out, Compression c, boolean canonical)201 rrToWire(DNSOutput out, Compression c, boolean canonical) {
202 alg.toWire(out, null, canonical);
203
204 out.writeU32(timeInception.getTime() / 1000);
205 out.writeU32(timeExpire.getTime() / 1000);
206
207 out.writeU16(mode);
208 out.writeU16(error);
209
210 if (key != null) {
211 out.writeU16(key.length);
212 out.writeByteArray(key);
213 }
214 else
215 out.writeU16(0);
216
217 if (other != null) {
218 out.writeU16(other.length);
219 out.writeByteArray(other);
220 }
221 else
222 out.writeU16(0);
223 }
224
225 }
226