Home | History | Annotate | Download | only in DNS
      1 // Copyright (c) 1999-2004 Brian Wellington (bwelling (at) 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 
     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 
     81 public 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) */
    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 
    292 KEYRecord() {}
    293 
    294 Record
    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
    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
    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
    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