Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/tools/base64.c
39536 views
1
/*
2
* Copyright (c) 2018 Yubico AB. All rights reserved.
3
* Use of this source code is governed by a BSD-style
4
* license that can be found in the LICENSE file.
5
* SPDX-License-Identifier: BSD-2-Clause
6
*/
7
8
#include <openssl/bio.h>
9
#include <openssl/evp.h>
10
11
#include <limits.h>
12
#include <stdint.h>
13
#include <string.h>
14
15
#include "../openbsd-compat/openbsd-compat.h"
16
#include "extern.h"
17
18
int
19
base64_encode(const void *ptr, size_t len, char **out)
20
{
21
BIO *bio_b64 = NULL;
22
BIO *bio_mem = NULL;
23
char *b64_ptr = NULL;
24
long b64_len;
25
int n;
26
int ok = -1;
27
28
if (ptr == NULL || out == NULL || len > INT_MAX)
29
return (-1);
30
31
*out = NULL;
32
33
if ((bio_b64 = BIO_new(BIO_f_base64())) == NULL)
34
goto fail;
35
if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
36
goto fail;
37
38
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
39
BIO_push(bio_b64, bio_mem);
40
41
n = BIO_write(bio_b64, ptr, (int)len);
42
if (n < 0 || (size_t)n != len)
43
goto fail;
44
45
if (BIO_flush(bio_b64) < 0)
46
goto fail;
47
48
b64_len = BIO_get_mem_data(bio_b64, &b64_ptr);
49
if (b64_len < 0 || (size_t)b64_len == SIZE_MAX || b64_ptr == NULL)
50
goto fail;
51
if ((*out = calloc(1, (size_t)b64_len + 1)) == NULL)
52
goto fail;
53
54
memcpy(*out, b64_ptr, (size_t)b64_len);
55
ok = 0;
56
57
fail:
58
BIO_free(bio_b64);
59
BIO_free(bio_mem);
60
61
return (ok);
62
}
63
64
int
65
base64_decode(const char *in, void **ptr, size_t *len)
66
{
67
BIO *bio_mem = NULL;
68
BIO *bio_b64 = NULL;
69
size_t alloc_len;
70
int n;
71
int ok = -1;
72
73
if (in == NULL || ptr == NULL || len == NULL || strlen(in) > INT_MAX)
74
return (-1);
75
76
*ptr = NULL;
77
*len = 0;
78
79
if ((bio_b64 = BIO_new(BIO_f_base64())) == NULL)
80
goto fail;
81
if ((bio_mem = BIO_new_mem_buf((const void *)in, -1)) == NULL)
82
goto fail;
83
84
BIO_set_flags(bio_b64, BIO_FLAGS_BASE64_NO_NL);
85
BIO_push(bio_b64, bio_mem);
86
87
alloc_len = strlen(in);
88
if ((*ptr = calloc(1, alloc_len)) == 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 = 0;
97
98
fail:
99
BIO_free(bio_b64);
100
BIO_free(bio_mem);
101
102
if (ok < 0) {
103
free(*ptr);
104
*ptr = NULL;
105
*len = 0;
106
}
107
108
return (ok);
109
}
110
111
int
112
base64_read(FILE *f, struct blob *out)
113
{
114
char *line = NULL;
115
size_t linesize = 0;
116
ssize_t n;
117
118
out->ptr = NULL;
119
out->len = 0;
120
121
if ((n = getline(&line, &linesize, f)) <= 0 ||
122
(size_t)n != strlen(line)) {
123
free(line); /* XXX should be free'd _even_ if getline() fails */
124
return (-1);
125
}
126
127
if (base64_decode(line, (void **)&out->ptr, &out->len) < 0) {
128
free(line);
129
return (-1);
130
}
131
132
free(line);
133
134
return (0);
135
}
136
137