varnish-cache/vmod/vmod_blob_base64.c
1
/*-
2
 * Copyright 2015-2016 UPLEX - Nils Goroll Systemoptimierung
3
 * All rights reserved.
4
 *
5
 * Authors: Nils Goroll <nils.goroll@uplex.de>
6
 *          Geoffrey Simmons <geoffrey.simmons@uplex.de>
7
 *
8
 * SPDX-License-Identifier: BSD-2-Clause
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions are met:
12
 * 1. Redistributions of source code must retain the above copyright notice,
13
 *    this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright notice,
15
 *    this list of conditions and the following disclaimer in the documentation
16
 *    and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 */
30
31
#include "config.h"
32
33
#include "vdef.h"
34
#include "vrt.h"
35
#include "vas.h"
36
37
#include "vmod_blob.h"
38
39
static const struct b64_alphabet {
40
        const char b64[64];
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 350
base64nopad_encode_l(size_t l)
205
{
206 350
        return (base64_l(l) + 4);
207
}
208
209
size_t
210 990
base64_encode_l(size_t l)
211
{
212 990
        return ((((base64_l(l)) + 3) & ~3) + 1);
213
}
214
215
size_t
216 640
base64_decode_l(size_t l)
217
{
218 640
        return ((l * 3) >> 2);
219
}
220
221
static inline int
222 25370
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 25370
        if (n <= 1) {
229 0
                errno = EINVAL;
230 0
                return (-1);
231
        }
232 25370
        d = *dest;
233 100590
        for (i = 0; i < n - 1; i++) {
234 75230
                if (d == buf + buflen) {
235 10
                        errno = ENOMEM;
236 10
                        return (-1);
237
                }
238 75220
                *d++ = (u >> 16) & 0xff;
239 75220
                u <<= 8;
240 75220
        }
241 25360
        *dest += d - *dest;
242 25360
        return (1);
243 25370
}
244
245
ssize_t
246 1140
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 1140
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
251 1140
        char *p = buf;
252 1140
        const uint8_t *in = (const uint8_t *)inbuf;
253 1140
        const uint8_t * const end = in + inlength;
254
255 1140
        (void)kase;
256 1140
        AN(buf);
257 1140
        AN(alpha);
258 1140
        if (in == NULL || inlength == 0)
259 40
                return (0);
260
261 1920
        if ((enc == BASE64URLNOPAD &&
262 280
            buflen < base64nopad_encode_l(inlength)) ||
263 1100
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
264 0
                errno = ENOMEM;
265 0
                return (-1);
266
        }
267
268 34590
        while (end - in >= 3) {
269 33490
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
270 33490
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
271 33490
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
272 33490
                *p++ = alpha->b64[in[2] & 0x3f];
273 33490
                in += 3;
274
        }
275 1100
        if (end - in > 0) {
276 940
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
277 940
                if (end - in == 1) {
278 720
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
279 720
                        if (alpha->padding) {
280 530
                                *p++ = alpha->padding;
281 530
                                *p++ = alpha->padding;
282 530
                        }
283 720
                }
284
                else {
285 220
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
286 220
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
287 220
                        if (alpha->padding) {
288 130
                                *p++ = alpha->padding;
289 130
                        }
290
                }
291 940
        }
292 1100
        assert(p >= buf);
293 1100
        assert(p <= buf + buflen);
294 1100
        return (p - buf);
295 1140
}
296
297
ssize_t
298 1270
base64_decode(const enum encoding dec, blob_dest_t buf,
299
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
300
{
301 1270
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
302
        const char *s;
303 1270
        char *dest = buf;
304 1270
        unsigned u = 0, term = 0;
305 1270
        size_t len = SIZE_MAX;
306 1270
        int n = 0, i;
307
        char b;
308
309 1270
        AN(buf);
310 1270
        AN(alpha);
311 1270
        AN(strings);
312
313 1270
        if (inlen >= 0)
314 470
                len = inlen;
315
316 2880
        for (i = 0; len > 0 && i < strings->n; i++) {
317 1830
                s = strings->p[i];
318
319 1830
                if (s == NULL)
320 60
                        continue;
321 1770
                if (*s && term) {
322 0
                        errno = EINVAL;
323 0
                        return (-1);
324
                }
325 103190
                while (*s && len) {
326 101640
                        b = alpha->i64[(uint8_t)*s];
327 101640
                        s++;
328 101640
                        len--;
329 101640
                        u <<= 6;
330 101640
                        if (b == ILL) {
331 210
                                errno = EINVAL;
332 210
                                return (-1);
333
                        }
334 101430
                        n++;
335 101430
                        if (b == PAD) {
336 600
                                term++;
337 600
                                continue;
338
                        }
339 100830
                        u |= (uint8_t)b;
340 100830
                        if (n == 4) {
341 24880
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
342 10
                                        return (-1);
343 24870
                                n = 0;
344 24870
                        }
345
                }
346 1550
        }
347 1050
        if (n) {
348 490
                if (n - term != 0)
349 490
                        u <<= (6 * (4 - n));
350 490
                if (decode(&dest, buf, buflen, u, n-term) < 0)
351 0
                        return (-1);
352 490
        }
353
354 1050
        return (dest - buf);
355 1270
}