varnish-cache/vmod/vmod_blob_base64.c
0
/*-
1
 * Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
2
 * All rights reserved.
3
 *
4
 * Authors: Nils Goroll <nils.goroll@uplex.de>
5
 *          Geoffrey Simmons <geoffrey.simmons@uplex.de>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions are met:
11
 * 1. Redistributions of source code must retain the above copyright notice,
12
 *    this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright notice,
14
 *    this list of conditions and the following disclaimer in the documentation
15
 *    and/or other materials provided with the distribution.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
18
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
 * DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
21
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 *
28
 */
29
30
#include "config.h"
31
32
#include "vdef.h"
33
#include "vrt.h"
34
#include "vas.h"
35
36
#include "vmod_blob.h"
37
38
static const struct b64_alphabet {
39
        const char b64[64];
40
        const int8_t i64[256];
41
        const int padding;
42
} b64_alphabet[] = {
43
        [BASE64] = {
44
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
45
                "ghijklmnopqrstuvwxyz0123456789+/",
46
                {
47
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
48
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
49
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
50
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
51
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
52
                        ILL, ILL, ILL,  62, ILL, ILL, ILL,  63, /* +, /    */
53
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
54
                         60,  61, ILL, ILL, ILL, PAD, ILL, ILL, /* 8, 9, = */
55
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
56
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
57
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
58
                         23,  24,  25, ILL, ILL, ILL, ILL, ILL, /* X, Y, Z */
59
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
60
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
61
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
62
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
63
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
64
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
65
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
66
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
67
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
68
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
69
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
70
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
71
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
72
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
73
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
74
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
75
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
76
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
77
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
78
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
79
                },
80
                '='
81
        },
82
        [BASE64URL] = {
83
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
84
                "ghijklmnopqrstuvwxyz0123456789-_",
85
                {
86
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
87
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
88
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
89
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
90
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
91
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -       */
92
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
93
                         60,  61, ILL, ILL, ILL, PAD, ILL, ILL, /* 8, 9, = */
94
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
95
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
96
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
97
                         23,  24,  25, ILL, ILL, ILL, ILL,  63, /* X-Z, _  */
98
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
99
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
100
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
101
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
102
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
103
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
104
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
105
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
106
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
107
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
108
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
109
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
110
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
111
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
112
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
113
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
114
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
115
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
116
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
117
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
118
                },
119
                '='
120
        },
121
        [BASE64URLNOPAD] = {
122
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
123
                "ghijklmnopqrstuvwxyz0123456789-_",
124
                {
125
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
126
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
127
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
128
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
129
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
130
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -       */
131
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
132
                         60,  61, ILL, ILL, ILL, ILL, ILL, ILL, /* 8, 9    */
133
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
134
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
135
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
136
                         23,  24,  25, ILL, ILL, ILL, ILL,  63, /* X-Z, _  */
137
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
138
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
139
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
140
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
141
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
142
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
143
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
144
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
145
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
146
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
147
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
148
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
149
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
150
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
151
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
152
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
153
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
154
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
155
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
156
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
157
                },
158
                0
159
        },
160
        [BASE64CF] = {
161
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
162
                "ghijklmnopqrstuvwxyz0123456789-~",
163
                {
164
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
165
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
166
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
167
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
168
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
169
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -          */
170
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7      */
171
                         60,  61, ILL, ILL, ILL, ILL, ILL, ILL, /* 8, 9       */
172
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G      */
173
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O      */
174
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W      */
175
                         23,  24,  25, ILL, ILL, ILL, ILL, PAD, /* X, Y, Z, _ */
176
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g      */
177
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o      */
178
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w      */
179
                         49,  50,  51, ILL, ILL, ILL,  63, ILL, /* x, y, z,  ~*/
180
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
181
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
182
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
183
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
184
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
185
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
186
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
187
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
188
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
189
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
190
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
191
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
192
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
193
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
194
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
195
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
196
                },
197
                '_'
198
        }
199
};
200
#define base64_l(l)             (((l) << 2) / 3)
201
202
size_t
203 140
base64nopad_encode_l(size_t l)
204
{
205 140
        return (base64_l(l) + 4);
206
}
207
208
size_t
209 396
base64_encode_l(size_t l)
210
{
211 396
        return ((((base64_l(l)) + 3) & ~3) + 1);
212
}
213
214
size_t
215 256
base64_decode_l(size_t l)
216
{
217 256
        return ((l * 3) >> 2);
218
}
219
220
static inline int
221 10148
decode(char *restrict *restrict dest, blob_src_t buf,
222
    blob_len_t buflen, unsigned u, const int n)
223
{
224
        char *d;
225
        int i;
226
227 10148
        if (n <= 1) {
228 0
                errno = EINVAL;
229 0
                return (-1);
230
        }
231 10148
        d = *dest;
232 40236
        for (i = 0; i < n - 1; i++) {
233 30092
                if (d == buf + buflen) {
234 4
                        errno = ENOMEM;
235 4
                        return (-1);
236
                }
237 30088
                *d++ = (u >> 16) & 0xff;
238 30088
                u <<= 8;
239 30088
        }
240 10144
        *dest += d - *dest;
241 10144
        return (1);
242 10148
}
243
244
ssize_t
245 648
base64_encode(const enum encoding enc, const enum case_e kase,
246
    blob_dest_t buf, blob_len_t buflen,
247
    blob_src_t inbuf, blob_len_t inlength)
248
{
249 648
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
250 648
        char *p = buf;
251 648
        const uint8_t *in = (const uint8_t *)inbuf;
252 648
        const uint8_t * const end = in + inlength;
253
254 648
        (void)kase;
255 648
        AN(buf);
256 648
        AN(alpha);
257 648
        if (in == NULL || inlength == 0)
258 400
                return (0);
259
260 992
        if ((enc == BASE64URLNOPAD &&
261 112
            buflen < base64nopad_encode_l(inlength)) ||
262 768
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
263 656
                errno = ENOMEM;
264 656
                return (-1);
265
        }
266
267 13836
        while (end - in >= 3) {
268 13396
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
269 13396
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
270 13396
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
271 13396
                *p++ = alpha->b64[in[2] & 0x3f];
272 13396
                in += 3;
273
        }
274 440
        if (end - in > 0) {
275 376
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
276 376
                if (end - in == 1) {
277 288
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
278 288
                        if (alpha->padding) {
279 212
                                *p++ = alpha->padding;
280 212
                                *p++ = alpha->padding;
281 212
                        }
282 288
                }
283
                else {
284 88
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
285 88
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
286 88
                        if (alpha->padding) {
287 52
                                *p++ = alpha->padding;
288 52
                        }
289
                }
290 376
        }
291 440
        assert(p >= buf);
292 440
        assert(p <= buf + buflen);
293 440
        return (p - buf);
294 456
}
295
296
ssize_t
297 508
base64_decode(const enum encoding dec, blob_dest_t buf,
298
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
299
{
300 508
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
301
        const char *s;
302 508
        char *dest = buf;
303 508
        unsigned u = 0, term = 0;
304 508
        size_t len = SIZE_MAX;
305 508
        int n = 0, i;
306
        char b;
307
308 508
        AN(buf);
309 508
        AN(alpha);
310 508
        AN(strings);
311
312 508
        if (inlen >= 0)
313 188
                len = inlen;
314
315 1152
        for (i = 0; len > 0 && i < strings->n; i++) {
316 732
                s = strings->p[i];
317
318 732
                if (s == NULL)
319 24
                        continue;
320 708
                if (*s && term) {
321 0
                        errno = EINVAL;
322 0
                        return (-1);
323
                }
324 41276
                while (*s && len) {
325 40656
                        b = alpha->i64[(uint8_t)*s];
326 40656
                        s++;
327 40656
                        len--;
328 40656
                        u <<= 6;
329 40656
                        if (b == ILL) {
330 84
                                errno = EINVAL;
331 84
                                return (-1);
332
                        }
333 40572
                        n++;
334 40572
                        if (b == PAD) {
335 240
                                term++;
336 240
                                continue;
337
                        }
338 40332
                        u |= (uint8_t)b;
339 40332
                        if (n == 4) {
340 9952
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
341 4
                                        return (-1);
342 9948
                                n = 0;
343 9948
                        }
344
                }
345 620
        }
346 420
        if (n) {
347 196
                if (n - term != 0)
348 196
                        u <<= (6 * (4 - n));
349 196
                if (decode(&dest, buf, buflen, u, n-term) < 0)
350 0
                        return (-1);
351 196
        }
352
353 420
        return (dest - buf);
354 508
}