0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * Copyright (C) 1998-2001, 2003-2005, 2007, 2009, 2013-2016 Internet Systems Consortium, Inc. ("ISC")
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/.
3cae549ddb56c52c1f585dabd54da5b9d7edeeb9Automatic Updater/* $Id: base64.c,v 1.34 2009/10/21 23:48:05 tbox Exp $ */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * These static functions are also present in lib/dns/rdata.c. I'm not
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington * sure where they should go. -- bwelling
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestr_totext(const char *source, isc_buffer_t *target);
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencemem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
5fc7ba3e1ac5d72239e9971e0f469dd5796738f9Andreas Gustafssonisc_base64_totext(isc_region_t *source, int wordlength,
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[2] = base64[((source->base[1]<<2)&0x3c)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)|
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[2] = base64[((source->base[1]<<2)&0x3c)];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[0] = base64[(source->base[0]>>2)&0x3f];
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington buf[1] = base64[((source->base[0]<<4)&0x30)];
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson * State of a base64 decoding process in progress.
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 Gustafssonstatic inline void
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_char(base64_decode_ctx_t *ctx, int c) {
5b1c7ef35bb495820360182b5192689f33f1cc7dMark Andrews const char *s;
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[0] == 64 || ctx->val[1] == 64)
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (ctx->val[2] == 64 && ctx->val[3] != 64)
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews * Check that bits that should be zero are.
f5af519ab547bc80c51387529103e4e852a1171eMark Andrews if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0)
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 if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0)
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 RETERR(mem_tobuffer(ctx->target, buf, n));
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafssonbase64_decode_finish(base64_decode_ctx_t *ctx) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonisc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson base64_decode_init(&ctx, length, target);
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson while (!ctx.seen_end && (ctx.length != 0)) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson unsigned int i;
add4043305ca411202ed9cf1929a4179016515ceBrian Wellington RETERR(isc_lex_getmastertoken(lexer, &token,
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson RETERR(base64_decode_char(&ctx, tr->base[i]));
734ae1f7c6abafe1f1ca164aad7a3dd01ee82cbdBrian Wellingtonisc_base64_decodestring(const char *cstr, isc_buffer_t *target) {
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (c == '\0')
2c9c7c5bb5975a18925c30aeb33a26094902f1c1Andreas Gustafsson if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
87cafc5e70f79f2586d067fbdd64f61bbab069d2David Lawrencestr_totext(const char *source, isc_buffer_t *target) {
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellington unsigned int l;
822f6cdabb1edd44472c7a758b5cae71376fa9beBrian Wellingtonmem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {