Commit 910a0155 authored by Michał Kępień's avatar Michał Kępień
Browse files

[master] Rename nsec3param_salt_totext() to dns_nsec3param_salttotext(), make...

[master] Rename nsec3param_salt_totext() to dns_nsec3param_salttotext(), make it public, add unit tests

4786.	[cleanup]	Turn nsec3param_salt_totext() into a public function,
			dns_nsec3param_salttotext(), and add unit tests for it.
			[RT #46289]
parent 65314b0f
4787. [cleanup] Turn nsec3param_salt_totext() into a public function,
dns_nsec3param_salttotext(), and add unit tests for it.
[RT #46289]
4786. [func] The "filter-aaaa-on-v4" and "filter-aaaa-on-v6"
options are no longer conditionally compiled.
[RT #46340]
......
......@@ -235,6 +235,19 @@ dns_nsec3param_toprivate(dns_rdata_t *src, dns_rdata_t *target,
* 'buf' should be at least src->length + 1 in size.
*/
isc_result_t
dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst,
size_t dstlen);
/*%<
* Convert the salt of given NSEC3PARAM RDATA into hex-encoded, NULL-terminated
* text stored at "dst".
*
* Requires:
*
*\li "dst" to have enough space (as indicated by "dstlen") to hold the
* resulting text and its NULL-terminating byte.
*/
isc_result_t
dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
dns_zone_t *zone, isc_boolean_t nonsec,
......
......@@ -1009,6 +1009,42 @@ rr_exists(dns_db_t *db, dns_dbversion_t *ver, const dns_name_t *name,
return (result);
}
isc_result_t
dns_nsec3param_salttotext(dns_rdata_nsec3param_t *nsec3param, char *dst,
size_t dstlen)
{
isc_result_t result;
isc_region_t r;
isc_buffer_t b;
REQUIRE(nsec3param != NULL);
REQUIRE(dst != NULL);
if (nsec3param->salt_length == 0) {
if (dstlen < 2U) {
return (ISC_R_NOSPACE);
}
strlcpy(dst, "-", dstlen);
return (ISC_R_SUCCESS);
}
r.base = nsec3param->salt;
r.length = nsec3param->salt_length;
isc_buffer_init(&b, dst, (unsigned int)dstlen);
result = isc_hex_totext(&r, 2, "", &b);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (isc_buffer_availablelength(&b) < 1) {
return (ISC_R_NOSPACE);
}
isc_buffer_putuint8(&b, 0);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
dns_zone_t *zone, isc_boolean_t nonsec,
......
......@@ -22,6 +22,7 @@
#include <isc/file.h>
#include <isc/hash.h>
#include <isc/hex.h>
#include <isc/lex.h>
#include <isc/mem.h>
#include <isc/os.h>
#include <isc/print.h>
......@@ -100,7 +101,7 @@ create_managers(void) {
CHECK(isc_task_create(taskmgr, 0, &maintask));
return (ISC_R_SUCCESS);
cleanup:
cleanup:
cleanup_managers();
return (result);
}
......@@ -158,7 +159,7 @@ dns_test_begin(FILE *logfile, isc_boolean_t start_managers) {
return (ISC_R_SUCCESS);
cleanup:
cleanup:
dns_test_end();
return (result);
}
......@@ -434,3 +435,58 @@ dns_test_getdata(const char *file, unsigned char *buf,
isc_stdio_close(f);
return (result);
}
isc_result_t
dns_test_rdata_fromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
dns_rdatatype_t rdtype, unsigned char *dst,
size_t dstlen, const char *src)
{
isc_buffer_t source, target;
isc_lex_t *lex = NULL;
isc_result_t result;
size_t length;
REQUIRE(rdata != NULL);
REQUIRE(DNS_RDATA_INITIALIZED(rdata));
REQUIRE(dst != NULL);
REQUIRE(src != NULL);
/*
* Set up source to hold the input string.
*/
length = strlen(src);
isc_buffer_constinit(&source, src, length);
isc_buffer_add(&source, length);
/*
* Create a lexer as one is required by dns_rdata_fromtext().
*/
result = isc_lex_create(mctx, 64, &lex);
if (result != ISC_R_SUCCESS) {
return (result);
}
/*
* Point lexer at source.
*/
result = isc_lex_openbuffer(lex, &source);
if (result != ISC_R_SUCCESS) {
goto destroy_lexer;
}
/*
* Set up target for storing uncompressed wire form of provided RDATA.
*/
isc_buffer_init(&target, dst, dstlen);
/*
* Parse input string, determining result.
*/
result = dns_rdata_fromtext(rdata, rdclass, rdtype, lex, dns_rootname,
0, NULL, &target, NULL);
destroy_lexer:
isc_lex_destroy(&lex);
return (result);
}
......@@ -80,3 +80,13 @@ dns_test_getdata(const char *file, unsigned char *buf,
char *
dns_test_tohex(const unsigned char *data, size_t len, char *buf, size_t buflen);
/*%
* Try parsing text form RDATA in "src" (of class "rdclass" and type "rdtype")
* into a structure representing that RDATA at "rdata", storing the
* uncompressed wire form of that RDATA at "dst", which is "dstlen" bytes long.
*/
isc_result_t
dns_test_rdata_fromstring(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
dns_rdatatype_t rdtype, unsigned char *dst,
size_t dstlen, const char *src);
......@@ -43,6 +43,82 @@ iteration_test(const char *file, unsigned int expected) {
dns_db_detach(&db);
}
/*%
* Structure containing parameters for nsec3param_salttotext_test().
*/
typedef struct {
const char *nsec3param_text; /* NSEC3PARAM RDATA in text form */
const char *expected_salt; /* string expected in target buffer */
} nsec3param_salttotext_test_params_t;
/*%
* Check whether dns_nsec3param_salttotext() handles supplied text form
* NSEC3PARAM RDATA correctly: test whether the result of calling the former is
* as expected and whether it properly checks available buffer space.
*
* Assumes supplied text form NSEC3PARAM RDATA is valid as testing handling of
* invalid NSEC3PARAM RDATA is out of scope of this unit test.
*/
static void
nsec3param_salttotext_test(const nsec3param_salttotext_test_params_t *params) {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_nsec3param_t nsec3param;
unsigned char buf[1024];
isc_result_t result;
char salt[64];
size_t length;
/*
* Prepare a dns_rdata_nsec3param_t structure for testing.
*/
result = dns_test_rdata_fromstring(&rdata, dns_rdataclass_in,
dns_rdatatype_nsec3param, buf,
sizeof(buf),
params->nsec3param_text);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Check typical use.
*/
result = dns_nsec3param_salttotext(&nsec3param, salt, sizeof(salt));
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
"\"%s\": expected success, got %s\n",
params->nsec3param_text, isc_result_totext(result));
ATF_CHECK_EQ_MSG(strcmp(salt, params->expected_salt), 0,
"\"%s\": expected salt \"%s\", got \"%s\"",
params->nsec3param_text, params->expected_salt, salt);
/*
* Ensure available space in the buffer is checked before the salt is
* printed to it and that the amount of space checked for includes the
* terminating NULL byte.
*/
length = strlen(params->expected_salt);
ATF_REQUIRE(length < sizeof(salt) - 1); /* prevent buffer overwrite */
ATF_REQUIRE(length > 0U); /* prevent length underflow */
result = dns_nsec3param_salttotext(&nsec3param, salt, length - 1);
ATF_CHECK_EQ_MSG(result, ISC_R_NOSPACE,
"\"%s\": expected a %lu-byte target buffer to be "
"rejected, got %s\n",
params->nsec3param_text, length - 1,
isc_result_totext(result));
result = dns_nsec3param_salttotext(&nsec3param, salt, length);
ATF_CHECK_EQ_MSG(result, ISC_R_NOSPACE,
"\"%s\": expected a %lu-byte target buffer to be "
"rejected, got %s\n",
params->nsec3param_text, length,
isc_result_totext(result));
result = dns_nsec3param_salttotext(&nsec3param, salt, length + 1);
ATF_CHECK_EQ_MSG(result, ISC_R_SUCCESS,
"\"%s\": expected a %lu-byte target buffer to be "
"accepted, got %s\n",
params->nsec3param_text, length + 1,
isc_result_totext(result));
}
/*
* Individual unit tests
*/
......@@ -68,6 +144,40 @@ ATF_TC_BODY(max_iterations, tc) {
dns_test_end();
}
ATF_TC(nsec3param_salttotext);
ATF_TC_HEAD(nsec3param_salttotext, tc) {
atf_tc_set_md_var(tc, "descr", "check dns_nsec3param_salttotext()");
}
ATF_TC_BODY(nsec3param_salttotext, tc) {
isc_result_t result;
size_t i;
const nsec3param_salttotext_test_params_t tests[] = {
/*
* Tests with non-empty salts.
*/
{ "0 0 10 0123456789abcdef", "0123456789ABCDEF" },
{ "0 1 11 0123456789abcdef", "0123456789ABCDEF" },
{ "1 0 12 42", "42" },
{ "1 1 13 42", "42" },
/*
* Test with empty salt.
*/
{ "0 0 0 -", "-" },
};
UNUSED(tc);
result = dns_test_begin(NULL, ISC_FALSE);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
nsec3param_salttotext_test(&tests[i]);
}
dns_test_end();
}
#else
ATF_TC(untested);
ATF_TC_HEAD(untested, tc) {
......@@ -85,6 +195,7 @@ ATF_TC_BODY(untested, tc) {
ATF_TP_ADD_TCS(tp) {
#if defined(OPENSSL) || defined(PKCS11CRYPTO)
ATF_TP_ADD_TC(tp, max_iterations);
ATF_TP_ADD_TC(tp, nsec3param_salttotext);
#else
ATF_TP_ADD_TC(tp, untested);
#endif
......
......@@ -141,38 +141,18 @@ static void
check_text_ok_single(const text_ok_t *text_ok, dns_rdataclass_t rdclass,
dns_rdatatype_t type, size_t structsize)
{
isc_buffer_t source, target;
dns_rdata_t rdata = DNS_RDATA_INIT;
unsigned char buf_fromtext[1024];
char buf_totext[1024] = { 0 };
isc_lex_t *lex = NULL;
isc_buffer_t target;
isc_result_t result;
dns_rdata_t rdata;
size_t length;
/*
* Set up lexer to read data.
*/
result = isc_lex_create(mctx, 64, &lex);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
length = strlen(text_ok->text_in);
isc_buffer_constinit(&source, text_ok->text_in, length);
isc_buffer_add(&source, length);
result = isc_lex_openbuffer(lex, &source);
ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
/*
* Initialize target structures.
*/
isc_buffer_init(&target, buf_fromtext, sizeof(buf_fromtext));
dns_rdata_init(&rdata);
/*
* Try converting text form RDATA into uncompressed wire form.
*/
result = dns_rdata_fromtext(&rdata, rdclass, type, lex, dns_rootname,
0, NULL, &target, NULL);
/*
* Destroy lexer now to simplify error handling below.
*/
isc_lex_destroy(&lex);
result = dns_test_rdata_fromstring(&rdata, rdclass, type, buf_fromtext,
sizeof(buf_fromtext),
text_ok->text_in);
/*
* Check whether result is as expected.
*/
......
......@@ -637,6 +637,7 @@ dns_nsec3_supportedhash
dns_nsec3_typepresent
dns_nsec3param_deletechains
dns_nsec3param_fromprivate
dns_nsec3param_salttotext
dns_nsec3param_toprivate
dns_nsec_build
dns_nsec_buildrdata
......
......@@ -3303,50 +3303,6 @@ resume_signingwithkey(dns_zone_t *zone) {
}
}
/*
* Convert the salt of given NSEC3PARAM RDATA into hex-encoded, NULL-terminated
* text stored at "dst".
*
* Requires:
* "dst" to have enough space (as indicated by "dstlen") to hold the
* resulting text and its NULL-terminating byte.
*/
static isc_result_t
nsec3param_salt_totext(dns_rdata_nsec3param_t *nsec3param, char *dst,
size_t dstlen)
{
isc_result_t result;
isc_region_t r;
isc_buffer_t b;
REQUIRE(nsec3param != NULL);
REQUIRE(dst != NULL);
if (nsec3param->salt_length == 0) {
if (dstlen < 2U) {
return (ISC_R_NOSPACE);
}
strlcpy(dst, "-", dstlen);
return (ISC_R_SUCCESS);
}
r.base = nsec3param->salt;
r.length = nsec3param->salt_length;
isc_buffer_init(&b, dst, (unsigned int)dstlen);
result = isc_hex_totext(&r, 2, "", &b);
if (result != ISC_R_SUCCESS) {
return (result);
}
if (isc_buffer_availablelength(&b) < 1) {
return (ISC_R_NOSPACE);
}
isc_buffer_putuint8(&b, 0);
return (ISC_R_SUCCESS);
}
/*
* Initiate adding/removing NSEC3 records belonging to the chain defined by the
* supplied NSEC3PARAM RDATA.
......@@ -3450,7 +3406,8 @@ zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
strlcat(flags, "|OPTOUT", sizeof(flags));
}
}
result = nsec3param_salt_totext(nsec3param, saltbuf, sizeof(saltbuf));
result = dns_nsec3param_salttotext(nsec3param, saltbuf,
sizeof(saltbuf));
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_zone_log(zone, ISC_LOG_INFO,
"zone_addnsec3chain(%u,%s,%u,%s)",
......@@ -17258,7 +17215,7 @@ dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
REQUIRE(DNS_ZONE_VALID(zone));
result = nsec3param_salt_totext(nsec3param, salt, sizeof(salt));
result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_zone_log(zone, ISC_LOG_NOTICE,
"dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment