001: // Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
002:
003: package org.xbill.DNS;
004:
005: import java.io.*;
006: import java.util.*;
007: import org.xbill.DNS.utils.*;
008:
009: /**
010: * Transaction Key - used to compute and/or securely transport a shared
011: * secret to be used with TSIG.
012: * @see TSIG
013: *
014: * @author Brian Wellington
015: */
016:
017: public class TKEYRecord extends Record {
018:
019: private Name alg;
020: private Date timeInception;
021: private Date timeExpire;
022: private int mode, error;
023: private byte[] key;
024: private byte[] other;
025:
026: /** The key is assigned by the server (unimplemented) */
027: public static final int SERVERASSIGNED = 1;
028:
029: /** The key is computed using a Diffie-Hellman key exchange */
030: public static final int DIFFIEHELLMAN = 2;
031:
032: /** The key is computed using GSS_API (unimplemented) */
033: public static final int GSSAPI = 3;
034:
035: /** The key is assigned by the resolver (unimplemented) */
036: public static final int RESOLVERASSIGNED = 4;
037:
038: /** The key should be deleted */
039: public static final int DELETE = 5;
040:
041: TKEYRecord() {
042: }
043:
044: Record getObject() {
045: return new TKEYRecord();
046: }
047:
048: /**
049: * Creates a TKEY Record from the given data.
050: * @param alg The shared key's algorithm
051: * @param timeInception The beginning of the validity period of the shared
052: * secret or keying material
053: * @param timeExpire The end of the validity period of the shared
054: * secret or keying material
055: * @param mode The mode of key agreement
056: * @param error The extended error field. Should be 0 in queries
057: * @param key The shared secret
058: * @param other The other data field. Currently unused
059: * responses.
060: */
061: public TKEYRecord(Name name, int dclass, long ttl, Name alg,
062: Date timeInception, Date timeExpire, int mode, int error,
063: byte[] key, byte other[]) {
064: super (name, Type.TKEY, dclass, ttl);
065: this .alg = checkName("alg", alg);
066: this .timeInception = timeInception;
067: this .timeExpire = timeExpire;
068: this .mode = checkU16("mode", mode);
069: this .error = checkU16("error", error);
070: this .key = key;
071: this .other = other;
072: }
073:
074: void rrFromWire(DNSInput in) throws IOException {
075: alg = new Name(in);
076: timeInception = new Date(1000 * in.readU32());
077: timeExpire = new Date(1000 * in.readU32());
078: mode = in.readU16();
079: error = in.readU16();
080:
081: int keylen = in.readU16();
082: if (keylen > 0)
083: key = in.readByteArray(keylen);
084: else
085: key = null;
086:
087: int otherlen = in.readU16();
088: if (otherlen > 0)
089: other = in.readByteArray(otherlen);
090: else
091: other = null;
092: }
093:
094: void rdataFromString(Tokenizer st, Name origin) throws IOException {
095: throw st.exception("no text format defined for TKEY");
096: }
097:
098: protected String modeString() {
099: switch (mode) {
100: case SERVERASSIGNED:
101: return "SERVERASSIGNED";
102: case DIFFIEHELLMAN:
103: return "DIFFIEHELLMAN";
104: case GSSAPI:
105: return "GSSAPI";
106: case RESOLVERASSIGNED:
107: return "RESOLVERASSIGNED";
108: case DELETE:
109: return "DELETE";
110: default:
111: return Integer.toString(mode);
112: }
113: }
114:
115: /** Converts rdata to a String */
116: String rrToString() {
117: StringBuffer sb = new StringBuffer();
118: sb.append(alg);
119: sb.append(" ");
120: if (Options.check("multiline"))
121: sb.append("(\n\t");
122: sb.append(FormattedTime.format(timeInception));
123: sb.append(" ");
124: sb.append(FormattedTime.format(timeExpire));
125: sb.append(" ");
126: sb.append(modeString());
127: sb.append(" ");
128: sb.append(Rcode.TSIGstring(error));
129: if (Options.check("multiline")) {
130: sb.append("\n");
131: if (key != null) {
132: sb.append(base64.formatString(key, 64, "\t", false));
133: sb.append("\n");
134: }
135: if (other != null)
136: sb.append(base64.formatString(other, 64, "\t", false));
137: sb.append(" )");
138: } else {
139: sb.append(" ");
140: if (key != null) {
141: sb.append(base64.toString(key));
142: sb.append(" ");
143: }
144: if (other != null)
145: sb.append(base64.toString(other));
146: }
147: return sb.toString();
148: }
149:
150: /** Returns the shared key's algorithm */
151: public Name getAlgorithm() {
152: return alg;
153: }
154:
155: /**
156: * Returns the beginning of the validity period of the shared secret or
157: * keying material
158: */
159: public Date getTimeInception() {
160: return timeInception;
161: }
162:
163: /**
164: * Returns the end of the validity period of the shared secret or
165: * keying material
166: */
167: public Date getTimeExpire() {
168: return timeExpire;
169: }
170:
171: /** Returns the key agreement mode */
172: public int getMode() {
173: return mode;
174: }
175:
176: /** Returns the extended error */
177: public int getError() {
178: return error;
179: }
180:
181: /** Returns the shared secret or keying material */
182: public byte[] getKey() {
183: return key;
184: }
185:
186: /** Returns the other data */
187: public byte[] getOther() {
188: return other;
189: }
190:
191: void rrToWire(DNSOutput out, Compression c, boolean canonical) {
192: alg.toWire(out, null, canonical);
193:
194: out.writeU32(timeInception.getTime() / 1000);
195: out.writeU32(timeExpire.getTime() / 1000);
196:
197: out.writeU16(mode);
198: out.writeU16(error);
199:
200: if (key != null) {
201: out.writeU16(key.length);
202: out.writeByteArray(key);
203: } else
204: out.writeU16(0);
205:
206: if (other != null) {
207: out.writeU16(other.length);
208: out.writeByteArray(other);
209: } else
210: out.writeU16(0);
211: }
212:
213: }
|