/* * Copied from the DnsJava project * * Copyright (c) 1998-2011, Brian Wellington. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package io.milton.dns.record; import io.milton.dns.Name; import io.milton.dns.utils.base64; import java.io.*; import java.util.*; /** * Transaction Key - used to compute and/or securely transport a shared * secret to be used with TSIG. * @see TSIG * * @author Brian Wellington */ public class TKEYRecord extends Record { private static final long serialVersionUID = 8828458121926391756L; private Name alg; private Date timeInception; private Date timeExpire; private int mode, error; private byte [] key; private byte [] other; /** The key is assigned by the server (unimplemented) */ public static final int SERVERASSIGNED = 1; /** The key is computed using a Diffie-Hellman key exchange */ public static final int DIFFIEHELLMAN = 2; /** The key is computed using GSS_API (unimplemented) */ public static final int GSSAPI = 3; /** The key is assigned by the resolver (unimplemented) */ public static final int RESOLVERASSIGNED = 4; /** The key should be deleted */ public static final int DELETE = 5; TKEYRecord() {} Record getObject() { return new TKEYRecord(); } /** * Creates a TKEY Record from the given data. * @param alg The shared key's algorithm * @param timeInception The beginning of the validity period of the shared * secret or keying material * @param timeExpire The end of the validity period of the shared * secret or keying material * @param mode The mode of key agreement * @param error The extended error field. Should be 0 in queries * @param key The shared secret * @param other The other data field. Currently unused * responses. */ public TKEYRecord(Name name, int dclass, long ttl, Name alg, Date timeInception, Date timeExpire, int mode, int error, byte [] key, byte other[]) { super(name, Type.TKEY, dclass, ttl); this.alg = checkName("alg", alg); this.timeInception = timeInception; this.timeExpire = timeExpire; this.mode = checkU16("mode", mode); this.error = checkU16("error", error); this.key = key; this.other = other; } void rrFromWire(DNSInput in) throws IOException { alg = new Name(in); timeInception = new Date(1000 * in.readU32()); timeExpire = new Date(1000 * in.readU32()); mode = in.readU16(); error = in.readU16(); int keylen = in.readU16(); if (keylen > 0) key = in.readByteArray(keylen); else key = null; 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 TKEY"); } protected String modeString() { switch (mode) { case SERVERASSIGNED: return "SERVERASSIGNED"; case DIFFIEHELLMAN: return "DIFFIEHELLMAN"; case GSSAPI: return "GSSAPI"; case RESOLVERASSIGNED: return "RESOLVERASSIGNED"; case DELETE: return "DELETE"; default: return Integer.toString(mode); } } /** Converts rdata to a String */ String rrToString() { StringBuilder sb = new StringBuilder(); sb.append(alg); sb.append(" "); if (Options.check("multiline")) sb.append("(\n\t"); sb.append(FormattedTime.format(timeInception)); sb.append(" "); sb.append(FormattedTime.format(timeExpire)); sb.append(" "); sb.append(modeString()); sb.append(" "); sb.append(Rcode.TSIGstring(error)); if (Options.check("multiline")) { sb.append("\n"); if (key != null) { sb.append(base64.formatString(key, 64, "\t", false)); sb.append("\n"); } if (other != null) sb.append(base64.formatString(other, 64, "\t", false)); sb.append(" )"); } else { sb.append(" "); if (key != null) { sb.append(base64.toString(key)); sb.append(" "); } if (other != null) sb.append(base64.toString(other)); } return sb.toString(); } /** Returns the shared key's algorithm */ public Name getAlgorithm() { return alg; } /** * Returns the beginning of the validity period of the shared secret or * keying material */ public Date getTimeInception() { return timeInception; } /** * Returns the end of the validity period of the shared secret or * keying material */ public Date getTimeExpire() { return timeExpire; } /** Returns the key agreement mode */ public int getMode() { return mode; } /** Returns the extended error */ public int getError() { return error; } /** Returns the shared secret or keying material */ public byte [] getKey() { return key; } /** Returns the other data */ public byte [] getOther() { return other; } void rrToWire(DNSOutput out, Compression c, boolean canonical) { alg.toWire(out, null, canonical); out.writeU32(timeInception.getTime() / 1000); out.writeU32(timeExpire.getTime() / 1000); out.writeU16(mode); out.writeU16(error); if (key != null) { out.writeU16(key.length); out.writeByteArray(key); } else out.writeU16(0); if (other != null) { out.writeU16(other.length); out.writeByteArray(other); } else out.writeU16(0); } }