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 35
base64nopad_encode_l(size_t l)
204
{
205 35
        return (base64_l(l) + 4);
206
}
207
208
size_t
209 99
base64_encode_l(size_t l)
210
{
211 99
        return ((((base64_l(l)) + 3) & ~3) + 1);
212
}
213
214
size_t
215 64
base64_decode_l(size_t l)
216
{
217 64
        return ((l * 3) >> 2);
218
}
219
220
static inline int
221 2537
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 2537
        if (n <= 1) {
228 0
                errno = EINVAL;
229 0
                return (-1);
230
        }
231 2537
        d = *dest;
232 10059
        for (i = 0; i < n - 1; i++) {
233 7523
                if (d == buf + buflen) {
234 1
                        errno = ENOMEM;
235 1
                        return (-1);
236
                }
237 7522
                *d++ = (u >> 16) & 0xff;
238 7522
                u <<= 8;
239 7522
        }
240 2536
        *dest += d - *dest;
241 2536
        return (1);
242 2537
}
243
244
ssize_t
245 162
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 162
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
250 162
        char *p = buf;
251 162
        const uint8_t *in = (const uint8_t *)inbuf;
252 162
        const uint8_t * const end = in + inlength;
253
254 162
        (void)kase;
255 162
        AN(buf);
256 162
        AN(alpha);
257 162
        if (in == NULL || inlength == 0)
258 100
                return (0);
259
260 248
        if ((enc == BASE64URLNOPAD &&
261 28
            buflen < base64nopad_encode_l(inlength)) ||
262 192
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
263 164
                errno = ENOMEM;
264 164
                return (-1);
265
        }
266
267 3459
        while (end - in >= 3) {
268 3349
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
269 3349
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
270 3349
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
271 3349
                *p++ = alpha->b64[in[2] & 0x3f];
272 3349
                in += 3;
273
        }
274 110
        if (end - in > 0) {
275 94
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
276 94
                if (end - in == 1) {
277 72
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
278 72
                        if (alpha->padding) {
279 53
                                *p++ = alpha->padding;
280 53
                                *p++ = alpha->padding;
281 53
                        }
282 72
                }
283
                else {
284 22
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
285 22
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
286 22
                        if (alpha->padding) {
287 13
                                *p++ = alpha->padding;
288 13
                        }
289
                }
290 94
        }
291 110
        assert(p >= buf);
292 110
        assert(p <= buf + buflen);
293 110
        return (p - buf);
294 114
}
295
296
ssize_t
297 127
base64_decode(const enum encoding dec, blob_dest_t buf,
298
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
299
{
300 127
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
301
        const char *s;
302 127
        char *dest = buf;
303 127
        unsigned u = 0, term = 0;
304 127
        size_t len = SIZE_MAX;
305 127
        int n = 0, i;
306
        char b;
307
308 127
        AN(buf);
309 127
        AN(alpha);
310 127
        AN(strings);
311
312 127
        if (inlen >= 0)
313 47
                len = inlen;
314
315 288
        for (i = 0; len > 0 && i < strings->n; i++) {
316 183
                s = strings->p[i];
317
318 183
                if (s == NULL)
319 6
                        continue;
320 177
                if (*s && term) {
321 0
                        errno = EINVAL;
322 0
                        return (-1);
323
                }
324 10319
                while (*s && len) {
325 10164
                        b = alpha->i64[(uint8_t)*s];
326 10164
                        s++;
327 10164
                        len--;
328 10164
                        u <<= 6;
329 10164
                        if (b == ILL) {
330 21
                                errno = EINVAL;
331 21
                                return (-1);
332
                        }
333 10143
                        n++;
334 10143
                        if (b == PAD) {
335 60
                                term++;
336 60
                                continue;
337
                        }
338 10083
                        u |= (uint8_t)b;
339 10083
                        if (n == 4) {
340 2488
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
341 1
                                        return (-1);
342 2487
                                n = 0;
343 2487
                        }
344
                }
345 155
        }
346 105
        if (n) {
347 49
                if (n - term != 0)
348 49
                        u <<= (6 * (4 - n));
349 49
                if (decode(&dest, buf, buflen, u, n-term) < 0)
350 0
                        return (-1);
351 49
        }
352
353 105
        return (dest - buf);
354 127
}