1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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 */
|