From: Mark Andrews Date: Thu, 24 Apr 2014 08:58:03 +0000 (+1000) Subject: 3819. [bug] NSEC3 hashes need to be able to be entered and X-Git-Tag: v9.10.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ce6651a2a89b994ea147e402a15f6aa56b94337;p=thirdparty%2Fbind9.git 3819. [bug] NSEC3 hashes need to be able to be entered and displayed without padding. This is not a issue for currently defined algorithms but may be for future hash algorithms. [RT #27925] (cherry picked from commit 36e5ac00333d89001f0c518a7d381d16c38d0402) --- diff --git a/CHANGES b/CHANGES index 847fc7d234d..46daf574328 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +3819. [bug] NSEC3 hashes need to be able to be entered and + displayed without padding. This is not a issue for + currently defined algorithms but may be for future + hash algorithms. [RT #27925] + 3818. [bug] Stop lying to the optimizer that 'void *arg' is a constant in isc_event_allocate. diff --git a/bin/tests/system/checkzone/zones/bad-nsec3-padded.db b/bin/tests/system/checkzone/zones/bad-nsec3-padded.db new file mode 100644 index 00000000000..adf26cd1f15 --- /dev/null +++ b/bin/tests/system/checkzone/zones/bad-nsec3-padded.db @@ -0,0 +1,24 @@ +; Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 600 +@ SOA ns hostmaster 2011012708 3600 1200 604800 1200 + NS ns +ns A 192.0.2.1 + +; The following NSEC3 RR is invalid as the Next Hashed Owner Name field +; is padded. See RFC 5155. +0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NSEC3 1 1 12 aabbccdd ( + CPNMU=== MX DNSKEY NS + SOA NSEC3PARAM RRSIG ) diff --git a/bin/tests/system/checkzone/zones/bad-nsec3owner-padded.db b/bin/tests/system/checkzone/zones/bad-nsec3owner-padded.db new file mode 100644 index 00000000000..0a0cf300746 --- /dev/null +++ b/bin/tests/system/checkzone/zones/bad-nsec3owner-padded.db @@ -0,0 +1,22 @@ +; Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 600 +@ SOA ns hostmaster 2011012708 3600 1200 604800 1200 + NS ns +ns A 192.0.2.1 + +; The following NSEC3 RR owner is invalid as the owner name is padded. +CPNMU=== NSEC3 2 1 12 aabbccdd ( CPNMU MX DNSKEY NS + SOA NSEC3PARAM RRSIG ) diff --git a/bin/tests/system/checkzone/zones/good-nsec3-nopadhash.db b/bin/tests/system/checkzone/zones/good-nsec3-nopadhash.db new file mode 100644 index 00000000000..12155142764 --- /dev/null +++ b/bin/tests/system/checkzone/zones/good-nsec3-nopadhash.db @@ -0,0 +1,22 @@ +; Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC") +; +; Permission to use, copy, modify, and/or distribute this software for any +; purpose with or without fee is hereby granted, provided that the above +; copyright notice and this permission notice appear in all copies. +; +; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH +; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +; AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, +; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +; PERFORMANCE OF THIS SOFTWARE. + +$TTL 600 +@ SOA ns hostmaster 2011012708 3600 1200 604800 1200 + NS ns +ns A 192.0.2.1 + +; a hash that isn't a multiple of 8 characters +CPNMU NSEC3 2 1 12 aabbccdd ( CPNMU MX DNSKEY NS + SOA NSEC3PARAM RRSIG ) diff --git a/bin/tools/nsec3hash.c b/bin/tools/nsec3hash.c index 486037ff165..1a2a9558bf3 100644 --- a/bin/tools/nsec3hash.c +++ b/bin/tools/nsec3hash.c @@ -116,7 +116,7 @@ main(int argc, char **argv) { region.base = hash; region.length = length; isc_buffer_init(&buffer, text, sizeof(text)); - isc_base32hex_totext(®ion, 1, "", &buffer); + isc_base32hexnp_totext(®ion, 1, "", &buffer); fprintf(stdout, "%.*s (salt=%s, hash=%u, iterations=%u)\n", (int)isc_buffer_usedlength(&buffer), text, argv[1], hash_alg, iterations); return(0); diff --git a/lib/dns/master.c b/lib/dns/master.c index 4b75843dea6..e6b1a0a8032 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -91,6 +91,8 @@ #define DNS_MASTER_LHS 2048 #define DNS_MASTER_RHS MINTSIZ +#define CHECKNAMESFAIL(x) (((x) & DNS_MASTER_CHECKNAMESFAIL) != 0) + typedef ISC_LIST(dns_rdatalist_t) rdatalist_head_t; typedef struct dns_incctx dns_incctx_t; @@ -1768,7 +1770,8 @@ load_text(dns_loadctx_t *lctx) { dns_name_format(name, namebuf, sizeof(namebuf)); result = DNS_R_BADOWNERNAME; desc = dns_result_totext(result); - if ((lctx->options & DNS_MASTER_CHECKNAMESFAIL) != 0) { + if (CHECKNAMESFAIL(lctx->options) || + type == dns_rdatatype_nsec3) { (*callbacks->error)(callbacks, "%s:%lu: %s: %s", source, line, diff --git a/lib/dns/message.c b/lib/dns/message.c index 5137cb11d9b..a062e951ba3 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -1381,6 +1381,16 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, } else covers = 0; + /* + * Check the ownername of NSEC3 records + */ + if (rdtype == dns_rdatatype_nsec3 && + !dns_rdata_checkowner(name, msg->rdclass, rdtype, + ISC_FALSE)) { + result = DNS_R_BADOWNERNAME; + goto cleanup; + } + /* * If we are doing a dynamic update or this is a meta-type, * don't bother searching for a name, just append this one diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c index 00ccf0e7eb0..e66cc5a56fa 100644 --- a/lib/dns/nsec3.c +++ b/lib/dns/nsec3.c @@ -253,11 +253,11 @@ dns_nsec3_hashname(dns_fixedname_t *result, if (hash_length != NULL) *hash_length = len; - /* convert the hash to base32hex */ + /* convert the hash to base32hex non-padded */ region.base = rethash; region.length = (unsigned int)len; isc_buffer_init(&namebuffer, nametext, sizeof nametext); - isc_base32hex_totext(®ion, 1, "", &namebuffer); + isc_base32hexnp_totext(®ion, 1, "", &namebuffer); /* convert the hex to a domain name */ dns_fixedname_init(result); @@ -269,7 +269,8 @@ unsigned int dns_nsec3_hashlength(dns_hash_t hash) { switch (hash) { - case dns_hash_sha1: return(ISC_SHA1_DIGESTLENGTH); + case dns_hash_sha1: + return(ISC_SHA1_DIGESTLENGTH); } return (0); } @@ -277,7 +278,8 @@ dns_nsec3_hashlength(dns_hash_t hash) { isc_boolean_t dns_nsec3_supportedhash(dns_hash_t hash) { switch (hash) { - case dns_hash_sha1: return (ISC_TRUE); + case dns_hash_sha1: + return (ISC_TRUE); } return (ISC_FALSE); } diff --git a/lib/dns/rdata/generic/nsec3_50.c b/lib/dns/rdata/generic/nsec3_50.c index 19b94efa06d..0b876896f73 100644 --- a/lib/dns/rdata/generic/nsec3_50.c +++ b/lib/dns/rdata/generic/nsec3_50.c @@ -100,7 +100,7 @@ fromtext_nsec3(ARGS_FROMTEXT) { RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, ISC_FALSE)); isc_buffer_init(&b, bm, sizeof(bm)); - RETTOK(isc_base32hex_decodestring(DNS_AS_STR(token), &b)); + RETTOK(isc_base32hexnp_decodestring(DNS_AS_STR(token), &b)); if (isc_buffer_usedlength(&b) > 0xffU) RETTOK(ISC_R_RANGE); RETERR(uint8_tobuffer(isc_buffer_usedlength(&b), target)); @@ -191,7 +191,7 @@ totext_nsec3(ARGS_TOTEXT) { i = sr.length; sr.length = j; - RETERR(isc_base32hex_totext(&sr, 1, "", target)); + RETERR(isc_base32hexnp_totext(&sr, 1, "", target)); sr.length = i - j; if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) == 0) @@ -474,15 +474,26 @@ digest_nsec3(ARGS_DIGEST) { static inline isc_boolean_t checkowner_nsec3(ARGS_CHECKOWNER) { + unsigned char owner[NSEC3_MAX_HASH_LENGTH]; + isc_buffer_t buffer; + dns_label_t label; - REQUIRE(type == 50); + REQUIRE(type == 50); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); - UNUSED(name); - UNUSED(type); - UNUSED(rdclass); - UNUSED(wildcard); + /* + * First label is a base32hex string without padding. + */ + dns_name_getlabel(name, 0, &label); + isc_region_consume(&label, 1); + isc_buffer_init(&buffer, owner, sizeof(owner)); + if (isc_base32hexnp_decoderegion(&label, &buffer) == ISC_R_SUCCESS) + return (ISC_TRUE); - return (ISC_TRUE); + return (ISC_FALSE); } static inline isc_boolean_t diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 9985e62ca6d..6e09762f60e 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -336,7 +336,7 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, dns_name_getlabel(&nsec3name, 0, &hashlabel); isc_region_consume(&hashlabel, 1); isc_buffer_init(&buffer, owner, sizeof(owner)); - result = isc_base32hex_decoderegion(&hashlabel, &buffer); + result = isc_base32hexnp_decoderegion(&hashlabel, &buffer); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&set); continue; diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c90488ed8a2..279a3304040 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -16242,10 +16242,12 @@ dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) { REQUIRE(DNS_ZONE_VALID(zone)); - if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) + if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) && + rdata->type != dns_rdatatype_nsec3) return (ISC_R_SUCCESS); - if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) { + if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) || + rdata->type == dns_rdatatype_nsec3) { level = ISC_LOG_ERROR; fail = ISC_TRUE; } diff --git a/lib/isc/base32.c b/lib/isc/base32.c index ad0b0da569e..2ee99b18242 100644 --- a/lib/isc/base32.c +++ b/lib/isc/base32.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base32.c,v 1.6 2009/10/21 01:22:29 each Exp $ */ +/* $Id: base32.c,v 1.6.698.1 2012/02/15 05:00:16 marka Exp $ */ /*! \file */ @@ -54,7 +54,7 @@ static const char base32hex[] = static isc_result_t base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, - isc_buffer_t *target, const char base[]) + isc_buffer_t *target, const char base[], char pad) { char buf[9]; unsigned int loops = 0; @@ -67,8 +67,8 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[0] = base[((source->base[0]>>3)&0x1f)]; /* 5 + */ if (source->length == 1) { buf[1] = base[(source->base[0]<<2)&0x1c]; - buf[2] = buf[3] = buf[4] = '='; - buf[5] = buf[6] = buf[7] = '='; + buf[2] = buf[3] = buf[4] = pad; + buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -77,7 +77,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[2] = base[((source->base[1]>>1)&0x1f)]; /* 5 + */ if (source->length == 2) { buf[3] = base[(source->base[1]<<4)&0x10]; - buf[4] = buf[5] = buf[6] = buf[7] = '='; + buf[4] = buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -85,7 +85,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, ((source->base[2]>>4)&0x0f)]; /* 4 + */ if (source->length == 3) { buf[4] = base[(source->base[2]<<1)&0x1e]; - buf[5] = buf[6] = buf[7] = '='; + buf[5] = buf[6] = buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -94,7 +94,7 @@ base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, buf[5] = base[((source->base[3]>>2)&0x1f)]; /* 5 + */ if (source->length == 4) { buf[6] = base[(source->base[3]<<3)&0x18]; - buf[7] = '='; + buf[7] = pad; RETERR(str_totext(buf, target)); break; } @@ -121,7 +121,8 @@ isc_result_t isc_base32_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { - return (base32_totext(source, wordlength, wordbreak, target, base32)); + return (base32_totext(source, wordlength, wordbreak, target, + base32, '=')); } isc_result_t @@ -129,7 +130,15 @@ isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target) { return (base32_totext(source, wordlength, wordbreak, target, - base32hex)); + base32hex, '=')); +} + +isc_result_t +isc_base32hexnp_totext(isc_region_t *source, int wordlength, + const char *wordbreak, isc_buffer_t *target) +{ + return (base32_totext(source, wordlength, wordbreak, target, + base32hex, 0)); } /*% @@ -143,11 +152,12 @@ typedef struct { int val[8]; const char *base; /*%< Which encoding we are using */ int seen_32; /*%< Number of significant bytes if non zero */ + isc_boolean_t pad; /*%< Expect padding */ } base32_decode_ctx_t; static inline void -base32_decode_init(base32_decode_ctx_t *ctx, int length, - const char base[], isc_buffer_t *target) +base32_decode_init(base32_decode_ctx_t *ctx, int length, const char base[], + isc_boolean_t pad, isc_buffer_t *target) { ctx->digits = 0; ctx->seen_end = ISC_FALSE; @@ -155,6 +165,7 @@ base32_decode_init(base32_decode_ctx_t *ctx, int length, ctx->length = length; ctx->target = target; ctx->base = base; + ctx->pad = pad; } static inline isc_result_t @@ -167,16 +178,25 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { if ((s = strchr(ctx->base, c)) == NULL) return (ISC_R_BADBASE32); last = (unsigned int)(s - ctx->base); + /* * Handle lower case. */ if (last > 32) last -= 33; + /* * Check that padding is contiguous. */ if (last != 32 && ctx->seen_32 != 0) return (ISC_R_BADBASE32); + + /* + * If padding is not permitted flag padding as a error. + */ + if (last == 32 && !ctx->pad) + return (ISC_R_BADBASE32); + /* * Check that padding starts at the right place and that * bits that should be zero are. @@ -212,6 +232,7 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { ctx->seen_32 = 4; break; } + /* * Zero fill pad values. */ @@ -244,23 +265,33 @@ base32_decode_char(base32_decode_ctx_t *ctx, int c) { static inline isc_result_t base32_decode_finish(base32_decode_ctx_t *ctx) { + if (ctx->length > 0) return (ISC_R_UNEXPECTEDEND); + /* + * Add missing padding if required. + */ + if (!ctx->pad && ctx->digits != 0) { + ctx->pad = ISC_TRUE; + do { + RETERR(base32_decode_char(ctx, '=')); + } while (ctx->digits != 0); + } if (ctx->digits != 0) return (ISC_R_BADBASE32); return (ISC_R_SUCCESS); } static isc_result_t -base32_tobuffer(isc_lex_t *lexer, const char base[], isc_buffer_t *target, - int length) +base32_tobuffer(isc_lex_t *lexer, const char base[], isc_boolean_t pad, + isc_buffer_t *target, int length) { base32_decode_ctx_t ctx; isc_textregion_t *tr; isc_token_t token; isc_boolean_t eol; - base32_decode_init(&ctx, length, base, target); + base32_decode_init(&ctx, length, base, pad, target); while (!ctx.seen_end && (ctx.length != 0)) { unsigned int i; @@ -285,19 +316,26 @@ base32_tobuffer(isc_lex_t *lexer, const char base[], isc_buffer_t *target, isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { - return (base32_tobuffer(lexer, base32, target, length)); + return (base32_tobuffer(lexer, base32, ISC_TRUE, target, length)); } isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { - return (base32_tobuffer(lexer, base32hex, target, length)); + return (base32_tobuffer(lexer, base32hex, ISC_TRUE, target, length)); +} + +isc_result_t +isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) { + return (base32_tobuffer(lexer, base32hex, ISC_FALSE, target, length)); } static isc_result_t -base32_decodestring(const char *cstr, const char base[], isc_buffer_t *target) { +base32_decodestring(const char *cstr, const char base[], isc_boolean_t pad, + isc_buffer_t *target) +{ base32_decode_ctx_t ctx; - base32_decode_init(&ctx, -1, base, target); + base32_decode_init(&ctx, -1, base, pad, target); for (;;) { int c = *cstr++; if (c == '\0') @@ -312,19 +350,26 @@ base32_decodestring(const char *cstr, const char base[], isc_buffer_t *target) { isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target) { - return (base32_decodestring(cstr, base32, target)); + return (base32_decodestring(cstr, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target) { - return (base32_decodestring(cstr, base32hex, target)); + return (base32_decodestring(cstr, base32hex, ISC_TRUE, target)); +} + +isc_result_t +isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target) { + return (base32_decodestring(cstr, base32hex, ISC_FALSE, target)); } static isc_result_t -base32_decoderegion(isc_region_t *source, const char base[], isc_buffer_t *target) { +base32_decoderegion(isc_region_t *source, const char base[], + isc_boolean_t pad, isc_buffer_t *target) +{ base32_decode_ctx_t ctx; - base32_decode_init(&ctx, -1, base, target); + base32_decode_init(&ctx, -1, base, pad, target); while (source->length != 0) { int c = *source->base; RETERR(base32_decode_char(&ctx, c)); @@ -336,12 +381,17 @@ base32_decoderegion(isc_region_t *source, const char base[], isc_buffer_t *targe isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target) { - return (base32_decoderegion(source, base32, target)); + return (base32_decoderegion(source, base32, ISC_TRUE, target)); } isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target) { - return (base32_decoderegion(source, base32hex, target)); + return (base32_decoderegion(source, base32hex, ISC_TRUE, target)); +} + +isc_result_t +isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target) { + return (base32_decoderegion(source, base32hex, ISC_FALSE, target)); } static isc_result_t diff --git a/lib/isc/include/isc/base32.h b/lib/isc/include/isc/base32.h index 978a8db463a..4144d25ebfd 100644 --- a/lib/isc/include/isc/base32.h +++ b/lib/isc/include/isc/base32.h @@ -14,8 +14,6 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: base32.h,v 1.3 2008/09/25 04:02:39 tbox Exp $ */ - #ifndef ISC_BASE32_H #define ISC_BASE32_H 1 @@ -27,6 +25,8 @@ * * Base 32 hex preserves the sort order of data when it is encoded / * decoded. + * + * Base 32 hex "np" is base 32 hex but no padding is produced or accepted. */ #include @@ -44,6 +44,9 @@ isc_base32_totext(isc_region_t *source, int wordlength, isc_result_t isc_base32hex_totext(isc_region_t *source, int wordlength, const char *wordbreak, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_totext(isc_region_t *source, int wordlength, + const char *wordbreak, isc_buffer_t *target); /*!< * \brief Convert data into base32 encoded text. * @@ -69,8 +72,11 @@ isc_result_t isc_base32_decodestring(const char *cstr, isc_buffer_t *target); isc_result_t isc_base32hex_decodestring(const char *cstr, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_decodestring(const char *cstr, isc_buffer_t *target); /*!< - * \brief Decode a null-terminated base32 string. + * \brief Decode a null-terminated string in base32, base32hex, or + * base32hex non-padded. * * Requires: *\li 'cstr' is non-null. @@ -91,8 +97,11 @@ isc_result_t isc_base32_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); isc_result_t isc_base32hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); +isc_result_t +isc_base32hexnp_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length); /*!< - * \brief Convert base32 encoded text from a lexer context into data. + * \brief Convert text encoded in base32, base32hex, or base32hex + * non-padded from a lexer context into data. * * Requires: *\li 'lex' is a valid lexer context @@ -110,8 +119,11 @@ isc_result_t isc_base32_decoderegion(isc_region_t *source, isc_buffer_t *target); isc_result_t isc_base32hex_decoderegion(isc_region_t *source, isc_buffer_t *target); +isc_result_t +isc_base32hexnp_decoderegion(isc_region_t *source, isc_buffer_t *target); /*!< - * \brief Decode a packed (no white space permitted) base32 region. + * \brief Decode a packed (no white space permitted) region in + * base32, base32hex or base32hex non-padded. * * Requires: *\li 'source' is a valid region.