isc_result_t result;
REQUIRE(out != NULL);
+ REQUIRE(alg != 0 && alg != DST_ALG_PRIVATEOID &&
+ alg != DST_ALG_PRIVATEDNS);
if ((type & DST_TYPE_PRIVATE) != 0) {
suffix = ".private";
REQUIRE(mctx != NULL);
REQUIRE(keyp != NULL && *keyp == NULL);
+ if (alg == DNS_KEYALG_PRIVATEDNS) {
+ isc_buffer_t b = *source;
+ alg = dst_algorithm_fromprivatedns(&b);
+ if (alg == 0) {
+ return DST_R_UNSUPPORTEDALG;
+ }
+ }
+
+ if (alg == DNS_KEYALG_PRIVATEOID) {
+ isc_buffer_t b = *source;
+ alg = dst_algorithm_fromprivateoid(&b);
+ if (alg == 0) {
+ return DST_R_UNSUPPORTEDALG;
+ }
+ }
+
key = get_key_struct(name, alg, flags, protocol, 0, rdclass, 0, mctx);
if (isc_buffer_remaininglength(source) > 0) {
return "unknown";
}
}
+
+dns_secalg_t
+dst_algorithm_tosecalg(dst_algorithm_t dst_alg) {
+ static dns_secalg_t dns_alg[DST_MAX_ALGS] = { 0 };
+
+ if (dst_alg < 256) {
+ return dst_alg;
+ }
+ if (dst_alg < DST_MAX_ALGS) {
+ return dns_alg[dst_alg];
+ }
+ return 0;
+}
+
+dst_algorithm_t
+dst_algorithm_fromprivatedns(isc_buffer_t *buffer) {
+ dns_fixedname_t fixed;
+ dns_name_t *name = dns_fixedname_initname(&fixed);
+ isc_result_t result;
+
+ result = dns_name_fromwire(name, buffer, DNS_DECOMPRESS_DEFAULT, NULL);
+ if (result != ISC_R_SUCCESS) {
+ return 0;
+ }
+
+ /*
+ * Do name to dst_algorithm number mapping here.
+ */
+ return 0;
+}
+
+dst_algorithm_t
+dst_algorithm_fromprivateoid(isc_buffer_t *buffer) {
+ isc_region_t r;
+
+ isc_buffer_remainingregion(buffer, &r);
+
+ /*
+ * Do OID to dst_algorithm number mapping here. There is a
+ * length byte followed by the OID of that length.
+ */
+ if (r.length > 0 && ((unsigned int)r.base[0] + 1) <= r.length) {
+ return 0;
+ }
+ return 0;
+}
+
+dst_algorithm_t
+dst_algorithm_fromdata(dns_secalg_t algorithm, unsigned char *data,
+ unsigned int length) {
+ isc_buffer_t b;
+ switch (algorithm) {
+ case DNS_KEYALG_PRIVATEDNS:
+ isc_buffer_init(&b, data, length);
+ isc_buffer_add(&b, length);
+ return dst_algorithm_fromprivatedns(&b);
+ case DNS_KEYALG_PRIVATEOID:
+ isc_buffer_init(&b, data, length);
+ isc_buffer_add(&b, length);
+ return dst_algorithm_fromprivateoid(&b);
+ default:
+ return algorithm;
+ }
+}
DST_ALG_HMAC_LAST = DST_ALG_HMACSHA512,
DST_ALG_INDIRECT = 252,
- DST_ALG_PRIVATE = 254,
+ DST_ALG_PRIVATEDNS = 253,
+ DST_ALG_PRIVATEOID = 254,
+ DST_ALG_RESERVED = 255,
+ /*
+ * Put PRIVATE DNS and PRIVATE OID identifiers here.
+ */
DST_MAX_ALGS = 256,
} dst_algorithm_t;
* \li false
*/
+dst_algorithm_t
+dst_algorithm_fromprivateoid(isc_buffer_t *buffer);
+/*
+ * Extract the dst algorithm identifier that matches
+ * the OID value found at the start of 'buffer'.
+ */
+
+dst_algorithm_t
+dst_algorithm_fromprivatedns(isc_buffer_t *buf);
+/*
+ * Extract the dst algorithm identifier that matches
+ * the DNS name found at the start of 'buffer'.
+ */
+
bool
dst_ds_digest_supported(unsigned int digest_type);
/*%<
* Return the name associtated with the HMAC algorithm 'alg'
* or return "unknown".
*/
+
+isc_result_t
+dst_algorithm_fromtext(dst_algorithm_t *algp, isc_textregion_t *source);
+/*%<
+ * Convert the text 'source' refers to into a DST security algorithm value.
+ * The text may contain either a mnemonic algorithm name or a decimal algorithm
+ * number. This supports more algorithms than 'dns_secalg_fromtext' as it
+ * supports private algorithms used with PRIVATEDNS and PRIVATEOID.
+ *
+ * Requires:
+ *\li 'algp' is a valid pointer.
+ *
+ *\li 'source' is a valid text region.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS on success
+ *\li ISC_R_RANGE numeric type is out of range
+ *\li DNS_R_UNKNOWN mnemonic type is unknown
+ */
+
+isc_result_t
+dst_algorithm_totext(dst_algorithm_t alg, isc_buffer_t *target);
+/*%<
+ * Put a textual representation of DST security algorithm 'alg'
+ * into 'target'. This supports a superset of dns_secalg_totext.
+ *
+ * Requires:
+ *\li 'alg' is a valid dst_algorithm_t.
+ *
+ *\li 'target' is a valid text buffer.
+ *
+ * Ensures,
+ * if the result is success:
+ *\li The used space in 'target' is updated.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS on success
+ *\li ISC_R_NOSPACE target buffer is too small
+ */
+
+#define DST_ALGORITHM_FORMATSIZE 20
+void
+dst_algorithm_format(dst_algorithm_t dst_alg, char *data, unsigned int length);
+/*%<
+ * Wrapper for dst_algorithm_totext(), writing text into 'cp'
+ */
+
+dns_secalg_t
+dst_algorithm_tosecalg(dst_algorithm_t dst_alg);
+/*%<
+ * Return the DNSSEC algorithm identifier that applies for the DST
+ * algorithm. For PRIVATEDNS and PRIVATEOID based algorithms, this
+ * is PRIVATEDNS and PRIVATEOID respectively.
+ *
+ * Zero is returned when there is no mapping.
+ */
+
+isc_result_t
+dst_privatedns_fromtext(dst_algorithm_t *algp, isc_textregion_t *source);
+
+isc_result_t
+dns_privatedns_totext(dst_algorithm_t alg, isc_buffer_t *b);
+
+void
+dns_privatedns_format(dst_algorithm_t alg, char *buf, unsigned int size);
+
+isc_result_t
+dst_privateoid_fromtext(dst_algorithm_t *algp, isc_textregion_t *source);
+
+isc_result_t
+dns_privateoid_totext(dst_algorithm_t alg, isc_buffer_t *b);
+
+void
+dns_privateoid_format(dst_algorithm_t alg, char *buf, unsigned int size);
+
+dst_algorithm_t
+dst_algorithm_fromdata(dns_secalg_t algorithm, unsigned char *data,
+ unsigned int length);
+/*%<
+ * If 'algorithm' is PRIVATEOID or PRIVATEDNS, extract the DNSSEC private
+ * algorithm encoded at the begining of data and return the DST algorithm
+ * number that corresponds to it; if the algorithm is unknown to DST,
+ * return 0.
+ *
+ * If 'algorithm' is any other value, return it directly.
+ */
#include <dns/secalg.h>
#include <dns/secproto.h>
+#include <dst/dst.h>
+
#define RETERR(x) \
do { \
isc_result_t _r = (x); \
{ DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
{ DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, SENTINEL
+/*
+ * PRIVATEDNS subtypes we support.
+ */
+#define PRIVATEDNSS /* currently empty */
+
+/*
+ * PRIVATEOID subtypes we support.
+ */
+#define PRIVATEOIDS /* currently empty */
+
/* RFC2535 section 7.1 */
#define SECPROTONAMES \
static struct tbl secprotos[] = { SECPROTONAMES };
static struct tbl hashalgs[] = { HASHALGNAMES };
static struct tbl dsdigests[] = { DSDIGESTNAMES };
+static struct tbl privatednss[] = { PRIVATEDNSS SENTINEL };
+static struct tbl privateoids[] = { PRIVATEOIDS SENTINEL };
+static struct tbl dstalgorithms[] = { PRIVATEDNSS PRIVATEOIDS SECALGNAMES };
static struct keyflag {
const char *name;
}
}
+isc_result_t
+dst_privatedns_fromtext(dst_algorithm_t *dstalgp, isc_textregion_t *source) {
+ unsigned int value;
+ RETERR(dns_mnemonic_fromtext(&value, source, privatednss, 0));
+ *dstalgp = value;
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t
+dns_privatedns_totext(dst_algorithm_t alg, isc_buffer_t *target) {
+ return dns_mnemonic_totext(alg, target, privatednss);
+}
+
+void
+dns_privatedns_format(dst_algorithm_t alg, char *cp, unsigned int size) {
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ REQUIRE(cp != NULL && size > 0);
+ isc_buffer_init(&b, cp, size - 1);
+ result = dns_privatedns_totext(alg, &b);
+ isc_buffer_usedregion(&b, &r);
+ r.base[r.length] = 0;
+ if (result != ISC_R_SUCCESS) {
+ r.base[0] = 0;
+ }
+}
+
+isc_result_t
+dst_privateoid_fromtext(dst_algorithm_t *dstalgp, isc_textregion_t *source) {
+ unsigned int value;
+ RETERR(dns_mnemonic_fromtext(&value, source, privateoids, 0));
+ *dstalgp = value;
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t
+dns_privateoid_totext(dst_algorithm_t alg, isc_buffer_t *target) {
+ return dns_mnemonic_totext(alg, target, privateoids);
+}
+
+void
+dns_privateoid_format(dst_algorithm_t alg, char *cp, unsigned int size) {
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ REQUIRE(cp != NULL && size > 0);
+ isc_buffer_init(&b, cp, size - 1);
+ result = dns_privateoid_totext(alg, &b);
+ isc_buffer_usedregion(&b, &r);
+ r.base[r.length] = 0;
+ if (result != ISC_R_SUCCESS) {
+ r.base[0] = 0;
+ }
+}
+
isc_result_t
dns_secproto_fromtext(dns_secproto_t *secprotop, isc_textregion_t *source) {
unsigned int value;
strlcpy(array, "<unknown>", size);
}
}
+
+isc_result_t
+dst_algorithm_fromtext(dst_algorithm_t *dstalgp, isc_textregion_t *source) {
+ unsigned int value;
+ RETERR(dns_mnemonic_fromtext(&value, source, dstalgorithms, 255));
+ *dstalgp = value;
+ return ISC_R_SUCCESS;
+}
+
+isc_result_t
+dst_algorithm_totext(dst_algorithm_t alg, isc_buffer_t *target) {
+ return dns_mnemonic_totext(alg, target, dstalgorithms);
+}
+
+void
+dst_algorithm_format(dst_algorithm_t alg, char *cp, unsigned int size) {
+ isc_buffer_t b;
+ isc_region_t r;
+ isc_result_t result;
+
+ REQUIRE(cp != NULL && size > 0);
+ isc_buffer_init(&b, cp, size - 1);
+ result = dst_algorithm_totext(alg, &b);
+ isc_buffer_usedregion(&b, &r);
+ r.base[r.length] = 0;
+ if (result != ISC_R_SUCCESS) {
+ r.base[0] = 0;
+ }
+}
unsigned int alg) {
REQUIRE(VALID_RESOLVER(resolver));
- if (alg > 255) {
+ if (alg >= DST_MAX_ALGS) {
return ISC_R_RANGE;
}
isc_result_t result;
dns_rdata_t dsrdata = DNS_RDATA_INIT;
dns_rdataset_current(rdataset, &dsrdata);
-
result = dns_rdata_tostruct(&dsrdata, &ds, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_result_t result;
dns_dbnode_t *node = NULL;
dns_rdataset_t dnskey, cds, cdnskey;
- unsigned char algorithms[256];
+ unsigned char algorithms[DST_MAX_ALGS];
unsigned int i;
bool empty = false;
dns_rdataset_t nsecsigs;
dns_rdataset_t nsec3paramset;
dns_rdataset_t nsec3paramsigs;
- unsigned char revoked_ksk[256];
- unsigned char revoked_zsk[256];
- unsigned char standby_ksk[256];
- unsigned char standby_zsk[256];
- unsigned char ksk_algorithms[256];
- unsigned char zsk_algorithms[256];
- unsigned char bad_algorithms[256];
- unsigned char act_algorithms[256];
+ unsigned char revoked_ksk[DST_MAX_ALGS];
+ unsigned char revoked_zsk[DST_MAX_ALGS];
+ unsigned char standby_ksk[DST_MAX_ALGS];
+ unsigned char standby_zsk[DST_MAX_ALGS];
+ unsigned char ksk_algorithms[DST_MAX_ALGS];
+ unsigned char zsk_algorithms[DST_MAX_ALGS];
+ unsigned char bad_algorithms[DST_MAX_ALGS];
+ unsigned char act_algorithms[DST_MAX_ALGS];
isc_heap_t *expected_chains;
isc_heap_t *found_chains;
} vctx_t;
static isc_result_t
verifyset(vctx_t *vctx, dns_rdataset_t *rdataset, const dns_name_t *name,
dns_dbnode_t *node, dst_key_t **dstkeys, size_t nkeys) {
- unsigned char set_algorithms[256] = { 0 };
+ unsigned char set_algorithms[DST_MAX_ALGS] = { 0 };
char namebuf[DNS_NAME_FORMATSIZE];
char algbuf[DNS_SECALG_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
(void)confget(maps, "keys", &keys);
if (keys != NULL) {
- char role[256] = { 0 };
- bool warn[256][2] = { { false } };
+ char role[DST_MAX_ALGS] = { 0 };
+ bool warn[DST_MAX_ALGS][2] = { { false } };
CFG_LIST_FOREACH (keys, element) {
cfg_obj_t *kobj = cfg_listelt_value(element);