LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/pem - pem_lib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 113 405 27.9 %
Date: 2015-10-10 Functions: 6 16 37.5 %

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

Generated by: LCOV version 1.10