1 /*
2 * Copyright (C) 2018 Yubico AB - See COPYING
3 */
4
5 #include <openssl/bio.h>
6 #include <openssl/evp.h>
7 #include <limits.h>
8 #include <stdint.h>
9 #include <string.h>
10
11 #include "b64.h"
12
b64_encode(const void * ptr,size_t len,char ** out)13 int b64_encode(const void *ptr, size_t len, char **out) {
14 BIO *bio_b64 = NULL;
15 BIO *bio_mem = NULL;
16 char *b64_ptr = NULL;
17 long b64_len;
18 int n;
19 int ok = 0;
20
21 if (ptr == NULL || out == NULL || len > INT_MAX)
22 return (0);
23
24 *out = NULL;
25
26 bio_b64 = BIO_new(BIO_f_base64());
27 if (bio_b64 == NULL)
28 goto fail;
29
30 bio_mem = BIO_new(BIO_s_mem());
31 if (bio_mem == NULL)
32 goto fail;
33
34 BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
35 BIO_push(bio_b64, bio_mem);
36
37 n = BIO_write(bio_b64, ptr, (int) len);
38 if (n < 0 || (size_t) n != len)
39 goto fail;
40
41 if (BIO_flush(bio_b64) < 0)
42 goto fail;
43
44 b64_len = BIO_get_mem_data(bio_b64, &b64_ptr);
45 if (b64_len < 0 || (size_t) b64_len == SIZE_MAX || b64_ptr == NULL)
46 goto fail;
47
48 *out = calloc(1, (size_t) b64_len + 1);
49 if (*out == NULL)
50 goto fail;
51
52 memcpy(*out, b64_ptr, (size_t) b64_len);
53 ok = 1;
54
55 fail:
56 BIO_free(bio_b64);
57 BIO_free(bio_mem);
58
59 return (ok);
60 }
61
b64_decode(const char * in,void ** ptr,size_t * len)62 int b64_decode(const char *in, void **ptr, size_t *len) {
63 BIO *bio_mem = NULL;
64 BIO *bio_b64 = NULL;
65 size_t alloc_len;
66 int n;
67 int ok = 0;
68
69 if (in == NULL || ptr == NULL || len == NULL || strlen(in) > INT_MAX)
70 return (0);
71
72 *ptr = NULL;
73 *len = 0;
74
75 bio_b64 = BIO_new(BIO_f_base64());
76 if (bio_b64 == NULL)
77 goto fail;
78
79 bio_mem = BIO_new_mem_buf((const void *) in, -1);
80 if (bio_mem == NULL)
81 goto fail;
82
83 BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
84 BIO_push(bio_b64, bio_mem);
85
86 alloc_len = strlen(in);
87 *ptr = calloc(1, alloc_len);
88 if (*ptr == NULL)
89 goto fail;
90
91 n = BIO_read(bio_b64, *ptr, (int) alloc_len);
92 if (n < 0 || BIO_eof(bio_b64) == 0)
93 goto fail;
94
95 *len = (size_t) n;
96 ok = 1;
97
98 fail:
99 BIO_free(bio_b64);
100 BIO_free(bio_mem);
101
102 if (!ok) {
103 free(*ptr);
104 *ptr = NULL;
105 *len = 0;
106 }
107
108 return (ok);
109 }
110