LCOV - code coverage report
Current view: top level - pem - pem_lib.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 194 409 47.4 %
Date: 2014-08-02 Functions: 8 16 50.0 %
Branches: 110 302 36.4 %

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

Generated by: LCOV version 1.9