1/* crypto/pem/pem_lib.c */ 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3 * All rights reserved. 4 * 5 * This package is an SSL implementation written 6 * by Eric Young (eay@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@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@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@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 59#include <stdio.h> 60#include "cryptlib.h" 61#include <openssl/buffer.h> 62#include <openssl/objects.h> 63#include <openssl/evp.h> 64#include <openssl/rand.h> 65#include <openssl/x509.h> 66#include <openssl/pem.h> 67#include <openssl/pkcs12.h> 68#ifndef OPENSSL_NO_DES 69#include <openssl/des.h> 70#endif 71 72const char *PEM_version="PEM" OPENSSL_VERSION_PTEXT; 73 74#define MIN_LENGTH 4 75 76static int load_iv(char **fromp,unsigned char *to, int num); 77static int check_pem(const char *nm, const char *name); 78 79int PEM_def_callback(char *buf, int num, int w, void *key) 80 { 81#ifdef OPENSSL_NO_FP_API 82 /* We should not ever call the default callback routine from 83 * windows. */ 84 PEMerr(PEM_F_DEF_CALLBACK,ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 85 return(-1); 86#else 87 int i,j; 88 const char *prompt; 89 if(key) { 90 i=strlen(key); 91 i=(i > num)?num:i; 92 memcpy(buf,key,i); 93 return(i); 94 } 95 96 prompt=EVP_get_pw_prompt(); 97 if (prompt == NULL) 98 prompt="Enter PEM pass phrase:"; 99 100 for (;;) 101 { 102 i=EVP_read_pw_string(buf,num,prompt,w); 103 if (i != 0) 104 { 105 PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD); 106 memset(buf,0,(unsigned int)num); 107 return(-1); 108 } 109 j=strlen(buf); 110 if (j < MIN_LENGTH) 111 { 112 fprintf(stderr,"phrase is too short, needs to be at least %d chars\n",MIN_LENGTH); 113 } 114 else 115 break; 116 } 117 return(j); 118#endif 119 } 120 121void PEM_proc_type(char *buf, int type) 122 { 123 const char *str; 124 125 if (type == PEM_TYPE_ENCRYPTED) 126 str="ENCRYPTED"; 127 else if (type == PEM_TYPE_MIC_CLEAR) 128 str="MIC-CLEAR"; 129 else if (type == PEM_TYPE_MIC_ONLY) 130 str="MIC-ONLY"; 131 else 132 str="BAD-TYPE"; 133 134 BUF_strlcat(buf,"Proc-Type: 4,",PEM_BUFSIZE); 135 BUF_strlcat(buf,str,PEM_BUFSIZE); 136 BUF_strlcat(buf,"\n",PEM_BUFSIZE); 137 } 138 139void PEM_dek_info(char *buf, const char *type, int len, char *str) 140 { 141 static const unsigned char map[17]="0123456789ABCDEF"; 142 long i; 143 int j; 144 145 BUF_strlcat(buf,"DEK-Info: ",PEM_BUFSIZE); 146 BUF_strlcat(buf,type,PEM_BUFSIZE); 147 BUF_strlcat(buf,",",PEM_BUFSIZE); 148 j=strlen(buf); 149 if (j + (len * 2) + 1 > PEM_BUFSIZE) 150 return; 151 for (i=0; i<len; i++) 152 { 153 buf[j+i*2] =map[(str[i]>>4)&0x0f]; 154 buf[j+i*2+1]=map[(str[i] )&0x0f]; 155 } 156 buf[j+i*2]='\n'; 157 buf[j+i*2+1]='\0'; 158 } 159 160#ifndef OPENSSL_NO_FP_API 161char *PEM_ASN1_read(char *(*d2i)(), const char *name, FILE *fp, char **x, 162 pem_password_cb *cb, void *u) 163 { 164 BIO *b; 165 char *ret; 166 167 if ((b=BIO_new(BIO_s_file())) == NULL) 168 { 169 PEMerr(PEM_F_PEM_ASN1_READ,ERR_R_BUF_LIB); 170 return(0); 171 } 172 BIO_set_fp(b,fp,BIO_NOCLOSE); 173 ret=PEM_ASN1_read_bio(d2i,name,b,x,cb,u); 174 BIO_free(b); 175 return(ret); 176 } 177#endif 178 179static int check_pem(const char *nm, const char *name) 180{ 181 /* Normal matching nm and name */ 182 if (!strcmp(nm,name)) return 1; 183 184 /* Make PEM_STRING_EVP_PKEY match any private key */ 185 186 if(!strcmp(nm,PEM_STRING_PKCS8) && 187 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 188 189 if(!strcmp(nm,PEM_STRING_PKCS8INF) && 190 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 191 192 if(!strcmp(nm,PEM_STRING_RSA) && 193 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 194 195 if(!strcmp(nm,PEM_STRING_DSA) && 196 !strcmp(name,PEM_STRING_EVP_PKEY)) return 1; 197 198 /* Permit older strings */ 199 200 if(!strcmp(nm,PEM_STRING_X509_OLD) && 201 !strcmp(name,PEM_STRING_X509)) return 1; 202 203 if(!strcmp(nm,PEM_STRING_X509_REQ_OLD) && 204 !strcmp(name,PEM_STRING_X509_REQ)) return 1; 205 206 /* Allow normal certs to be read as trusted certs */ 207 if(!strcmp(nm,PEM_STRING_X509) && 208 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; 209 210 if(!strcmp(nm,PEM_STRING_X509_OLD) && 211 !strcmp(name,PEM_STRING_X509_TRUSTED)) return 1; 212 213 /* Some CAs use PKCS#7 with CERTIFICATE headers */ 214 if(!strcmp(nm, PEM_STRING_X509) && 215 !strcmp(name, PEM_STRING_PKCS7)) return 1; 216 217 return 0; 218} 219 220int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, 221 pem_password_cb *cb, void *u) 222 { 223 EVP_CIPHER_INFO cipher; 224 char *nm=NULL,*header=NULL; 225 unsigned char *data=NULL; 226 long len; 227 int ret = 0; 228 229 for (;;) 230 { 231 if (!PEM_read_bio(bp,&nm,&header,&data,&len)) { 232 if(ERR_GET_REASON(ERR_peek_error()) == 233 PEM_R_NO_START_LINE) 234 ERR_add_error_data(2, "Expecting: ", name); 235 return 0; 236 } 237 if(check_pem(nm, name)) break; 238 OPENSSL_free(nm); 239 OPENSSL_free(header); 240 OPENSSL_free(data); 241 } 242 if (!PEM_get_EVP_CIPHER_INFO(header,&cipher)) goto err; 243 if (!PEM_do_header(&cipher,data,&len,cb,u)) goto err; 244 245 *pdata = data; 246 *plen = len; 247 248 if (pnm) 249 *pnm = nm; 250 251 ret = 1; 252 253err: 254 if (!ret || !pnm) OPENSSL_free(nm); 255 OPENSSL_free(header); 256 if (!ret) OPENSSL_free(data); 257 return ret; 258 } 259 260#ifndef OPENSSL_NO_FP_API 261int PEM_ASN1_write(int (*i2d)(), const char *name, FILE *fp, char *x, 262 const EVP_CIPHER *enc, unsigned char *kstr, int klen, 263 pem_password_cb *callback, void *u) 264 { 265 BIO *b; 266 int ret; 267 268 if ((b=BIO_new(BIO_s_file())) == NULL) 269 { 270 PEMerr(PEM_F_PEM_ASN1_WRITE,ERR_R_BUF_LIB); 271 return(0); 272 } 273 BIO_set_fp(b,fp,BIO_NOCLOSE); 274 ret=PEM_ASN1_write_bio(i2d,name,b,x,enc,kstr,klen,callback,u); 275 BIO_free(b); 276 return(ret); 277 } 278#endif 279 280int PEM_ASN1_write_bio(int (*i2d)(), const char *name, BIO *bp, char *x, 281 const EVP_CIPHER *enc, unsigned char *kstr, int klen, 282 pem_password_cb *callback, void *u) 283 { 284 EVP_CIPHER_CTX ctx; 285 int dsize=0,i,j,ret=0; 286 unsigned char *p,*data=NULL; 287 const char *objstr=NULL; 288 char buf[PEM_BUFSIZE]; 289 unsigned char key[EVP_MAX_KEY_LENGTH]; 290 unsigned char iv[EVP_MAX_IV_LENGTH]; 291 292 if (enc != NULL) 293 { 294 objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc)); 295 if (objstr == NULL) 296 { 297 PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_UNSUPPORTED_CIPHER); 298 goto err; 299 } 300 } 301 302 if ((dsize=i2d(x,NULL)) < 0) 303 { 304 PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_ASN1_LIB); 305 dsize=0; 306 goto err; 307 } 308 /* dzise + 8 bytes are needed */ 309 /* actually it needs the cipher block size extra... */ 310 data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20); 311 if (data == NULL) 312 { 313 PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,ERR_R_MALLOC_FAILURE); 314 goto err; 315 } 316 p=data; 317 i=i2d(x,&p); 318 319 if (enc != NULL) 320 { 321 if (kstr == NULL) 322 { 323 if (callback == NULL) 324 klen=PEM_def_callback(buf,PEM_BUFSIZE,1,u); 325 else 326 klen=(*callback)(buf,PEM_BUFSIZE,1,u); 327 if (klen <= 0) 328 { 329 PEMerr(PEM_F_PEM_ASN1_WRITE_BIO,PEM_R_READ_KEY); 330 goto err; 331 } 332#ifdef CHARSET_EBCDIC 333 /* Convert the pass phrase from EBCDIC */ 334 ebcdic2ascii(buf, buf, klen); 335#endif 336 kstr=(unsigned char *)buf; 337 } 338 RAND_add(data,i,0);/* put in the RSA key. */ 339 OPENSSL_assert(enc->iv_len <= sizeof iv); 340 if (RAND_pseudo_bytes(iv,enc->iv_len) < 0) /* Generate a salt */ 341 goto err; 342 /* The 'iv' is used as the iv and as a salt. It is 343 * NOT taken from the BytesToKey function */ 344 EVP_BytesToKey(enc,EVP_md5(),iv,kstr,klen,1,key,NULL); 345 346 if (kstr == (unsigned char *)buf) OPENSSL_cleanse(buf,PEM_BUFSIZE); 347 348 OPENSSL_assert(strlen(objstr)+23+2*enc->iv_len+13 <= sizeof buf); 349 350 buf[0]='\0'; 351 PEM_proc_type(buf,PEM_TYPE_ENCRYPTED); 352 PEM_dek_info(buf,objstr,enc->iv_len,(char *)iv); 353 /* k=strlen(buf); */ 354 355 EVP_CIPHER_CTX_init(&ctx); 356 EVP_EncryptInit_ex(&ctx,enc,NULL,key,iv); 357 EVP_EncryptUpdate(&ctx,data,&j,data,i); 358 EVP_EncryptFinal_ex(&ctx,&(data[j]),&i); 359 EVP_CIPHER_CTX_cleanup(&ctx); 360 i+=j; 361 ret=1; 362 } 363 else 364 { 365 ret=1; 366 buf[0]='\0'; 367 } 368 i=PEM_write_bio(bp,name,buf,data,i); 369 if (i <= 0) ret=0; 370err: 371 OPENSSL_cleanse(key,sizeof(key)); 372 OPENSSL_cleanse(iv,sizeof(iv)); 373 OPENSSL_cleanse((char *)&ctx,sizeof(ctx)); 374 OPENSSL_cleanse(buf,PEM_BUFSIZE); 375 if (data != NULL) 376 { 377 OPENSSL_cleanse(data,(unsigned int)dsize); 378 OPENSSL_free(data); 379 } 380 return(ret); 381 } 382 383int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, 384 pem_password_cb *callback,void *u) 385 { 386 int i,j,o,klen; 387 long len; 388 EVP_CIPHER_CTX ctx; 389 unsigned char key[EVP_MAX_KEY_LENGTH]; 390 char buf[PEM_BUFSIZE]; 391 392 len= *plen; 393 394 if (cipher->cipher == NULL) return(1); 395 if (callback == NULL) 396 klen=PEM_def_callback(buf,PEM_BUFSIZE,0,u); 397 else 398 klen=callback(buf,PEM_BUFSIZE,0,u); 399 if (klen <= 0) 400 { 401 PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_PASSWORD_READ); 402 return(0); 403 } 404#ifdef CHARSET_EBCDIC 405 /* Convert the pass phrase from EBCDIC */ 406 ebcdic2ascii(buf, buf, klen); 407#endif 408 409 EVP_BytesToKey(cipher->cipher,EVP_md5(),&(cipher->iv[0]), 410 (unsigned char *)buf,klen,1,key,NULL); 411 412 j=(int)len; 413 EVP_CIPHER_CTX_init(&ctx); 414 EVP_DecryptInit_ex(&ctx,cipher->cipher,NULL, key,&(cipher->iv[0])); 415 EVP_DecryptUpdate(&ctx,data,&i,data,j); 416 o=EVP_DecryptFinal_ex(&ctx,&(data[i]),&j); 417 EVP_CIPHER_CTX_cleanup(&ctx); 418 OPENSSL_cleanse((char *)buf,sizeof(buf)); 419 OPENSSL_cleanse((char *)key,sizeof(key)); 420 j+=i; 421 if (!o) 422 { 423 PEMerr(PEM_F_PEM_DO_HEADER,PEM_R_BAD_DECRYPT); 424 return(0); 425 } 426 *plen=j; 427 return(1); 428 } 429 430int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) 431 { 432 int o; 433 const EVP_CIPHER *enc=NULL; 434 char *p,c; 435 char **header_pp = &header; 436 437 cipher->cipher=NULL; 438 if ((header == NULL) || (*header == '\0') || (*header == '\n')) 439 return(1); 440 if (strncmp(header,"Proc-Type: ",11) != 0) 441 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_PROC_TYPE); return(0); } 442 header+=11; 443 if (*header != '4') return(0); header++; 444 if (*header != ',') return(0); header++; 445 if (strncmp(header,"ENCRYPTED",9) != 0) 446 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_ENCRYPTED); return(0); } 447 for (; (*header != '\n') && (*header != '\0'); header++) 448 ; 449 if (*header == '\0') 450 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_SHORT_HEADER); return(0); } 451 header++; 452 if (strncmp(header,"DEK-Info: ",10) != 0) 453 { PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_NOT_DEK_INFO); return(0); } 454 header+=10; 455 456 p=header; 457 for (;;) 458 { 459 c= *header; 460#ifndef CHARSET_EBCDIC 461 if (!( ((c >= 'A') && (c <= 'Z')) || (c == '-') || 462 ((c >= '0') && (c <= '9')))) 463 break; 464#else 465 if (!( isupper(c) || (c == '-') || 466 isdigit(c))) 467 break; 468#endif 469 header++; 470 } 471 *header='\0'; 472 o=OBJ_sn2nid(p); 473 cipher->cipher=enc=EVP_get_cipherbyname(p); 474 *header=c; 475 header++; 476 477 if (enc == NULL) 478 { 479 PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO,PEM_R_UNSUPPORTED_ENCRYPTION); 480 return(0); 481 } 482 if (!load_iv(header_pp,&(cipher->iv[0]),enc->iv_len)) 483 return(0); 484 485 return(1); 486 } 487 488static int load_iv(char **fromp, unsigned char *to, int num) 489 { 490 int v,i; 491 char *from; 492 493 from= *fromp; 494 for (i=0; i<num; i++) to[i]=0; 495 num*=2; 496 for (i=0; i<num; i++) 497 { 498 if ((*from >= '0') && (*from <= '9')) 499 v= *from-'0'; 500 else if ((*from >= 'A') && (*from <= 'F')) 501 v= *from-'A'+10; 502 else if ((*from >= 'a') && (*from <= 'f')) 503 v= *from-'a'+10; 504 else 505 { 506 PEMerr(PEM_F_LOAD_IV,PEM_R_BAD_IV_CHARS); 507 return(0); 508 } 509 from++; 510 to[i/2]|=v<<(long)((!(i&1))*4); 511 } 512 513 *fromp=from; 514 return(1); 515 } 516 517#ifndef OPENSSL_NO_FP_API 518int PEM_write(FILE *fp, char *name, char *header, unsigned char *data, 519 long len) 520 { 521 BIO *b; 522 int ret; 523 524 if ((b=BIO_new(BIO_s_file())) == NULL) 525 { 526 PEMerr(PEM_F_PEM_WRITE,ERR_R_BUF_LIB); 527 return(0); 528 } 529 BIO_set_fp(b,fp,BIO_NOCLOSE); 530 ret=PEM_write_bio(b, name, header, data,len); 531 BIO_free(b); 532 return(ret); 533 } 534#endif 535 536int PEM_write_bio(BIO *bp, const char *name, char *header, unsigned char *data, 537 long len) 538 { 539 int nlen,n,i,j,outl; 540 unsigned char *buf = NULL; 541 EVP_ENCODE_CTX ctx; 542 int reason=ERR_R_BUF_LIB; 543 544 EVP_EncodeInit(&ctx); 545 nlen=strlen(name); 546 547 if ( (BIO_write(bp,"-----BEGIN ",11) != 11) || 548 (BIO_write(bp,name,nlen) != nlen) || 549 (BIO_write(bp,"-----\n",6) != 6)) 550 goto err; 551 552 i=strlen(header); 553 if (i > 0) 554 { 555 if ( (BIO_write(bp,header,i) != i) || 556 (BIO_write(bp,"\n",1) != 1)) 557 goto err; 558 } 559 560 buf = OPENSSL_malloc(PEM_BUFSIZE*8); 561 if (buf == NULL) 562 { 563 reason=ERR_R_MALLOC_FAILURE; 564 goto err; 565 } 566 567 i=j=0; 568 while (len > 0) 569 { 570 n=(int)((len>(PEM_BUFSIZE*5))?(PEM_BUFSIZE*5):len); 571 EVP_EncodeUpdate(&ctx,buf,&outl,&(data[j]),n); 572 if ((outl) && (BIO_write(bp,(char *)buf,outl) != outl)) 573 goto err; 574 i+=outl; 575 len-=n; 576 j+=n; 577 } 578 EVP_EncodeFinal(&ctx,buf,&outl); 579 if ((outl > 0) && (BIO_write(bp,(char *)buf,outl) != outl)) goto err; 580 OPENSSL_free(buf); 581 buf = NULL; 582 if ( (BIO_write(bp,"-----END ",9) != 9) || 583 (BIO_write(bp,name,nlen) != nlen) || 584 (BIO_write(bp,"-----\n",6) != 6)) 585 goto err; 586 return(i+outl); 587err: 588 if (buf) 589 OPENSSL_free(buf); 590 PEMerr(PEM_F_PEM_WRITE_BIO,reason); 591 return(0); 592 } 593 594#ifndef OPENSSL_NO_FP_API 595int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, 596 long *len) 597 { 598 BIO *b; 599 int ret; 600 601 if ((b=BIO_new(BIO_s_file())) == NULL) 602 { 603 PEMerr(PEM_F_PEM_READ,ERR_R_BUF_LIB); 604 return(0); 605 } 606 BIO_set_fp(b,fp,BIO_NOCLOSE); 607 ret=PEM_read_bio(b, name, header, data,len); 608 BIO_free(b); 609 return(ret); 610 } 611#endif 612 613int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, 614 long *len) 615 { 616 EVP_ENCODE_CTX ctx; 617 int end=0,i,k,bl=0,hl=0,nohead=0; 618 char buf[256]; 619 BUF_MEM *nameB; 620 BUF_MEM *headerB; 621 BUF_MEM *dataB,*tmpB; 622 623 nameB=BUF_MEM_new(); 624 headerB=BUF_MEM_new(); 625 dataB=BUF_MEM_new(); 626 if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) 627 { 628 BUF_MEM_free(nameB); 629 BUF_MEM_free(headerB); 630 BUF_MEM_free(dataB); 631 PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); 632 return(0); 633 } 634 635 buf[254]='\0'; 636 for (;;) 637 { 638 i=BIO_gets(bp,buf,254); 639 640 if (i <= 0) 641 { 642 PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE); 643 goto err; 644 } 645 646 while ((i >= 0) && (buf[i] <= ' ')) i--; 647 buf[++i]='\n'; buf[++i]='\0'; 648 649 if (strncmp(buf,"-----BEGIN ",11) == 0) 650 { 651 i=strlen(&(buf[11])); 652 653 if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0) 654 continue; 655 if (!BUF_MEM_grow(nameB,i+9)) 656 { 657 PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); 658 goto err; 659 } 660 memcpy(nameB->data,&(buf[11]),i-6); 661 nameB->data[i-6]='\0'; 662 break; 663 } 664 } 665 hl=0; 666 if (!BUF_MEM_grow(headerB,256)) 667 { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } 668 headerB->data[0]='\0'; 669 for (;;) 670 { 671 i=BIO_gets(bp,buf,254); 672 if (i <= 0) break; 673 674 while ((i >= 0) && (buf[i] <= ' ')) i--; 675 buf[++i]='\n'; buf[++i]='\0'; 676 677 if (buf[0] == '\n') break; 678 if (!BUF_MEM_grow(headerB,hl+i+9)) 679 { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } 680 if (strncmp(buf,"-----END ",9) == 0) 681 { 682 nohead=1; 683 break; 684 } 685 memcpy(&(headerB->data[hl]),buf,i); 686 headerB->data[hl+i]='\0'; 687 hl+=i; 688 } 689 690 bl=0; 691 if (!BUF_MEM_grow(dataB,1024)) 692 { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; } 693 dataB->data[0]='\0'; 694 if (!nohead) 695 { 696 for (;;) 697 { 698 i=BIO_gets(bp,buf,254); 699 if (i <= 0) break; 700 701 while ((i >= 0) && (buf[i] <= ' ')) i--; 702 buf[++i]='\n'; buf[++i]='\0'; 703 704 if (i != 65) end=1; 705 if (strncmp(buf,"-----END ",9) == 0) 706 break; 707 if (i > 65) break; 708 if (!BUF_MEM_grow_clean(dataB,i+bl+9)) 709 { 710 PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); 711 goto err; 712 } 713 memcpy(&(dataB->data[bl]),buf,i); 714 dataB->data[bl+i]='\0'; 715 bl+=i; 716 if (end) 717 { 718 buf[0]='\0'; 719 i=BIO_gets(bp,buf,254); 720 if (i <= 0) break; 721 722 while ((i >= 0) && (buf[i] <= ' ')) i--; 723 buf[++i]='\n'; buf[++i]='\0'; 724 725 break; 726 } 727 } 728 } 729 else 730 { 731 tmpB=headerB; 732 headerB=dataB; 733 dataB=tmpB; 734 bl=hl; 735 } 736 i=strlen(nameB->data); 737 if ( (strncmp(buf,"-----END ",9) != 0) || 738 (strncmp(nameB->data,&(buf[9]),i) != 0) || 739 (strncmp(&(buf[9+i]),"-----\n",6) != 0)) 740 { 741 PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE); 742 goto err; 743 } 744 745 EVP_DecodeInit(&ctx); 746 i=EVP_DecodeUpdate(&ctx, 747 (unsigned char *)dataB->data,&bl, 748 (unsigned char *)dataB->data,bl); 749 if (i < 0) 750 { 751 PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE); 752 goto err; 753 } 754 i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k); 755 if (i < 0) 756 { 757 PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE); 758 goto err; 759 } 760 bl+=k; 761 762 if (bl == 0) goto err; 763 *name=nameB->data; 764 *header=headerB->data; 765 *data=(unsigned char *)dataB->data; 766 *len=bl; 767 OPENSSL_free(nameB); 768 OPENSSL_free(headerB); 769 OPENSSL_free(dataB); 770 return(1); 771err: 772 BUF_MEM_free(nameB); 773 BUF_MEM_free(headerB); 774 BUF_MEM_free(dataB); 775 return(0); 776 } 777