1 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
2 * All rights reserved.
3 *
4 * This package is an SSL implementation written
5 * by Eric Young (eay@cryptsoft.com).
6 * The implementation was written so as to conform with Netscapes SSL.
7 *
8 * This library is free for commercial and non-commercial use as long as
9 * the following conditions are aheared to. The following conditions
10 * apply to all code found in this distribution, be it the RC4, RSA,
11 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
12 * included with this distribution is covered by the same copyright terms
13 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
14 *
15 * Copyright remains Eric Young's, and as such any Copyright notices in
16 * the code are not to be removed.
17 * If this package is used in a product, Eric Young should be given attribution
18 * as the author of the parts of the library used.
19 * This can be in the form of a textual message at program startup or
20 * in documentation (online or textual) provided with the package.
21 *
22 * Redistribution and use in source and binary forms, with or without
23 * modification, are permitted provided that the following conditions
24 * are met:
25 * 1. Redistributions of source code must retain the copyright
26 * notice, this list of conditions and the following disclaimer.
27 * 2. Redistributions in binary form must reproduce the above copyright
28 * notice, this list of conditions and the following disclaimer in the
29 * documentation and/or other materials provided with the distribution.
30 * 3. All advertising materials mentioning features or use of this software
31 * must display the following acknowledgement:
32 * "This product includes cryptographic software written by
33 * Eric Young (eay@cryptsoft.com)"
34 * The word 'cryptographic' can be left out if the rouines from the library
35 * being used are not cryptographic related :-).
36 * 4. If you include any Windows specific code (or a derivative thereof) from
37 * the apps directory (application code) you must include an acknowledgement:
38 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 * SUCH DAMAGE.
51 *
52 * The licence and distribution terms for any publically available version or
53 * derivative of this code cannot be changed. i.e. this code cannot simply be
54 * copied and put under another distribution licence
55 * [including the GNU Public Licence.] */
56
57 #include <openssl/base64.h>
58
59 #include <assert.h>
60 #include <limits.h>
61 #include <string.h>
62
63 #include <openssl/type_check.h>
64
65 #include "../internal.h"
66
67
68 /* Encoding. */
69
70 static const unsigned char data_bin2ascii[65] =
71 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
72
73 #define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
74
75 OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0,
76 data_length_must_be_multiple_of_base64_chunk_size);
77
EVP_EncodedLength(size_t * out_len,size_t len)78 int EVP_EncodedLength(size_t *out_len, size_t len) {
79 if (len + 2 < len) {
80 return 0;
81 }
82 len += 2;
83 len /= 3;
84
85 if (((len << 2) >> 2) != len) {
86 return 0;
87 }
88 len <<= 2;
89
90 if (len + 1 < len) {
91 return 0;
92 }
93 len++;
94
95 *out_len = len;
96 return 1;
97 }
98
EVP_EncodeInit(EVP_ENCODE_CTX * ctx)99 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
100 OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
101 }
102
EVP_EncodeUpdate(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len,const uint8_t * in,size_t in_len)103 void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
104 const uint8_t *in, size_t in_len) {
105 size_t total = 0;
106
107 *out_len = 0;
108 if (in_len == 0) {
109 return;
110 }
111
112 assert(ctx->data_used < sizeof(ctx->data));
113
114 if (sizeof(ctx->data) - ctx->data_used > in_len) {
115 OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len);
116 ctx->data_used += (unsigned)in_len;
117 return;
118 }
119
120 if (ctx->data_used != 0) {
121 const size_t todo = sizeof(ctx->data) - ctx->data_used;
122 OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo);
123 in += todo;
124 in_len -= todo;
125
126 size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data));
127 ctx->data_used = 0;
128
129 out += encoded;
130 *(out++) = '\n';
131 *out = '\0';
132
133 total = encoded + 1;
134 }
135
136 while (in_len >= sizeof(ctx->data)) {
137 size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data));
138 in += sizeof(ctx->data);
139 in_len -= sizeof(ctx->data);
140
141 out += encoded;
142 *(out++) = '\n';
143 *out = '\0';
144
145 if (total + encoded + 1 < total) {
146 *out_len = 0;
147 return;
148 }
149
150 total += encoded + 1;
151 }
152
153 if (in_len != 0) {
154 OPENSSL_memcpy(ctx->data, in, in_len);
155 }
156
157 ctx->data_used = (unsigned)in_len;
158
159 if (total > INT_MAX) {
160 /* We cannot signal an error, but we can at least avoid making *out_len
161 * negative. */
162 total = 0;
163 }
164 *out_len = (int)total;
165 }
166
EVP_EncodeFinal(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len)167 void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
168 if (ctx->data_used == 0) {
169 *out_len = 0;
170 return;
171 }
172
173 size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used);
174 out[encoded++] = '\n';
175 out[encoded] = '\0';
176 ctx->data_used = 0;
177
178 /* ctx->data_used is bounded by sizeof(ctx->data), so this does not
179 * overflow. */
180 assert(encoded <= INT_MAX);
181 *out_len = (int)encoded;
182 }
183
EVP_EncodeBlock(uint8_t * dst,const uint8_t * src,size_t src_len)184 size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
185 uint32_t l;
186 size_t remaining = src_len, ret = 0;
187
188 while (remaining) {
189 if (remaining >= 3) {
190 l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2];
191 *(dst++) = conv_bin2ascii(l >> 18L);
192 *(dst++) = conv_bin2ascii(l >> 12L);
193 *(dst++) = conv_bin2ascii(l >> 6L);
194 *(dst++) = conv_bin2ascii(l);
195 remaining -= 3;
196 } else {
197 l = ((uint32_t)src[0]) << 16L;
198 if (remaining == 2) {
199 l |= ((uint32_t)src[1] << 8L);
200 }
201
202 *(dst++) = conv_bin2ascii(l >> 18L);
203 *(dst++) = conv_bin2ascii(l >> 12L);
204 *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L);
205 *(dst++) = '=';
206 remaining = 0;
207 }
208 ret += 4;
209 src += 3;
210 }
211
212 *dst = '\0';
213 return ret;
214 }
215
216
217 /* Decoding. */
218
EVP_DecodedLength(size_t * out_len,size_t len)219 int EVP_DecodedLength(size_t *out_len, size_t len) {
220 if (len % 4 != 0) {
221 return 0;
222 }
223
224 *out_len = (len / 4) * 3;
225 return 1;
226 }
227
EVP_DecodeInit(EVP_ENCODE_CTX * ctx)228 void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
229 OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
230 }
231
232 /* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
233 * else 0xff if they are invalid. As a special case, the padding character
234 * ('=') is mapped to zero. */
235 static const uint8_t kBase64ASCIIToBinData[128] = {
236 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
237 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
238 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
239 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
240 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
241 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
242 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
243 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
244 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
245 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
246 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
247 };
248
base64_ascii_to_bin(uint8_t a)249 static uint8_t base64_ascii_to_bin(uint8_t a) {
250 if (a >= 128) {
251 return 0xFF;
252 }
253
254 return kBase64ASCIIToBinData[a];
255 }
256
257 /* base64_decode_quad decodes a single “quad” (i.e. four characters) of base64
258 * data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the
259 * number of bytes written, which will be less than three if the quad ended
260 * with padding. It returns one on success or zero on error. */
base64_decode_quad(uint8_t * out,size_t * out_num_bytes,const uint8_t * in)261 static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes,
262 const uint8_t *in) {
263 const uint8_t a = base64_ascii_to_bin(in[0]);
264 const uint8_t b = base64_ascii_to_bin(in[1]);
265 const uint8_t c = base64_ascii_to_bin(in[2]);
266 const uint8_t d = base64_ascii_to_bin(in[3]);
267 if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) {
268 return 0;
269 }
270
271 const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 |
272 ((uint32_t)c) << 6 | (uint32_t)d;
273
274 const unsigned padding_pattern = (in[0] == '=') << 3 |
275 (in[1] == '=') << 2 |
276 (in[2] == '=') << 1 |
277 (in[3] == '=');
278
279 switch (padding_pattern) {
280 case 0:
281 /* The common case of no padding. */
282 *out_num_bytes = 3;
283 out[0] = v >> 16;
284 out[1] = v >> 8;
285 out[2] = v;
286 break;
287
288 case 1: /* xxx= */
289 *out_num_bytes = 2;
290 out[0] = v >> 16;
291 out[1] = v >> 8;
292 break;
293
294 case 3: /* xx== */
295 *out_num_bytes = 1;
296 out[0] = v >> 16;
297 break;
298
299 default:
300 return 0;
301 }
302
303 return 1;
304 }
305
EVP_DecodeUpdate(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len,const uint8_t * in,size_t in_len)306 int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
307 const uint8_t *in, size_t in_len) {
308 *out_len = 0;
309
310 if (ctx->error_encountered) {
311 return -1;
312 }
313
314 size_t bytes_out = 0, i;
315 for (i = 0; i < in_len; i++) {
316 const char c = in[i];
317 switch (c) {
318 case ' ':
319 case '\t':
320 case '\r':
321 case '\n':
322 continue;
323 }
324
325 if (base64_ascii_to_bin(c) == 0xff || ctx->eof_seen) {
326 ctx->error_encountered = 1;
327 return -1;
328 }
329
330 ctx->data[ctx->data_used++] = c;
331 if (ctx->data_used == 4) {
332 size_t num_bytes_resulting;
333 if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) {
334 ctx->error_encountered = 1;
335 return -1;
336 }
337
338 ctx->data_used = 0;
339 bytes_out += num_bytes_resulting;
340 out += num_bytes_resulting;
341
342 if (num_bytes_resulting < 3) {
343 ctx->eof_seen = 1;
344 }
345 }
346 }
347
348 if (bytes_out > INT_MAX) {
349 ctx->error_encountered = 1;
350 *out_len = 0;
351 return -1;
352 }
353 *out_len = (int)bytes_out;
354
355 if (ctx->eof_seen) {
356 return 0;
357 }
358
359 return 1;
360 }
361
EVP_DecodeFinal(EVP_ENCODE_CTX * ctx,uint8_t * out,int * out_len)362 int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
363 *out_len = 0;
364 if (ctx->error_encountered || ctx->data_used != 0) {
365 return -1;
366 }
367
368 return 1;
369 }
370
EVP_DecodeBase64(uint8_t * out,size_t * out_len,size_t max_out,const uint8_t * in,size_t in_len)371 int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
372 const uint8_t *in, size_t in_len) {
373 *out_len = 0;
374
375 if (in_len % 4 != 0) {
376 return 0;
377 }
378
379 size_t max_len;
380 if (!EVP_DecodedLength(&max_len, in_len) ||
381 max_out < max_len) {
382 return 0;
383 }
384
385 size_t i, bytes_out = 0;
386 for (i = 0; i < in_len; i += 4) {
387 size_t num_bytes_resulting;
388
389 if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) {
390 return 0;
391 }
392
393 bytes_out += num_bytes_resulting;
394 out += num_bytes_resulting;
395 if (num_bytes_resulting != 3 && i != in_len - 4) {
396 return 0;
397 }
398 }
399
400 *out_len = bytes_out;
401 return 1;
402 }
403
EVP_DecodeBlock(uint8_t * dst,const uint8_t * src,size_t src_len)404 int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
405 /* Trim spaces and tabs from the beginning of the input. */
406 while (src_len > 0) {
407 if (src[0] != ' ' && src[0] != '\t') {
408 break;
409 }
410
411 src++;
412 src_len--;
413 }
414
415 /* Trim newlines, spaces and tabs from the end of the line. */
416 while (src_len > 0) {
417 switch (src[src_len-1]) {
418 case ' ':
419 case '\t':
420 case '\r':
421 case '\n':
422 src_len--;
423 continue;
424 }
425
426 break;
427 }
428
429 size_t dst_len;
430 if (!EVP_DecodedLength(&dst_len, src_len) ||
431 dst_len > INT_MAX ||
432 !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
433 return -1;
434 }
435
436 /* EVP_DecodeBlock does not take padding into account, so put the
437 * NULs back in... so the caller can strip them back out. */
438 while (dst_len % 3 != 0) {
439 dst[dst_len++] = '\0';
440 }
441 assert(dst_len <= INT_MAX);
442
443 return (int)dst_len;
444 }
445