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 875
base64nopad_encode_l(size_t l)
204
{
205 875
        return (base64_l(l) + 4);
206
}
207
208
size_t
209 2475
base64_encode_l(size_t l)
210
{
211 2475
        return ((((base64_l(l)) + 3) & ~3) + 1);
212
}
213
214
size_t
215 1600
base64_decode_l(size_t l)
216
{
217 1600
        return ((l * 3) >> 2);
218
}
219
220
static inline int
221 63425
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 63425
        if (n <= 1) {
228 0
                errno = EINVAL;
229 0
                return (-1);
230
        }
231 63425
        d = *dest;
232 251475
        for (i = 0; i < n - 1; i++) {
233 188075
                if (d == buf + buflen) {
234 25
                        errno = ENOMEM;
235 25
                        return (-1);
236
                }
237 188050
                *d++ = (u >> 16) & 0xff;
238 188050
                u <<= 8;
239 188050
        }
240 63400
        *dest += d - *dest;
241 63400
        return (1);
242 63425
}
243
244
ssize_t
245 4050
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 4050
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
250 4050
        char *p = buf;
251 4050
        const uint8_t *in = (const uint8_t *)inbuf;
252 4050
        const uint8_t * const end = in + inlength;
253
254 4050
        (void)kase;
255 4050
        AN(buf);
256 4050
        AN(alpha);
257 4050
        if (in == NULL || inlength == 0)
258 2500
                return (0);
259
260 6200
        if ((enc == BASE64URLNOPAD &&
261 700
            buflen < base64nopad_encode_l(inlength)) ||
262 4800
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
263 4100
                errno = ENOMEM;
264 4100
                return (-1);
265
        }
266
267 86475
        while (end - in >= 3) {
268 83725
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
269 83725
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
270 83725
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
271 83725
                *p++ = alpha->b64[in[2] & 0x3f];
272 83725
                in += 3;
273
        }
274 2750
        if (end - in > 0) {
275 2350
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
276 2350
                if (end - in == 1) {
277 1800
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
278 1800
                        if (alpha->padding) {
279 1325
                                *p++ = alpha->padding;
280 1325
                                *p++ = alpha->padding;
281 1325
                        }
282 1800
                }
283
                else {
284 550
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
285 550
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
286 550
                        if (alpha->padding) {
287 325
                                *p++ = alpha->padding;
288 325
                        }
289
                }
290 2350
        }
291 2750
        assert(p >= buf);
292 2750
        assert(p <= buf + buflen);
293 2750
        return (p - buf);
294 2850
}
295
296
ssize_t
297 3175
base64_decode(const enum encoding dec, blob_dest_t buf,
298
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
299
{
300 3175
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
301
        const char *s;
302 3175
        char *dest = buf;
303 3175
        unsigned u = 0, term = 0;
304 3175
        size_t len = SIZE_MAX;
305 3175
        int n = 0, i;
306
        char b;
307
308 3175
        AN(buf);
309 3175
        AN(alpha);
310 3175
        AN(strings);
311
312 3175
        if (inlen >= 0)
313 1175
                len = inlen;
314
315 7200
        for (i = 0; len > 0 && i < strings->n; i++) {
316 4575
                s = strings->p[i];
317
318 4575
                if (s == NULL)
319 150
                        continue;
320 4425
                if (*s && term) {
321 0
                        errno = EINVAL;
322 0
                        return (-1);
323
                }
324 257975
                while (*s && len) {
325 254100
                        b = alpha->i64[(uint8_t)*s];
326 254100
                        s++;
327 254100
                        len--;
328 254100
                        u <<= 6;
329 254100
                        if (b == ILL) {
330 525
                                errno = EINVAL;
331 525
                                return (-1);
332
                        }
333 253575
                        n++;
334 253575
                        if (b == PAD) {
335 1500
                                term++;
336 1500
                                continue;
337
                        }
338 252075
                        u |= (uint8_t)b;
339 252075
                        if (n == 4) {
340 62200
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
341 25
                                        return (-1);
342 62175
                                n = 0;
343 62175
                        }
344
                }
345 3875
        }
346 2625
        if (n) {
347 1225
                if (n - term != 0)
348 1225
                        u <<= (6 * (4 - n));
349 1225
                if (decode(&dest, buf, buflen, u, n-term) < 0)
350 0
                        return (-1);
351 1225
        }
352
353 2625
        return (dest - buf);
354 3175
}