blob: 3d2e01cbeef60c31c351e9e2ae00494ccbc3582a [file] [log] [blame]
Shuyi Chend7955ce2013-05-22 14:51:55 -07001// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.io.*;
6import java.security.PublicKey;
7import 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
17public class KEYRecord extends KEYBase {
18
19private static final long serialVersionUID = 6385613447571488906L;
20
21public static class Protocol {
22 /**
23 * KEY protocol identifiers.
24 */
25
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
53 protocols.add(NONE, "NONE");
54 protocols.add(TLS, "TLS");
55 protocols.add(EMAIL, "EMAIL");
56 protocols.add(DNSSEC, "DNSSEC");
57 protocols.add(IPSEC, "IPSEC");
58 protocols.add(ANY, "ANY");
59 }
60
61 /**
62 * Converts an KEY protocol value into its textual representation
63 */
64 public static String
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
76 value(String s) {
77 return protocols.getValue(s);
78 }
79}
80
81public static class Flags {
82 /**
83 * KEY flags identifiers.
84 */
85
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
194 flags.add(NOCONF, "NOCONF");
195 flags.add(NOAUTH, "NOAUTH");
196 flags.add(NOKEY, "NOKEY");
197 flags.add(FLAG2, "FLAG2");
198 flags.add(EXTEND, "EXTEND");
199 flags.add(FLAG4, "FLAG4");
200 flags.add(FLAG5, "FLAG5");
201 flags.add(USER, "USER");
202 flags.add(ZONE, "ZONE");
203 flags.add(HOST, "HOST");
204 flags.add(NTYP3, "NTYP3");
205 flags.add(FLAG8, "FLAG8");
206 flags.add(FLAG9, "FLAG9");
207 flags.add(FLAG10, "FLAG10");
208 flags.add(FLAG11, "FLAG11");
209 flags.add(SIG0, "SIG0");
210 flags.add(SIG1, "SIG1");
211 flags.add(SIG2, "SIG2");
212 flags.add(SIG3, "SIG3");
213 flags.add(SIG4, "SIG4");
214 flags.add(SIG5, "SIG5");
215 flags.add(SIG6, "SIG6");
216 flags.add(SIG7, "SIG7");
217 flags.add(SIG8, "SIG8");
218 flags.add(SIG9, "SIG9");
219 flags.add(SIG10, "SIG10");
220 flags.add(SIG11, "SIG11");
221 flags.add(SIG12, "SIG12");
222 flags.add(SIG13, "SIG13");
223 flags.add(SIG14, "SIG14");
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
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) */
259public static final int FLAG_NOCONF = Flags.NOCONF;
260
261/** This key cannot be used for authentication */
262public static final int FLAG_NOAUTH = Flags.NOAUTH;
263
264/** This key cannot be used for authentication or confidentiality */
265public static final int FLAG_NOKEY = Flags.NOKEY;
266
267/** A zone key */
268public static final int OWNER_ZONE = Flags.ZONE;
269
270/** A host/end entity key */
271public static final int OWNER_HOST = Flags.HOST;
272
273/** A user key */
274public static final int OWNER_USER = Flags.USER;
275
276/* protocols */
277/** Key was created for use with transaction level security */
278public static final int PROTOCOL_TLS = Protocol.TLS;
279
280/** Key was created for use with email */
281public static final int PROTOCOL_EMAIL = Protocol.EMAIL;
282
283/** Key was created for use with DNSSEC */
284public static final int PROTOCOL_DNSSEC = Protocol.DNSSEC;
285
286/** Key was created for use with IPSEC */
287public static final int PROTOCOL_IPSEC = Protocol.IPSEC;
288
289/** Key was created for use with any protocol */
290public static final int PROTOCOL_ANY = Protocol.ANY;
291
292KEYRecord() {}
293
294Record
295getObject() {
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 */
306public
307KEYRecord(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 */
322public
323KEYRecord(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
331void
332rdataFromString(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}