LCOV - code coverage report
Current view: top level - pkcs7 - pk7_doit.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 328 558 58.8 %
Date: 2014-08-02 Functions: 18 24 75.0 %
Branches: 176 404 43.6 %

           Branch data     Line data    Source code
       1                 :            : /* crypto/pkcs7/pk7_doit.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/rand.h>
      62                 :            : #include <openssl/objects.h>
      63                 :            : #include <openssl/x509.h>
      64                 :            : #include <openssl/x509v3.h>
      65                 :            : #include <openssl/err.h>
      66                 :            : 
      67                 :            : static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
      68                 :            :                          void *value);
      69                 :            : static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
      70                 :            : 
      71                 :         30 : static int PKCS7_type_is_other(PKCS7* p7)
      72                 :            :         {
      73                 :         15 :         int isOther=1;
      74                 :            :         
      75                 :         15 :         int nid=OBJ_obj2nid(p7->type);
      76                 :            : 
      77         [ +  - ]:         15 :         switch( nid )
      78                 :            :                 {
      79                 :            :         case NID_pkcs7_data:
      80                 :            :         case NID_pkcs7_signed:
      81                 :            :         case NID_pkcs7_enveloped:
      82                 :            :         case NID_pkcs7_signedAndEnveloped:
      83                 :            :         case NID_pkcs7_digest:
      84                 :            :         case NID_pkcs7_encrypted:
      85                 :            :                 isOther=0;
      86                 :            :                 break;
      87                 :            :         default:
      88                 :         15 :                 isOther=1;
      89                 :            :                 }
      90                 :            : 
      91                 :         15 :         return isOther;
      92                 :            : 
      93                 :            :         }
      94                 :            : 
      95                 :         46 : static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
      96                 :            :         {
      97         [ +  + ]:         46 :         if ( PKCS7_type_is_data(p7))
      98                 :         31 :                 return p7->d.data;
      99 [ +  - ][ +  - ]:         15 :         if ( PKCS7_type_is_other(p7) && p7->d.other
     100         [ +  - ]:         15 :                 && (p7->d.other->type == V_ASN1_OCTET_STRING))
     101                 :         15 :                 return p7->d.other->value.octet_string;
     102                 :            :         return NULL;
     103                 :            :         }
     104                 :            : 
     105                 :         66 : static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
     106                 :            :         {
     107                 :            :         BIO *btmp;
     108                 :            :         const EVP_MD *md;
     109         [ -  + ]:         33 :         if ((btmp=BIO_new(BIO_f_md())) == NULL)
     110                 :            :                 {
     111                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
     112                 :            :                 goto err;
     113                 :            :                 }
     114                 :            : 
     115                 :         33 :         md=EVP_get_digestbyobj(alg->algorithm);
     116         [ -  + ]:         33 :         if (md == NULL)
     117                 :            :                 {
     118                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,PKCS7_R_UNKNOWN_DIGEST_TYPE);
     119                 :            :                 goto err;
     120                 :            :                 }
     121                 :            : 
     122                 :         33 :         BIO_set_md(btmp,md);
     123         [ +  - ]:         33 :         if (*pbio == NULL)
     124                 :         33 :                 *pbio=btmp;
     125         [ #  # ]:          0 :         else if (!BIO_push(*pbio,btmp))
     126                 :            :                 {
     127                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST,ERR_R_BIO_LIB);
     128                 :            :                 goto err;
     129                 :            :                 }
     130                 :            :         btmp=NULL;
     131                 :            : 
     132                 :            :         return 1;
     133                 :            : 
     134                 :            :         err:
     135         [ #  # ]:          0 :         if (btmp)
     136                 :          0 :                 BIO_free(btmp);
     137                 :            :         return 0;
     138                 :            : 
     139                 :            :         }
     140                 :            : 
     141                 :         12 : static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
     142                 :            :                                         unsigned char *key, int keylen)
     143                 :            :         {
     144                 :         12 :         EVP_PKEY_CTX *pctx = NULL;
     145                 :         12 :         EVP_PKEY *pkey = NULL;
     146                 :         12 :         unsigned char *ek = NULL;
     147                 :         12 :         int ret = 0;
     148                 :            :         size_t eklen;
     149                 :            : 
     150                 :         12 :         pkey = X509_get_pubkey(ri->cert);
     151                 :            : 
     152         [ +  - ]:         12 :         if (!pkey)
     153                 :            :                 return 0;
     154                 :            : 
     155                 :         12 :         pctx = EVP_PKEY_CTX_new(pkey, NULL);
     156         [ +  - ]:         12 :         if (!pctx)
     157                 :            :                 return 0;
     158                 :            : 
     159         [ +  - ]:         12 :         if (EVP_PKEY_encrypt_init(pctx) <= 0)
     160                 :            :                 goto err;
     161                 :            : 
     162         [ -  + ]:         12 :         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
     163                 :            :                                 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
     164                 :            :                 {
     165                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
     166                 :          0 :                 goto err;
     167                 :            :                 }
     168                 :            : 
     169         [ +  - ]:         12 :         if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
     170                 :            :                 goto err;
     171                 :            : 
     172                 :         12 :         ek = OPENSSL_malloc(eklen);
     173                 :            : 
     174         [ -  + ]:         12 :         if (ek == NULL)
     175                 :            :                 {
     176                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
     177                 :          0 :                 goto err;
     178                 :            :                 }
     179                 :            : 
     180         [ +  - ]:         12 :         if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
     181                 :            :                 goto err;
     182                 :            : 
     183                 :         12 :         ASN1_STRING_set0(ri->enc_key, ek, eklen);
     184                 :         12 :         ek = NULL;
     185                 :            : 
     186                 :         12 :         ret = 1;
     187                 :            : 
     188                 :            :         err:
     189         [ +  - ]:         12 :         if (pkey)
     190                 :         12 :                 EVP_PKEY_free(pkey);
     191         [ +  - ]:         12 :         if (pctx)
     192                 :         12 :                 EVP_PKEY_CTX_free(pctx);
     193         [ -  + ]:         12 :         if (ek)
     194                 :          0 :                 OPENSSL_free(ek);
     195                 :         12 :         return ret;
     196                 :            : 
     197                 :            :         }
     198                 :            : 
     199                 :            : 
     200                 :          6 : static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
     201                 :            :                                PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
     202                 :            :         {
     203                 :          6 :         EVP_PKEY_CTX *pctx = NULL;
     204                 :          6 :         unsigned char *ek = NULL;
     205                 :            :         size_t eklen;
     206                 :            : 
     207                 :          6 :         int ret = -1;
     208                 :            : 
     209                 :          6 :         pctx = EVP_PKEY_CTX_new(pkey, NULL);
     210         [ +  - ]:          6 :         if (!pctx)
     211                 :            :                 return -1;
     212                 :            : 
     213         [ +  - ]:          6 :         if (EVP_PKEY_decrypt_init(pctx) <= 0)
     214                 :            :                 goto err;
     215                 :            : 
     216         [ -  + ]:          6 :         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
     217                 :            :                                 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
     218                 :            :                 {
     219                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
     220                 :          0 :                 goto err;
     221                 :            :                 }
     222                 :            : 
     223         [ +  - ]:          6 :         if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
     224                 :         12 :                                 ri->enc_key->data, ri->enc_key->length) <= 0)
     225                 :            :                 goto err;
     226                 :            : 
     227                 :          6 :         ek = OPENSSL_malloc(eklen);
     228                 :            : 
     229         [ -  + ]:          6 :         if (ek == NULL)
     230                 :            :                 {
     231                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
     232                 :          0 :                 goto err;
     233                 :            :                 }
     234                 :            : 
     235         [ +  + ]:          6 :         if (EVP_PKEY_decrypt(pctx, ek, &eklen,
     236                 :         12 :                                 ri->enc_key->data, ri->enc_key->length) <= 0)
     237                 :            :                 {
     238                 :          2 :                 ret = 0;
     239                 :          2 :                 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
     240                 :          2 :                 goto err;
     241                 :            :                 }
     242                 :            : 
     243                 :          4 :         ret = 1;
     244                 :            : 
     245         [ -  + ]:          4 :         if (*pek)
     246                 :            :                 {
     247                 :          0 :                 OPENSSL_cleanse(*pek, *peklen);
     248                 :          0 :                 OPENSSL_free(*pek);
     249                 :            :                 }
     250                 :            : 
     251                 :          4 :         *pek = ek;
     252                 :          4 :         *peklen = eklen;
     253                 :            : 
     254                 :            :         err:
     255         [ +  - ]:          6 :         if (pctx)
     256                 :          6 :                 EVP_PKEY_CTX_free(pctx);
     257         [ +  + ]:          6 :         if (!ret && ek)
     258                 :          2 :                 OPENSSL_free(ek);
     259                 :            : 
     260                 :          6 :         return ret;
     261                 :            :         }
     262                 :            : 
     263                 :         37 : BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
     264                 :            :         {
     265                 :            :         int i;
     266                 :         37 :         BIO *out=NULL,*btmp=NULL;
     267                 :         37 :         X509_ALGOR *xa = NULL;
     268                 :         37 :         const EVP_CIPHER *evp_cipher=NULL;
     269                 :         37 :         STACK_OF(X509_ALGOR) *md_sk=NULL;
     270                 :         37 :         STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
     271                 :         37 :         X509_ALGOR *xalg=NULL;
     272                 :         37 :         PKCS7_RECIP_INFO *ri=NULL;
     273                 :         37 :         ASN1_OCTET_STRING *os=NULL;
     274                 :            : 
     275                 :         37 :         i=OBJ_obj2nid(p7->type);
     276                 :         37 :         p7->state=PKCS7_S_HEADER;
     277                 :            : 
     278   [ +  -  +  -  :         37 :         switch (i)
                   -  - ]
     279                 :            :                 {
     280                 :            :         case NID_pkcs7_signed:
     281                 :         33 :                 md_sk=p7->d.sign->md_algs;
     282                 :         33 :                 os = PKCS7_get_octet_string(p7->d.sign->contents);
     283                 :         33 :                 break;
     284                 :            :         case NID_pkcs7_signedAndEnveloped:
     285                 :          0 :                 rsk=p7->d.signed_and_enveloped->recipientinfo;
     286                 :          0 :                 md_sk=p7->d.signed_and_enveloped->md_algs;
     287                 :          0 :                 xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
     288                 :          0 :                 evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
     289         [ #  # ]:          0 :                 if (evp_cipher == NULL)
     290                 :            :                         {
     291                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATAINIT,
     292                 :            :                                                 PKCS7_R_CIPHER_NOT_INITIALIZED);
     293                 :          0 :                         goto err;
     294                 :            :                         }
     295                 :            :                 break;
     296                 :            :         case NID_pkcs7_enveloped:
     297                 :          4 :                 rsk=p7->d.enveloped->recipientinfo;
     298                 :          4 :                 xalg=p7->d.enveloped->enc_data->algorithm;
     299                 :          4 :                 evp_cipher=p7->d.enveloped->enc_data->cipher;
     300         [ -  + ]:          4 :                 if (evp_cipher == NULL)
     301                 :            :                         {
     302                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATAINIT,
     303                 :            :                                                 PKCS7_R_CIPHER_NOT_INITIALIZED);
     304                 :          0 :                         goto err;
     305                 :            :                         }
     306                 :            :                 break;
     307                 :            :         case NID_pkcs7_digest:
     308                 :          0 :                 xa = p7->d.digest->md;
     309                 :          0 :                 os = PKCS7_get_octet_string(p7->d.digest->contents);
     310                 :          0 :                 break;
     311                 :            :         case NID_pkcs7_data:
     312                 :            :                 break;
     313                 :            :         default:
     314                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
     315                 :          0 :                 goto err;
     316                 :            :                 }
     317                 :            : 
     318         [ +  + ]:         70 :         for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
     319         [ +  - ]:         33 :                 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
     320                 :            :                         goto err;
     321                 :            : 
     322 [ -  + ][ #  # ]:         37 :         if (xa && !PKCS7_bio_add_digest(&out, xa))
     323                 :            :                         goto err;
     324                 :            : 
     325         [ +  + ]:         37 :         if (evp_cipher != NULL)
     326                 :            :                 {
     327                 :            :                 unsigned char key[EVP_MAX_KEY_LENGTH];
     328                 :            :                 unsigned char iv[EVP_MAX_IV_LENGTH];
     329                 :            :                 int keylen,ivlen;
     330                 :            :                 EVP_CIPHER_CTX *ctx;
     331                 :            : 
     332         [ -  + ]:          4 :                 if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
     333                 :            :                         {
     334                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
     335                 :          0 :                         goto err;
     336                 :            :                         }
     337                 :          4 :                 BIO_get_cipher_ctx(btmp, &ctx);
     338                 :          4 :                 keylen=EVP_CIPHER_key_length(evp_cipher);
     339                 :          4 :                 ivlen=EVP_CIPHER_iv_length(evp_cipher);
     340                 :          4 :                 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
     341         [ +  - ]:          4 :                 if (ivlen > 0)
     342         [ +  - ]:          4 :                         if (RAND_pseudo_bytes(iv,ivlen) <= 0)
     343                 :            :                                 goto err;
     344         [ +  - ]:          4 :                 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1)<=0)
     345                 :            :                         goto err;
     346         [ +  - ]:          4 :                 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
     347                 :            :                         goto err;
     348         [ +  - ]:          4 :                 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
     349                 :            :                         goto err;
     350                 :            : 
     351         [ +  - ]:          4 :                 if (ivlen > 0) {
     352         [ +  - ]:          4 :                         if (xalg->parameter == NULL) {
     353                 :          4 :                                 xalg->parameter = ASN1_TYPE_new();
     354         [ +  - ]:          4 :                                 if (xalg->parameter == NULL)
     355                 :            :                                         goto err;
     356                 :            :                         }
     357         [ +  - ]:          4 :                         if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
     358                 :            :                                 goto err;
     359                 :            :                 }
     360                 :            : 
     361                 :            :                 /* Lets do the pub key stuff :-) */
     362         [ +  + ]:         16 :                 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
     363                 :            :                         {
     364                 :         12 :                         ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
     365         [ +  - ]:         12 :                         if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
     366                 :            :                                 goto err;
     367                 :            :                         }
     368                 :          4 :                 OPENSSL_cleanse(key, keylen);
     369                 :            : 
     370         [ +  - ]:          4 :                 if (out == NULL)
     371                 :          4 :                         out=btmp;
     372                 :            :                 else
     373                 :          0 :                         BIO_push(out,btmp);
     374                 :          4 :                 btmp=NULL;
     375                 :            :                 }
     376                 :            : 
     377         [ +  + ]:         37 :         if (bio == NULL)
     378                 :            :                 {
     379 [ +  - ][ +  + ]:         23 :                 if (PKCS7_is_detached(p7))
     380                 :          2 :                         bio=BIO_new(BIO_s_null());
     381 [ +  - ][ +  + ]:         21 :                 else if (os && os->length > 0)
     382                 :         16 :                         bio = BIO_new_mem_buf(os->data, os->length);
     383         [ +  + ]:         23 :                 if(bio == NULL)
     384                 :            :                         {
     385                 :          5 :                         bio=BIO_new(BIO_s_mem());
     386         [ +  - ]:          5 :                         if (bio == NULL)
     387                 :            :                                 goto err;
     388                 :          5 :                         BIO_set_mem_eof_return(bio,0);
     389                 :            :                         }
     390                 :            :                 }
     391         [ +  - ]:         37 :         if (out)
     392                 :         37 :                 BIO_push(out,bio);
     393                 :            :         else
     394                 :          0 :                 out = bio;
     395                 :            :         bio=NULL;
     396                 :            :         if (0)
     397                 :            :                 {
     398                 :            : err:
     399         [ #  # ]:          0 :                 if (out != NULL)
     400                 :          0 :                         BIO_free_all(out);
     401         [ #  # ]:          0 :                 if (btmp != NULL)
     402                 :          0 :                         BIO_free_all(btmp);
     403                 :          0 :                 out=NULL;
     404                 :            :                 }
     405                 :         37 :         return(out);
     406                 :            :         }
     407                 :            : 
     408                 :         10 : static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
     409                 :            :         {
     410                 :            :         int ret;
     411                 :          5 :         ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
     412                 :          5 :                                 pcert->cert_info->issuer);
     413         [ +  - ]:          5 :         if (ret)
     414                 :            :                 return ret;
     415                 :          5 :         return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
     416                 :            :                                         ri->issuer_and_serial->serial);
     417                 :            :         }
     418                 :            : 
     419                 :            : /* int */
     420                 :          4 : BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
     421                 :            :         {
     422                 :            :         int i,j;
     423                 :          4 :         BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
     424                 :            :         X509_ALGOR *xa;
     425                 :          4 :         ASN1_OCTET_STRING *data_body=NULL;
     426                 :            :         const EVP_MD *evp_md;
     427                 :          4 :         const EVP_CIPHER *evp_cipher=NULL;
     428                 :          4 :         EVP_CIPHER_CTX *evp_ctx=NULL;
     429                 :          4 :         X509_ALGOR *enc_alg=NULL;
     430                 :          4 :         STACK_OF(X509_ALGOR) *md_sk=NULL;
     431                 :          4 :         STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
     432                 :          4 :         PKCS7_RECIP_INFO *ri=NULL;
     433                 :          4 :        unsigned char *ek = NULL, *tkey = NULL;
     434                 :          4 :        int eklen = 0, tkeylen = 0;
     435                 :            : 
     436                 :          4 :         i=OBJ_obj2nid(p7->type);
     437                 :          4 :         p7->state=PKCS7_S_HEADER;
     438                 :            : 
     439   [ -  -  +  - ]:          4 :         switch (i)
     440                 :            :                 {
     441                 :            :         case NID_pkcs7_signed:
     442                 :          0 :                 data_body=PKCS7_get_octet_string(p7->d.sign->contents);
     443 [ #  # ][ #  # ]:          0 :                 if (!PKCS7_is_detached(p7) && data_body == NULL)
                 [ #  # ]
     444                 :            :                         {
     445                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_INVALID_SIGNED_DATA_TYPE);
     446                 :          0 :                         goto err;
     447                 :            :                         }
     448                 :          0 :                 md_sk=p7->d.sign->md_algs;
     449                 :          0 :                 break;
     450                 :            :         case NID_pkcs7_signedAndEnveloped:
     451                 :          0 :                 rsk=p7->d.signed_and_enveloped->recipientinfo;
     452                 :          0 :                 md_sk=p7->d.signed_and_enveloped->md_algs;
     453                 :          0 :                 data_body=p7->d.signed_and_enveloped->enc_data->enc_data;
     454                 :          0 :                 enc_alg=p7->d.signed_and_enveloped->enc_data->algorithm;
     455                 :          0 :                 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
     456         [ #  # ]:          0 :                 if (evp_cipher == NULL)
     457                 :            :                         {
     458                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
     459                 :          0 :                         goto err;
     460                 :            :                         }
     461                 :            :                 break;
     462                 :            :         case NID_pkcs7_enveloped:
     463                 :          4 :                 rsk=p7->d.enveloped->recipientinfo;
     464                 :          4 :                 enc_alg=p7->d.enveloped->enc_data->algorithm;
     465                 :          4 :                 data_body=p7->d.enveloped->enc_data->enc_data;
     466                 :          4 :                 evp_cipher=EVP_get_cipherbyobj(enc_alg->algorithm);
     467         [ -  + ]:          4 :                 if (evp_cipher == NULL)
     468                 :            :                         {
     469                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
     470                 :          0 :                         goto err;
     471                 :            :                         }
     472                 :            :                 break;
     473                 :            :         default:
     474                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
     475                 :          0 :                 goto err;
     476                 :            :                 }
     477                 :            : 
     478                 :            :         /* We will be checking the signature */
     479         [ -  + ]:          4 :         if (md_sk != NULL)
     480                 :            :                 {
     481         [ #  # ]:          0 :                 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++)
     482                 :            :                         {
     483                 :          0 :                         xa=sk_X509_ALGOR_value(md_sk,i);
     484         [ #  # ]:          0 :                         if ((btmp=BIO_new(BIO_f_md())) == NULL)
     485                 :            :                                 {
     486                 :          0 :                                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
     487                 :          0 :                                 goto err;
     488                 :            :                                 }
     489                 :            : 
     490                 :          0 :                         j=OBJ_obj2nid(xa->algorithm);
     491                 :          0 :                         evp_md=EVP_get_digestbynid(j);
     492         [ #  # ]:          0 :                         if (evp_md == NULL)
     493                 :            :                                 {
     494                 :          0 :                                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
     495                 :          0 :                                 goto err;
     496                 :            :                                 }
     497                 :            : 
     498                 :          0 :                         BIO_set_md(btmp,evp_md);
     499         [ #  # ]:          0 :                         if (out == NULL)
     500                 :            :                                 out=btmp;
     501                 :            :                         else
     502                 :          0 :                                 BIO_push(out,btmp);
     503                 :          0 :                         btmp=NULL;
     504                 :            :                         }
     505                 :            :                 }
     506                 :            : 
     507         [ +  - ]:          4 :         if (evp_cipher != NULL)
     508                 :            :                 {
     509                 :            : #if 0
     510                 :            :                 unsigned char key[EVP_MAX_KEY_LENGTH];
     511                 :            :                 unsigned char iv[EVP_MAX_IV_LENGTH];
     512                 :            :                 unsigned char *p;
     513                 :            :                 int keylen,ivlen;
     514                 :            :                 int max;
     515                 :            :                 X509_OBJECT ret;
     516                 :            : #endif
     517                 :            : 
     518         [ -  + ]:          4 :                 if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
     519                 :            :                         {
     520                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
     521                 :          0 :                         goto err;
     522                 :            :                         }
     523                 :            : 
     524                 :            :                 /* It was encrypted, we need to decrypt the secret key
     525                 :            :                  * with the private key */
     526                 :            : 
     527                 :            :                 /* Find the recipientInfo which matches the passed certificate
     528                 :            :                  * (if any)
     529                 :            :                  */
     530                 :            : 
     531         [ +  + ]:          4 :                 if (pcert)
     532                 :            :                         {
     533         [ +  - ]:          5 :                         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
     534                 :            :                                 {
     535                 :          5 :                                 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
     536         [ +  + ]:          5 :                                 if (!pkcs7_cmp_ri(ri, pcert))
     537                 :            :                                         break;
     538                 :          2 :                                 ri=NULL;
     539                 :            :                                 }
     540         [ -  + ]:          3 :                         if (ri == NULL)
     541                 :            :                                 {
     542                 :          0 :                                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
     543                 :            :                                       PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
     544                 :          0 :                                 goto err;
     545                 :            :                                 }
     546                 :            :                         }
     547                 :            : 
     548                 :            :                 /* If we haven't got a certificate try each ri in turn */
     549         [ +  + ]:          4 :                 if (pcert == NULL)
     550                 :            :                         {
     551                 :            :                         /* Always attempt to decrypt all rinfo even
     552                 :            :                          * after success as a defence against MMA timing
     553                 :            :                          * attacks.
     554                 :            :                          */
     555         [ +  + ]:          4 :                         for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
     556                 :            :                                 {
     557                 :          3 :                                 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
     558                 :            :                                 
     559         [ +  - ]:          3 :                                 if (pkcs7_decrypt_rinfo(&ek, &eklen,
     560                 :            :                                                         ri, pkey) < 0)
     561                 :            :                                         goto err;
     562                 :          3 :                                 ERR_clear_error();
     563                 :            :                                 }
     564                 :            :                         }
     565                 :            :                 else
     566                 :            :                         {
     567                 :            :                         /* Only exit on fatal errors, not decrypt failure */
     568         [ +  - ]:          3 :                         if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
     569                 :            :                                 goto err;
     570                 :          3 :                         ERR_clear_error();
     571                 :            :                         }
     572                 :            : 
     573                 :          4 :                 evp_ctx=NULL;
     574                 :          4 :                 BIO_get_cipher_ctx(etmp,&evp_ctx);
     575         [ +  - ]:          4 :                 if (EVP_CipherInit_ex(evp_ctx,evp_cipher,NULL,NULL,NULL,0) <= 0)
     576                 :            :                         goto err;
     577         [ +  - ]:          4 :                 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
     578                 :            :                         goto err;
     579                 :            :                 /* Generate random key as MMA defence */
     580                 :          4 :                 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
     581                 :          4 :                 tkey = OPENSSL_malloc(tkeylen);
     582         [ +  - ]:          4 :                 if (!tkey)
     583                 :            :                         goto err;
     584         [ +  - ]:          4 :                 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
     585                 :            :                         goto err;
     586         [ -  + ]:          4 :                 if (ek == NULL)
     587                 :            :                         {
     588                 :          0 :                         ek = tkey;
     589                 :          0 :                         eklen = tkeylen;
     590                 :          0 :                         tkey = NULL;
     591                 :            :                         }
     592                 :            : 
     593         [ -  + ]:          4 :                 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
     594                 :            :                         /* Some S/MIME clients don't use the same key
     595                 :            :                          * and effective key length. The key length is
     596                 :            :                          * determined by the size of the decrypted RSA key.
     597                 :            :                          */
     598         [ #  # ]:          0 :                         if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
     599                 :            :                                 {
     600                 :            :                                 /* Use random key as MMA defence */
     601                 :          0 :                                 OPENSSL_cleanse(ek, eklen);
     602                 :          0 :                                 OPENSSL_free(ek);
     603                 :          0 :                                 ek = tkey;
     604                 :          0 :                                 eklen = tkeylen;
     605                 :          0 :                                 tkey = NULL;
     606                 :            :                                 }
     607                 :            :                 } 
     608                 :            :                 /* Clear errors so we don't leak information useful in MMA */
     609                 :          4 :                 ERR_clear_error();
     610         [ +  - ]:          4 :                 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
     611                 :            :                         goto err;
     612                 :            : 
     613         [ +  - ]:          4 :                 if (ek)
     614                 :            :                         {
     615                 :          4 :                         OPENSSL_cleanse(ek,eklen);
     616                 :          4 :                         OPENSSL_free(ek);
     617                 :          4 :                        ek = NULL;
     618                 :            :                         }
     619         [ +  - ]:          4 :                 if (tkey)
     620                 :            :                         {
     621                 :          4 :                         OPENSSL_cleanse(tkey,tkeylen);
     622                 :          4 :                         OPENSSL_free(tkey);
     623                 :          4 :                        tkey = NULL;
     624                 :            :                         }
     625                 :            : 
     626         [ -  + ]:          4 :                 if (out == NULL)
     627                 :            :                         out=etmp;
     628                 :            :                 else
     629                 :          0 :                         BIO_push(out,etmp);
     630                 :            :                 etmp=NULL;
     631                 :            :                 }
     632                 :            : 
     633                 :            : #if 1
     634 [ -  + ][ #  # ]:          4 :         if (PKCS7_is_detached(p7) || (in_bio != NULL))
                 [ -  + ]
     635                 :            :                 {
     636                 :          0 :                 bio=in_bio;
     637                 :            :                 }
     638                 :            :         else 
     639                 :            :                 {
     640                 :            : #if 0
     641                 :            :                 bio=BIO_new(BIO_s_mem());
     642                 :            :                 /* We need to set this so that when we have read all
     643                 :            :                  * the data, the encrypt BIO, if present, will read
     644                 :            :                  * EOF and encode the last few bytes */
     645                 :            :                 BIO_set_mem_eof_return(bio,0);
     646                 :            : 
     647                 :            :                 if (data_body->length > 0)
     648                 :            :                         BIO_write(bio,(char *)data_body->data,data_body->length);
     649                 :            : #else
     650         [ +  - ]:          4 :                 if (data_body->length > 0)
     651                 :          4 :                       bio = BIO_new_mem_buf(data_body->data,data_body->length);
     652                 :            :                 else {
     653                 :          0 :                         bio=BIO_new(BIO_s_mem());
     654                 :          0 :                         BIO_set_mem_eof_return(bio,0);
     655                 :            :                 }
     656         [ +  - ]:          4 :                 if (bio == NULL)
     657                 :            :                         goto err;
     658                 :            : #endif
     659                 :            :                 }
     660                 :          4 :         BIO_push(out,bio);
     661                 :          4 :         bio=NULL;
     662                 :            : #endif
     663                 :            :         if (0)
     664                 :            :                 {
     665                 :            : err:
     666         [ #  # ]:          0 :                if (ek)
     667                 :            :                        {
     668                 :          0 :                        OPENSSL_cleanse(ek,eklen);
     669                 :          0 :                        OPENSSL_free(ek);
     670                 :            :                        }
     671         [ #  # ]:          0 :                if (tkey)
     672                 :            :                        {
     673                 :          0 :                        OPENSSL_cleanse(tkey,tkeylen);
     674                 :          0 :                        OPENSSL_free(tkey);
     675                 :            :                        }
     676         [ #  # ]:          0 :                 if (out != NULL) BIO_free_all(out);
     677         [ #  # ]:          0 :                 if (btmp != NULL) BIO_free_all(btmp);
     678         [ #  # ]:          0 :                 if (etmp != NULL) BIO_free_all(etmp);
     679         [ #  # ]:          0 :                 if (bio != NULL) BIO_free_all(bio);
     680                 :            :                 out=NULL;
     681                 :            :                 }
     682                 :          4 :         return(out);
     683                 :            :         }
     684                 :            : 
     685                 :         50 : static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
     686                 :            :         {
     687                 :            :         for (;;)
     688                 :            :                 {
     689                 :         25 :                 bio=BIO_find_type(bio,BIO_TYPE_MD);
     690         [ -  + ]:         25 :                 if (bio == NULL)
     691                 :            :                         {
     692                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
     693                 :          0 :                         return NULL;    
     694                 :            :                         }
     695                 :         25 :                 BIO_get_md_ctx(bio,pmd);
     696         [ -  + ]:         25 :                 if (*pmd == NULL)
     697                 :            :                         {
     698                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,ERR_R_INTERNAL_ERROR);
     699                 :          0 :                         return NULL;
     700                 :            :                         }       
     701         [ -  + ]:         25 :                 if (EVP_MD_CTX_type(*pmd) == nid)
     702                 :            :                         return bio;
     703                 :          0 :                 bio=BIO_next(bio);
     704                 :          0 :                 }
     705                 :            :         return NULL;
     706                 :            :         }
     707                 :            : 
     708                 :         21 : static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
     709                 :            :         {
     710                 :            :         unsigned char md_data[EVP_MAX_MD_SIZE];
     711                 :            :         unsigned int md_len;
     712                 :            : 
     713                 :            :         /* Add signing time if not already present */
     714         [ +  - ]:         21 :         if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
     715                 :            :                 {
     716         [ -  + ]:         21 :                 if (!PKCS7_add0_attrib_signing_time(si, NULL))
     717                 :            :                         {
     718                 :          0 :                         PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
     719                 :            :                                         ERR_R_MALLOC_FAILURE);
     720                 :          0 :                         return 0;
     721                 :            :                         }
     722                 :            :                 }
     723                 :            : 
     724                 :            :         /* Add digest */
     725         [ -  + ]:         21 :         if (!EVP_DigestFinal_ex(mctx, md_data,&md_len))
     726                 :            :                 {
     727                 :          0 :                 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
     728                 :          0 :                 return 0;
     729                 :            :                 }
     730         [ -  + ]:         21 :         if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
     731                 :            :                 {
     732                 :          0 :                 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
     733                 :          0 :                 return 0;
     734                 :            :                 }
     735                 :            : 
     736                 :            :         /* Now sign the attributes */
     737         [ +  - ]:         21 :         if (!PKCS7_SIGNER_INFO_sign(si))
     738                 :            :                         return 0;
     739                 :            : 
     740                 :         21 :         return 1;
     741                 :            :         }
     742                 :            :         
     743                 :            :                                 
     744                 :         17 : int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
     745                 :            :         {
     746                 :         17 :         int ret=0;
     747                 :            :         int i,j;
     748                 :            :         BIO *btmp;
     749                 :            :         PKCS7_SIGNER_INFO *si;
     750                 :            :         EVP_MD_CTX *mdc,ctx_tmp;
     751                 :            :         STACK_OF(X509_ATTRIBUTE) *sk;
     752                 :         17 :         STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
     753                 :         17 :         ASN1_OCTET_STRING *os=NULL;
     754                 :            : 
     755                 :         17 :         EVP_MD_CTX_init(&ctx_tmp);
     756                 :         17 :         i=OBJ_obj2nid(p7->type);
     757                 :         17 :         p7->state=PKCS7_S_HEADER;
     758                 :            : 
     759   [ -  -  +  +  :         17 :         switch (i)
                   -  - ]
     760                 :            :                 {
     761                 :            :         case NID_pkcs7_data:
     762                 :          0 :                 os = p7->d.data;
     763                 :          0 :                 break;
     764                 :            :         case NID_pkcs7_signedAndEnveloped:
     765                 :            :                 /* XXXXXXXXXXXXXXXX */
     766                 :          0 :                 si_sk=p7->d.signed_and_enveloped->signer_info;
     767                 :          0 :                 os = p7->d.signed_and_enveloped->enc_data->enc_data;
     768         [ #  # ]:          0 :                 if (!os)
     769                 :            :                         {
     770                 :          0 :                         os=M_ASN1_OCTET_STRING_new();
     771         [ #  # ]:          0 :                         if (!os)
     772                 :            :                                 {
     773                 :          0 :                                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
     774                 :          0 :                                 goto err;
     775                 :            :                                 }
     776                 :          0 :                         p7->d.signed_and_enveloped->enc_data->enc_data=os;
     777                 :            :                         }
     778                 :            :                 break;
     779                 :            :         case NID_pkcs7_enveloped:
     780                 :            :                 /* XXXXXXXXXXXXXXXX */
     781                 :          4 :                 os = p7->d.enveloped->enc_data->enc_data;
     782         [ -  + ]:          4 :                 if (!os)
     783                 :            :                         {
     784                 :          0 :                         os=M_ASN1_OCTET_STRING_new();
     785         [ #  # ]:          0 :                         if (!os)
     786                 :            :                                 {
     787                 :          0 :                                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
     788                 :          0 :                                 goto err;
     789                 :            :                                 }
     790                 :          0 :                         p7->d.enveloped->enc_data->enc_data=os;
     791                 :            :                         }
     792                 :            :                 break;
     793                 :            :         case NID_pkcs7_signed:
     794                 :         13 :                 si_sk=p7->d.sign->signer_info;
     795                 :         13 :                 os=PKCS7_get_octet_string(p7->d.sign->contents);
     796                 :            :                 /* If detached data then the content is excluded */
     797 [ +  + ][ +  + ]:         13 :                 if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
     798                 :          3 :                         M_ASN1_OCTET_STRING_free(os);
     799                 :          3 :                         p7->d.sign->contents->d.data = NULL;
     800                 :            :                 }
     801                 :            :                 break;
     802                 :            : 
     803                 :            :         case NID_pkcs7_digest:
     804                 :          0 :                 os=PKCS7_get_octet_string(p7->d.digest->contents);
     805                 :            :                 /* If detached data then the content is excluded */
     806 [ #  # ][ #  # ]:          0 :                 if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
     807                 :            :                         {
     808                 :          0 :                         M_ASN1_OCTET_STRING_free(os);
     809                 :          0 :                         p7->d.digest->contents->d.data = NULL;
     810                 :            :                         }
     811                 :            :                 break;
     812                 :            : 
     813                 :            :         default:
     814                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
     815                 :          0 :                 goto err;
     816                 :            :                 }
     817                 :            : 
     818         [ +  + ]:         17 :         if (si_sk != NULL)
     819                 :            :                 {
     820         [ +  + ]:         38 :                 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
     821                 :            :                         {
     822                 :         25 :                         si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
     823         [ -  + ]:         25 :                         if (si->pkey == NULL)
     824                 :          0 :                                 continue;
     825                 :            : 
     826                 :         25 :                         j = OBJ_obj2nid(si->digest_alg->algorithm);
     827                 :            : 
     828                 :         25 :                         btmp=bio;
     829                 :            : 
     830                 :         25 :                         btmp = PKCS7_find_digest(&mdc, btmp, j);
     831                 :            : 
     832         [ +  - ]:         25 :                         if (btmp == NULL)
     833                 :            :                                 goto err;
     834                 :            : 
     835                 :            :                         /* We now have the EVP_MD_CTX, lets do the
     836                 :            :                          * signing. */
     837         [ +  - ]:         25 :                         if (!EVP_MD_CTX_copy_ex(&ctx_tmp,mdc))
     838                 :            :                                 goto err;
     839                 :            : 
     840                 :         25 :                         sk=si->auth_attr;
     841                 :            : 
     842                 :            :                         /* If there are attributes, we add the digest
     843                 :            :                          * attribute and only sign the attributes */
     844         [ +  + ]:         25 :                         if (sk_X509_ATTRIBUTE_num(sk) > 0)
     845                 :            :                                 {
     846         [ +  - ]:         21 :                                 if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
     847                 :            :                                         goto err;
     848                 :            :                                 }
     849                 :            :                         else
     850                 :            :                                 {
     851                 :          4 :                                 unsigned char *abuf = NULL;
     852                 :            :                                 unsigned int abuflen;
     853                 :          4 :                                 abuflen = EVP_PKEY_size(si->pkey);
     854                 :          4 :                                 abuf = OPENSSL_malloc(abuflen);
     855         [ +  - ]:          4 :                                 if (!abuf)
     856                 :            :                                         goto err;
     857                 :            : 
     858         [ -  + ]:          4 :                                 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
     859                 :            :                                                         si->pkey))
     860                 :            :                                         {
     861                 :          0 :                                         PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
     862                 :            :                                                         ERR_R_EVP_LIB);
     863                 :          0 :                                         goto err;
     864                 :            :                                         }
     865                 :          4 :                                 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
     866                 :            :                                 }
     867                 :            :                         }
     868                 :            :                 }
     869         [ -  + ]:          4 :         else if (i == NID_pkcs7_digest)
     870                 :            :                 {
     871                 :            :                 unsigned char md_data[EVP_MAX_MD_SIZE];
     872                 :            :                 unsigned int md_len;
     873         [ #  # ]:          0 :                 if (!PKCS7_find_digest(&mdc, bio,
     874                 :          0 :                                 OBJ_obj2nid(p7->d.digest->md->algorithm)))
     875                 :            :                         goto err;
     876         [ #  # ]:          0 :                 if (!EVP_DigestFinal_ex(mdc,md_data,&md_len))
     877                 :            :                         goto err;
     878                 :          0 :                 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
     879                 :            :                 }
     880                 :            : 
     881 [ +  + ][ +  + ]:         17 :         if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
                 [ +  + ]
     882                 :            :                 {
     883                 :            :                 char *cont;
     884                 :            :                 long contlen;
     885                 :          5 :                 btmp=BIO_find_type(bio,BIO_TYPE_MEM);
     886         [ -  + ]:          5 :                 if (btmp == NULL)
     887                 :            :                         {
     888                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
     889                 :          0 :                         goto err;
     890                 :            :                         }
     891                 :          5 :                 contlen = BIO_get_mem_data(btmp, &cont);
     892                 :            :                 /* Mark the BIO read only then we can use its copy of the data
     893                 :            :                  * instead of making an extra copy.
     894                 :            :                  */
     895                 :          5 :                 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
     896                 :          5 :                 BIO_set_mem_eof_return(btmp, 0);
     897                 :          5 :                 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
     898                 :            :                 }
     899                 :            :         ret=1;
     900                 :            : err:
     901                 :         17 :         EVP_MD_CTX_cleanup(&ctx_tmp);
     902                 :         17 :         return(ret);
     903                 :            :         }
     904                 :            : 
     905                 :         22 : int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
     906                 :            :         {
     907                 :            :         EVP_MD_CTX mctx;
     908                 :            :         EVP_PKEY_CTX *pctx;
     909                 :         22 :         unsigned char *abuf = NULL;
     910                 :            :         int alen;
     911                 :            :         size_t siglen;
     912                 :         22 :         const EVP_MD *md = NULL;
     913                 :            : 
     914                 :         22 :         md = EVP_get_digestbyobj(si->digest_alg->algorithm);
     915         [ +  - ]:         22 :         if (md == NULL)
     916                 :            :                 return 0;
     917                 :            : 
     918                 :         22 :         EVP_MD_CTX_init(&mctx);
     919         [ +  - ]:         22 :         if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
     920                 :            :                 goto err;
     921                 :            : 
     922         [ -  + ]:         22 :         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
     923                 :            :                                 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
     924                 :            :                 {
     925                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
     926                 :          0 :                 goto err;
     927                 :            :                 }
     928                 :            : 
     929                 :         22 :         alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
     930                 :            :                                 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
     931         [ +  - ]:         22 :         if(!abuf)
     932                 :            :                 goto err;
     933         [ +  - ]:         22 :         if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
     934                 :            :                 goto err;
     935                 :         22 :         OPENSSL_free(abuf);
     936                 :         22 :         abuf = NULL;
     937         [ +  - ]:         22 :         if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
     938                 :            :                 goto err;
     939                 :         22 :         abuf = OPENSSL_malloc(siglen);
     940         [ +  - ]:         22 :         if(!abuf)
     941                 :            :                 goto err;
     942         [ +  - ]:         22 :         if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
     943                 :            :                 goto err;
     944                 :            : 
     945         [ -  + ]:         22 :         if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
     946                 :            :                                 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
     947                 :            :                 {
     948                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
     949                 :          0 :                 goto err;
     950                 :            :                 }
     951                 :            : 
     952                 :         22 :         EVP_MD_CTX_cleanup(&mctx);
     953                 :            : 
     954                 :         22 :         ASN1_STRING_set0(si->enc_digest, abuf, siglen);
     955                 :            : 
     956                 :         22 :         return 1;
     957                 :            : 
     958                 :            :         err:
     959         [ #  # ]:          0 :         if (abuf)
     960                 :          0 :                 OPENSSL_free(abuf);
     961                 :          0 :         EVP_MD_CTX_cleanup(&mctx);
     962                 :          0 :         return 0;
     963                 :            : 
     964                 :            :         }
     965                 :            : 
     966                 :          0 : int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
     967                 :            :              PKCS7 *p7, PKCS7_SIGNER_INFO *si)
     968                 :            :         {
     969                 :            :         PKCS7_ISSUER_AND_SERIAL *ias;
     970                 :          0 :         int ret=0,i;
     971                 :            :         STACK_OF(X509) *cert;
     972                 :            :         X509 *x509;
     973                 :            : 
     974         [ #  # ]:          0 :         if (PKCS7_type_is_signed(p7))
     975                 :            :                 {
     976                 :          0 :                 cert=p7->d.sign->cert;
     977                 :            :                 }
     978         [ #  # ]:          0 :         else if (PKCS7_type_is_signedAndEnveloped(p7))
     979                 :            :                 {
     980                 :          0 :                 cert=p7->d.signed_and_enveloped->cert;
     981                 :            :                 }
     982                 :            :         else
     983                 :            :                 {
     984                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_WRONG_PKCS7_TYPE);
     985                 :          0 :                 goto err;
     986                 :            :                 }
     987                 :            :         /* XXXXXXXXXXXXXXXXXXXXXXX */
     988                 :          0 :         ias=si->issuer_and_serial;
     989                 :            : 
     990                 :          0 :         x509=X509_find_by_issuer_and_serial(cert,ias->issuer,ias->serial);
     991                 :            : 
     992                 :            :         /* were we able to find the cert in passed to us */
     993         [ #  # ]:          0 :         if (x509 == NULL)
     994                 :            :                 {
     995                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
     996                 :          0 :                 goto err;
     997                 :            :                 }
     998                 :            : 
     999                 :            :         /* Lets verify */
    1000         [ #  # ]:          0 :         if(!X509_STORE_CTX_init(ctx,cert_store,x509,cert))
    1001                 :            :                 {
    1002                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
    1003                 :          0 :                 goto err;
    1004                 :            :                 }
    1005                 :          0 :         X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
    1006                 :          0 :         i=X509_verify_cert(ctx);
    1007         [ #  # ]:          0 :         if (i <= 0) 
    1008                 :            :                 {
    1009                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,ERR_R_X509_LIB);
    1010                 :          0 :                 X509_STORE_CTX_cleanup(ctx);
    1011                 :          0 :                 goto err;
    1012                 :            :                 }
    1013                 :          0 :         X509_STORE_CTX_cleanup(ctx);
    1014                 :            : 
    1015                 :          0 :         return PKCS7_signatureVerify(bio, p7, si, x509);
    1016                 :            :         err:
    1017                 :            :         return ret;
    1018                 :            :         }
    1019                 :            : 
    1020                 :         33 : int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
    1021                 :            :                                                                 X509 *x509)
    1022                 :            :         {
    1023                 :            :         ASN1_OCTET_STRING *os;
    1024                 :            :         EVP_MD_CTX mdc_tmp,*mdc;
    1025                 :         33 :         int ret=0,i;
    1026                 :            :         int md_type;
    1027                 :            :         STACK_OF(X509_ATTRIBUTE) *sk;
    1028                 :            :         BIO *btmp;
    1029                 :            :         EVP_PKEY *pkey;
    1030                 :            : 
    1031                 :         33 :         EVP_MD_CTX_init(&mdc_tmp);
    1032                 :            : 
    1033   [ -  +  #  # ]:         33 :         if (!PKCS7_type_is_signed(p7) && 
    1034                 :          0 :                                 !PKCS7_type_is_signedAndEnveloped(p7)) {
    1035                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1036                 :            :                                                 PKCS7_R_WRONG_PKCS7_TYPE);
    1037                 :          0 :                 goto err;
    1038                 :            :         }
    1039                 :            : 
    1040                 :         33 :         md_type=OBJ_obj2nid(si->digest_alg->algorithm);
    1041                 :            : 
    1042                 :         33 :         btmp=bio;
    1043                 :            :         for (;;)
    1044                 :            :                 {
    1045 [ +  - ][ -  + ]:         33 :                 if ((btmp == NULL) ||
    1046                 :            :                         ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) == NULL))
    1047                 :            :                         {
    1048                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1049                 :            :                                         PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
    1050                 :          0 :                         goto err;
    1051                 :            :                         }
    1052                 :         33 :                 BIO_get_md_ctx(btmp,&mdc);
    1053         [ -  + ]:         33 :                 if (mdc == NULL)
    1054                 :            :                         {
    1055                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1056                 :            :                                                         ERR_R_INTERNAL_ERROR);
    1057                 :          0 :                         goto err;
    1058                 :            :                         }
    1059         [ -  + ]:         33 :                 if (EVP_MD_CTX_type(mdc) == md_type)
    1060                 :            :                         break;
    1061                 :            :                 /* Workaround for some broken clients that put the signature
    1062                 :            :                  * OID instead of the digest OID in digest_alg->algorithm
    1063                 :            :                  */
    1064         [ #  # ]:          0 :                 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
    1065                 :            :                         break;
    1066                 :          0 :                 btmp=BIO_next(btmp);
    1067                 :          0 :                 }
    1068                 :            : 
    1069                 :            :         /* mdc is the digest ctx that we want, unless there are attributes,
    1070                 :            :          * in which case the digest is the signed attributes */
    1071         [ +  - ]:         33 :         if (!EVP_MD_CTX_copy_ex(&mdc_tmp,mdc))
    1072                 :            :                 goto err;
    1073                 :            : 
    1074                 :         33 :         sk=si->auth_attr;
    1075 [ +  + ][ +  - ]:         33 :         if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
    1076                 :            :                 {
    1077                 :         29 :                 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
    1078                 :            :                 unsigned int md_len;
    1079                 :            :                 int alen;
    1080                 :            :                 ASN1_OCTET_STRING *message_digest;
    1081                 :            : 
    1082         [ +  - ]:         29 :                 if (!EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len))
    1083                 :            :                         goto err;
    1084                 :         29 :                 message_digest=PKCS7_digest_from_attributes(sk);
    1085         [ -  + ]:         29 :                 if (!message_digest)
    1086                 :            :                         {
    1087                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1088                 :            :                                         PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
    1089                 :          0 :                         goto err;
    1090                 :            :                         }
    1091 [ +  - ][ -  + ]:         29 :                 if ((message_digest->length != (int)md_len) ||
    1092                 :         29 :                         (memcmp(message_digest->data,md_dat,md_len)))
    1093                 :            :                         {
    1094                 :            : #if 0
    1095                 :            : {
    1096                 :            : int ii;
    1097                 :            : for (ii=0; ii<message_digest->length; ii++)
    1098                 :            :         printf("%02X",message_digest->data[ii]); printf(" sent\n");
    1099                 :            : for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
    1100                 :            : }
    1101                 :            : #endif
    1102                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1103                 :            :                                                         PKCS7_R_DIGEST_FAILURE);
    1104                 :          0 :                         ret= -1;
    1105                 :          0 :                         goto err;
    1106                 :            :                         }
    1107                 :            : 
    1108         [ +  - ]:         29 :                 if (!EVP_VerifyInit_ex(&mdc_tmp,EVP_get_digestbynid(md_type), NULL))
    1109                 :            :                         goto err;
    1110                 :            : 
    1111                 :         29 :                 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
    1112                 :            :                                                 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
    1113         [ -  + ]:         29 :                 if (alen <= 0) 
    1114                 :            :                         {
    1115                 :          0 :                         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
    1116                 :          0 :                         ret = -1;
    1117                 :          0 :                         goto err;
    1118                 :            :                         }
    1119         [ +  - ]:         29 :                 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
    1120                 :            :                         goto err;
    1121                 :            : 
    1122                 :         29 :                 OPENSSL_free(abuf);
    1123                 :            :                 }
    1124                 :            : 
    1125                 :         33 :         os=si->enc_digest;
    1126                 :         33 :         pkey = X509_get_pubkey(x509);
    1127         [ +  - ]:         33 :         if (!pkey)
    1128                 :            :                 {
    1129                 :            :                 ret = -1;
    1130                 :            :                 goto err;
    1131                 :            :                 }
    1132                 :            : 
    1133                 :         33 :         i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
    1134                 :         33 :         EVP_PKEY_free(pkey);
    1135         [ -  + ]:         33 :         if (i <= 0)
    1136                 :            :                 {
    1137                 :          0 :                 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
    1138                 :            :                                                 PKCS7_R_SIGNATURE_FAILURE);
    1139                 :          0 :                 ret= -1;
    1140                 :          0 :                 goto err;
    1141                 :            :                 }
    1142                 :            :         else
    1143                 :            :                 ret=1;
    1144                 :            : err:
    1145                 :         33 :         EVP_MD_CTX_cleanup(&mdc_tmp);
    1146                 :         33 :         return(ret);
    1147                 :            :         }
    1148                 :            : 
    1149                 :          0 : PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
    1150                 :            :         {
    1151                 :            :         STACK_OF(PKCS7_RECIP_INFO) *rsk;
    1152                 :            :         PKCS7_RECIP_INFO *ri;
    1153                 :            :         int i;
    1154                 :            : 
    1155                 :          0 :         i=OBJ_obj2nid(p7->type);
    1156         [ #  # ]:          0 :         if (i != NID_pkcs7_signedAndEnveloped)
    1157                 :            :                 return NULL;
    1158         [ #  # ]:          0 :         if (p7->d.signed_and_enveloped == NULL)
    1159                 :            :                 return NULL;
    1160                 :          0 :         rsk=p7->d.signed_and_enveloped->recipientinfo;
    1161         [ #  # ]:          0 :         if (rsk == NULL)
    1162                 :            :                 return NULL;
    1163                 :          0 :         ri=sk_PKCS7_RECIP_INFO_value(rsk,0);
    1164         [ #  # ]:          0 :         if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) return(NULL);
    1165                 :          0 :         ri=sk_PKCS7_RECIP_INFO_value(rsk,idx);
    1166                 :          0 :         return(ri->issuer_and_serial);
    1167                 :            :         }
    1168                 :            : 
    1169                 :         49 : ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
    1170                 :            :         {
    1171                 :         49 :         return(get_attribute(si->auth_attr,nid));
    1172                 :            :         }
    1173                 :            : 
    1174                 :          0 : ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
    1175                 :            :         {
    1176                 :          0 :         return(get_attribute(si->unauth_attr,nid));
    1177                 :            :         }
    1178                 :            : 
    1179                 :         79 : static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
    1180                 :            :         {
    1181                 :            :         int i;
    1182                 :            :         X509_ATTRIBUTE *xa;
    1183                 :            :         ASN1_OBJECT *o;
    1184                 :            : 
    1185                 :         79 :         o=OBJ_nid2obj(nid);
    1186         [ +  + ]:         79 :         if (!o || !sk) return(NULL);
    1187         [ +  + ]:        188 :         for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
    1188                 :            :                 {
    1189                 :        167 :                 xa=sk_X509_ATTRIBUTE_value(sk,i);
    1190         [ +  + ]:        167 :                 if (OBJ_cmp(xa->object,o) == 0)
    1191                 :            :                         {
    1192 [ +  - ][ +  - ]:         39 :                         if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
    1193                 :         39 :                                 return(sk_ASN1_TYPE_value(xa->value.set,0));
    1194                 :            :                         else
    1195                 :            :                                 return(NULL);
    1196                 :            :                         }
    1197                 :            :                 }
    1198                 :            :         return(NULL);
    1199                 :            :         }
    1200                 :            : 
    1201                 :         30 : ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
    1202                 :            : {
    1203                 :            :         ASN1_TYPE *astype;
    1204         [ +  - ]:         30 :         if(!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) return NULL;
    1205                 :         30 :         return astype->value.octet_string;
    1206                 :            : }
    1207                 :            : 
    1208                 :          0 : int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
    1209                 :            :                                 STACK_OF(X509_ATTRIBUTE) *sk)
    1210                 :            :         {
    1211                 :            :         int i;
    1212                 :            : 
    1213         [ #  # ]:          0 :         if (p7si->auth_attr != NULL)
    1214                 :          0 :                 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,X509_ATTRIBUTE_free);
    1215                 :          0 :         p7si->auth_attr=sk_X509_ATTRIBUTE_dup(sk);
    1216         [ #  # ]:          0 :         if (p7si->auth_attr == NULL)
    1217                 :            :                 return 0;
    1218         [ #  # ]:          0 :         for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
    1219                 :            :                 {
    1220         [ #  # ]:          0 :                 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr,i,
    1221                 :            :                         X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
    1222                 :            :                     == NULL)
    1223                 :            :                         return(0);
    1224                 :            :                 }
    1225                 :            :         return(1);
    1226                 :            :         }
    1227                 :            : 
    1228                 :          0 : int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
    1229                 :            :         {
    1230                 :            :         int i;
    1231                 :            : 
    1232         [ #  # ]:          0 :         if (p7si->unauth_attr != NULL)
    1233                 :          0 :                 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
    1234                 :            :                                            X509_ATTRIBUTE_free);
    1235                 :          0 :         p7si->unauth_attr=sk_X509_ATTRIBUTE_dup(sk);
    1236         [ #  # ]:          0 :         if (p7si->unauth_attr == NULL)
    1237                 :            :                 return 0;
    1238         [ #  # ]:          0 :         for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
    1239                 :            :                 {
    1240         [ #  # ]:          0 :                 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr,i,
    1241                 :            :                         X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk,i))))
    1242                 :            :                     == NULL)
    1243                 :            :                         return(0);
    1244                 :            :                 }
    1245                 :            :         return(1);
    1246                 :            :         }
    1247                 :            : 
    1248                 :         87 : int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
    1249                 :            :              void *value)
    1250                 :            :         {
    1251                 :         87 :         return(add_attribute(&(p7si->auth_attr),nid,atrtype,value));
    1252                 :            :         }
    1253                 :            : 
    1254                 :          0 : int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
    1255                 :            :              void *value)
    1256                 :            :         {
    1257                 :          0 :         return(add_attribute(&(p7si->unauth_attr),nid,atrtype,value));
    1258                 :            :         }
    1259                 :            : 
    1260                 :         87 : static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
    1261                 :            :                          void *value)
    1262                 :            :         {
    1263                 :         87 :         X509_ATTRIBUTE *attr=NULL;
    1264                 :            : 
    1265         [ +  + ]:         87 :         if (*sk == NULL)
    1266                 :            :                 {
    1267                 :         22 :                 *sk = sk_X509_ATTRIBUTE_new_null();
    1268         [ +  - ]:         22 :                 if (*sk == NULL)
    1269                 :            :                         return 0;       
    1270                 :            : new_attrib:
    1271         [ +  - ]:         87 :                 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
    1272                 :            :                         return 0;
    1273         [ -  + ]:         87 :                 if (!sk_X509_ATTRIBUTE_push(*sk,attr))
    1274                 :            :                         {
    1275                 :          0 :                         X509_ATTRIBUTE_free(attr);
    1276                 :          0 :                         return 0;
    1277                 :            :                         }
    1278                 :            :                 }
    1279                 :            :         else
    1280                 :            :                 {
    1281                 :            :                 int i;
    1282                 :            : 
    1283         [ +  + ]:        194 :                 for (i=0; i<sk_X509_ATTRIBUTE_num(*sk); i++)
    1284                 :            :                         {
    1285                 :        129 :                         attr=sk_X509_ATTRIBUTE_value(*sk,i);
    1286         [ -  + ]:        129 :                         if (OBJ_obj2nid(attr->object) == nid)
    1287                 :            :                                 {
    1288                 :          0 :                                 X509_ATTRIBUTE_free(attr);
    1289                 :          0 :                                 attr=X509_ATTRIBUTE_create(nid,atrtype,value);
    1290         [ #  # ]:          0 :                                 if (attr == NULL)
    1291                 :            :                                         return 0;
    1292         [ #  # ]:          0 :                                 if (!sk_X509_ATTRIBUTE_set(*sk,i,attr))
    1293                 :            :                                         {
    1294                 :          0 :                                         X509_ATTRIBUTE_free(attr);
    1295                 :          0 :                                         return 0;
    1296                 :            :                                         }
    1297                 :            :                                 goto end;
    1298                 :            :                                 }
    1299                 :            :                         }
    1300                 :            :                 goto new_attrib;
    1301                 :            :                 }
    1302                 :            : end:
    1303                 :            :         return(1);
    1304                 :            :         }
    1305                 :            : 

Generated by: LCOV version 1.9