diff options
author | Vincent Sanders <vince@kyllikki.org> | 2020-02-21 19:52:14 +0000 |
---|---|---|
committer | Vincent Sanders <vince@kyllikki.org> | 2020-02-21 19:52:14 +0000 |
commit | b7199a77aca01f85a3359737cd4e6c73c29bd82a (patch) | |
tree | 2b2cc48e145ef725e967886570623dd305402cd7 /src/base64.c | |
parent | 28a80ecdf8588afe5ee521acf3ba48d81aae7373 (diff) | |
download | libnsutils-b7199a77aca01f85a3359737cd4e6c73c29bd82a.tar.gz libnsutils-b7199a77aca01f85a3359737cd4e6c73c29bd82a.tar.bz2 |
extend base64 api with url safe versions
Diffstat (limited to 'src/base64.c')
-rw-r--r-- | src/base64.c | 219 |
1 files changed, 193 insertions, 26 deletions
diff --git a/src/base64.c b/src/base64.c index c11364f..79909ea 100644 --- a/src/base64.c +++ b/src/base64.c @@ -21,22 +21,112 @@ #include "nsutils/base64.h" -static uint8_t decoding_table[256]; -static uint8_t encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', - 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', - 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', - 'w', 'x', 'y', 'z', '0', '1', '2', '3', - '4', '5', '6', '7', '8', '9', '+', '/'}; +static const uint8_t b64_decoding_table[256] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 8 - F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 10 - 17 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 18 - 1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 20 - 27 */ + 0xff, 0xff, 0xff, 62, 0xff, 0xff, 0xff, 63, /* 28 - 2F */ + 52, 53, 54, 55, 56, 57, 58, 59, /* 30 - 37 */ + 60, 61, 0xff, 0xff, 0xff, 64, 0xff, 0xff, /* 38 - 3F */ + 0xff, 0, 1, 2, 3, 4, 5, 6, /* 40 - 47 */ + 7, 8, 9, 10, 11, 12, 13, 14, /* 48 - 4F */ + 15, 16, 17, 18, 19, 20, 21, 22, /* 50 - 57 */ + 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 0xff, /* 58 - 5F */ + 0xff, 26, 27, 28, 29, 30, 31, 32, /* 60 - 67 */ + 33, 34, 35, 36, 37, 38, 39, 40, /* 68 - 6F */ + 41, 42, 43, 44, 45, 46, 47, 48, /* 70 - 77 */ + 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff, /* 78 - 7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 - 87 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 8F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 90 - 97 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 98 - 9F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* A0 - A7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* A8 - AF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* B0 - B7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* B8 - BF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* C0 - C7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* C8 - CF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* D0 - D7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* D8 - DF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* E0 - E7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* E8 - EF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* F0 - F7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* F8 - FF */ +}; +static const uint8_t b64_encoding_table[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '+', '/'}; +static const uint8_t b64url_decoding_table[256] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0 - 7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 8 - F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 10 - 17 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 18 - 1F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 20 - 27 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 62, 0xff, 0xff, /* 28 - 2F */ + 52, 53, 54, 55, 56, 57, 58, 59, /* 30 - 37 */ + 60, 61, 0xff, 0xff, 0xff, 64, 0xff, 0xff, /* 38 - 3F */ + 0xff, 0, 1, 2, 3, 4, 5, 6, /* 40 - 47 */ + 7, 8, 9, 10, 11, 12, 13, 14, /* 48 - 4F */ + 15, 16, 17, 18, 19, 20, 21, 22, /* 50 - 57 */ + 23, 24, 25, 0xff, 0xff, 0xff, 0xff, 63, /* 58 - 5F */ + 0xff, 26, 27, 28, 29, 30, 31, 32, /* 60 - 67 */ + 33, 34, 35, 36, 37, 38, 39, 40, /* 68 - 6F */ + 41, 42, 43, 44, 45, 46, 47, 48, /* 70 - 77 */ + 49, 50, 51, 0xff, 0xff, 0xff, 0xff, 0xff, /* 78 - 7F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 80 - 87 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 88 - 8F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 90 - 97 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 98 - 9F */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* A0 - A7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* A8 - AF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* B0 - B7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* B8 - BF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* C0 - C7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* C8 - CF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* D0 - D7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* D8 - DF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* E0 - E7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* E8 - EF */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* F0 - F7 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* F8 - FF */ +}; +static const uint8_t b64url_encoding_table[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', + 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', + 'w', 'x', 'y', 'z', '0', '1', '2', '3', + '4', '5', '6', '7', '8', '9', '-', '_'}; static unsigned int mod_table[] = {0, 2, 1}; -/* exported interface documented in nsutils/base64.h */ -nsuerror nsu_base64_encode_alloc(const uint8_t *input, - size_t input_length, - uint8_t **output, - size_t *output_length) + +/** + * Base 64 encode data using a given encoding table. + * + * allocate a buffer and encode source data into it using the Base64 encoding. + * + * \param input The source data to encode. + * \param input_length The length of the source data. + * \param output The buffer to recive data into, the caller must free. + * \param output_length The length of data placed in \a output + * \return NSERROR_OK on success and \a output updated else error code. + */ +static nsuerror +table_encode_alloc(const uint8_t *encoding_table, + const uint8_t *input, + size_t input_length, + uint8_t **output, + size_t *output_length) { uint8_t *encoded; size_t encoded_len; @@ -74,14 +164,62 @@ nsuerror nsu_base64_encode_alloc(const uint8_t *input, return NSUERROR_OK; } +/* + * standard base64 encoding + * + * exported interface documented in nsutils/base64.h + */ +nsuerror +nsu_base64_encode_alloc(const uint8_t *input, + size_t input_length, + uint8_t **output, + size_t *output_length) +{ + return table_encode_alloc(b64_encoding_table, + input, + input_length, + output, + output_length); +} -/* exported interface documented in nsutils/base64.h */ -nsuerror nsu_base64_decode_alloc(const uint8_t *input, +/* + * url base64 encoding + * + * exported interface documented in nsutils/base64.h + */ +nsuerror +nsu_base64_encode_alloc_url(const uint8_t *input, size_t input_length, uint8_t **output, size_t *output_length) { - static bool decode_initialised = false; + return table_encode_alloc(b64url_encoding_table, + input, + input_length, + output, + output_length); +} + + +/** + * Base 64 decode data with a given decoding table. + * + * Allocate a buffer and decode source data into it using the Base64 decoding + * table. + * + * \param input The source data to decode. + * \param input_length The length of the source data. + * \param output The buffer to recive data into, the caller must free. + * \param output_length The length of data placed in \a output + * \return NSERROR_OK on success and \a output updated else error code. + */ +static nsuerror +base64_decode_alloc(const uint8_t *decoding_table, + const uint8_t *input, + size_t input_length, + uint8_t **output, + size_t *output_length) +{ uint8_t *decoded; size_t decoded_len; size_t idx; @@ -89,15 +227,6 @@ nsuerror nsu_base64_decode_alloc(const uint8_t *input, uint8_t sextet[4]; int sextet_idx; - if (!decode_initialised) { - memset(decoding_table, 0xff, sizeof(decoding_table)); - for (idx = 0; idx < 64; idx++) { - decoding_table[encoding_table[idx]] = idx; - } - decoding_table['='] = 64; - decode_initialised = true; - } - decoded_len = ((input_length + 3) / 4) * 3; if (input[input_length - 1] == '=') (decoded_len)--; if (input[input_length - 2] == '=') (decoded_len)--; @@ -179,3 +308,41 @@ nsuerror nsu_base64_decode_alloc(const uint8_t *input, return NSUERROR_OK; } + + +/* + * standard base64 decoding + * + * exported interface documented in nsutils/base64.h + */ +nsuerror +nsu_base64_decode_alloc(const uint8_t *input, + size_t input_length, + uint8_t **output, + size_t *output_length) +{ + return base64_decode_alloc(b64_decoding_table, + input, + input_length, + output, + output_length); +} + + +/* + * standard base64 decoding + * + * exported interface documented in nsutils/base64.h + */ +nsuerror +nsu_base64_decode_alloc_url(const uint8_t *input, + size_t input_length, + uint8_t **output, + size_t *output_length) +{ + return base64_decode_alloc(b64url_decoding_table, + input, + input_length, + output, + output_length); +} |