diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2020-11-27 19:28:50 +0100 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2021-05-11 00:14:27 +0200 |
commit | b021d3c7188a5705a858144c0bdd8e6a962fc677 (patch) | |
tree | 3f07247fa0c6f8ce6590a776c38fc2de87a58b80 /src/utilities.h | |
parent | 6068d8fd74218213aadc5d57f246c87907c77fc8 (diff) |
Add a base64 encoder and decoder
Diffstat (limited to 'src/utilities.h')
-rw-r--r-- | src/utilities.h | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/utilities.h b/src/utilities.h new file mode 100644 index 0000000..b5b91f9 --- /dev/null +++ b/src/utilities.h @@ -0,0 +1,88 @@ +#ifndef H_UTILITIES_INCLUDED +#define H_UTILITIES_INCLUDED + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <libguile.h> +#include <assert.h> +#include <string.h> +#include <stdlib.h> +#include <nettle/base64.h> +#include <nettle/ecc.h> +#include <nettle/ecdsa.h> +#include <nettle/rsa.h> +#include <nettle/ecc-curve.h> +#include <nettle/yarrow.h> +#include <gettext.h> +#include <stdio.h> +#include <unistd.h> + +/* Return a base64 encoding of some raw data. */ +static SCM wrap_bytevector (size_t length, uint8_t * data); + +/* Decode a base64 of binary data. */ +static uint8_t *get_as_bytevector (SCM data, size_t *size, int throw_if_fail); + +static inline SCM +wrap_bytevector (size_t length, uint8_t * data) +{ + char *head; + char tail[BASE64_ENCODE_FINAL_LENGTH]; + size_t head_size, tail_size; + char *full; + struct base64_encode_ctx encoder; + SCM ret; + base64url_encode_init (&encoder); + scm_dynwind_begin (0); + head = scm_malloc (BASE64_ENCODE_LENGTH (length)); + scm_dynwind_free (head); + head_size = base64_encode_update (&encoder, head, length, data); + tail_size = base64_encode_final (&encoder, tail); + while (tail_size != 0 && tail[tail_size - 1] == '=') + { + tail_size--; + } + full = scm_malloc (head_size + tail_size); + memcpy (full, head, head_size); + memcpy (full + head_size, tail, tail_size); + ret = scm_from_utf8_stringn (full, head_size + tail_size); + scm_dynwind_end (); + return ret; +} + +static inline uint8_t * +get_as_bytevector (SCM data, size_t *size, int throw_if_fail) +{ + uint8_t *ret = NULL; + size_t data_length; + char *data_str = NULL; + struct base64_decode_ctx decoder; + int ok = 1; + if (!scm_is_bytevector (data) && !throw_if_fail) + { + return NULL; + } + base64url_decode_init (&decoder); + scm_dynwind_begin (0); + data_str = scm_to_utf8_stringn (data, &data_length); + scm_dynwind_free (data_str); + ret = scm_malloc (BASE64_DECODE_LENGTH (data_length)); + /* Not protected! Nothing will throw until scm_dynwind_end. */ + ok = base64_decode_update (&decoder, size, ret, data_length, data_str); + scm_dynwind_end (); + if (!ok) + { + ret = NULL; + if (throw_if_fail) + { + SCM base64_decoding_error = + scm_from_utf8_symbol ("base64-decoding-error"); + scm_throw (base64_decoding_error, scm_list_1 (data)); + } + } + return ret; +} + +#endif /* not H_UTILITIES_INCLUDED */ |