blob: 3d2e01cbeef60c31c351e9e2ae00494ccbc3582a [file] [log] [blame]
// 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();
}
}