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
#include "miniobj.h"
36
37
#include "vmod_blob.h"
38
39
static const struct b64_alphabet {
40
        const char b64[65];
41
        const int8_t i64[256];
42
        const int padding;
43
} b64_alphabet[] = {
44
        [BASE64] = {
45
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
46
                "ghijklmnopqrstuvwxyz0123456789+/",
47
                {
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, ILL, ILL, ILL, ILL, ILL,
53
                        ILL, ILL, ILL,  62, ILL, ILL, ILL,  63, /* +, /    */
54
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
55
                         60,  61, ILL, ILL, ILL, PAD, ILL, ILL, /* 8, 9, = */
56
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
57
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
58
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
59
                         23,  24,  25, ILL, ILL, ILL, ILL, ILL, /* X, Y, Z */
60
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
61
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
62
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
63
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
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
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
80
                },
81
                '='
82
        },
83
        [BASE64URL] = {
84
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
85
                "ghijklmnopqrstuvwxyz0123456789-_",
86
                {
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, ILL, ILL, ILL,
92
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -       */
93
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
94
                         60,  61, ILL, ILL, ILL, PAD, ILL, ILL, /* 8, 9, = */
95
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
96
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
97
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
98
                         23,  24,  25, ILL, ILL, ILL, ILL,  63, /* X-Z, _  */
99
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
100
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
101
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
102
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
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
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
119
                },
120
                '='
121
        },
122
        [BASE64URLNOPAD] = {
123
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
124
                "ghijklmnopqrstuvwxyz0123456789-_",
125
                {
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, ILL, ILL, ILL,
131
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -       */
132
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7   */
133
                         60,  61, ILL, ILL, ILL, ILL, ILL, ILL, /* 8, 9    */
134
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G   */
135
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O   */
136
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W   */
137
                         23,  24,  25, ILL, ILL, ILL, ILL,  63, /* X-Z, _  */
138
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g   */
139
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o   */
140
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w   */
141
                         49,  50,  51, ILL, ILL, ILL, ILL, ILL, /* x, y, z */
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
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
158
                },
159
                0
160
        },
161
        [BASE64CF] = {
162
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdef"
163
                "ghijklmnopqrstuvwxyz0123456789-~",
164
                {
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, ILL, ILL, ILL,
170
                        ILL, ILL, ILL, ILL, ILL,  62, ILL, ILL, /* -          */
171
                         52,  53,  54,  55,  56,  57,  58,  59, /* 0 - 7      */
172
                         60,  61, ILL, ILL, ILL, ILL, ILL, ILL, /* 8, 9       */
173
                        ILL,   0,   1,   2,   3,   4,   5,   6, /* A - G      */
174
                          7,   8,   9,  10,  11,  12,  13,  14, /* H - O      */
175
                         15,  16,  17,  18,  19,  20,  21,  22, /* P - W      */
176
                         23,  24,  25, ILL, ILL, ILL, ILL, PAD, /* X, Y, Z, _ */
177
                        ILL,  26,  27,  28,  29,  30,  31,  32, /* a - g      */
178
                         33,  34,  35,  36,  37,  38,  39,  40, /* h - o      */
179
                         41,  42,  43,  44,  45,  46,  47,  48, /* p - w      */
180
                         49,  50,  51, ILL, ILL, ILL,  63, ILL, /* x, y, z,  ~*/
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
                        ILL, ILL, ILL, ILL, ILL, ILL, ILL, ILL,
197
                },
198
                '_'
199
        }
200
};
201
#define base64_l(l)             (((l) << 2) / 3)
202
203
size_t
204 455
base64nopad_encode_l(size_t l)
205
{
206 455
        return (base64_l(l) + 4);
207
}
208
209
size_t
210 1287
base64_encode_l(size_t l)
211
{
212 1287
        return ((((base64_l(l)) + 3) & ~3) + 1);
213
}
214
215
size_t
216 832
base64_decode_l(size_t l)
217
{
218 832
        return ((l * 3) >> 2);
219
}
220
221
static inline int
222 32981
decode(char *restrict *restrict dest, blob_src_t buf,
223
    blob_len_t buflen, unsigned u, const int n)
224
{
225
        char *d;
226
        int i;
227
228 32981
        if (n <= 1) {
229 0
                errno = EINVAL;
230 0
                return (-1);
231
        }
232 32981
        d = *dest;
233 130767
        for (i = 0; i < n - 1; i++) {
234 97799
                if (d == buf + buflen) {
235 13
                        errno = ENOMEM;
236 13
                        return (-1);
237
                }
238 97786
                *d++ = (u >> 16) & 0xff;
239 97786
                u <<= 8;
240 97786
        }
241 32968
        *dest += d - *dest;
242 32968
        return (1);
243 32981
}
244
245
ssize_t
246 2106
base64_encode(const enum encoding enc, const enum case_e kase,
247
    blob_dest_t buf, blob_len_t buflen,
248
    blob_src_t inbuf, blob_len_t inlength)
249
{
250 2106
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
251 2106
        char *p = buf;
252 2106
        const uint8_t *in = (const uint8_t *)inbuf;
253 2106
        const uint8_t * const end = in + inlength;
254
255 2106
        (void)kase;
256 2106
        AN(buf);
257 2106
        AN(alpha);
258 2106
        if (in == NULL || inlength == 0)
259 1300
                return (0);
260
261 3224
        if ((enc == BASE64URLNOPAD &&
262 364
            buflen < base64nopad_encode_l(inlength)) ||
263 2496
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
264 2132
                errno = ENOMEM;
265 2132
                return (-1);
266
        }
267
268 44967
        while (end - in >= 3) {
269 43537
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
270 43537
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
271 43537
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
272 43537
                *p++ = alpha->b64[in[2] & 0x3f];
273 43537
                in += 3;
274
        }
275 1430
        if (end - in > 0) {
276 1222
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
277 1222
                if (end - in == 1) {
278 936
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
279 936
                        if (alpha->padding) {
280 689
                                *p++ = alpha->padding;
281 689
                                *p++ = alpha->padding;
282 689
                        }
283 936
                }
284
                else {
285 286
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
286 286
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
287 286
                        if (alpha->padding) {
288 169
                                *p++ = alpha->padding;
289 169
                        }
290
                }
291 1222
        }
292 1430
        assert(p >= buf);
293 1430
        assert(p <= buf + buflen);
294 1430
        return (p - buf);
295 1482
}
296
297
ssize_t
298 1651
base64_decode(const enum encoding dec, blob_dest_t buf,
299
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
300
{
301 1651
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
302
        const char *s;
303 1651
        char *dest = buf;
304 1651
        unsigned u = 0, term = 0;
305 1651
        size_t len = SIZE_MAX;
306 1651
        int n = 0, i;
307
        char b;
308
309 1651
        AN(buf);
310 1651
        AN(alpha);
311 1651
        CHECK_OBJ_NOTNULL(strings, STRANDS_MAGIC);
312
313 1651
        if (inlen >= 0)
314 611
                len = inlen;
315
316 3744
        for (i = 0; len > 0 && i < strings->n; i++) {
317 2379
                s = strings->p[i];
318
319 2379
                if (s == NULL)
320 78
                        continue;
321 2301
                if (*s && term) {
322 0
                        errno = EINVAL;
323 0
                        return (-1);
324
                }
325 134147
                while (*s && len) {
326 132132
                        b = alpha->i64[(uint8_t)*s];
327 132132
                        s++;
328 132132
                        len--;
329 132132
                        u <<= 6;
330 132132
                        if (b == ILL) {
331 273
                                errno = EINVAL;
332 273
                                return (-1);
333
                        }
334 131859
                        n++;
335 131859
                        if (b == PAD) {
336 780
                                term++;
337 780
                                continue;
338
                        }
339 131079
                        u |= (uint8_t)b;
340 131079
                        if (n == 4) {
341 32344
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
342 13
                                        return (-1);
343 32331
                                n = 0;
344 32331
                        }
345
                }
346 2015
        }
347 1365
        if (n) {
348 637
                if (n - term != 0)
349 637
                        u <<= (6 * (4 - n));
350 637
                if (decode(&dest, buf, buflen, u, n-term) < 0)
351 0
                        return (-1);
352 637
        }
353
354 1365
        return (dest - buf);
355 1651
}