LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/pem - pem_info.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 136 0.0 %
Date: 2015-10-10 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /* crypto/pem/pem_info.c */
       2             : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
       3             :  * All rights reserved.
       4             :  *
       5             :  * This package is an SSL implementation written
       6             :  * by Eric Young (eay@cryptsoft.com).
       7             :  * The implementation was written so as to conform with Netscapes SSL.
       8             :  *
       9             :  * This library is free for commercial and non-commercial use as long as
      10             :  * the following conditions are aheared to.  The following conditions
      11             :  * apply to all code found in this distribution, be it the RC4, RSA,
      12             :  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
      13             :  * included with this distribution is covered by the same copyright terms
      14             :  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
      15             :  *
      16             :  * Copyright remains Eric Young's, and as such any Copyright notices in
      17             :  * the code are not to be removed.
      18             :  * If this package is used in a product, Eric Young should be given attribution
      19             :  * as the author of the parts of the library used.
      20             :  * This can be in the form of a textual message at program startup or
      21             :  * in documentation (online or textual) provided with the package.
      22             :  *
      23             :  * Redistribution and use in source and binary forms, with or without
      24             :  * modification, are permitted provided that the following conditions
      25             :  * are met:
      26             :  * 1. Redistributions of source code must retain the copyright
      27             :  *    notice, this list of conditions and the following disclaimer.
      28             :  * 2. Redistributions in binary form must reproduce the above copyright
      29             :  *    notice, this list of conditions and the following disclaimer in the
      30             :  *    documentation and/or other materials provided with the distribution.
      31             :  * 3. All advertising materials mentioning features or use of this software
      32             :  *    must display the following acknowledgement:
      33             :  *    "This product includes cryptographic software written by
      34             :  *     Eric Young (eay@cryptsoft.com)"
      35             :  *    The word 'cryptographic' can be left out if the rouines from the library
      36             :  *    being used are not cryptographic related :-).
      37             :  * 4. If you include any Windows specific code (or a derivative thereof) from
      38             :  *    the apps directory (application code) you must include an acknowledgement:
      39             :  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
      40             :  *
      41             :  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
      42             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      43             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      44             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
      45             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      46             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      47             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      49             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      50             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      51             :  * SUCH DAMAGE.
      52             :  *
      53             :  * The licence and distribution terms for any publically available version or
      54             :  * derivative of this code cannot be changed.  i.e. this code cannot simply be
      55             :  * copied and put under another distribution licence
      56             :  * [including the GNU Public Licence.]
      57             :  */
      58             : 
      59             : #include <stdio.h>
      60             : #include "cryptlib.h"
      61             : #include <openssl/buffer.h>
      62             : #include <openssl/objects.h>
      63             : #include <openssl/evp.h>
      64             : #include <openssl/x509.h>
      65             : #include <openssl/pem.h>
      66             : #ifndef OPENSSL_NO_RSA
      67             : # include <openssl/rsa.h>
      68             : #endif
      69             : #ifndef OPENSSL_NO_DSA
      70             : # include <openssl/dsa.h>
      71             : #endif
      72             : 
      73             : #ifndef OPENSSL_NO_FP_API
      74           0 : STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
      75             :                                         pem_password_cb *cb, void *u)
      76             : {
      77             :     BIO *b;
      78             :     STACK_OF(X509_INFO) *ret;
      79             : 
      80           0 :     if ((b = BIO_new(BIO_s_file())) == NULL) {
      81           0 :         PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB);
      82           0 :         return (0);
      83             :     }
      84           0 :     BIO_set_fp(b, fp, BIO_NOCLOSE);
      85           0 :     ret = PEM_X509_INFO_read_bio(b, sk, cb, u);
      86           0 :     BIO_free(b);
      87           0 :     return (ret);
      88             : }
      89             : #endif
      90             : 
      91           0 : STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
      92             :                                             pem_password_cb *cb, void *u)
      93             : {
      94             :     X509_INFO *xi = NULL;
      95           0 :     char *name = NULL, *header = NULL;
      96             :     void *pp;
      97           0 :     unsigned char *data = NULL;
      98             :     const unsigned char *p;
      99             :     long len, error = 0;
     100             :     int ok = 0;
     101             :     STACK_OF(X509_INFO) *ret = NULL;
     102             :     unsigned int i, raw, ptype;
     103             :     d2i_of_void *d2i = 0;
     104             : 
     105           0 :     if (sk == NULL) {
     106           0 :         if ((ret = sk_X509_INFO_new_null()) == NULL) {
     107           0 :             PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE);
     108           0 :             goto err;
     109             :         }
     110             :     } else
     111             :         ret = sk;
     112             : 
     113           0 :     if ((xi = X509_INFO_new()) == NULL)
     114             :         goto err;
     115             :     for (;;) {
     116             :         raw = 0;
     117             :         ptype = 0;
     118           0 :         i = PEM_read_bio(bp, &name, &header, &data, &len);
     119           0 :         if (i == 0) {
     120           0 :             error = ERR_GET_REASON(ERR_peek_last_error());
     121           0 :             if (error == PEM_R_NO_START_LINE) {
     122           0 :                 ERR_clear_error();
     123             :                 break;
     124             :             }
     125             :             goto err;
     126             :         }
     127             :  start:
     128           0 :         if ((strcmp(name, PEM_STRING_X509) == 0) ||
     129           0 :             (strcmp(name, PEM_STRING_X509_OLD) == 0)) {
     130             :             d2i = (D2I_OF(void)) d2i_X509;
     131           0 :             if (xi->x509 != NULL) {
     132           0 :                 if (!sk_X509_INFO_push(ret, xi))
     133             :                     goto err;
     134           0 :                 if ((xi = X509_INFO_new()) == NULL)
     135             :                     goto err;
     136             :                 goto start;
     137             :             }
     138           0 :             pp = &(xi->x509);
     139           0 :         } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) {
     140             :             d2i = (D2I_OF(void)) d2i_X509_AUX;
     141           0 :             if (xi->x509 != NULL) {
     142           0 :                 if (!sk_X509_INFO_push(ret, xi))
     143             :                     goto err;
     144           0 :                 if ((xi = X509_INFO_new()) == NULL)
     145             :                     goto err;
     146             :                 goto start;
     147             :             }
     148           0 :             pp = &(xi->x509);
     149           0 :         } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) {
     150             :             d2i = (D2I_OF(void)) d2i_X509_CRL;
     151           0 :             if (xi->crl != NULL) {
     152           0 :                 if (!sk_X509_INFO_push(ret, xi))
     153             :                     goto err;
     154           0 :                 if ((xi = X509_INFO_new()) == NULL)
     155             :                     goto err;
     156             :                 goto start;
     157             :             }
     158           0 :             pp = &(xi->crl);
     159             :         } else
     160             : #ifndef OPENSSL_NO_RSA
     161           0 :         if (strcmp(name, PEM_STRING_RSA) == 0) {
     162             :             d2i = (D2I_OF(void)) d2i_RSAPrivateKey;
     163           0 :             if (xi->x_pkey != NULL) {
     164           0 :                 if (!sk_X509_INFO_push(ret, xi))
     165             :                     goto err;
     166           0 :                 if ((xi = X509_INFO_new()) == NULL)
     167             :                     goto err;
     168             :                 goto start;
     169             :             }
     170             : 
     171           0 :             xi->enc_data = NULL;
     172           0 :             xi->enc_len = 0;
     173             : 
     174           0 :             xi->x_pkey = X509_PKEY_new();
     175             :             ptype = EVP_PKEY_RSA;
     176           0 :             pp = &xi->x_pkey->dec_pkey;
     177           0 :             if ((int)strlen(header) > 10) /* assume encrypted */
     178             :                 raw = 1;
     179             :         } else
     180             : #endif
     181             : #ifndef OPENSSL_NO_DSA
     182           0 :         if (strcmp(name, PEM_STRING_DSA) == 0) {
     183             :             d2i = (D2I_OF(void)) d2i_DSAPrivateKey;
     184           0 :             if (xi->x_pkey != NULL) {
     185           0 :                 if (!sk_X509_INFO_push(ret, xi))
     186             :                     goto err;
     187           0 :                 if ((xi = X509_INFO_new()) == NULL)
     188             :                     goto err;
     189             :                 goto start;
     190             :             }
     191             : 
     192           0 :             xi->enc_data = NULL;
     193           0 :             xi->enc_len = 0;
     194             : 
     195           0 :             xi->x_pkey = X509_PKEY_new();
     196             :             ptype = EVP_PKEY_DSA;
     197           0 :             pp = &xi->x_pkey->dec_pkey;
     198           0 :             if ((int)strlen(header) > 10) /* assume encrypted */
     199             :                 raw = 1;
     200             :         } else
     201             : #endif
     202             : #ifndef OPENSSL_NO_EC
     203           0 :         if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) {
     204             :             d2i = (D2I_OF(void)) d2i_ECPrivateKey;
     205           0 :             if (xi->x_pkey != NULL) {
     206           0 :                 if (!sk_X509_INFO_push(ret, xi))
     207             :                     goto err;
     208           0 :                 if ((xi = X509_INFO_new()) == NULL)
     209             :                     goto err;
     210             :                 goto start;
     211             :             }
     212             : 
     213           0 :             xi->enc_data = NULL;
     214           0 :             xi->enc_len = 0;
     215             : 
     216           0 :             xi->x_pkey = X509_PKEY_new();
     217             :             ptype = EVP_PKEY_EC;
     218           0 :             pp = &xi->x_pkey->dec_pkey;
     219           0 :             if ((int)strlen(header) > 10) /* assume encrypted */
     220             :                 raw = 1;
     221             :         } else
     222             : #endif
     223             :         {
     224             :             d2i = NULL;
     225             :             pp = NULL;
     226             :         }
     227             : 
     228           0 :         if (d2i != NULL) {
     229           0 :             if (!raw) {
     230             :                 EVP_CIPHER_INFO cipher;
     231             : 
     232           0 :                 if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
     233             :                     goto err;
     234           0 :                 if (!PEM_do_header(&cipher, data, &len, cb, u))
     235             :                     goto err;
     236           0 :                 p = data;
     237           0 :                 if (ptype) {
     238           0 :                     if (!d2i_PrivateKey(ptype, pp, &p, len)) {
     239           0 :                         PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
     240           0 :                         goto err;
     241             :                     }
     242           0 :                 } else if (d2i(pp, &p, len) == NULL) {
     243           0 :                     PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB);
     244           0 :                     goto err;
     245             :                 }
     246             :             } else {            /* encrypted RSA data */
     247           0 :                 if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher))
     248             :                     goto err;
     249           0 :                 xi->enc_data = (char *)data;
     250           0 :                 xi->enc_len = (int)len;
     251           0 :                 data = NULL;
     252             :             }
     253             :         } else {
     254             :             /* unknown */
     255             :         }
     256           0 :         if (name != NULL)
     257           0 :             OPENSSL_free(name);
     258           0 :         if (header != NULL)
     259           0 :             OPENSSL_free(header);
     260           0 :         if (data != NULL)
     261           0 :             OPENSSL_free(data);
     262           0 :         name = NULL;
     263           0 :         header = NULL;
     264           0 :         data = NULL;
     265           0 :     }
     266             : 
     267             :     /*
     268             :      * if the last one hasn't been pushed yet and there is anything in it
     269             :      * then add it to the stack ...
     270             :      */
     271           0 :     if ((xi->x509 != NULL) || (xi->crl != NULL) ||
     272           0 :         (xi->x_pkey != NULL) || (xi->enc_data != NULL)) {
     273           0 :         if (!sk_X509_INFO_push(ret, xi))
     274             :             goto err;
     275             :         xi = NULL;
     276             :     }
     277             :     ok = 1;
     278             :  err:
     279           0 :     if (xi != NULL)
     280           0 :         X509_INFO_free(xi);
     281           0 :     if (!ok) {
     282           0 :         for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) {
     283           0 :             xi = sk_X509_INFO_value(ret, i);
     284           0 :             X509_INFO_free(xi);
     285             :         }
     286           0 :         if (ret != sk)
     287           0 :             sk_X509_INFO_free(ret);
     288             :         ret = NULL;
     289             :     }
     290             : 
     291           0 :     if (name != NULL)
     292           0 :         OPENSSL_free(name);
     293           0 :     if (header != NULL)
     294           0 :         OPENSSL_free(header);
     295           0 :     if (data != NULL)
     296           0 :         OPENSSL_free(data);
     297           0 :     return (ret);
     298             : }
     299             : 
     300             : /* A TJH addition */
     301           0 : int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
     302             :                             unsigned char *kstr, int klen,
     303             :                             pem_password_cb *cb, void *u)
     304             : {
     305             :     EVP_CIPHER_CTX ctx;
     306             :     int i, ret = 0;
     307             :     unsigned char *data = NULL;
     308             :     const char *objstr = NULL;
     309             :     char buf[PEM_BUFSIZE];
     310             :     unsigned char *iv = NULL;
     311             : 
     312           0 :     if (enc != NULL) {
     313           0 :         objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
     314           0 :         if (objstr == NULL) {
     315           0 :             PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
     316           0 :             goto err;
     317             :         }
     318             :     }
     319             : 
     320             :     /*
     321             :      * now for the fun part ... if we have a private key then we have to be
     322             :      * able to handle a not-yet-decrypted key being written out correctly ...
     323             :      * if it is decrypted or it is non-encrypted then we use the base code
     324             :      */
     325           0 :     if (xi->x_pkey != NULL) {
     326           0 :         if ((xi->enc_data != NULL) && (xi->enc_len > 0)) {
     327           0 :             if (enc == NULL) {
     328           0 :                 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL);
     329           0 :                 goto err;
     330             :             }
     331             : 
     332             :             /* copy from weirdo names into more normal things */
     333           0 :             iv = xi->enc_cipher.iv;
     334             :             data = (unsigned char *)xi->enc_data;
     335             :             i = xi->enc_len;
     336             : 
     337             :             /*
     338             :              * we take the encryption data from the internal stuff rather
     339             :              * than what the user has passed us ... as we have to match
     340             :              * exactly for some strange reason
     341             :              */
     342           0 :             objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher));
     343           0 :             if (objstr == NULL) {
     344           0 :                 PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO,
     345             :                        PEM_R_UNSUPPORTED_CIPHER);
     346           0 :                 goto err;
     347             :             }
     348             : 
     349             :             /* create the right magic header stuff */
     350           0 :             OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <=
     351             :                            sizeof buf);
     352           0 :             buf[0] = '\0';
     353           0 :             PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
     354           0 :             PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
     355             : 
     356             :             /* use the normal code to write things out */
     357           0 :             i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i);
     358           0 :             if (i <= 0)
     359             :                 goto err;
     360             :         } else {
     361             :             /* Add DSA/DH */
     362             : #ifndef OPENSSL_NO_RSA
     363             :             /* normal optionally encrypted stuff */
     364           0 :             if (PEM_write_bio_RSAPrivateKey(bp,
     365           0 :                                             xi->x_pkey->dec_pkey->pkey.rsa,
     366             :                                             enc, kstr, klen, cb, u) <= 0)
     367             :                 goto err;
     368             : #endif
     369             :         }
     370             :     }
     371             : 
     372             :     /* if we have a certificate then write it out now */
     373           0 :     if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0))
     374             :         goto err;
     375             : 
     376             :     /*
     377             :      * we are ignoring anything else that is loaded into the X509_INFO
     378             :      * structure for the moment ... as I don't need it so I'm not coding it
     379             :      * here and Eric can do it when this makes it into the base library --tjh
     380             :      */
     381             : 
     382             :     ret = 1;
     383             : 
     384             :  err:
     385           0 :     OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
     386           0 :     OPENSSL_cleanse(buf, PEM_BUFSIZE);
     387           0 :     return (ret);
     388             : }

Generated by: LCOV version 1.10