2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 22:45:39 +00:00

[master] refactor tsig.c

4701.	[cleanup]	Refactored lib/dns/tsig.c to reduce code
			duplication and simplify the disabling of MD5.
			[RT #45490]
This commit is contained in:
Evan Hunt
2017-09-06 10:57:40 -07:00
parent 023ab19634
commit e90926bb9e
4 changed files with 297 additions and 293 deletions

View File

@@ -1,3 +1,7 @@
4701. [cleanup] Refactored lib/dns/tsig.c to reduce code
duplication and simplify the disabling of MD5.
[RT #45490]
4700. [func] Serving of stale answers is now supported. This 4700. [func] Serving of stale answers is now supported. This
allows named to provide stale cached answers when allows named to provide stale cached answers when
the authoritative server is under attack. the authoritative server is under attack.

View File

@@ -6,11 +6,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
/* ! \file */ /*! \file */
#include <config.h> #include <config.h>
#include <atf-c.h> #include <atf-c.h>
#include <unistd.h>
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/print.h> #include <isc/print.h>
@@ -18,12 +21,20 @@
#include <dns/rdataset.h> #include <dns/rdataset.h>
#include <dns/tsig.h> #include <dns/tsig.h>
#include "../tsig_p.h"
#include "dnstest.h" #include "dnstest.h"
#ifdef HAVE_INTTYPES_H #ifdef HAVE_INTTYPES_H
#include <inttypes.h> /* uintptr_t */ #include <inttypes.h> /* uintptr_t */
#endif #endif
#define TEST_ORIGIN "test"
/*
* Individual unit tests
*/
static int debug = 0; static int debug = 0;
static isc_result_t static isc_result_t
@@ -485,10 +496,130 @@ ATF_TC_BODY(tsig_tcp, tc) {
dns_test_end(); dns_test_end();
} }
ATF_TC(algvalid);
ATF_TC_HEAD(algvalid, tc) {
atf_tc_set_md_var(tc, "descr", "Tests the dns__tsig_algvalid function");
}
ATF_TC_BODY(algvalid, tc) {
UNUSED(tc);
#ifndef PK11_MD5_DISABLE
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACMD5), ISC_TRUE);
#else
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACMD5), ISC_FALSE);
#endif
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACSHA1), ISC_TRUE);
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACSHA224), ISC_TRUE);
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACSHA256), ISC_TRUE);
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACSHA384), ISC_TRUE);
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_HMACSHA512), ISC_TRUE);
ATF_REQUIRE_EQ(dns__tsig_algvalid(DST_ALG_GSSAPI), ISC_FALSE);
}
ATF_TC(algfromname);
ATF_TC_HEAD(algfromname, tc) {
atf_tc_set_md_var(tc, "descr", "Tests the dns__tsig_algfromname function");
}
ATF_TC_BODY(algfromname, tc) {
UNUSED(tc);
#ifndef PK11_MD5_DISABLE
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACMD5_NAME), DST_ALG_HMACMD5);
#endif
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACSHA1_NAME), DST_ALG_HMACSHA1);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACSHA224_NAME), DST_ALG_HMACSHA224);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACSHA256_NAME), DST_ALG_HMACSHA256);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACSHA384_NAME), DST_ALG_HMACSHA384);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_HMACSHA512_NAME), DST_ALG_HMACSHA512);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_GSSAPI_NAME), DST_ALG_GSSAPI);
ATF_REQUIRE_EQ(dns__tsig_algfromname(DNS_TSIG_GSSAPIMS_NAME), DST_ALG_GSSAPI);
ATF_REQUIRE_EQ(dns__tsig_algfromname(dns_rootname), 0);
}
ATF_TC(algnamefromname);
ATF_TC_HEAD(algnamefromname, tc) {
atf_tc_set_md_var(tc, "descr", "Tests the dns__tsig_algnamefromname function");
}
/*
* Helper function to create a dns_name_t from a string and see if
* the dns__tsig_algnamefromname function can correctly match it against the
* static table of known algorithms.
*/
static void test_name(const char *name_string, const dns_name_t *expected) {
dns_name_t name;
dns_name_init(&name, NULL);
ATF_CHECK_EQ(dns_name_fromstring(&name, name_string, 0, mctx), ISC_R_SUCCESS);
ATF_REQUIRE_EQ_MSG(dns__tsig_algnamefromname(&name), expected, "%s", name_string);
dns_name_free(&name, mctx);
}
ATF_TC_BODY(algnamefromname, tc) {
isc_result_t result;
UNUSED(tc);
result = dns_test_begin(stderr, ISC_TRUE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/* test the standard algorithms */
#ifndef PK11_MD5_DISABLE
test_name("hmac-md5.sig-alg.reg.int", DNS_TSIG_HMACMD5_NAME);
#endif
test_name("hmac-sha1", DNS_TSIG_HMACSHA1_NAME);
test_name("hmac-sha224", DNS_TSIG_HMACSHA224_NAME);
test_name("hmac-sha256", DNS_TSIG_HMACSHA256_NAME);
test_name("hmac-sha384", DNS_TSIG_HMACSHA384_NAME);
test_name("hmac-sha512", DNS_TSIG_HMACSHA512_NAME);
test_name("gss-tsig", DNS_TSIG_GSSAPI_NAME);
test_name("gss.microsoft.com", DNS_TSIG_GSSAPIMS_NAME);
/* try another name that isn't a standard algorithm name */
ATF_REQUIRE_EQ(dns__tsig_algnamefromname(dns_rootname), NULL);
/* cleanup */
dns_test_end();
}
ATF_TC(algallocated);
ATF_TC_HEAD(algallocated, tc) {
atf_tc_set_md_var(tc, "descr", "Tests the dns__tsig_algallocated function");
}
ATF_TC_BODY(algallocated, tc) {
/* test the standard algorithms */
#ifndef PK11_MD5_DISABLE
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACMD5_NAME), ISC_FALSE);
#endif
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA1_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA224_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA256_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA384_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA512_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA512_NAME), ISC_FALSE);
ATF_REQUIRE_EQ(dns__tsig_algallocated(DNS_TSIG_HMACSHA512_NAME), ISC_FALSE);
/* try another name that isn't a standard algorithm name */
ATF_REQUIRE_EQ(dns__tsig_algallocated(dns_rootname), ISC_TRUE);
}
/* /*
* Main * Main
*/ */
ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TCS(tp) {
ATF_TP_ADD_TC(tp, tsig_tcp); ATF_TP_ADD_TC(tp, tsig_tcp);
ATF_TP_ADD_TC(tp, algvalid);
ATF_TP_ADD_TC(tp, algfromname);
ATF_TP_ADD_TC(tp, algnamefromname);
ATF_TP_ADD_TC(tp, algallocated);
return (atf_no_error()); return (atf_no_error());
} }

View File

@@ -6,9 +6,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
/*
* $Id$
*/
/*! \file */ /*! \file */
#include <config.h> #include <config.h>
#include <stdlib.h> #include <stdlib.h>
@@ -36,6 +33,8 @@
#include <dns/result.h> #include <dns/result.h>
#include <dns/tsig.h> #include <dns/tsig.h>
#include "tsig_p.h"
#include <dst/result.h> #include <dst/result.h>
#define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G') #define TSIG_MAGIC ISC_MAGIC('T', 'S', 'I', 'G')
@@ -46,26 +45,6 @@
#endif #endif
#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR) #define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
#ifndef PK11_MD5_DISABLE
#define algname_is_allocated(algname) \
((algname) != dns_tsig_hmacmd5_name && \
(algname) != dns_tsig_hmacsha1_name && \
(algname) != dns_tsig_hmacsha224_name && \
(algname) != dns_tsig_hmacsha256_name && \
(algname) != dns_tsig_hmacsha384_name && \
(algname) != dns_tsig_hmacsha512_name && \
(algname) != dns_tsig_gssapi_name && \
(algname) != dns_tsig_gssapims_name)
#else
#define algname_is_allocated(algname) \
((algname) != dns_tsig_hmacsha1_name && \
(algname) != dns_tsig_hmacsha224_name && \
(algname) != dns_tsig_hmacsha256_name && \
(algname) != dns_tsig_hmacsha384_name && \
(algname) != dns_tsig_hmacsha512_name && \
(algname) != dns_tsig_gssapi_name && \
(algname) != dns_tsig_gssapims_name)
#endif
#define BADTIMELEN 6 #define BADTIMELEN 6
@@ -73,28 +52,15 @@
static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int"; static unsigned char hmacmd5_ndata[] = "\010hmac-md5\007sig-alg\003reg\003int";
static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 }; static unsigned char hmacmd5_offsets[] = { 0, 9, 17, 21, 25 };
static dns_name_t hmacmd5 = { static dns_name_t hmacmd5 =
DNS_NAME_MAGIC, DNS_NAME_INITABSOLUTE(hmacmd5_ndata, hmacmd5_offsets);
hmacmd5_ndata, 26, 5,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacmd5_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacmd5_name = &hmacmd5;
#endif #endif
static unsigned char gsstsig_ndata[] = "\010gss-tsig"; static unsigned char gsstsig_ndata[] = "\010gss-tsig";
static unsigned char gsstsig_offsets[] = { 0, 9 }; static unsigned char gsstsig_offsets[] = { 0, 9 };
static dns_name_t gsstsig = { static dns_name_t gsstsig =
DNS_NAME_MAGIC, DNS_NAME_INITABSOLUTE(gsstsig_ndata, gsstsig_offsets);
gsstsig_ndata, 10, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
gsstsig_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapi_name = &gsstsig; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapi_name = &gsstsig;
/* /*
@@ -103,86 +69,56 @@ LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapi_name = &gsstsig;
*/ */
static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com"; static unsigned char gsstsigms_ndata[] = "\003gss\011microsoft\003com";
static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 }; static unsigned char gsstsigms_offsets[] = { 0, 4, 14, 18 };
static dns_name_t gsstsigms = { static dns_name_t gsstsigms =
DNS_NAME_MAGIC, DNS_NAME_INITABSOLUTE(gsstsigms_ndata, gsstsigms_offsets);
gsstsigms_ndata, 19, 4,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
gsstsigms_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapims_name = &gsstsigms; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_gssapims_name = &gsstsigms;
static unsigned char hmacsha1_ndata[] = "\011hmac-sha1"; static unsigned char hmacsha1_ndata[] = "\011hmac-sha1";
static unsigned char hmacsha1_offsets[] = { 0, 10 }; static unsigned char hmacsha1_offsets[] = { 0, 10 };
static dns_name_t hmacsha1 =
static dns_name_t hmacsha1 = { DNS_NAME_INITABSOLUTE(hmacsha1_ndata, hmacsha1_offsets);
DNS_NAME_MAGIC,
hmacsha1_ndata, 11, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacsha1_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha1_name = &hmacsha1;
static unsigned char hmacsha224_ndata[] = "\013hmac-sha224"; static unsigned char hmacsha224_ndata[] = "\013hmac-sha224";
static unsigned char hmacsha224_offsets[] = { 0, 12 }; static unsigned char hmacsha224_offsets[] = { 0, 12 };
static dns_name_t hmacsha224 =
static dns_name_t hmacsha224 = { DNS_NAME_INITABSOLUTE(hmacsha224_ndata, hmacsha224_offsets);
DNS_NAME_MAGIC,
hmacsha224_ndata, 13, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacsha224_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha224_name = &hmacsha224;
static unsigned char hmacsha256_ndata[] = "\013hmac-sha256"; static unsigned char hmacsha256_ndata[] = "\013hmac-sha256";
static unsigned char hmacsha256_offsets[] = { 0, 12 }; static unsigned char hmacsha256_offsets[] = { 0, 12 };
static dns_name_t hmacsha256 =
static dns_name_t hmacsha256 = { DNS_NAME_INITABSOLUTE(hmacsha256_ndata, hmacsha256_offsets);
DNS_NAME_MAGIC,
hmacsha256_ndata, 13, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacsha256_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha256_name = &hmacsha256;
static unsigned char hmacsha384_ndata[] = "\013hmac-sha384"; static unsigned char hmacsha384_ndata[] = "\013hmac-sha384";
static unsigned char hmacsha384_offsets[] = { 0, 12 }; static unsigned char hmacsha384_offsets[] = { 0, 12 };
static dns_name_t hmacsha384 =
static dns_name_t hmacsha384 = { DNS_NAME_INITABSOLUTE(hmacsha384_ndata, hmacsha384_offsets);
DNS_NAME_MAGIC,
hmacsha384_ndata, 13, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacsha384_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha384_name = &hmacsha384;
static unsigned char hmacsha512_ndata[] = "\013hmac-sha512"; static unsigned char hmacsha512_ndata[] = "\013hmac-sha512";
static unsigned char hmacsha512_offsets[] = { 0, 12 }; static unsigned char hmacsha512_offsets[] = { 0, 12 };
static dns_name_t hmacsha512 =
static dns_name_t hmacsha512 = { DNS_NAME_INITABSOLUTE(hmacsha512_ndata, hmacsha512_offsets);
DNS_NAME_MAGIC,
hmacsha512_ndata, 13, 2,
DNS_NAMEATTR_READONLY | DNS_NAMEATTR_ABSOLUTE,
hmacsha512_offsets, NULL,
{(void *)-1, (void *)-1},
{NULL, NULL}
};
LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512; LIBDNS_EXTERNAL_DATA const dns_name_t *dns_tsig_hmacsha512_name = &hmacsha512;
static struct {
const dns_name_t *name;
unsigned int dstalg;
} known_algs[] = {
#ifndef PK11_MD5_DISABLE
{ &hmacmd5, DST_ALG_HMACMD5 },
#endif
{ &gsstsig, DST_ALG_GSSAPI },
{ &gsstsigms, DST_ALG_GSSAPI },
{ &hmacsha1, DST_ALG_HMACSHA1 },
{ &hmacsha224, DST_ALG_HMACSHA224 },
{ &hmacsha256, DST_ALG_HMACSHA256 },
{ &hmacsha384, DST_ALG_HMACSHA384 },
{ &hmacsha512, DST_ALG_HMACSHA512 }
};
static isc_result_t static isc_result_t
tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg); tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg);
@@ -195,6 +131,20 @@ cleanup_ring(dns_tsig_keyring_t *ring);
static void static void
tsigkey_free(dns_tsigkey_t *key); tsigkey_free(dns_tsigkey_t *key);
isc_boolean_t
dns__tsig_algvalid(unsigned int alg) {
return (ISC_TF(
#ifndef PK11_MD5_DISABLE
alg == DST_ALG_HMACMD5 ||
#endif
alg == DST_ALG_HMACSHA1 ||
alg == DST_ALG_HMACSHA224 ||
alg == DST_ALG_HMACSHA256 ||
alg == DST_ALG_HMACSHA384 ||
alg == DST_ALG_HMACSHA512
));
}
static void static void
tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) { tsig_log(dns_tsigkey_t *key, int level, const char *fmt, ...) {
va_list ap; va_list ap;
@@ -305,6 +255,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
dns_tsigkey_t *tkey; dns_tsigkey_t *tkey;
isc_result_t ret; isc_result_t ret;
unsigned int refs = 0; unsigned int refs = 0;
unsigned int dstalg = 0;
REQUIRE(key == NULL || *key == NULL); REQUIRE(key == NULL || *key == NULL);
REQUIRE(name != NULL); REQUIRE(name != NULL);
@@ -322,58 +273,15 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
goto cleanup_key; goto cleanup_key;
(void)dns_name_downcase(&tkey->name, &tkey->name, NULL); (void)dns_name_downcase(&tkey->name, &tkey->name, NULL);
#ifndef PK11_MD5_DISABLE /* Check against known algorithm names */
if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { dstalg = dns__tsig_algfromname(algorithm);
tkey->algorithm = DNS_TSIG_HMACMD5_NAME; if (dstalg != 0) {
if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACMD5) { /*
ret = DNS_R_BADALG; * 'algorithm' must be set to a static pointer
goto cleanup_name; * so that dns__tsig_algallocated() can compare them.
} */
} else tkey->algorithm = dns__tsig_algnamefromname(algorithm);
#endif if (dstkey != NULL && dst_key_alg(dstkey) != dstalg) {
if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) {
tkey->algorithm = DNS_TSIG_HMACSHA1_NAME;
if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_HMACSHA1) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) {
tkey->algorithm = DNS_TSIG_HMACSHA224_NAME;
if (dstkey != NULL &&
dst_key_alg(dstkey) != DST_ALG_HMACSHA224) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) {
tkey->algorithm = DNS_TSIG_HMACSHA256_NAME;
if (dstkey != NULL &&
dst_key_alg(dstkey) != DST_ALG_HMACSHA256) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
tkey->algorithm = DNS_TSIG_HMACSHA384_NAME;
if (dstkey != NULL &&
dst_key_alg(dstkey) != DST_ALG_HMACSHA384) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
tkey->algorithm = DNS_TSIG_HMACSHA512_NAME;
if (dstkey != NULL &&
dst_key_alg(dstkey) != DST_ALG_HMACSHA512) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) {
tkey->algorithm = DNS_TSIG_GSSAPI_NAME;
if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
tkey->algorithm = DNS_TSIG_GSSAPIMS_NAME;
if (dstkey != NULL && dst_key_alg(dstkey) != DST_ALG_GSSAPI) {
ret = DNS_R_BADALG; ret = DNS_R_BADALG;
goto cleanup_name; goto cleanup_name;
} }
@@ -445,8 +353,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
* Ignore this if it's a GSS key, since the key size is meaningless. * Ignore this if it's a GSS key, since the key size is meaningless.
*/ */
if (dstkey != NULL && dst_key_size(dstkey) < 64 && if (dstkey != NULL && dst_key_size(dstkey) < 64 &&
!dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME) && dstalg != DST_ALG_GSSAPI) {
!dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
char namestr[DNS_NAME_FORMATSIZE]; char namestr[DNS_NAME_FORMATSIZE];
dns_name_format(name, namestr, sizeof(namestr)); dns_name_format(name, namestr, sizeof(namestr));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC, isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
@@ -473,7 +380,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm,
isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t)); isc_mem_put(mctx, tkey->creator, sizeof(dns_name_t));
} }
cleanup_algorithm: cleanup_algorithm:
if (algname_is_allocated(tkey->algorithm)) { if (dns__tsig_algallocated(tkey->algorithm)) {
dns_name_t *tmpname; dns_name_t *tmpname;
DE_CONST(tkey->algorithm, tmpname); DE_CONST(tkey->algorithm, tmpname);
if (dns_name_dynamic(tmpname)) if (dns_name_dynamic(tmpname))
@@ -552,31 +459,60 @@ destroyring(dns_tsig_keyring_t *ring) {
isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t)); isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t));
} }
static unsigned int /*
dst_alg_fromname(const dns_name_t *algorithm) { * Look up the DST_ALG_ constant for a given name.
#ifndef PK11_MD5_DISABLE */
if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { unsigned int
return (DST_ALG_HMACMD5); dns__tsig_algfromname(const dns_name_t *algorithm) {
} else int i;
#endif int n = sizeof(known_algs) / sizeof(*known_algs);
if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) { for (i = 0; i < n; ++i) {
return (DST_ALG_HMACSHA1); const dns_name_t *name = known_algs[i].name;
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) { if (algorithm == name || dns_name_equal(algorithm, name)) {
return (DST_ALG_HMACSHA224); return (known_algs[i].dstalg);
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) { }
return (DST_ALG_HMACSHA256); }
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
return (DST_ALG_HMACSHA384);
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
return (DST_ALG_HMACSHA512);
} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPI_NAME)) {
return (DST_ALG_GSSAPI);
} else if (dns_name_equal(algorithm, DNS_TSIG_GSSAPIMS_NAME)) {
return (DST_ALG_GSSAPI);
} else
return (0); return (0);
} }
/*
* Convert an algorithm name into a pointer to the
* corresponding pre-defined dns_name_t structure.
*/
const dns_name_t*
dns__tsig_algnamefromname(const dns_name_t *algorithm) {
int i;
int n = sizeof(known_algs) / sizeof(*known_algs);
for (i = 0; i < n; ++i) {
const dns_name_t *name = known_algs[i].name;
if (algorithm == name || dns_name_equal(algorithm, name)) {
return (name);
}
}
return (NULL);
}
/*
* Test whether the passed algorithm is NOT a pointer to one of the
* pre-defined known algorithms (and therefore one that has been
* dynamically allocated).
*
* This will return an incorrect result if passed a dynamically allocated
* dns_name_t that happens to match one of the pre-defined names.
*/
isc_boolean_t
dns__tsig_algallocated(const dns_name_t *algorithm) {
int i;
int n = sizeof(known_algs) / sizeof(*known_algs);
for (i = 0; i < n; ++i) {
const dns_name_t *name = known_algs[i].name;
if (algorithm == name) {
return (ISC_FALSE);
}
}
return (ISC_TRUE);
}
static isc_result_t static isc_result_t
restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) { restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
dst_key_t *dstkey = NULL; dst_key_t *dstkey = NULL;
@@ -626,7 +562,7 @@ restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
dstalg = dst_alg_fromname(algorithm); dstalg = dns__tsig_algfromname(algorithm);
if (dstalg == 0) if (dstalg == 0)
return (DNS_R_BADALG); return (DNS_R_BADALG);
@@ -737,19 +673,20 @@ dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm,
{ {
dst_key_t *dstkey = NULL; dst_key_t *dstkey = NULL;
isc_result_t result; isc_result_t result;
unsigned int dstalg = 0;
REQUIRE(length >= 0); REQUIRE(length >= 0);
if (length > 0) if (length > 0)
REQUIRE(secret != NULL); REQUIRE(secret != NULL);
#ifndef PK11_MD5_DISABLE dstalg = dns__tsig_algfromname(algorithm);
if (dns_name_equal(algorithm, DNS_TSIG_HMACMD5_NAME)) { if (dns__tsig_algvalid(dstalg)) {
if (secret != NULL) { if (secret != NULL) {
isc_buffer_t b; isc_buffer_t b;
isc_buffer_init(&b, secret, length); isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length); isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACMD5, result = dst_key_frombuffer(name, dstalg,
DNS_KEYOWNER_ENTITY, DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC, DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in, dns_rdataclass_in,
@@ -757,80 +694,9 @@ dns_tsigkey_create(const dns_name_t *name, const dns_name_t *algorithm,
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return (result); return (result);
} }
} else } else if (length > 0) {
#endif
if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA1_NAME)) {
if (secret != NULL) {
isc_buffer_t b;
isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACSHA1,
DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in,
&b, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (result);
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA224_NAME)) {
if (secret != NULL) {
isc_buffer_t b;
isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACSHA224,
DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in,
&b, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (result);
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA256_NAME)) {
if (secret != NULL) {
isc_buffer_t b;
isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACSHA256,
DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in,
&b, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (result);
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA384_NAME)) {
if (secret != NULL) {
isc_buffer_t b;
isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACSHA384,
DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in,
&b, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (result);
}
} else if (dns_name_equal(algorithm, DNS_TSIG_HMACSHA512_NAME)) {
if (secret != NULL) {
isc_buffer_t b;
isc_buffer_init(&b, secret, length);
isc_buffer_add(&b, length);
result = dst_key_frombuffer(name, DST_ALG_HMACSHA512,
DNS_KEYOWNER_ENTITY,
DNS_KEYPROTO_DNSSEC,
dns_rdataclass_in,
&b, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (result);
}
} else if (length > 0)
return (DNS_R_BADALG); return (DNS_R_BADALG);
}
result = dns_tsigkey_createfromkey(name, algorithm, dstkey, result = dns_tsigkey_createfromkey(name, algorithm, dstkey,
generated, creator, generated, creator,
@@ -855,7 +721,7 @@ tsigkey_free(dns_tsigkey_t *key) {
key->magic = 0; key->magic = 0;
dns_name_free(&key->name, key->mctx); dns_name_free(&key->name, key->mctx);
if (algname_is_allocated(key->algorithm)) { if (dns__tsig_algallocated(key->algorithm)) {
dns_name_t *name; dns_name_t *name;
DE_CONST(key->algorithm, name); DE_CONST(key->algorithm, name);
dns_name_free(name, key->mctx); dns_name_free(name, key->mctx);
@@ -1343,14 +1209,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
ret = dst_key_sigsize(key, &siglen); ret = dst_key_sigsize(key, &siglen);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
return (ret); return (ret);
if ( if (dns__tsig_algvalid(alg)) {
#ifndef PK11_MD5_DISABLE
alg == DST_ALG_HMACMD5 ||
#endif
alg == DST_ALG_HMACSHA1 ||
alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 ||
alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512)
{
if (tsig.siglen > siglen) { if (tsig.siglen > siglen) {
tsig_log(msg->tsigkey, 2, "signature length too big"); tsig_log(msg->tsigkey, 2, "signature length too big");
return (DNS_R_FORMERR); return (DNS_R_FORMERR);
@@ -1512,14 +1371,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
goto cleanup_context; goto cleanup_context;
} }
if ( if (dns__tsig_algvalid(alg)) {
#ifndef PK11_MD5_DISABLE
alg == DST_ALG_HMACMD5 ||
#endif
alg == DST_ALG_HMACSHA1 ||
alg == DST_ALG_HMACSHA224 || alg == DST_ALG_HMACSHA256 ||
alg == DST_ALG_HMACSHA384 || alg == DST_ALG_HMACSHA512)
{
isc_uint16_t digestbits = dst_key_getbits(key); isc_uint16_t digestbits = dst_key_getbits(key);
/* /*
@@ -1653,16 +1505,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
ret = dst_key_sigsize(key, &siglen); ret = dst_key_sigsize(key, &siglen);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
goto cleanup_querystruct; goto cleanup_querystruct;
if ( if (dns__tsig_algvalid(alg)) {
#ifndef PK11_MD5_DISABLE
alg == DST_ALG_HMACMD5 ||
#endif
alg == DST_ALG_HMACSHA1 ||
alg == DST_ALG_HMACSHA224 ||
alg == DST_ALG_HMACSHA256 ||
alg == DST_ALG_HMACSHA384 ||
alg == DST_ALG_HMACSHA512)
{
if (tsig.siglen > siglen) { if (tsig.siglen > siglen) {
tsig_log(tsigkey, 2, tsig_log(tsigkey, 2,
"signature length too big"); "signature length too big");
@@ -1832,16 +1675,7 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
ret = dst_key_sigsize(key, &siglen); ret = dst_key_sigsize(key, &siglen);
if (ret != ISC_R_SUCCESS) if (ret != ISC_R_SUCCESS)
goto cleanup_context; goto cleanup_context;
if ( if (dns__tsig_algvalid(alg)) {
#ifndef PK11_MD5_DISABLE
alg == DST_ALG_HMACMD5 ||
#endif
alg == DST_ALG_HMACSHA1 ||
alg == DST_ALG_HMACSHA224 ||
alg == DST_ALG_HMACSHA256 ||
alg == DST_ALG_HMACSHA384 ||
alg == DST_ALG_HMACSHA512)
{
isc_uint16_t digestbits = dst_key_getbits(key); isc_uint16_t digestbits = dst_key_getbits(key);
/* /*

35
lib/dns/tsig_p.h Normal file
View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef DNS_TSIG_P_H
#define DNS_TSIG_P_H
/*! \file */
#include <isc/result.h>
#include <dns/types.h>
/*%
* These functions must not be used outside this module and
* its associated unit tests.
*/
ISC_LANG_BEGINDECLS
isc_boolean_t
dns__tsig_algvalid(unsigned int alg);
unsigned int
dns__tsig_algfromname(const dns_name_t *algorithm);
const dns_name_t *
dns__tsig_algnamefromname(const dns_name_t *algorithm);
isc_boolean_t
dns__tsig_algallocated(const dns_name_t *algorithm);
ISC_LANG_ENDDECLS
#endif /* DNS_TSIG_P_H */