• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2 
3 package org.xbill.DNS;
4 
5 import java.io.*;
6 import java.security.PublicKey;
7 import java.util.*;
8 
9 /**
10  * Key - contains a cryptographic public key.  The data can be converted
11  * to objects implementing java.security.interfaces.PublicKey
12  * @see DNSSEC
13  *
14  * @author Brian Wellington
15  */
16 
17 public class KEYRecord extends KEYBase {
18 
19 private static final long serialVersionUID = 6385613447571488906L;
20 
21 public static class Protocol {
22 	/**
23 	 * KEY protocol identifiers.
24 	 */
25 
Protocol()26 	private Protocol() {}
27 
28 	/** No defined protocol. */
29 	public static final int NONE = 0;
30 
31 	/** Transaction Level Security */
32 	public static final int TLS = 1;
33 
34 	/** Email */
35 	public static final int EMAIL = 2;
36 
37 	/** DNSSEC */
38 	public static final int DNSSEC = 3;
39 
40 	/** IPSEC Control */
41 	public static final int IPSEC = 4;
42 
43 	/** Any protocol */
44 	public static final int ANY = 255;
45 
46 	private static Mnemonic protocols = new Mnemonic("KEY protocol",
47 							 Mnemonic.CASE_UPPER);
48 
49 	static {
50 		protocols.setMaximum(0xFF);
51 		protocols.setNumericAllowed(true);
52 
protocols.add(NONE, "NONE")53 		protocols.add(NONE, "NONE");
protocols.add(TLS, "TLS")54 		protocols.add(TLS, "TLS");
protocols.add(EMAIL, "EMAIL")55 		protocols.add(EMAIL, "EMAIL");
protocols.add(DNSSEC, "DNSSEC")56 		protocols.add(DNSSEC, "DNSSEC");
protocols.add(IPSEC, "IPSEC")57 		protocols.add(IPSEC, "IPSEC");
protocols.add(ANY, "ANY")58 		protocols.add(ANY, "ANY");
59 	}
60 
61 	/**
62 	 * Converts an KEY protocol value into its textual representation
63 	 */
64 	public static String
string(int type)65 	string(int type) {
66 		return protocols.getText(type);
67 	}
68 
69 	/**
70 	 * Converts a textual representation of a KEY protocol into its
71 	 * numeric code.  Integers in the range 0..255 are also accepted.
72 	 * @param s The textual representation of the protocol
73 	 * @return The protocol code, or -1 on error.
74 	 */
75 	public static int
value(String s)76 	value(String s) {
77 		return protocols.getValue(s);
78 	}
79 }
80 
81 public static class Flags {
82 	/**
83 	 * KEY flags identifiers.
84 	 */
85 
Flags()86 	private Flags() {}
87 
88 	/** KEY cannot be used for confidentiality */
89 	public static final int NOCONF = 0x4000;
90 
91 	/** KEY cannot be used for authentication */
92 	public static final int NOAUTH = 0x8000;
93 
94 	/** No key present */
95 	public static final int NOKEY = 0xC000;
96 
97 	/** Bitmask of the use fields */
98 	public static final int USE_MASK = 0xC000;
99 
100 	/** Flag 2 (unused) */
101 	public static final int FLAG2 = 0x2000;
102 
103 	/** Flags extension */
104 	public static final int EXTEND = 0x1000;
105 
106 	/** Flag 4 (unused) */
107 	public static final int FLAG4 = 0x0800;
108 
109 	/** Flag 5 (unused) */
110 	public static final int FLAG5 = 0x0400;
111 
112 	/** Key is owned by a user. */
113 	public static final int USER = 0x0000;
114 
115 	/** Key is owned by a zone. */
116 	public static final int ZONE = 0x0100;
117 
118 	/** Key is owned by a host. */
119 	public static final int HOST = 0x0200;
120 
121 	/** Key owner type 3 (reserved). */
122 	public static final int NTYP3 = 0x0300;
123 
124 	/** Key owner bitmask. */
125 	public static final int OWNER_MASK = 0x0300;
126 
127 	/** Flag 8 (unused) */
128 	public static final int FLAG8 = 0x0080;
129 
130 	/** Flag 9 (unused) */
131 	public static final int FLAG9 = 0x0040;
132 
133 	/** Flag 10 (unused) */
134 	public static final int FLAG10 = 0x0020;
135 
136 	/** Flag 11 (unused) */
137 	public static final int FLAG11 = 0x0010;
138 
139 	/** Signatory value 0 */
140 	public static final int SIG0 = 0;
141 
142 	/** Signatory value 1 */
143 	public static final int SIG1 = 1;
144 
145 	/** Signatory value 2 */
146 	public static final int SIG2 = 2;
147 
148 	/** Signatory value 3 */
149 	public static final int SIG3 = 3;
150 
151 	/** Signatory value 4 */
152 	public static final int SIG4 = 4;
153 
154 	/** Signatory value 5 */
155 	public static final int SIG5 = 5;
156 
157 	/** Signatory value 6 */
158 	public static final int SIG6 = 6;
159 
160 	/** Signatory value 7 */
161 	public static final int SIG7 = 7;
162 
163 	/** Signatory value 8 */
164 	public static final int SIG8 = 8;
165 
166 	/** Signatory value 9 */
167 	public static final int SIG9 = 9;
168 
169 	/** Signatory value 10 */
170 	public static final int SIG10 = 10;
171 
172 	/** Signatory value 11 */
173 	public static final int SIG11 = 11;
174 
175 	/** Signatory value 12 */
176 	public static final int SIG12 = 12;
177 
178 	/** Signatory value 13 */
179 	public static final int SIG13 = 13;
180 
181 	/** Signatory value 14 */
182 	public static final int SIG14 = 14;
183 
184 	/** Signatory value 15 */
185 	public static final int SIG15 = 15;
186 
187 	private static Mnemonic flags = new Mnemonic("KEY flags",
188 						      Mnemonic.CASE_UPPER);
189 
190 	static {
191 		flags.setMaximum(0xFFFF);
192 		flags.setNumericAllowed(false);
193 
flags.add(NOCONF, "NOCONF")194 		flags.add(NOCONF, "NOCONF");
flags.add(NOAUTH, "NOAUTH")195 		flags.add(NOAUTH, "NOAUTH");
flags.add(NOKEY, "NOKEY")196 		flags.add(NOKEY, "NOKEY");
flags.add(FLAG2, "FLAG2")197 		flags.add(FLAG2, "FLAG2");
flags.add(EXTEND, "EXTEND")198 		flags.add(EXTEND, "EXTEND");
flags.add(FLAG4, "FLAG4")199 		flags.add(FLAG4, "FLAG4");
flags.add(FLAG5, "FLAG5")200 		flags.add(FLAG5, "FLAG5");
flags.add(USER, "USER")201 		flags.add(USER, "USER");
flags.add(ZONE, "ZONE")202 		flags.add(ZONE, "ZONE");
flags.add(HOST, "HOST")203 		flags.add(HOST, "HOST");
flags.add(NTYP3, "NTYP3")204 		flags.add(NTYP3, "NTYP3");
flags.add(FLAG8, "FLAG8")205 		flags.add(FLAG8, "FLAG8");
flags.add(FLAG9, "FLAG9")206 		flags.add(FLAG9, "FLAG9");
flags.add(FLAG10, "FLAG10")207 		flags.add(FLAG10, "FLAG10");
flags.add(FLAG11, "FLAG11")208 		flags.add(FLAG11, "FLAG11");
flags.add(SIG0, "SIG0")209 		flags.add(SIG0, "SIG0");
flags.add(SIG1, "SIG1")210 		flags.add(SIG1, "SIG1");
flags.add(SIG2, "SIG2")211 		flags.add(SIG2, "SIG2");
flags.add(SIG3, "SIG3")212 		flags.add(SIG3, "SIG3");
flags.add(SIG4, "SIG4")213 		flags.add(SIG4, "SIG4");
flags.add(SIG5, "SIG5")214 		flags.add(SIG5, "SIG5");
flags.add(SIG6, "SIG6")215 		flags.add(SIG6, "SIG6");
flags.add(SIG7, "SIG7")216 		flags.add(SIG7, "SIG7");
flags.add(SIG8, "SIG8")217 		flags.add(SIG8, "SIG8");
flags.add(SIG9, "SIG9")218 		flags.add(SIG9, "SIG9");
flags.add(SIG10, "SIG10")219 		flags.add(SIG10, "SIG10");
flags.add(SIG11, "SIG11")220 		flags.add(SIG11, "SIG11");
flags.add(SIG12, "SIG12")221 		flags.add(SIG12, "SIG12");
flags.add(SIG13, "SIG13")222 		flags.add(SIG13, "SIG13");
flags.add(SIG14, "SIG14")223 		flags.add(SIG14, "SIG14");
flags.add(SIG15, "SIG15")224 		flags.add(SIG15, "SIG15");
225 	}
226 
227 	/**
228 	 * Converts a textual representation of KEY flags into its
229 	 * numeric code.  Integers in the range 0..65535 are also accepted.
230 	 * @param s The textual representation of the protocol
231 	 * @return The protocol code, or -1 on error.
232 	 */
233 	public static int
value(String s)234 	value(String s) {
235 		int value;
236 		try {
237 			value = Integer.parseInt(s);
238 			if (value >= 0 && value <= 0xFFFF) {
239 				return value;
240 			}
241 			return -1;
242 		} catch (NumberFormatException e) {
243 		}
244 		StringTokenizer st = new StringTokenizer(s, "|");
245 		value = 0;
246 		while (st.hasMoreTokens()) {
247 			int val = flags.getValue(st.nextToken());
248 			if (val < 0) {
249 				return -1;
250 			}
251 			value |= val;
252 		}
253 		return value;
254 	}
255 }
256 
257 /* flags */
258 /** This key cannot be used for confidentiality (encryption) */
259 public static final int FLAG_NOCONF = Flags.NOCONF;
260 
261 /** This key cannot be used for authentication */
262 public static final int FLAG_NOAUTH = Flags.NOAUTH;
263 
264 /** This key cannot be used for authentication or confidentiality */
265 public static final int FLAG_NOKEY = Flags.NOKEY;
266 
267 /** A zone key */
268 public static final int OWNER_ZONE = Flags.ZONE;
269 
270 /** A host/end entity key */
271 public static final int OWNER_HOST = Flags.HOST;
272 
273 /** A user key */
274 public static final int OWNER_USER = Flags.USER;
275 
276 /* protocols */
277 /** Key was created for use with transaction level security */
278 public static final int PROTOCOL_TLS = Protocol.TLS;
279 
280 /** Key was created for use with email */
281 public static final int PROTOCOL_EMAIL = Protocol.EMAIL;
282 
283 /** Key was created for use with DNSSEC */
284 public static final int PROTOCOL_DNSSEC = Protocol.DNSSEC;
285 
286 /** Key was created for use with IPSEC */
287 public static final int PROTOCOL_IPSEC = Protocol.IPSEC;
288 
289 /** Key was created for use with any protocol */
290 public static final int PROTOCOL_ANY = Protocol.ANY;
291 
KEYRecord()292 KEYRecord() {}
293 
294 Record
getObject()295 getObject() {
296 	return new KEYRecord();
297 }
298 
299 /**
300  * Creates a KEY Record from the given data
301  * @param flags Flags describing the key's properties
302  * @param proto The protocol that the key was created for
303  * @param alg The key's algorithm
304  * @param key Binary data representing the key
305  */
306 public
KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, byte [] key)307 KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg,
308 	  byte [] key)
309 {
310 	super(name, Type.KEY, dclass, ttl, flags, proto, alg, key);
311 }
312 
313 /**
314  * Creates a KEY Record from the given data
315  * @param flags Flags describing the key's properties
316  * @param proto The protocol that the key was created for
317  * @param alg The key's algorithm
318  * @param key The key as a PublicKey
319  * @throws DNSSEC.DNSSECException The PublicKey could not be converted into DNS
320  * format.
321  */
322 public
KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg, PublicKey key)323 KEYRecord(Name name, int dclass, long ttl, int flags, int proto, int alg,
324 	  PublicKey key) throws DNSSEC.DNSSECException
325 {
326 	super(name, Type.KEY, dclass, ttl, flags, proto, alg,
327 	      DNSSEC.fromPublicKey(key, alg));
328 	publicKey = key;
329 }
330 
331 void
rdataFromString(Tokenizer st, Name origin)332 rdataFromString(Tokenizer st, Name origin) throws IOException {
333 	String flagString = st.getIdentifier();
334 	flags = Flags.value(flagString);
335 	if (flags < 0)
336 		throw st.exception("Invalid flags: " + flagString);
337 	String protoString = st.getIdentifier();
338 	proto = Protocol.value(protoString);
339 	if (proto < 0)
340 		throw st.exception("Invalid protocol: " + protoString);
341 	String algString = st.getIdentifier();
342 	alg = DNSSEC.Algorithm.value(algString);
343 	if (alg < 0)
344 		throw st.exception("Invalid algorithm: " + algString);
345 	/* If this is a null KEY, there's no key data */
346 	if ((flags & Flags.USE_MASK) == Flags.NOKEY)
347 		key = null;
348 	else
349 		key = st.getBase64();
350 }
351 
352 }
353