| // 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(); |
| } |
| |
| } |