1 /* crypto/pem/pem_lib.c */ 2 /* Copyright (C) 1995-1998 Eric Young (eay (at) cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay (at) cryptsoft.com). 7 * The implementation was written so as to conform with Netscapes SSL. 8 * 9 * This library is free for commercial and non-commercial use as long as 10 * the following conditions are aheared to. The following conditions 11 * apply to all code found in this distribution, be it the RC4, RSA, 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13 * included with this distribution is covered by the same copyright terms 14 * except that the holder is Tim Hudson (tjh (at) cryptsoft.com). 15 * 16 * Copyright remains Eric Young's, and as such any Copyright notices in 17 * the code are not to be removed. 18 * If this package is used in a product, Eric Young should be given attribution 19 * as the author of the parts of the library used. 20 * This can be in the form of a textual message at program startup or 21 * in documentation (online or textual) provided with the package. 22 * 23 * Redistribution and use in source and binary forms, with or without 24 * modification, are permitted provided that the following conditions 25 * are met: 26 * 1. Redistributions of source code must retain the copyright 27 * notice, this list of conditions and the following disclaimer. 28 * 2. Redistributions in binary form must reproduce the above copyright 29 * notice, this list of conditions and the following disclaimer in the 30 * documentation and/or other materials provided with the distribution. 31 * 3. All advertising materials mentioning features or use of this software 32 * must display the following acknowledgement: 33 * "This product includes cryptographic software written by 34 * Eric Young (eay (at) cryptsoft.com)" 35 * The word 'cryptographic' can be left out if the rouines from the library 36 * being used are not cryptographic related :-). 37 * 4. If you include any Windows specific code (or a derivative thereof) from 38 * the apps directory (application code) you must include an acknowledgement: 39 * "This product includes software written by Tim Hudson (tjh (at) cryptsoft.com)" 40 * 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51 * SUCH DAMAGE. 52 * 53 * The licence and distribution terms for any publically available version or 54 * derivative of this code cannot be changed. i.e. this code cannot simply be 55 * copied and put under another distribution licence 56 * [including the GNU Public Licence.] */ 57 58 #include <assert.h> 59 #include <ctype.h> 60 #include <stdio.h> 61 #include <string.h> 62 63 #include <openssl/base64.h> 64 #include <openssl/buf.h> 65 #include <openssl/des.h> 66 #include <openssl/err.h> 67 #include <openssl/evp.h> 68 #include <openssl/mem.h> 69 #include <openssl/obj.h> 70 #include <openssl/pem.h> 71 #include <openssl/rand.h> 72 #include <openssl/x509.h> 73 74 #include "../internal.h" 75 76 77 #define MIN_LENGTH 4 78 79 static int load_iv(char **fromp, unsigned char *to, int num); 80 static int check_pem(const char *nm, const char *name); 81 82 void PEM_proc_type(char *buf, int type) 83 { 84 const char *str; 85 86 if (type == PEM_TYPE_ENCRYPTED) 87 str = "ENCRYPTED"; 88 else if (type == PEM_TYPE_MIC_CLEAR) 89 str = "MIC-CLEAR"; 90 else if (type == PEM_TYPE_MIC_ONLY) 91 str = "MIC-ONLY"; 92 else 93 str = "BAD-TYPE"; 94 95 BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); 96 BUF_strlcat(buf, str, PEM_BUFSIZE); 97 BUF_strlcat(buf, "\n", PEM_BUFSIZE); 98 } 99 100 void PEM_dek_info(char *buf, const char *type, int len, char *str) 101 { 102 static const unsigned char map[17] = "0123456789ABCDEF"; 103 long i; 104 int j; 105 106 BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); 107 BUF_strlcat(buf, type, PEM_BUFSIZE); 108 BUF_strlcat(buf, ",", PEM_BUFSIZE); 109 j = strlen(buf); 110 if (j + (len * 2) + 1 > PEM_BUFSIZE) 111 return; 112 for (i = 0; i < len; i++) { 113 buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; 114 buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; 115 } 116 buf[j + i * 2] = '\n'; 117 buf[j + i * 2 + 1] = '\0'; 118 } 119 120 #ifndef OPENSSL_NO_FP_API 121 void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, 122 pem_password_cb *cb, void *u) 123 { 124 BIO *b; 125 void *ret; 126 127 if ((b = BIO_new(BIO_s_file())) == NULL) { 128 OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); 129 return (0); 130 } 131 BIO_set_fp(b, fp, BIO_NOCLOSE); 132 ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); 133 BIO_free(b); 134 return (ret); 135 } 136 #endif 137 138 static int check_pem(const char *nm, const char *name) 139 { 140 /* Normal matching nm and name */ 141 if (!strcmp(nm, name)) 142 return 1; 143 144 /* Make PEM_STRING_EVP_PKEY match any private key */ 145 146 if (!strcmp(name, PEM_STRING_EVP_PKEY)) { 147 return !strcmp(nm, PEM_STRING_PKCS8) || 148 !strcmp(nm, PEM_STRING_PKCS8INF) || 149 !strcmp(nm, PEM_STRING_RSA) || 150 !strcmp(nm, PEM_STRING_EC) || 151 !strcmp(nm, PEM_STRING_DSA); 152 } 153 154 /* Permit older strings */ 155 156 if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) 157 return 1; 158 159 if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && 160 !strcmp(name, PEM_STRING_X509_REQ)) 161 return 1; 162 163 /* Allow normal certs to be read as trusted certs */ 164 if (!strcmp(nm, PEM_STRING_X509) && 165 !strcmp(name, PEM_STRING_X509_TRUSTED)) 166 return 1; 167 168 if (!strcmp(nm, PEM_STRING_X509_OLD) && 169 !strcmp(name, PEM_STRING_X509_TRUSTED)) 170 return 1; 171 172 /* Some CAs use PKCS#7 with CERTIFICATE headers */ 173 if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) 174 return 1; 175 176 if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && 177 !strcmp(name, PEM_STRING_PKCS7)) 178 return 1; 179 180 #ifndef OPENSSL_NO_CMS 181 if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) 182 return 1; 183 /* Allow CMS to be read from PKCS#7 headers */ 184 if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) 185 return 1; 186 #endif 187 188 return 0; 189 } 190 191 int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, 192 const char *name, BIO *bp, pem_password_cb *cb, 193 void *u) 194 { 195 EVP_CIPHER_INFO cipher; 196 char *nm = NULL, *header = NULL; 197 unsigned char *data = NULL; 198 long len; 199 int ret = 0; 200 201 for (;;) { 202 if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { 203 if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) 204 ERR_add_error_data(2, "Expecting: ", name); 205 return 0; 206 } 207 if (check_pem(nm, name)) 208 break; 209 OPENSSL_free(nm); 210 OPENSSL_free(header); 211 OPENSSL_free(data); 212 } 213 if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) 214 goto err; 215 if (!PEM_do_header(&cipher, data, &len, cb, u)) 216 goto err; 217 218 *pdata = data; 219 *plen = len; 220 221 if (pnm) 222 *pnm = nm; 223 224 ret = 1; 225 226 err: 227 if (!ret || !pnm) 228 OPENSSL_free(nm); 229 OPENSSL_free(header); 230 if (!ret) 231 OPENSSL_free(data); 232 return ret; 233 } 234 235 #ifndef OPENSSL_NO_FP_API 236 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, 237 void *x, const EVP_CIPHER *enc, unsigned char *kstr, 238 int klen, pem_password_cb *callback, void *u) 239 { 240 BIO *b; 241 int ret; 242 243 if ((b = BIO_new(BIO_s_file())) == NULL) { 244 OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); 245 return (0); 246 } 247 BIO_set_fp(b, fp, BIO_NOCLOSE); 248 ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); 249 BIO_free(b); 250 return (ret); 251 } 252 #endif 253 254 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, 255 void *x, const EVP_CIPHER *enc, unsigned char *kstr, 256 int klen, pem_password_cb *callback, void *u) 257 { 258 EVP_CIPHER_CTX ctx; 259 int dsize = 0, i, j, ret = 0; 260 unsigned char *p, *data = NULL; 261 const char *objstr = NULL; 262 char buf[PEM_BUFSIZE]; 263 unsigned char key[EVP_MAX_KEY_LENGTH]; 264 unsigned char iv[EVP_MAX_IV_LENGTH]; 265 266 if (enc != NULL) { 267 objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); 268 if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) { 269 OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); 270 goto err; 271 } 272 } 273 274 if ((dsize = i2d(x, NULL)) < 0) { 275 OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); 276 dsize = 0; 277 goto err; 278 } 279 /* dzise + 8 bytes are needed */ 280 /* actually it needs the cipher block size extra... */ 281 data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); 282 if (data == NULL) { 283 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 284 goto err; 285 } 286 p = data; 287 i = i2d(x, &p); 288 289 if (enc != NULL) { 290 const unsigned iv_len = EVP_CIPHER_iv_length(enc); 291 292 if (kstr == NULL) { 293 klen = 0; 294 if (!callback) 295 callback = PEM_def_callback; 296 klen = (*callback) (buf, PEM_BUFSIZE, 1, u); 297 if (klen <= 0) { 298 OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); 299 goto err; 300 } 301 kstr = (unsigned char *)buf; 302 } 303 assert(iv_len <= (int)sizeof(iv)); 304 if (!RAND_bytes(iv, iv_len)) /* Generate a salt */ 305 goto err; 306 /* 307 * The 'iv' is used as the iv and as a salt. It is NOT taken from 308 * the BytesToKey function 309 */ 310 if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) 311 goto err; 312 313 if (kstr == (unsigned char *)buf) 314 OPENSSL_cleanse(buf, PEM_BUFSIZE); 315 316 assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); 317 318 buf[0] = '\0'; 319 PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); 320 PEM_dek_info(buf, objstr, iv_len, (char *)iv); 321 /* k=strlen(buf); */ 322 323 EVP_CIPHER_CTX_init(&ctx); 324 ret = 1; 325 if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) 326 || !EVP_EncryptUpdate(&ctx, data, &j, data, i) 327 || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) 328 ret = 0; 329 else 330 i += j; 331 EVP_CIPHER_CTX_cleanup(&ctx); 332 if (ret == 0) 333 goto err; 334 } else { 335 ret = 1; 336 buf[0] = '\0'; 337 } 338 i = PEM_write_bio(bp, name, buf, data, i); 339 if (i <= 0) 340 ret = 0; 341 err: 342 OPENSSL_cleanse(key, sizeof(key)); 343 OPENSSL_cleanse(iv, sizeof(iv)); 344 OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); 345 OPENSSL_cleanse(buf, PEM_BUFSIZE); 346 OPENSSL_free(data); 347 return (ret); 348 } 349 350 int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, 351 pem_password_cb *callback, void *u) 352 { 353 int i = 0, j, o, klen; 354 long len; 355 EVP_CIPHER_CTX ctx; 356 unsigned char key[EVP_MAX_KEY_LENGTH]; 357 char buf[PEM_BUFSIZE]; 358 359 len = *plen; 360 361 if (cipher->cipher == NULL) 362 return (1); 363 364 klen = 0; 365 if (!callback) 366 callback = PEM_def_callback; 367 klen = callback(buf, PEM_BUFSIZE, 0, u); 368 if (klen <= 0) { 369 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); 370 return (0); 371 } 372 373 if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), 374 (unsigned char *)buf, klen, 1, key, NULL)) 375 return 0; 376 377 j = (int)len; 378 EVP_CIPHER_CTX_init(&ctx); 379 o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); 380 if (o) 381 o = EVP_DecryptUpdate(&ctx, data, &i, data, j); 382 if (o) 383 o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); 384 EVP_CIPHER_CTX_cleanup(&ctx); 385 OPENSSL_cleanse((char *)buf, sizeof(buf)); 386 OPENSSL_cleanse((char *)key, sizeof(key)); 387 if (!o) { 388 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); 389 return (0); 390 } 391 j += i; 392 *plen = j; 393 return (1); 394 } 395 396 static const EVP_CIPHER *cipher_by_name(const char *name) 397 { 398 /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */ 399 if (0 == strcmp(name, SN_rc4)) { 400 return EVP_rc4(); 401 } else if (0 == strcmp(name, SN_des_cbc)) { 402 return EVP_des_cbc(); 403 } else if (0 == strcmp(name, SN_des_ede3_cbc)) { 404 return EVP_des_ede3_cbc(); 405 } else if (0 == strcmp(name, SN_aes_128_cbc)) { 406 return EVP_aes_128_cbc(); 407 } else if (0 == strcmp(name, SN_aes_192_cbc)) { 408 return EVP_aes_192_cbc(); 409 } else if (0 == strcmp(name, SN_aes_256_cbc)) { 410 return EVP_aes_256_cbc(); 411 } else { 412 return NULL; 413 } 414 } 415 416 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) 417 { 418 const EVP_CIPHER *enc = NULL; 419 char *p, c; 420 char **header_pp = &header; 421 422 cipher->cipher = NULL; 423 if ((header == NULL) || (*header == '\0') || (*header == '\n')) 424 return (1); 425 if (strncmp(header, "Proc-Type: ", 11) != 0) { 426 OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); 427 return (0); 428 } 429 header += 11; 430 if (*header != '4') 431 return (0); 432 header++; 433 if (*header != ',') 434 return (0); 435 header++; 436 if (strncmp(header, "ENCRYPTED", 9) != 0) { 437 OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); 438 return (0); 439 } 440 for (; (*header != '\n') && (*header != '\0'); header++) ; 441 if (*header == '\0') { 442 OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); 443 return (0); 444 } 445 header++; 446 if (strncmp(header, "DEK-Info: ", 10) != 0) { 447 OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); 448 return (0); 449 } 450 header += 10; 451 452 p = header; 453 for (;;) { 454 c = *header; 455 if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || 456 ((c >= '0') && (c <= '9')))) 457 break; 458 header++; 459 } 460 *header = '\0'; 461 cipher->cipher = enc = cipher_by_name(p); 462 *header = c; 463 header++; 464 465 if (enc == NULL) { 466 OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); 467 return (0); 468 } 469 if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) 470 return (0); 471 472 return (1); 473 } 474 475 static int load_iv(char **fromp, unsigned char *to, int num) 476 { 477 int v, i; 478 char *from; 479 480 from = *fromp; 481 for (i = 0; i < num; i++) 482 to[i] = 0; 483 num *= 2; 484 for (i = 0; i < num; i++) { 485 if ((*from >= '0') && (*from <= '9')) 486 v = *from - '0'; 487 else if ((*from >= 'A') && (*from <= 'F')) 488 v = *from - 'A' + 10; 489 else if ((*from >= 'a') && (*from <= 'f')) 490 v = *from - 'a' + 10; 491 else { 492 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS); 493 return (0); 494 } 495 from++; 496 to[i / 2] |= v << (long)((!(i & 1)) * 4); 497 } 498 499 *fromp = from; 500 return (1); 501 } 502 503 #ifndef OPENSSL_NO_FP_API 504 int PEM_write(FILE *fp, const char *name, const char *header, 505 const unsigned char *data, long len) 506 { 507 BIO *b; 508 int ret; 509 510 if ((b = BIO_new(BIO_s_file())) == NULL) { 511 OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); 512 return (0); 513 } 514 BIO_set_fp(b, fp, BIO_NOCLOSE); 515 ret = PEM_write_bio(b, name, header, data, len); 516 BIO_free(b); 517 return (ret); 518 } 519 #endif 520 521 int PEM_write_bio(BIO *bp, const char *name, const char *header, 522 const unsigned char *data, long len) 523 { 524 int nlen, n, i, j, outl; 525 unsigned char *buf = NULL; 526 EVP_ENCODE_CTX ctx; 527 int reason = ERR_R_BUF_LIB; 528 529 EVP_EncodeInit(&ctx); 530 nlen = strlen(name); 531 532 if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || 533 (BIO_write(bp, name, nlen) != nlen) || 534 (BIO_write(bp, "-----\n", 6) != 6)) 535 goto err; 536 537 i = strlen(header); 538 if (i > 0) { 539 if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) 540 goto err; 541 } 542 543 buf = OPENSSL_malloc(PEM_BUFSIZE * 8); 544 if (buf == NULL) { 545 reason = ERR_R_MALLOC_FAILURE; 546 goto err; 547 } 548 549 i = j = 0; 550 while (len > 0) { 551 n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); 552 EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); 553 if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) 554 goto err; 555 i += outl; 556 len -= n; 557 j += n; 558 } 559 EVP_EncodeFinal(&ctx, buf, &outl); 560 if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) 561 goto err; 562 OPENSSL_free(buf); 563 buf = NULL; 564 if ((BIO_write(bp, "-----END ", 9) != 9) || 565 (BIO_write(bp, name, nlen) != nlen) || 566 (BIO_write(bp, "-----\n", 6) != 6)) 567 goto err; 568 return (i + outl); 569 err: 570 if (buf) { 571 OPENSSL_free(buf); 572 } 573 OPENSSL_PUT_ERROR(PEM, reason); 574 return (0); 575 } 576 577 #ifndef OPENSSL_NO_FP_API 578 int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, 579 long *len) 580 { 581 BIO *b; 582 int ret; 583 584 if ((b = BIO_new(BIO_s_file())) == NULL) { 585 OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); 586 return (0); 587 } 588 BIO_set_fp(b, fp, BIO_NOCLOSE); 589 ret = PEM_read_bio(b, name, header, data, len); 590 BIO_free(b); 591 return (ret); 592 } 593 #endif 594 595 int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, 596 long *len) 597 { 598 EVP_ENCODE_CTX ctx; 599 int end = 0, i, k, bl = 0, hl = 0, nohead = 0; 600 char buf[256]; 601 BUF_MEM *nameB; 602 BUF_MEM *headerB; 603 BUF_MEM *dataB, *tmpB; 604 605 nameB = BUF_MEM_new(); 606 headerB = BUF_MEM_new(); 607 dataB = BUF_MEM_new(); 608 if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { 609 BUF_MEM_free(nameB); 610 BUF_MEM_free(headerB); 611 BUF_MEM_free(dataB); 612 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 613 return (0); 614 } 615 616 buf[254] = '\0'; 617 for (;;) { 618 i = BIO_gets(bp, buf, 254); 619 620 if (i <= 0) { 621 OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE); 622 goto err; 623 } 624 625 while ((i >= 0) && (buf[i] <= ' ')) 626 i--; 627 buf[++i] = '\n'; 628 buf[++i] = '\0'; 629 630 if (strncmp(buf, "-----BEGIN ", 11) == 0) { 631 i = strlen(&(buf[11])); 632 633 if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) 634 continue; 635 if (!BUF_MEM_grow(nameB, i + 9)) { 636 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 637 goto err; 638 } 639 OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); 640 nameB->data[i - 6] = '\0'; 641 break; 642 } 643 } 644 hl = 0; 645 if (!BUF_MEM_grow(headerB, 256)) { 646 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 647 goto err; 648 } 649 headerB->data[0] = '\0'; 650 for (;;) { 651 i = BIO_gets(bp, buf, 254); 652 if (i <= 0) 653 break; 654 655 while ((i >= 0) && (buf[i] <= ' ')) 656 i--; 657 buf[++i] = '\n'; 658 buf[++i] = '\0'; 659 660 if (buf[0] == '\n') 661 break; 662 if (!BUF_MEM_grow(headerB, hl + i + 9)) { 663 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 664 goto err; 665 } 666 if (strncmp(buf, "-----END ", 9) == 0) { 667 nohead = 1; 668 break; 669 } 670 OPENSSL_memcpy(&(headerB->data[hl]), buf, i); 671 headerB->data[hl + i] = '\0'; 672 hl += i; 673 } 674 675 bl = 0; 676 if (!BUF_MEM_grow(dataB, 1024)) { 677 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 678 goto err; 679 } 680 dataB->data[0] = '\0'; 681 if (!nohead) { 682 for (;;) { 683 i = BIO_gets(bp, buf, 254); 684 if (i <= 0) 685 break; 686 687 while ((i >= 0) && (buf[i] <= ' ')) 688 i--; 689 buf[++i] = '\n'; 690 buf[++i] = '\0'; 691 692 if (i != 65) 693 end = 1; 694 if (strncmp(buf, "-----END ", 9) == 0) 695 break; 696 if (i > 65) 697 break; 698 if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { 699 OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); 700 goto err; 701 } 702 OPENSSL_memcpy(&(dataB->data[bl]), buf, i); 703 dataB->data[bl + i] = '\0'; 704 bl += i; 705 if (end) { 706 buf[0] = '\0'; 707 i = BIO_gets(bp, buf, 254); 708 if (i <= 0) 709 break; 710 711 while ((i >= 0) && (buf[i] <= ' ')) 712 i--; 713 buf[++i] = '\n'; 714 buf[++i] = '\0'; 715 716 break; 717 } 718 } 719 } else { 720 tmpB = headerB; 721 headerB = dataB; 722 dataB = tmpB; 723 bl = hl; 724 } 725 i = strlen(nameB->data); 726 if ((strncmp(buf, "-----END ", 9) != 0) || 727 (strncmp(nameB->data, &(buf[9]), i) != 0) || 728 (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { 729 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE); 730 goto err; 731 } 732 733 EVP_DecodeInit(&ctx); 734 i = EVP_DecodeUpdate(&ctx, 735 (unsigned char *)dataB->data, &bl, 736 (unsigned char *)dataB->data, bl); 737 if (i < 0) { 738 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); 739 goto err; 740 } 741 i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); 742 if (i < 0) { 743 OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); 744 goto err; 745 } 746 bl += k; 747 748 if (bl == 0) 749 goto err; 750 *name = nameB->data; 751 *header = headerB->data; 752 *data = (unsigned char *)dataB->data; 753 *len = bl; 754 OPENSSL_free(nameB); 755 OPENSSL_free(headerB); 756 OPENSSL_free(dataB); 757 return (1); 758 err: 759 BUF_MEM_free(nameB); 760 BUF_MEM_free(headerB); 761 BUF_MEM_free(dataB); 762 return (0); 763 } 764 765 int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) 766 { 767 if (!buf || !userdata || size < 0) { 768 return 0; 769 } 770 size_t len = strlen((char *)userdata); 771 if (len >= (size_t)size) { 772 return 0; 773 } 774 BUF_strlcpy(buf, userdata, (size_t)size); 775 return len; 776 } 777