1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS;
4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*;
6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.security.*;
7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.xbill.DNS.utils.*;
9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Next SECure name 3 - this record contains the next hashed name in an
12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * ordered list of hashed names in the zone, and a set of types for which
13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * records exist for this name. The presence of this record in a response
14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * signifies a negative response from a DNSSEC-signed zone.
15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * This replaces the NSEC and NXT records, when used.
17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington
19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author David Blacka
20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class NSEC3Record extends Record {
23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static class Flags {
25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/**
26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 * NSEC3 flags identifiers.
27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Flags() {}
30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/** Unsigned delegation are not included in the NSEC3 chain.
32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 *
33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	 */
34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public static final int OPT_OUT = 0x01;
35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static class Digest {
38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	private Digest() {}
39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	/** SHA-1 */
41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	public static final int SHA1 = 1;
42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int SHA1_DIGEST_ID = Digest.SHA1;
45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final long serialVersionUID = -7123504635968932855L;
47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int hashAlg;
49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int flags;
50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate int iterations;
51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate byte [] salt;
52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate byte [] next;
53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate TypeBitmap types;
54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final base32 b32 = new base32(base32.Alphabet.BASE32HEX,
56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen					     false, false);
57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
58d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenNSEC3Record() {}
59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
60d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenRecord getObject() {
61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return new NSEC3Record();
62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates an NSEC3 record from the given data.
66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen *
67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The ownername of the NSEC3 record (base32'd hash plus zonename).
68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param dclass The class.
69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param ttl The TTL.
70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param hashAlg The hash algorithm.
71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param flags The value of the flags field.
72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param iterations The number of hash iterations.
73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param salt The salt to use (may be null).
74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param next The next hash (may not be null).
75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param types The types present at the original ownername.
76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic NSEC3Record(Name name, int dclass, long ttl, int hashAlg,
78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		   int flags, int iterations, byte [] salt, byte [] next,
79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		   int [] types)
80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	super(name, Type.NSEC3, dclass, ttl);
82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	this.hashAlg = checkU8("hashAlg", hashAlg);
83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	this.flags = checkU8("flags", flags);
84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	this.iterations = checkU16("iterations", iterations);
85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (salt != null) {
87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (salt.length > 255)
88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			throw new IllegalArgumentException("Invalid salt");
89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (salt.length > 0) {
90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			this.salt = new byte[salt.length];
91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			System.arraycopy(salt, 0, this.salt, 0, salt.length);
92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		}
93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (next.length > 255) {
96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		throw new IllegalArgumentException("Invalid next hash");
97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	this.next = new byte[next.length];
99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	System.arraycopy(next, 0, this.next, 0, next.length);
100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	this.types = new TypeBitmap(types);
101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid
104d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrFromWire(DNSInput in) throws IOException {
105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	hashAlg = in.readU8();
106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	flags = in.readU8();
107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	iterations = in.readU16();
108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	int salt_length = in.readU8();
110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (salt_length > 0)
111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		salt = in.readByteArray(salt_length);
112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	else
113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		salt = null;
114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	int next_length = in.readU8();
116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	next = in.readByteArray(next_length);
117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	types = new TypeBitmap(in);
118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid
121d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToWire(DNSOutput out, Compression c, boolean canonical) {
122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	out.writeU8(hashAlg);
123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	out.writeU8(flags);
124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	out.writeU16(iterations);
125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (salt != null) {
127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		out.writeU8(salt.length);
128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		out.writeByteArray(salt);
129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	} else
130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		out.writeU8(0);
131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	out.writeU8(next.length);
133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	out.writeByteArray(next);
134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	types.toWire(out);
135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid
138d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrdataFromString(Tokenizer st, Name origin) throws IOException {
139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	hashAlg = st.getUInt8();
140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	flags = st.getUInt8();
141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	iterations = st.getUInt16();
142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	String s = st.getString();
144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (s.equals("-"))
145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		salt = null;
146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	else {
147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		st.unget();
148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		salt = st.getHexString();
149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (salt.length > 255)
150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			throw st.exception("salt value too long");
151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	next = st.getBase32String(b32);
154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	types = new TypeBitmap(st);
155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Converts rdata to a String */
158d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenString
159d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToString() {
160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	StringBuffer sb = new StringBuffer();
161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(hashAlg);
162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(' ');
163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(flags);
164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(' ');
165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(iterations);
166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(' ');
167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (salt == null)
168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		sb.append('-');
169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	else
170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		sb.append(base16.toString(salt));
171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(' ');
172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	sb.append(b32.toString(next));
173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	if (!types.empty()) {
175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		sb.append(' ');
176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		sb.append(types.toString());
177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return sb.toString();
180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the hash algorithm */
183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int
184d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetHashAlgorithm() {
185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return hashAlg;
186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the flags */
189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int
190d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetFlags() {
191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return flags;
192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the number of iterations */
195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int
196d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetIterations() {
197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return iterations;
198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the salt */
201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic byte []
202d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetSalt()
203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return salt;
205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the next hash */
208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic byte []
209d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetNext() {
210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return next;
211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen  /** Returns the set of types defined for this name */
214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic int []
215d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetTypes() {
216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return types.toArray();
217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns whether a specific type is in the set of types. */
220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic boolean
221d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenhasType(int type)
222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return types.contains(type);
224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenstatic byte []
227d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenhashName(Name name, int hashAlg, int iterations, byte [] salt)
228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenthrows NoSuchAlgorithmException
229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	MessageDigest digest;
231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	switch (hashAlg) {
232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	case Digest.SHA1:
233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		digest = MessageDigest.getInstance("sha-1");
234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		break;
235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	default:
236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		throw new NoSuchAlgorithmException("Unknown NSEC3 algorithm" +
237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen						   "identifier: " +
238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen						   hashAlg);
239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	byte [] hash = null;
241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	for (int i = 0; i <= iterations; i++) {
242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		digest.reset();
243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (i == 0)
244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			digest.update(name.toWireCanonical());
245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		else
246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			digest.update(hash);
247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		if (salt != null)
248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen			digest.update(salt);
249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen		hash = digest.digest();
250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	}
251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return hash;
252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/**
255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Hashes a name with the parameters of this NSEC3 record.
256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The name to hash
257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The hashed version of the name
258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws NoSuchAlgorithmException The hash algorithm is unknown.
259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */
260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic byte []
261d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenhashName(Name name) throws NoSuchAlgorithmException
262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{
263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen	return hashName(name, hashAlg, iterations, salt);
264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen
266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen}
267