int decode_context (char *dst, int *dstlen, const void *src, int srclen) { base64_ctx x; int i; int n; int m; const unsigned char *p = src; if (base64_init (&x) < 0) return (-1); for (i = 0, n = 0; i < srclen; i++) { if (base64_decode_update (&x, dst, &m, p + i, 1) < 0) return (-1); dst += m; n += m; } if (base64_decode_final (&x, dst, &m) < 0) return (-1); if (base64_cleanup (&x) < 0) return (-1); n += m; *dstlen = n; return (0); }
static void test_fuzz_once(struct base64_encode_ctx *encode, struct base64_decode_ctx *decode, size_t size, const uint8_t *input) { size_t base64_len = BASE64_ENCODE_RAW_LENGTH (size); size_t out_len; uint8_t *base64 = xalloc (base64_len + 2); uint8_t *decoded = xalloc (size + 2); *base64++ = 0x12; base64[base64_len] = 0x34; *decoded++ = 0x56; decoded[size] = 0x78; out_len = base64_encode_update(encode, base64, size, input); ASSERT (out_len <= base64_len); out_len += base64_encode_final(encode, base64 + out_len); ASSERT (out_len == base64_len); ASSERT (base64[-1] == 0x12); ASSERT (base64[base64_len] == 0x34); ASSERT(base64_decode_update(decode, &out_len, decoded, base64_len, base64)); ASSERT(base64_decode_final(decode)); ASSERT (out_len == size); ASSERT (decoded[-1] == 0x56); ASSERT (decoded[size] == 0x78); ASSERT(MEMEQ(size, input, decoded)); free (base64 - 1); free (decoded - 1); }
void test_main(void) { ASSERT(BASE64_ENCODE_LENGTH(0) == 0); /* At most 4 bits */ ASSERT(BASE64_ENCODE_LENGTH(1) == 2); /* At most 12 bits */ ASSERT(BASE64_ENCODE_LENGTH(2) == 3); /* At most 20 bits */ ASSERT(BASE64_ENCODE_LENGTH(3) == 4); /* At most 28 bits */ ASSERT(BASE64_ENCODE_LENGTH(4) == 6); /* At most 36 bits */ ASSERT(BASE64_ENCODE_LENGTH(5) == 7); /* At most 44 bits */ ASSERT(BASE64_ENCODE_LENGTH(12) == 16); /* At most 100 bits */ ASSERT(BASE64_ENCODE_LENGTH(13) == 18); /* At most 108 bits */ ASSERT(BASE64_DECODE_LENGTH(0) == 0); /* At most 6 bits */ ASSERT(BASE64_DECODE_LENGTH(1) == 1); /* At most 12 bits */ ASSERT(BASE64_DECODE_LENGTH(2) == 2); /* At most 18 bits */ ASSERT(BASE64_DECODE_LENGTH(3) == 3); /* At most 24 bits */ ASSERT(BASE64_DECODE_LENGTH(4) == 3); /* At most 30 bits */ test_armor(&nettle_base64, LDATA(""), ""); test_armor(&nettle_base64, LDATA("H"), "SA=="); test_armor(&nettle_base64, LDATA("He"), "SGU="); test_armor(&nettle_base64, LDATA("Hel"), "SGVs"); test_armor(&nettle_base64, LDATA("Hell"), "SGVsbA=="); test_armor(&nettle_base64, LDATA("Hello"), "SGVsbG8="); test_armor(&nettle_base64, LDATA("Hello\0"), "SGVsbG8A"); test_armor(&nettle_base64, LDATA("Hello?>>>"), "SGVsbG8/Pj4+"); test_armor(&nettle_base64, LDATA("\xff\xff\xff\xff"), "/////w=="); test_armor(&nettle_base64url, LDATA(""), ""); test_armor(&nettle_base64url, LDATA("H"), "SA=="); test_armor(&nettle_base64url, LDATA("He"), "SGU="); test_armor(&nettle_base64url, LDATA("Hel"), "SGVs"); test_armor(&nettle_base64url, LDATA("Hell"), "SGVsbA=="); test_armor(&nettle_base64url, LDATA("Hello"), "SGVsbG8="); test_armor(&nettle_base64url, LDATA("Hello\0"), "SGVsbG8A"); test_armor(&nettle_base64url, LDATA("Hello?>>>"), "SGVsbG8_Pj4-"); test_armor(&nettle_base64url, LDATA("\xff\xff\xff\xff"), "_____w=="); { /* Test overlapping areas */ uint8_t buffer[] = "Helloxxxx"; struct base64_decode_ctx ctx; size_t dst_length; ASSERT(BASE64_ENCODE_RAW_LENGTH(5) == 8); base64_encode_raw(buffer, 5, buffer); ASSERT(MEMEQ(9, buffer, "SGVsbG8=x")); base64_decode_init(&ctx); dst_length = 0; /* Output parameter only. */ ASSERT(base64_decode_update(&ctx, &dst_length, buffer, 8, buffer)); ASSERT(dst_length == 5); ASSERT(MEMEQ(9, buffer, "HelloG8=x")); } test_fuzz (); }
stl_string base64_decode (const char *line) { stl_string ret; unsigned len = strlen (line); char *res = (char *)malloc (len); struct base64_decode_ctx str; base64_decode_init (&str); base64_decode_update (&str, &len, (uint8_t*)res, len, (uint8_t*)line); base64_decode_final (&str); ret.append (res, len); free (res); return ret; }
/* decodes data and puts the result into result (locally allocated) * The result_size is the return value */ int _gnutls_base64_decode(const uint8_t * data, size_t data_size, gnutls_datum_t * result) { int ret; size_t size; gnutls_datum_t pdata; struct base64_decode_ctx ctx; ret = cpydata(data, data_size, &pdata); if (ret < 0) { gnutls_assert(); return ret; } base64_decode_init(&ctx); size = BASE64_DECODE_LENGTH(data_size); result->data = gnutls_malloc(size); if (result->data == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); ret = base64_decode_update(&ctx, &size, result->data, pdata.size, pdata.data); if (ret == 0) { gnutls_assert(); gnutls_free(result->data); result->data = NULL; ret = GNUTLS_E_PARSING_ERROR; goto cleanup; } ret = base64_decode_final(&ctx); if (ret != 1) return gnutls_assert_val(GNUTLS_E_PARSING_ERROR); result->size = size; ret = size; cleanup: gnutls_free(pdata.data); return ret; }
// Convert string to uint8 array; return outsize size_t str_to_uint8(unsigned char *in, uint8_t *out, size_t insize) { int errU; //update error int errF; //final error size_t outsize; //outgoing decoded bytes struct base64_decode_ctx decoder; //nettle decoder base64_decode_init(&decoder); //init decoder errU = base64_decode_update(&decoder, &outsize, out, insize, in); //decode errF = base64_decode_final(&decoder); //check padding size if (errU == 0) //throw b64 errors err(ERR_B64, "Decode update error"); if (errF == 0) err(ERR_B64, "Decode final error"); return outsize; //return number of bytes written to out }
static int decode_base64(struct nettle_buffer *buffer, unsigned start, unsigned *length) { struct base64_decode_ctx ctx; base64_decode_init(&ctx); /* Decode in place */ if (base64_decode_update(&ctx, length, buffer->contents + start, *length, buffer->contents + start) && base64_decode_final(&ctx)) return 1; else { werror("Invalid base64 date.\n"); return 0; } }
/* NOTE: Decodes the input string in place */ int sexp_transport_iterator_first(struct sexp_iterator *iterator, unsigned length, uint8_t *input) { /* We first base64 decode any transport encoded sexp at the start of * the input. */ unsigned in = 0; unsigned out = 0; while (in < length) switch(input[in]) { case ' ': /* SPC, TAB, LF, CR */ case '\t': case '\n': case '\r': in++; break; case ';': /* Comments */ while (++in < length && input[in] != '\n') ; break; case '{': { /* Found transport encoding */ struct base64_decode_ctx ctx; unsigned coded_length; unsigned end; for (end = ++in; end < length && input[end] != '}'; end++) ; if (end == length) return 0; base64_decode_init(&ctx); coded_length = end - in; if (base64_decode_update(&ctx, &coded_length, input + out, coded_length, input + in) && base64_decode_final(&ctx)) { out += coded_length; in = end + 1; } else return 0; break; } default: /* Expression isn't in transport encoding. Rest of the input * should be in canonical encoding. */ goto transport_done; } transport_done: /* Here, we have two, possibly empty, input parts in canonical * encoding: * * 0...out-1, in...length -1 * * If the input was already in canonical encoding, out = 0 and in = * amount of leading space. * * If all input was in transport encoding, in == length. */ if (!out) { input += in; length -= in; } else if (in == length) length = out; else if (out == in) /* Unusual case, nothing happens */ ; else { /* Both parts non-empty */ assert(out < in); memmove(input + out, input + in, length - in); length -= (in - out); } return sexp_iterator_first(iterator, length, input); }