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