summaryrefslogtreecommitdiff
path: root/src/utilities.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/utilities.h')
-rw-r--r--src/utilities.h88
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 */