aboutsummaryrefslogtreecommitdiff
path: root/src/org/xbill/DNS/KEYRecord.java
blob: 3d2e01cbeef60c31c351e9e2ae00494ccbc3582a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)

package org.xbill.DNS;

import java.io.*;
import java.security.PublicKey;
import java.util.*;

/**
 * Key - contains a cryptographic public key.  The data can be converted
 * to objects implementing java.security.interfaces.PublicKey
 * @see DNSSEC
 *
 * @author Brian Wellington
 */

public class KEYRecord extends KEYBase {

private static final long serialVersionUID = 6385613447571488906L;

public static class Protocol {
	/**
	 * KEY protocol identifiers.
	 */

	private Protocol() {}

	/** No defined protocol. */
	public static final int NONE = 0;

	/** Transaction Level Security */
	public static final int TLS = 1;

	/** Email */
	public static final int EMAIL = 2;

	/** DNSSEC */
	public static final int DNSSEC = 3;

	/** IPSEC Control */
	public static final int IPSEC = 4;

	/** Any protocol */
	public static final int ANY = 255;

	private static Mnemonic protocols = new Mnemonic("KEY protocol",
							 Mnemonic.CASE_UPPER);

	static {
		protocols.setMaximum(0xFF);
		protocols.setNumericAllowed(true);

		protocols.add(NONE, "NONE");
		protocols.add(TLS, "TLS");
		protocols.add(EMAIL, "EMAIL");
		protocols.add(DNSSEC, "DNSSEC");
		protocols.add(IPSEC, "IPSEC");
		protocols.add(ANY, "ANY");
	}

	/**
	 * Converts an KEY protocol value into its textual representation
	 */
	public static String
	string(int type) {
		return protocols.getText(type);
	}

	/**
	 * Converts a textual representation of a KEY protocol into its
	 * numeric code.  Integers in the range 0..255 are also accepted.
	 * @param s The textual representation of the protocol
	 * @return The protocol code, or -1 on error.
	 */
	public static int
	value(String s) {
		return protocols.getValue(s);
	}
}
	
public static class Flags {
	/**
	 * KEY flags identifiers.
	 */

	private Flags() {}

	/** KEY cannot be used for confidentiality */
	public static final int NOCONF = 0x4000;

	/** KEY cannot be used for authentication */
	public static final int NOAUTH = 0x8000;

	/** No key present */
	public static final int NOKEY = 0xC000;

	/** Bitmask of the use fields */
	public static final int USE_MASK = 0xC000;

	/** Flag 2 (unused) */
	public static final int FLAG2 = 0x2000;

	/** Flags extension */
	public static final int EXTEND = 0x1000;

	/** Flag 4 (unused) */
	public static final int FLAG4 = 0x0800;

	/** Flag 5 (unused) */
	public static final int FLAG5 = 0x0400;

	/** Key is owned by a user. */
	public static final int USER = 0x0000;

	/** Key is owned by a zone. */
	public static final int ZONE = 0x0100;

	/** Key is owned by a host. */
	public static final int HOST = 0x0200;

	/** Key owner type 3 (reserved). */
	public static final int NTYP3 = 0x0300;

	/** Key owner bitmask. */
	public static final int OWNER_MASK = 0x0300;

	/** Flag 8 (unused) */
	public static final int FLAG8 = 0x0080;

	/** Flag 9 (unused) */
	public static final int FLAG9 = 0x0040;

	/** Flag 10 (unused) */
	public static final int FLAG10 = 0x0020;

	/** Flag 11 (unused) */
	public static final int FLAG11 = 0x0010;

	/** Signatory value 0 */
	public static final int SIG0 = 0;

	/** Signatory value 1 */
	public static final int SIG1 = 1;

	/** Signatory value 2 */
	public static final int SIG2 = 2;

	/** Signatory value 3 */
	public static final int SIG3 = 3;

	/** Signatory value 4 */
	public static final int SIG4 = 4;

	/** Signatory value 5 */
	public static final int SIG5 = 5;

	/** Signatory value 6 */
	public static final int SIG6 = 6;

	/** Signatory value 7 */
	public static final int SIG7 = 7;

	/** Signatory value 8 */
	public static final int SIG8 = 8;

	/** Signatory value 9 */
	public static final int SIG9 = 9;

	/** Signatory value 10 */
	public static final int SIG10 = 10;

	/** Signatory value 11 */
	public static final int SIG11 = 11;

	/** Signatory value 12 */
	public static final int SIG12 = 12;

	/** Signatory value 13 */
	public static final int SIG13 = 13;

	/** Signatory value 14 */
	public static final int SIG14 = 14;

	/** Signatory value 15 */
	public static final int SIG15 = 15;

	private static Mnemonic flags = new Mnemonic("KEY flags",
						      Mnemonic.CASE_UPPER);

	static {
		flags.setMaximum(0xFFFF);
		flags.setNumericAllowed(false);

		flags.add(NOCONF, "NOCONF");
		flags.add(NOAUTH, "NOAUTH");
		flags.add(NOKEY, "NOKEY");
		flags.add(FLAG2, "FLAG2");
		flags.add(EXTEND, "EXTEND");
		flags.add(FLAG4, "FLAG4");
		flags.add(FLAG5, "FLAG5");
		flags.add(USER, "USER");
		flags.add(ZONE, "ZONE");
		flags.add(HOST, "HOST");
		flags.add(NTYP3, "NTYP3");
		flags.add(FLAG8, "FLAG8");
		flags.add(FLAG9, "FLAG9");
		flags.add(FLAG10, "FLAG10");
		flags.add(FLAG11, "FLAG11");
		flags.add(SIG0, "SIG0");
		flags.add(SIG1, "SIG1");
		flags.add(SIG2, "SIG2");
		flags.add(SIG3, "SIG3");
		flags.add(SIG4, "SIG4");
		flags.add(SIG5, "SIG5");
		flags.add(SIG6, "SIG6");
		flags.add(SIG7, "SIG7");
		flags.add(SIG8, "SIG8");
		flags.add(SIG9, "SIG9");
		flags.add(SIG10, "SIG10");
		flags.add(SIG11, "SIG11");
		flags.add(SIG12, "SIG12");
		flags.add(SIG13, "SIG13");
		flags.add(SIG14, "SIG14");
		flags.add(SIG15, "SIG15");
	}

	/**
	 * Converts a textual representation of KEY flags into its
	 * numeric code.  Integers in the range 0..65535 are also accepted.
	 * @param s The textual representation of the protocol
	 * @return The protocol code, or -1 on error.
	 */
	public static int
	value(String s) {
		int value;
		try {
			value = Integer.parseInt(s);
			if (value >= 0 && value <= 0xFFFF) {
				return value;
			}
			return -1;
		} catch (NumberFormatException e) {
		}
		StringTokenizer st = new StringTokenizer(s, "|");
		value = 0;
		while (st.hasMoreTokens()) {
			int val = flags.getValue(st.nextToken());
			if (val < 0) {
				return -1;
			}
			value |= val;
		}
		return value;
	}
}

/* flags */
/** This key cannot be used for confidentiality (encryption) */
public static final int FLAG_NOCONF = Flags.NOCONF;

/** This key cannot be used for authentication */
public static final int FLAG_NOAUTH = Flags.NOAUTH;

/** This key cannot be used for authentication or confidentiality */
public static final int FLAG_NOKEY = Flags.NOKEY;

/** A zone key */
public static final int OWNER_ZONE = Flags.ZONE;

/** A host/end entity key */
public static final int OWNER_HOST = Flags.HOST;

/** A user key */
public static final int OWNER_USER = Flags.USER;

/* protocols */
/** Key was created for use with transaction level security */
public static final int PROTOCOL_TLS = Protocol.TLS;

/** Key was created for use with email */
public static final int PROTOCOL_EMAIL = Protocol.EMAIL;

/** Key was created for use with DNSSEC */
public static final int PROTOCOL_DNSSEC = Protocol.DNSSEC;

/** Key was created for use with IPSEC */
public static final int PROTOCOL_IPSEC = Protocol.IPSEC;

/** Key was created for use with any protocol */
public static final int PROTOCOL_ANY = Protocol.ANY;

KEYRecord() {}

Record
getObject() {
	return new KEYRecord();
}

/**
 * Creates a KEY Record from the given data
 * @param flags Flags describing the key's properties
 * @param proto The protocol that the key was created for
 * @param alg The key's algorithm
 * @param key Binary data representing the key
 */
public
KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg,
	  byte [] key)
{
	super(name, Type.KEY, dclass, ttl, flags, proto, alg, key);
}

/**
 * Creates a KEY Record from the given data
 * @param flags Flags describing the key's properties
 * @param proto The protocol that the key was created for
 * @param alg The key's algorithm
 * @param key The key as a PublicKey
 * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS
 * format.
 */
public
KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg,
	  PublicKey key) throws DNSSEC.DNSSECException
{
	super(name, Type.KEY, dclass, ttl, flags, proto, alg,
	      DNSSEC.fromPublicKey(key, alg));
	publicKey = key;
}

void
rdataFromString(Tokenizer st, Name origin) throws IOException {
	String flagString = st.getIdentifier();
	flags = Flags.value(flagString);
	if (flags < 0)
		throw st.exception("Invalid flags: " + flagString);
	String protoString = st.getIdentifier();
	proto = Protocol.value(protoString);
	if (proto < 0)
		throw st.exception("Invalid protocol: " + protoString);
	String algString = st.getIdentifier();
	alg = DNSSEC.Algorithm.value(algString);
	if (alg < 0)
		throw st.exception("Invalid algorithm: " + algString);
	/* If this is a null KEY, there's no key data */
	if ((flags & Flags.USE_MASK) == Flags.NOKEY)
		key = null;
	else
		key = st.getBase64();
}

}