/* * Base64 encoding/decoding (RFC1341) * Copyright (c) 2005-2019, Jouni Malinen * Copyright (c) 2022 Loïc Gomez * * Source: http://w1.fi/cgit/hostap/commit/src/utils/base64.c * Last synchronization date: 2022-03-18 * (c7e6dbdad8ee043a9d7f856502196dbeb65cb4ac hostap commit was then used) * * This software may be distributed under the terms of the BSD license. * See README for more details. */ #include #include #include #include #include "base64.h" static const char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; #define BASE64_PAD 1 #define BASE64_LF 2 static char *base64_gen_encode(const unsigned char *src, size_t len, size_t *out_len, const char *table, int add_pad) { char *out, *pos; const unsigned char *end, *in; size_t olen; int line_len; if (len >= SIZE_MAX / 4) return NULL; olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */ if (add_pad & BASE64_LF) olen += olen / 72; /* line feeds */ olen++; /* nul termination */ if (olen < len) return NULL; /* integer overflow */ out = malloc(olen); if (out == NULL) return NULL; end = src + len; in = src; pos = out; line_len = 0; while (end - in >= 3) { *pos++ = table[(in[0] >> 2) & 0x3f]; *pos++ = table[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3f]; *pos++ = table[(((in[1] & 0x0f) << 2) | (in[2] >> 6)) & 0x3f]; *pos++ = table[in[2] & 0x3f]; in += 3; line_len += 4; if ((add_pad & BASE64_LF) && line_len >= 72) { *pos++ = '\n'; line_len = 0; } } if (end - in) { *pos++ = table[(in[0] >> 2) & 0x3f]; if (end - in == 1) { *pos++ = table[((in[0] & 0x03) << 4) & 0x3f]; if (add_pad & BASE64_PAD) *pos++ = '='; } else { *pos++ = table[(((in[0] & 0x03) << 4) | (in[1] >> 4)) & 0x3f]; *pos++ = table[((in[1] & 0x0f) << 2) & 0x3f]; } if (add_pad & BASE64_PAD) *pos++ = '='; line_len += 4; } if ((add_pad & BASE64_LF) && line_len) *pos++ = '\n'; *pos = '\0'; if (out_len) *out_len = (size_t)(pos - out); return out; } /** * base64_encode - Base64 encode without line feeds * @src: Data to be encoded * @len: Length of the data to be encoded * @out_len: Pointer to output length variable, or %NULL if not used * Returns: Allocated buffer of out_len bytes of encoded data, * or %NULL on failure * * Caller is responsible for freeing the returned buffer. Returned buffer is * nul terminated to make it easier to use as a C string. The nul terminator is * not included in out_len. */ char *base64_encode(const void *src, size_t len, size_t *out_len) { return base64_gen_encode(src, len, out_len, base64_table, BASE64_PAD); }