summaryrefslogtreecommitdiff
path: root/lib/isc/base32.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/isc/base32.c')
-rw-r--r--lib/isc/base32.c98
1 files changed, 74 insertions, 24 deletions
diff --git a/lib/isc/base32.c b/lib/isc/base32.c
index ad0b0da569e1..2ee99b182426 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