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 560
base64nopad_encode_l(size_t l)
204
{
205 560
        return (base64_l(l) + 4);
206
}
207
208
size_t
209 1584
base64_encode_l(size_t l)
210
{
211 1584
        return ((((base64_l(l)) + 3) & ~3) + 1);
212
}
213
214
size_t
215 1024
base64_decode_l(size_t l)
216
{
217 1024
        return ((l * 3) >> 2);
218
}
219
220
static inline int
221 40592
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 40592
        if (n <= 1) {
228 0
                errno = EINVAL;
229 0
                return (-1);
230
        }
231 40592
        d = *dest;
232 160944
        for (i = 0; i < n - 1; i++) {
233 120368
                if (d == buf + buflen) {
234 16
                        errno = ENOMEM;
235 16
                        return (-1);
236
                }
237 120352
                *d++ = (u >> 16) & 0xff;
238 120352
                u <<= 8;
239 120352
        }
240 40576
        *dest += d - *dest;
241 40576
        return (1);
242 40592
}
243
244
ssize_t
245 2592
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 2592
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
250 2592
        char *p = buf;
251 2592
        const uint8_t *in = (const uint8_t *)inbuf;
252 2592
        const uint8_t * const end = in + inlength;
253
254 2592
        (void)kase;
255 2592
        AN(buf);
256 2592
        AN(alpha);
257 2592
        if (in == NULL || inlength == 0)
258 1600
                return (0);
259
260 3968
        if ((enc == BASE64URLNOPAD &&
261 448
            buflen < base64nopad_encode_l(inlength)) ||
262 3072
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
263 2624
                errno = ENOMEM;
264 2624
                return (-1);
265
        }
266
267 55344
        while (end - in >= 3) {
268 53584
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
269 53584
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
270 53584
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
271 53584
                *p++ = alpha->b64[in[2] & 0x3f];
272 53584
                in += 3;
273
        }
274 1760
        if (end - in > 0) {
275 1504
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
276 1504
                if (end - in == 1) {
277 1152
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
278 1152
                        if (alpha->padding) {
279 848
                                *p++ = alpha->padding;
280 848
                                *p++ = alpha->padding;
281 848
                        }
282 1152
                }
283
                else {
284 352
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
285 352
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
286 352
                        if (alpha->padding) {
287 208
                                *p++ = alpha->padding;
288 208
                        }
289
                }
290 1504
        }
291 1760
        assert(p >= buf);
292 1760
        assert(p <= buf + buflen);
293 1760
        return (p - buf);
294 1824
}
295
296
ssize_t
297 2032
base64_decode(const enum encoding dec, blob_dest_t buf,
298
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
299
{
300 2032
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
301
        const char *s;
302 2032
        char *dest = buf;
303 2032
        unsigned u = 0, term = 0;
304 2032
        size_t len = SIZE_MAX;
305 2032
        int n = 0, i;
306
        char b;
307
308 2032
        AN(buf);
309 2032
        AN(alpha);
310 2032
        AN(strings);
311
312 2032
        if (inlen >= 0)
313 752
                len = inlen;
314
315 4608
        for (i = 0; len > 0 && i < strings->n; i++) {
316 2928
                s = strings->p[i];
317
318 2928
                if (s == NULL)
319 96
                        continue;
320 2832
                if (*s && term) {
321 0
                        errno = EINVAL;
322 0
                        return (-1);
323
                }
324 165104
                while (*s && len) {
325 162624
                        b = alpha->i64[(uint8_t)*s];
326 162624
                        s++;
327 162624
                        len--;
328 162624
                        u <<= 6;
329 162624
                        if (b == ILL) {
330 336
                                errno = EINVAL;
331 336
                                return (-1);
332
                        }
333 162288
                        n++;
334 162288
                        if (b == PAD) {
335 960
                                term++;
336 960
                                continue;
337
                        }
338 161328
                        u |= (uint8_t)b;
339 161328
                        if (n == 4) {
340 39808
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
341 16
                                        return (-1);
342 39792
                                n = 0;
343 39792
                        }
344
                }
345 2480
        }
346 1680
        if (n) {
347 784
                if (n - term != 0)
348 784
                        u <<= (6 * (4 - n));
349 784
                if (decode(&dest, buf, buflen, u, n-term) < 0)
350 0
                        return (-1);
351 784
        }
352
353 1680
        return (dest - buf);
354 2032
}