mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 14:35:26 +00:00
433. [func] isc_base64_decodestring() now accepts newlines
within the base64 data. This makes it possible to break up the key data in a trusted-keys statement into multiple lines. [RT #284]
This commit is contained in:
5
CHANGES
5
CHANGES
@@ -1,4 +1,9 @@
|
|||||||
|
|
||||||
|
433. [func] isc_base64_decodestring() now accepts newlines
|
||||||
|
within the base64 data. This makes it possible
|
||||||
|
to break up the key data in a "trusted-keys"
|
||||||
|
statement into multiple lines. [RT #284]
|
||||||
|
|
||||||
432. [func] Added refresh/retry jitter. This is currently
|
432. [func] Added refresh/retry jitter. This is currently
|
||||||
hard-coded to be no more than 20% of the SOA
|
hard-coded to be no more than 20% of the SOA
|
||||||
provided time or 10 minutes, whichever is less.
|
provided time or 10 minutes, whichever is less.
|
||||||
|
164
lib/isc/base64.c
164
lib/isc/base64.c
@@ -15,7 +15,7 @@
|
|||||||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: base64.c,v 1.18 2000/08/01 01:29:14 tale Exp $ */
|
/* $Id: base64.c,v 1.19 2000/09/08 00:34:21 gson Exp $ */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
@@ -94,20 +94,86 @@ isc_base64_totext(isc_region_t *source, int wordlength,
|
|||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* State of a base64 decoding process in progress.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int length; /* Desired length of binary data or -1 */
|
||||||
|
isc_buffer_t *target; /* Buffer for resulting binary data */
|
||||||
|
int digits; /* Number of buffered base64 digits */
|
||||||
|
isc_boolean_t seen_end; /* True if "=" end marker seen */
|
||||||
|
int val[4];
|
||||||
|
} base64_decode_ctx_t;
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target)
|
||||||
|
{
|
||||||
|
ctx->digits = 0;
|
||||||
|
ctx->seen_end = ISC_FALSE;
|
||||||
|
ctx->length = length;
|
||||||
|
ctx->target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline isc_result_t
|
||||||
|
base64_decode_char(base64_decode_ctx_t *ctx, int c) {
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
if (ctx->seen_end)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
if ((s = strchr(base64, c)) == NULL)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
ctx->val[ctx->digits++] = s - base64;
|
||||||
|
if (ctx->digits == 4) {
|
||||||
|
int n;
|
||||||
|
unsigned char buf[3];
|
||||||
|
if (ctx->val[0] == 64 || ctx->val[1] == 64)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
if (ctx->val[2] == 64 && ctx->val[3] != 64)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
n = (ctx->val[2] == 64) ? 1 :
|
||||||
|
(ctx->val[3] == 64) ? 2 : 3;
|
||||||
|
if (n != 3) {
|
||||||
|
ctx->seen_end = ISC_TRUE;
|
||||||
|
if (ctx->val[2] == 64)
|
||||||
|
ctx->val[2] = 0;
|
||||||
|
if (ctx->val[3] == 64)
|
||||||
|
ctx->val[3] = 0;
|
||||||
|
}
|
||||||
|
buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4);
|
||||||
|
buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2);
|
||||||
|
buf[2] = (ctx->val[2]<<6)|(ctx->val[3]);
|
||||||
|
RETERR(mem_tobuffer(ctx->target, buf, n));
|
||||||
|
if (ctx->length >= 0) {
|
||||||
|
if (n > ctx->length)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
else
|
||||||
|
ctx->length -= n;
|
||||||
|
}
|
||||||
|
ctx->digits = 0;
|
||||||
|
}
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline isc_result_t
|
||||||
|
base64_decode_finish(base64_decode_ctx_t *ctx) {
|
||||||
|
if (ctx->length > 0)
|
||||||
|
return (ISC_R_UNEXPECTEDEND);
|
||||||
|
if (ctx->digits != 0)
|
||||||
|
return (ISC_R_BADBASE64);
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
|
isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
|
||||||
int digits = 0;
|
base64_decode_ctx_t ctx;
|
||||||
isc_textregion_t *tr;
|
isc_textregion_t *tr;
|
||||||
int val[4];
|
|
||||||
unsigned char buf[3];
|
|
||||||
int seen_end = 0;
|
|
||||||
unsigned int i;
|
|
||||||
isc_token_t token;
|
isc_token_t token;
|
||||||
char *s;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
|
base64_decode_init(&ctx, length, target);
|
||||||
|
|
||||||
|
while (!ctx.seen_end && (ctx.length != 0)) {
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
while (!seen_end && (length != 0)) {
|
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
RETERR(gettoken(lexer, &token, isc_tokentype_string,
|
RETERR(gettoken(lexer, &token, isc_tokentype_string,
|
||||||
ISC_FALSE));
|
ISC_FALSE));
|
||||||
@@ -117,82 +183,34 @@ isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
|
|||||||
if (token.type != isc_tokentype_string)
|
if (token.type != isc_tokentype_string)
|
||||||
break;
|
break;
|
||||||
tr = &token.value.as_textregion;
|
tr = &token.value.as_textregion;
|
||||||
for (i = 0 ;i < tr->length; i++) {
|
for (i = 0 ;i < tr->length; i++)
|
||||||
if (seen_end)
|
RETERR(base64_decode_char(&ctx, tr->base[i]));
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
if ((s = strchr(base64, tr->base[i])) == NULL)
|
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
val[digits++] = s - base64;
|
|
||||||
if (digits == 4) {
|
|
||||||
if (val[0] == 64 || val[1] == 64)
|
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
if (val[2] == 64 && val[3] != 64)
|
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
n = (val[2] == 64) ? 1 :
|
|
||||||
(val[3] == 64) ? 2 : 3;
|
|
||||||
if (n != 3) {
|
|
||||||
seen_end = 1;
|
|
||||||
if (val[2] == 64)
|
|
||||||
val[2] = 0;
|
|
||||||
if (val[3] == 64)
|
|
||||||
val[3] = 0;
|
|
||||||
}
|
|
||||||
buf[0] = (val[0]<<2)|(val[1]>>4);
|
|
||||||
buf[1] = (val[1]<<4)|(val[2]>>2);
|
|
||||||
buf[2] = (val[2]<<6)|(val[3]);
|
|
||||||
RETERR(mem_tobuffer(target, buf, n));
|
|
||||||
if (length >= 0) {
|
|
||||||
if (n > length)
|
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
else
|
|
||||||
length -= n;
|
|
||||||
}
|
|
||||||
digits = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (length < 0 && !seen_end)
|
if (ctx.length < 0 && !ctx.seen_end)
|
||||||
isc_lex_ungettoken(lexer, &token);
|
isc_lex_ungettoken(lexer, &token);
|
||||||
if (length > 0)
|
RETERR(base64_decode_finish(&ctx));
|
||||||
return (ISC_R_UNEXPECTEDEND);
|
|
||||||
if (digits != 0)
|
|
||||||
return (ISC_R_BADBASE64);
|
|
||||||
return (ISC_R_SUCCESS);
|
return (ISC_R_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
isc_base64_decodestring(isc_mem_t *mctx, char *cstr, isc_buffer_t *target) {
|
isc_base64_decodestring(isc_mem_t *mctx, char *cstr, isc_buffer_t *target) {
|
||||||
isc_result_t result;
|
base64_decode_ctx_t ctx;
|
||||||
isc_buffer_t source;
|
|
||||||
isc_lex_t *lex = NULL;
|
|
||||||
isc_boolean_t isopen = ISC_FALSE;
|
|
||||||
|
|
||||||
REQUIRE(mctx != NULL);
|
UNUSED(mctx);
|
||||||
REQUIRE(cstr != NULL);
|
|
||||||
REQUIRE(ISC_BUFFER_VALID(target));
|
|
||||||
|
|
||||||
isc_buffer_init(&source, cstr, strlen(cstr));
|
base64_decode_init(&ctx, -1, target);
|
||||||
isc_buffer_add(&source, strlen(cstr));
|
for (;;) {
|
||||||
|
int c = *cstr++;
|
||||||
result = isc_lex_create(mctx, 256, &lex);
|
if (c == '\0')
|
||||||
|
break;
|
||||||
if (result == ISC_R_SUCCESS)
|
if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
|
||||||
result = isc_lex_openbuffer(lex, &source);
|
continue;
|
||||||
|
RETERR(base64_decode_char(&ctx, c));
|
||||||
if (result == ISC_R_SUCCESS) {
|
|
||||||
isopen = ISC_TRUE;
|
|
||||||
result = isc_base64_tobuffer(lex, target, -1);
|
|
||||||
}
|
}
|
||||||
|
RETERR(base64_decode_finish(&ctx));
|
||||||
if (isopen)
|
return (ISC_R_SUCCESS);
|
||||||
(void)isc_lex_close(lex);
|
|
||||||
if (lex != NULL)
|
|
||||||
isc_lex_destroy(&lex);
|
|
||||||
|
|
||||||
return (result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
str_totext(const char *source, isc_buffer_t *target) {
|
str_totext(const char *source, isc_buffer_t *target) {
|
||||||
unsigned int l;
|
unsigned int l;
|
||||||
|
Reference in New Issue
Block a user