1// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.IOException;
6import java.security.NoSuchAlgorithmException;
7
8import org.xbill.DNS.utils.base16;
9
10/**
11 * Next SECure name 3 Parameters - this record contains the parameters (hash
12 * algorithm, salt, iterations) used for a valid, complete NSEC3 chain present
13 * in a zone. Zones signed using NSEC3 must include this record at the zone apex
14 * to inform authoritative servers that NSEC3 is being used with the given
15 * parameters.
16 *
17 * @author Brian Wellington
18 * @author David Blacka
19 */
20
21public class NSEC3PARAMRecord extends Record {
22
23private static final long serialVersionUID = -8689038598776316533L;
24
25private int hashAlg;
26private int flags;
27private int iterations;
28private byte salt[];
29
30NSEC3PARAMRecord() {}
31
32Record getObject() {
33	return new NSEC3PARAMRecord();
34}
35
36/**
37 * Creates an NSEC3PARAM record from the given data.
38 *
39 * @param name The ownername of the NSEC3PARAM record (generally the zone name).
40 * @param dclass The class.
41 * @param ttl The TTL.
42 * @param hashAlg The hash algorithm.
43 * @param flags The value of the flags field.
44 * @param iterations The number of hash iterations.
45 * @param salt The salt to use (may be null).
46 */
47public NSEC3PARAMRecord(Name name, int dclass, long ttl, int hashAlg,
48			int flags, int iterations, byte [] salt)
49{
50	super(name, Type.NSEC3PARAM, dclass, ttl);
51	this.hashAlg = checkU8("hashAlg", hashAlg);
52	this.flags = checkU8("flags", flags);
53	this.iterations = checkU16("iterations", iterations);
54
55	if (salt != null) {
56		if (salt.length > 255)
57			throw new IllegalArgumentException("Invalid salt " +
58							   "length");
59		if (salt.length > 0) {
60			this.salt = new byte[salt.length];
61			System.arraycopy(salt, 0, this.salt, 0, salt.length);
62		}
63	}
64}
65
66void
67rrFromWire(DNSInput in) throws IOException {
68	hashAlg = in.readU8();
69	flags = in.readU8();
70	iterations = in.readU16();
71
72	int salt_length = in.readU8();
73	if (salt_length > 0)
74		salt = in.readByteArray(salt_length);
75	else
76		salt = null;
77}
78
79void
80rrToWire(DNSOutput out, Compression c, boolean canonical) {
81	out.writeU8(hashAlg);
82	out.writeU8(flags);
83	out.writeU16(iterations);
84
85	if (salt != null) {
86		out.writeU8(salt.length);
87		out.writeByteArray(salt);
88	} else
89		out.writeU8(0);
90}
91
92void
93rdataFromString(Tokenizer st, Name origin) throws IOException
94{
95	hashAlg = st.getUInt8();
96	flags = st.getUInt8();
97	iterations = st.getUInt16();
98
99	String s = st.getString();
100	if (s.equals("-"))
101		salt = null;
102	else {
103		st.unget();
104		salt = st.getHexString();
105		if (salt.length > 255)
106			throw st.exception("salt value too long");
107	}
108}
109
110/** Converts rdata to a String */
111String
112rrToString() {
113	StringBuffer sb = new StringBuffer();
114	sb.append(hashAlg);
115	sb.append(' ');
116	sb.append(flags);
117	sb.append(' ');
118	sb.append(iterations);
119	sb.append(' ');
120	if (salt == null)
121		sb.append('-');
122	else
123		sb.append(base16.toString(salt));
124
125	return sb.toString();
126}
127
128/** Returns the hash algorithm */
129public int
130getHashAlgorithm() {
131	return hashAlg;
132}
133
134/** Returns the flags */
135public int
136getFlags() {
137	return flags;
138}
139
140/** Returns the number of iterations */
141public int
142getIterations() {
143	return iterations;
144}
145
146/** Returns the salt */
147public byte []
148getSalt()
149{
150	return salt;
151}
152
153/**
154 * Hashes a name with the parameters of this NSEC3PARAM record.
155 * @param name The name to hash
156 * @return The hashed version of the name
157 * @throws NoSuchAlgorithmException The hash algorithm is unknown.
158 */
159public byte []
160hashName(Name name) throws NoSuchAlgorithmException
161{
162	return NSEC3Record.hashName(name, hashAlg, iterations, salt);
163}
164
165}
166