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[65];
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 525
base64nopad_encode_l(size_t l)
204
{
205 525
        return (base64_l(l) + 4);
206
}
207
208
size_t
209 1485
base64_encode_l(size_t l)
210
{
211 1485
        return ((((base64_l(l)) + 3) & ~3) + 1);
212
}
213
214
size_t
215 960
base64_decode_l(size_t l)
216
{
217 960
        return ((l * 3) >> 2);
218
}
219
220
static inline int
221 38055
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 38055
        if (n <= 1) {
228 0
                errno = EINVAL;
229 0
                return (-1);
230
        }
231 38055
        d = *dest;
232 150885
        for (i = 0; i < n - 1; i++) {
233 112845
                if (d == buf + buflen) {
234 15
                        errno = ENOMEM;
235 15
                        return (-1);
236
                }
237 112830
                *d++ = (u >> 16) & 0xff;
238 112830
                u <<= 8;
239 112830
        }
240 38040
        *dest += d - *dest;
241 38040
        return (1);
242 38055
}
243
244
ssize_t
245 2430
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 2430
        const struct b64_alphabet *alpha = &b64_alphabet[enc];
250 2430
        char *p = buf;
251 2430
        const uint8_t *in = (const uint8_t *)inbuf;
252 2430
        const uint8_t * const end = in + inlength;
253
254 2430
        (void)kase;
255 2430
        AN(buf);
256 2430
        AN(alpha);
257 2430
        if (in == NULL || inlength == 0)
258 1500
                return (0);
259
260 3720
        if ((enc == BASE64URLNOPAD &&
261 420
            buflen < base64nopad_encode_l(inlength)) ||
262 2880
            (enc != BASE64URLNOPAD && buflen < base64_encode_l(inlength))) {
263 2460
                errno = ENOMEM;
264 2460
                return (-1);
265
        }
266
267 51885
        while (end - in >= 3) {
268 50235
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
269 50235
                *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
270 50235
                *p++ = alpha->b64[((in[1] << 2) | (in[2] >> 6)) & 0x3f];
271 50235
                *p++ = alpha->b64[in[2] & 0x3f];
272 50235
                in += 3;
273
        }
274 1650
        if (end - in > 0) {
275 1410
                *p++ = alpha->b64[(in[0] >> 2) & 0x3f];
276 1410
                if (end - in == 1) {
277 1080
                        *p++ = alpha->b64[(in[0] << 4) & 0x3f];
278 1080
                        if (alpha->padding) {
279 795
                                *p++ = alpha->padding;
280 795
                                *p++ = alpha->padding;
281 795
                        }
282 1080
                }
283
                else {
284 330
                        *p++ = alpha->b64[((in[0] << 4) | (in[1] >> 4)) & 0x3f];
285 330
                        *p++ = alpha->b64[(in[1] << 2) & 0x3f];
286 330
                        if (alpha->padding) {
287 195
                                *p++ = alpha->padding;
288 195
                        }
289
                }
290 1410
        }
291 1650
        assert(p >= buf);
292 1650
        assert(p <= buf + buflen);
293 1650
        return (p - buf);
294 1710
}
295
296
ssize_t
297 1905
base64_decode(const enum encoding dec, blob_dest_t buf,
298
    blob_len_t buflen, ssize_t inlen, VCL_STRANDS strings)
299
{
300 1905
        const struct b64_alphabet *alpha = &b64_alphabet[dec];
301
        const char *s;
302 1905
        char *dest = buf;
303 1905
        unsigned u = 0, term = 0;
304 1905
        size_t len = SIZE_MAX;
305 1905
        int n = 0, i;
306
        char b;
307
308 1905
        AN(buf);
309 1905
        AN(alpha);
310 1905
        AN(strings);
311
312 1905
        if (inlen >= 0)
313 705
                len = inlen;
314
315 4320
        for (i = 0; len > 0 && i < strings->n; i++) {
316 2745
                s = strings->p[i];
317
318 2745
                if (s == NULL)
319 90
                        continue;
320 2655
                if (*s && term) {
321 0
                        errno = EINVAL;
322 0
                        return (-1);
323
                }
324 154785
                while (*s && len) {
325 152460
                        b = alpha->i64[(uint8_t)*s];
326 152460
                        s++;
327 152460
                        len--;
328 152460
                        u <<= 6;
329 152460
                        if (b == ILL) {
330 315
                                errno = EINVAL;
331 315
                                return (-1);
332
                        }
333 152145
                        n++;
334 152145
                        if (b == PAD) {
335 900
                                term++;
336 900
                                continue;
337
                        }
338 151245
                        u |= (uint8_t)b;
339 151245
                        if (n == 4) {
340 37320
                                if (decode(&dest, buf, buflen, u, n-term) < 0)
341 15
                                        return (-1);
342 37305
                                n = 0;
343 37305
                        }
344
                }
345 2325
        }
346 1575
        if (n) {
347 735
                if (n - term != 0)
348 735
                        u <<= (6 * (4 - n));
349 735
                if (decode(&dest, buf, buflen, u, n-term) < 0)
350 0
                        return (-1);
351 735
        }
352
353 1575
        return (dest - buf);
354 1905
}