1 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 2 * All rights reserved. 3 * 4 * This package is an SSL implementation written 5 * by Eric Young (eay (at) 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 (at) 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 (at) 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 (at) 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 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 99 void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { 100 OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); 101 } 102 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 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 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 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 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 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. */ 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 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 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 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 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