822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington/*
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1998-2001, 2003-2005, 2007, 2009, 2013-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington */
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
3cae549ddb56c52c1f585dabd54da5b9d7edeeb9Automatic Updater/* $Id: base64.c,v 1.34 2009/10/21 23:48:05 tbox Exp $ */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#include <config.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#include <isc/base64.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#include <isc/buffer.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#include <isc/lex.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/string.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington#define RETERR(x) do { \
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence isc_result_t _r = (x); \
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence if (_r != ISC_R_SUCCESS) \
600cfa2ba4c50017581b6c14e3a688a82ecebbe0David Lawrence return (_r); \
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington } while (0)
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*@{*/
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*!
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * These static functions are also present in lib/dns/rdata.c. I'm not
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington * sure where they should go. -- bwelling
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington */
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestatic isc_result_t
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestr_totext(const char *source, isc_buffer_t *target);
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestatic isc_result_t
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencemem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonstatic const char base64[] =
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*@}*/
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonisc_result_t
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonisc_base64_totext(isc_region_t *source, int wordlength,
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrence const char *wordbreak, isc_buffer_t *target)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson{
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington char buf[5];
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson unsigned int loops = 0;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (wordlength < 4)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson wordlength = 4;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
91cd0f93ad34d23e8b09dca337120f64fbe8f0a1Andreas Gustafsson memset(buf, 0, sizeof(buf));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington while (source->length > 2) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington ((source->base[1]>>4)&0x0f)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[2] = base64[((source->base[1]<<2)&0x3c)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington ((source->base[2]>>6)&0x03)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[3] = base64[source->base[2]&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington RETERR(str_totext(buf, target));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_region_consume(source, 3);
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson loops++;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson if (source->length != 0 &&
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson (int)((loops + 1) * 4) >= wordlength)
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington loops = 0;
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafsson RETERR(str_totext(wordbreak, target));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington }
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington }
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington if (source->length == 2) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington ((source->base[1]>>4)&0x0f)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[2] = base64[((source->base[1]<<2)&0x3c)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[3] = '=';
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington RETERR(str_totext(buf, target));
8ec993c774d7c996cb266d0ff5f1282fa3940f09Evan Hunt isc_region_consume(source, 2);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington } else if (source->length == 1) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[2] = buf[3] = '=';
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington RETERR(str_totext(buf, target));
8ec993c774d7c996cb266d0ff5f1282fa3940f09Evan Hunt isc_region_consume(source, 1);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington }
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_SUCCESS);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington}
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson * State of a base64 decoding process in progress.
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson */
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssontypedef struct {
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein int length; /*%< Desired length of binary data or -1 */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_buffer_t *target; /*%< Buffer for resulting binary data */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein int digits; /*%< Number of buffered base64 digits */
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein isc_boolean_t seen_end; /*%< True if "=" end marker seen */
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson int val[4];
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson} base64_decode_ctx_t;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonstatic inline void
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson{
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->digits = 0;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->seen_end = ISC_FALSE;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->length = length;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->target = target;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson}
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonstatic inline isc_result_t
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_char(base64_decode_ctx_t *ctx, int c) {
5b1c7ef35bb495820360182b5192689f33f1cc7dMark Andrews const char *s;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->seen_end)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if ((s = strchr(base64, c)) == NULL)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews ctx->val[ctx->digits++] = (int)(s - base64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->digits == 4) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson int n;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson unsigned char buf[3];
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[0] == 64 || ctx->val[1] == 64)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[2] == 64 && ctx->val[3] != 64)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews /*
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews * Check that bits that should be zero are.
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews */
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0)
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews return (ISC_R_BADBASE64);
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews /*
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews * We don't need to test for ctx->val[2] != 64 as
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews * the bottom two bits of 64 are zero.
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews */
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0)
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews return (ISC_R_BADBASE64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson n = (ctx->val[2] == 64) ? 1 :
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson (ctx->val[3] == 64) ? 2 : 3;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (n != 3) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->seen_end = ISC_TRUE;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[2] == 64)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->val[2] = 0;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[3] == 64)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->val[3] = 0;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson }
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson buf[2] = (ctx->val[2]<<6)|(ctx->val[3]);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson RETERR(mem_tobuffer(ctx->target, buf, n));
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->length >= 0) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (n > ctx->length)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson else
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->length -= n;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson }
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson ctx->digits = 0;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson }
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_SUCCESS);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson}
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonstatic inline isc_result_t
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_finish(base64_decode_ctx_t *ctx) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->length > 0)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_UNEXPECTEDEND);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->digits != 0)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_BADBASE64);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_SUCCESS);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson}
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonisc_result_t
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonisc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson base64_decode_ctx_t ctx;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_textregion_t *tr;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_token_t token;
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington isc_boolean_t eol;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson base64_decode_init(&ctx, length, target);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson while (!ctx.seen_end && (ctx.length != 0)) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson unsigned int i;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington if (length > 0)
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington eol = ISC_FALSE;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington else
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington eol = ISC_TRUE;
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington RETERR(isc_lex_getmastertoken(lexer, &token,
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington isc_tokentype_string, eol));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington if (token.type != isc_tokentype_string)
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington break;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington tr = &token.value.as_textregion;
a2b8bb87775ed6c7cd245cd615fca4529ec18ae0Mark Andrews for (i = 0; i < tr->length; i++)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson RETERR(base64_decode_char(&ctx, tr->base[i]));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington }
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx.length < 0 && !ctx.seen_end)
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_lex_ungettoken(lexer, &token);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson RETERR(base64_decode_finish(&ctx));
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_SUCCESS);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington}
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
9bf765ab3a5203b854d32266e6162e547791383cDavid Lawrenceisc_result_t
734ae1f7c6abafe1f1ca164aad7a3dd01ee82cbdBrian Wellingtonisc_base64_decodestring(const char *cstr, isc_buffer_t *target) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson base64_decode_ctx_t ctx;
9bf765ab3a5203b854d32266e6162e547791383cDavid Lawrence
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson base64_decode_init(&ctx, -1, target);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson for (;;) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson int c = *cstr++;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (c == '\0')
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson break;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson continue;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson RETERR(base64_decode_char(&ctx, c));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence }
3cae549ddb56c52c1f585dabd54da5b9d7edeeb9Automatic Updater RETERR(base64_decode_finish(&ctx));
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson return (ISC_R_SUCCESS);
9bf765ab3a5203b854d32266e6162e547791383cDavid Lawrence}
9bf765ab3a5203b854d32266e6162e547791383cDavid Lawrence
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonstatic isc_result_t
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestr_totext(const char *source, isc_buffer_t *target) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington unsigned int l;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_region_t region;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &region);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington l = strlen(source);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington if (l > region.length)
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_NOSPACE);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(region.base, source, l);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_buffer_add(target, l);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_SUCCESS);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington}
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonstatic isc_result_t
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_region_t tr;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &tr);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington if (length > tr.length)
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_NOSPACE);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(tr.base, base, length);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington isc_buffer_add(target, length);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington return (ISC_R_SUCCESS);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington}