1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <errno.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/buffer.h> 14 #include <openssl/evp.h> 15 #include "internal/bio.h" 16 17 static int b64_write(BIO *h, const char *buf, int num); 18 static int b64_read(BIO *h, char *buf, int size); 19 static int b64_puts(BIO *h, const char *str); 20 static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); 21 static int b64_new(BIO *h); 22 static int b64_free(BIO *data); 23 static long b64_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); 24 #define B64_BLOCK_SIZE 1024 25 #define B64_BLOCK_SIZE2 768 26 #define B64_NONE 0 27 #define B64_ENCODE 1 28 #define B64_DECODE 2 29 30 typedef struct b64_struct { 31 /* 32 * BIO *bio; moved to the BIO structure 33 */ 34 int buf_len; 35 int buf_off; 36 int tmp_len; /* used to find the start when decoding */ 37 int tmp_nl; /* If true, scan until '\n' */ 38 int encode; 39 int start; /* have we started decoding yet? */ 40 int cont; /* <= 0 when finished */ 41 EVP_ENCODE_CTX *base64; 42 char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; 43 char tmp[B64_BLOCK_SIZE]; 44 } BIO_B64_CTX; 45 46 static const BIO_METHOD methods_b64 = { 47 BIO_TYPE_BASE64, 48 "base64 encoding", 49 bwrite_conv, 50 b64_write, 51 bread_conv, 52 b64_read, 53 b64_puts, 54 NULL, /* b64_gets, */ 55 b64_ctrl, 56 b64_new, 57 b64_free, 58 b64_callback_ctrl, 59 }; 60 61 62 const BIO_METHOD *BIO_f_base64(void) 63 { 64 return &methods_b64; 65 } 66 67 static int b64_new(BIO *bi) 68 { 69 BIO_B64_CTX *ctx; 70 71 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 72 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 73 return 0; 74 } 75 76 ctx->cont = 1; 77 ctx->start = 1; 78 ctx->base64 = EVP_ENCODE_CTX_new(); 79 if (ctx->base64 == NULL) { 80 OPENSSL_free(ctx); 81 return 0; 82 } 83 84 BIO_set_data(bi, ctx); 85 BIO_set_init(bi, 1); 86 87 return 1; 88 } 89 90 static int b64_free(BIO *a) 91 { 92 BIO_B64_CTX *ctx; 93 if (a == NULL) 94 return 0; 95 96 ctx = BIO_get_data(a); 97 if (ctx == NULL) 98 return 0; 99 100 EVP_ENCODE_CTX_free(ctx->base64); 101 OPENSSL_free(ctx); 102 BIO_set_data(a, NULL); 103 BIO_set_init(a, 0); 104 105 return 1; 106 } 107 108 static int b64_read(BIO *b, char *out, int outl) 109 { 110 int ret = 0, i, ii, j, k, x, n, num, ret_code = 0; 111 BIO_B64_CTX *ctx; 112 unsigned char *p, *q; 113 BIO *next; 114 115 if (out == NULL) 116 return 0; 117 ctx = (BIO_B64_CTX *)BIO_get_data(b); 118 119 next = BIO_next(b); 120 if ((ctx == NULL) || (next == NULL)) 121 return 0; 122 123 BIO_clear_retry_flags(b); 124 125 if (ctx->encode != B64_DECODE) { 126 ctx->encode = B64_DECODE; 127 ctx->buf_len = 0; 128 ctx->buf_off = 0; 129 ctx->tmp_len = 0; 130 EVP_DecodeInit(ctx->base64); 131 } 132 133 /* First check if there are bytes decoded/encoded */ 134 if (ctx->buf_len > 0) { 135 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 136 i = ctx->buf_len - ctx->buf_off; 137 if (i > outl) 138 i = outl; 139 OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf)); 140 memcpy(out, &(ctx->buf[ctx->buf_off]), i); 141 ret = i; 142 out += i; 143 outl -= i; 144 ctx->buf_off += i; 145 if (ctx->buf_len == ctx->buf_off) { 146 ctx->buf_len = 0; 147 ctx->buf_off = 0; 148 } 149 } 150 151 /* 152 * At this point, we have room of outl bytes and an empty buffer, so we 153 * should read in some more. 154 */ 155 156 ret_code = 0; 157 while (outl > 0) { 158 if (ctx->cont <= 0) 159 break; 160 161 i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]), 162 B64_BLOCK_SIZE - ctx->tmp_len); 163 164 if (i <= 0) { 165 ret_code = i; 166 167 /* Should we continue next time we are called? */ 168 if (!BIO_should_retry(next)) { 169 ctx->cont = i; 170 /* If buffer empty break */ 171 if (ctx->tmp_len == 0) 172 break; 173 /* Fall through and process what we have */ 174 else 175 i = 0; 176 } 177 /* else we retry and add more data to buffer */ 178 else 179 break; 180 } 181 i += ctx->tmp_len; 182 ctx->tmp_len = i; 183 184 /* 185 * We need to scan, a line at a time until we have a valid line if we 186 * are starting. 187 */ 188 if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { 189 /* ctx->start=1; */ 190 ctx->tmp_len = 0; 191 } else if (ctx->start) { 192 q = p = (unsigned char *)ctx->tmp; 193 num = 0; 194 for (j = 0; j < i; j++) { 195 if (*(q++) != '\n') 196 continue; 197 198 /* 199 * due to a previous very long line, we need to keep on 200 * scanning for a '\n' before we even start looking for 201 * base64 encoded stuff. 202 */ 203 if (ctx->tmp_nl) { 204 p = q; 205 ctx->tmp_nl = 0; 206 continue; 207 } 208 209 k = EVP_DecodeUpdate(ctx->base64, 210 (unsigned char *)ctx->buf, 211 &num, p, q - p); 212 if ((k <= 0) && (num == 0) && (ctx->start)) 213 EVP_DecodeInit(ctx->base64); 214 else { 215 if (p != (unsigned char *) 216 &(ctx->tmp[0])) { 217 i -= (p - (unsigned char *) 218 &(ctx->tmp[0])); 219 for (x = 0; x < i; x++) 220 ctx->tmp[x] = p[x]; 221 } 222 EVP_DecodeInit(ctx->base64); 223 ctx->start = 0; 224 break; 225 } 226 p = q; 227 } 228 229 /* we fell off the end without starting */ 230 if ((j == i) && (num == 0)) { 231 /* 232 * Is this is one long chunk?, if so, keep on reading until a 233 * new line. 234 */ 235 if (p == (unsigned char *)&(ctx->tmp[0])) { 236 /* Check buffer full */ 237 if (i == B64_BLOCK_SIZE) { 238 ctx->tmp_nl = 1; 239 ctx->tmp_len = 0; 240 } 241 } else if (p != q) { /* finished on a '\n' */ 242 n = q - p; 243 for (ii = 0; ii < n; ii++) 244 ctx->tmp[ii] = p[ii]; 245 ctx->tmp_len = n; 246 } 247 /* else finished on a '\n' */ 248 continue; 249 } else { 250 ctx->tmp_len = 0; 251 } 252 } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { 253 /* 254 * If buffer isn't full and we can retry then restart to read in 255 * more data. 256 */ 257 continue; 258 } 259 260 if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { 261 int z, jj; 262 263 jj = i & ~3; /* process per 4 */ 264 z = EVP_DecodeBlock((unsigned char *)ctx->buf, 265 (unsigned char *)ctx->tmp, jj); 266 if (jj > 2) { 267 if (ctx->tmp[jj - 1] == '=') { 268 z--; 269 if (ctx->tmp[jj - 2] == '=') 270 z--; 271 } 272 } 273 /* 274 * z is now number of output bytes and jj is the number consumed 275 */ 276 if (jj != i) { 277 memmove(ctx->tmp, &ctx->tmp[jj], i - jj); 278 ctx->tmp_len = i - jj; 279 } 280 ctx->buf_len = 0; 281 if (z > 0) { 282 ctx->buf_len = z; 283 } 284 i = z; 285 } else { 286 i = EVP_DecodeUpdate(ctx->base64, 287 (unsigned char *)ctx->buf, &ctx->buf_len, 288 (unsigned char *)ctx->tmp, i); 289 ctx->tmp_len = 0; 290 } 291 /* 292 * If eof or an error was signalled, then the condition 293 * 'ctx->cont <= 0' will prevent b64_read() from reading 294 * more data on subsequent calls. This assignment was 295 * deleted accidentally in commit 5562cfaca4f3. 296 */ 297 ctx->cont = i; 298 299 ctx->buf_off = 0; 300 if (i < 0) { 301 ret_code = 0; 302 ctx->buf_len = 0; 303 break; 304 } 305 306 if (ctx->buf_len <= outl) 307 i = ctx->buf_len; 308 else 309 i = outl; 310 311 memcpy(out, ctx->buf, i); 312 ret += i; 313 ctx->buf_off = i; 314 if (ctx->buf_off == ctx->buf_len) { 315 ctx->buf_len = 0; 316 ctx->buf_off = 0; 317 } 318 outl -= i; 319 out += i; 320 } 321 /* BIO_clear_retry_flags(b); */ 322 BIO_copy_next_retry(b); 323 return ((ret == 0) ? ret_code : ret); 324 } 325 326 static int b64_write(BIO *b, const char *in, int inl) 327 { 328 int ret = 0; 329 int n; 330 int i; 331 BIO_B64_CTX *ctx; 332 BIO *next; 333 334 ctx = (BIO_B64_CTX *)BIO_get_data(b); 335 next = BIO_next(b); 336 if ((ctx == NULL) || (next == NULL)) 337 return 0; 338 339 BIO_clear_retry_flags(b); 340 341 if (ctx->encode != B64_ENCODE) { 342 ctx->encode = B64_ENCODE; 343 ctx->buf_len = 0; 344 ctx->buf_off = 0; 345 ctx->tmp_len = 0; 346 EVP_EncodeInit(ctx->base64); 347 } 348 349 OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); 350 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); 351 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 352 n = ctx->buf_len - ctx->buf_off; 353 while (n > 0) { 354 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); 355 if (i <= 0) { 356 BIO_copy_next_retry(b); 357 return i; 358 } 359 OPENSSL_assert(i <= n); 360 ctx->buf_off += i; 361 OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); 362 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 363 n -= i; 364 } 365 /* at this point all pending data has been written */ 366 ctx->buf_off = 0; 367 ctx->buf_len = 0; 368 369 if ((in == NULL) || (inl <= 0)) 370 return 0; 371 372 while (inl > 0) { 373 n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; 374 375 if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { 376 if (ctx->tmp_len > 0) { 377 OPENSSL_assert(ctx->tmp_len <= 3); 378 n = 3 - ctx->tmp_len; 379 /* 380 * There's a theoretical possibility for this 381 */ 382 if (n > inl) 383 n = inl; 384 memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); 385 ctx->tmp_len += n; 386 ret += n; 387 if (ctx->tmp_len < 3) 388 break; 389 ctx->buf_len = 390 EVP_EncodeBlock((unsigned char *)ctx->buf, 391 (unsigned char *)ctx->tmp, ctx->tmp_len); 392 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); 393 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 394 /* 395 * Since we're now done using the temporary buffer, the 396 * length should be 0'd 397 */ 398 ctx->tmp_len = 0; 399 } else { 400 if (n < 3) { 401 memcpy(ctx->tmp, in, n); 402 ctx->tmp_len = n; 403 ret += n; 404 break; 405 } 406 n -= n % 3; 407 ctx->buf_len = 408 EVP_EncodeBlock((unsigned char *)ctx->buf, 409 (const unsigned char *)in, n); 410 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); 411 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 412 ret += n; 413 } 414 } else { 415 if (!EVP_EncodeUpdate(ctx->base64, 416 (unsigned char *)ctx->buf, &ctx->buf_len, 417 (unsigned char *)in, n)) 418 return ((ret == 0) ? -1 : ret); 419 OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); 420 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 421 ret += n; 422 } 423 inl -= n; 424 in += n; 425 426 ctx->buf_off = 0; 427 n = ctx->buf_len; 428 while (n > 0) { 429 i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); 430 if (i <= 0) { 431 BIO_copy_next_retry(b); 432 return ((ret == 0) ? i : ret); 433 } 434 OPENSSL_assert(i <= n); 435 n -= i; 436 ctx->buf_off += i; 437 OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); 438 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 439 } 440 ctx->buf_len = 0; 441 ctx->buf_off = 0; 442 } 443 return ret; 444 } 445 446 static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) 447 { 448 BIO_B64_CTX *ctx; 449 long ret = 1; 450 int i; 451 BIO *next; 452 453 ctx = (BIO_B64_CTX *)BIO_get_data(b); 454 next = BIO_next(b); 455 if ((ctx == NULL) || (next == NULL)) 456 return 0; 457 458 switch (cmd) { 459 case BIO_CTRL_RESET: 460 ctx->cont = 1; 461 ctx->start = 1; 462 ctx->encode = B64_NONE; 463 ret = BIO_ctrl(next, cmd, num, ptr); 464 break; 465 case BIO_CTRL_EOF: /* More to read */ 466 if (ctx->cont <= 0) 467 ret = 1; 468 else 469 ret = BIO_ctrl(next, cmd, num, ptr); 470 break; 471 case BIO_CTRL_WPENDING: /* More to write in buffer */ 472 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 473 ret = ctx->buf_len - ctx->buf_off; 474 if ((ret == 0) && (ctx->encode != B64_NONE) 475 && (EVP_ENCODE_CTX_num(ctx->base64) != 0)) 476 ret = 1; 477 else if (ret <= 0) 478 ret = BIO_ctrl(next, cmd, num, ptr); 479 break; 480 case BIO_CTRL_PENDING: /* More to read in buffer */ 481 OPENSSL_assert(ctx->buf_len >= ctx->buf_off); 482 ret = ctx->buf_len - ctx->buf_off; 483 if (ret <= 0) 484 ret = BIO_ctrl(next, cmd, num, ptr); 485 break; 486 case BIO_CTRL_FLUSH: 487 /* do a final write */ 488 again: 489 while (ctx->buf_len != ctx->buf_off) { 490 i = b64_write(b, NULL, 0); 491 if (i < 0) 492 return i; 493 } 494 if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { 495 if (ctx->tmp_len != 0) { 496 ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, 497 (unsigned char *)ctx->tmp, 498 ctx->tmp_len); 499 ctx->buf_off = 0; 500 ctx->tmp_len = 0; 501 goto again; 502 } 503 } else if (ctx->encode != B64_NONE 504 && EVP_ENCODE_CTX_num(ctx->base64) != 0) { 505 ctx->buf_off = 0; 506 EVP_EncodeFinal(ctx->base64, 507 (unsigned char *)ctx->buf, &(ctx->buf_len)); 508 /* push out the bytes */ 509 goto again; 510 } 511 /* Finally flush the underlying BIO */ 512 ret = BIO_ctrl(next, cmd, num, ptr); 513 break; 514 515 case BIO_C_DO_STATE_MACHINE: 516 BIO_clear_retry_flags(b); 517 ret = BIO_ctrl(next, cmd, num, ptr); 518 BIO_copy_next_retry(b); 519 break; 520 521 case BIO_CTRL_DUP: 522 break; 523 case BIO_CTRL_INFO: 524 case BIO_CTRL_GET: 525 case BIO_CTRL_SET: 526 default: 527 ret = BIO_ctrl(next, cmd, num, ptr); 528 break; 529 } 530 return ret; 531 } 532 533 static long b64_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 534 { 535 BIO *next = BIO_next(b); 536 537 if (next == NULL) 538 return 0; 539 540 return BIO_callback_ctrl(next, cmd, fp); 541 } 542 543 static int b64_puts(BIO *b, const char *str) 544 { 545 return b64_write(b, str, strlen(str)); 546 } 547