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

          Line data    Source code
       1             : /* crypto/cms/cms_sd.c */
       2             : /*
       3             :  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
       4             :  * project.
       5             :  */
       6             : /* ====================================================================
       7             :  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
       8             :  *
       9             :  * Redistribution and use in source and binary forms, with or without
      10             :  * modification, are permitted provided that the following conditions
      11             :  * are met:
      12             :  *
      13             :  * 1. Redistributions of source code must retain the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer.
      15             :  *
      16             :  * 2. Redistributions in binary form must reproduce the above copyright
      17             :  *    notice, this list of conditions and the following disclaimer in
      18             :  *    the documentation and/or other materials provided with the
      19             :  *    distribution.
      20             :  *
      21             :  * 3. All advertising materials mentioning features or use of this
      22             :  *    software must display the following acknowledgment:
      23             :  *    "This product includes software developed by the OpenSSL Project
      24             :  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
      25             :  *
      26             :  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
      27             :  *    endorse or promote products derived from this software without
      28             :  *    prior written permission. For written permission, please contact
      29             :  *    licensing@OpenSSL.org.
      30             :  *
      31             :  * 5. Products derived from this software may not be called "OpenSSL"
      32             :  *    nor may "OpenSSL" appear in their names without prior written
      33             :  *    permission of the OpenSSL Project.
      34             :  *
      35             :  * 6. Redistributions of any form whatsoever must retain the following
      36             :  *    acknowledgment:
      37             :  *    "This product includes software developed by the OpenSSL Project
      38             :  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
      39             :  *
      40             :  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
      41             :  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      42             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      43             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
      44             :  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      45             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      46             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
      47             :  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      48             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
      49             :  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      50             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
      51             :  * OF THE POSSIBILITY OF SUCH DAMAGE.
      52             :  * ====================================================================
      53             :  */
      54             : 
      55             : #include "cryptlib.h"
      56             : #include <openssl/asn1t.h>
      57             : #include <openssl/pem.h>
      58             : #include <openssl/x509.h>
      59             : #include <openssl/x509v3.h>
      60             : #include <openssl/err.h>
      61             : #include <openssl/cms.h>
      62             : #include "cms_lcl.h"
      63             : #include "asn1_locl.h"
      64             : 
      65             : /* CMS SignedData Utilities */
      66             : 
      67             : DECLARE_ASN1_ITEM(CMS_SignedData)
      68             : 
      69           0 : static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
      70             : {
      71           0 :     if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
      72           0 :         CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
      73           0 :         return NULL;
      74             :     }
      75           0 :     return cms->d.signedData;
      76             : }
      77             : 
      78           0 : static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
      79             : {
      80           0 :     if (cms->d.other == NULL) {
      81           0 :         cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
      82           0 :         if (!cms->d.signedData) {
      83           0 :             CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
      84           0 :             return NULL;
      85             :         }
      86           0 :         cms->d.signedData->version = 1;
      87           0 :         cms->d.signedData->encapContentInfo->eContentType =
      88           0 :             OBJ_nid2obj(NID_pkcs7_data);
      89           0 :         cms->d.signedData->encapContentInfo->partial = 1;
      90           0 :         ASN1_OBJECT_free(cms->contentType);
      91           0 :         cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
      92           0 :         return cms->d.signedData;
      93             :     }
      94           0 :     return cms_get0_signed(cms);
      95             : }
      96             : 
      97             : /* Just initialize SignedData e.g. for certs only structure */
      98             : 
      99           0 : int CMS_SignedData_init(CMS_ContentInfo *cms)
     100             : {
     101           0 :     if (cms_signed_data_init(cms))
     102             :         return 1;
     103             :     else
     104           0 :         return 0;
     105             : }
     106             : 
     107             : /* Check structures and fixup version numbers (if necessary) */
     108             : 
     109           0 : static void cms_sd_set_version(CMS_SignedData *sd)
     110             : {
     111             :     int i;
     112             :     CMS_CertificateChoices *cch;
     113             :     CMS_RevocationInfoChoice *rch;
     114             :     CMS_SignerInfo *si;
     115             : 
     116           0 :     for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
     117           0 :         cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
     118           0 :         if (cch->type == CMS_CERTCHOICE_OTHER) {
     119           0 :             if (sd->version < 5)
     120           0 :                 sd->version = 5;
     121           0 :         } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
     122           0 :             if (sd->version < 4)
     123           0 :                 sd->version = 4;
     124           0 :         } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
     125           0 :             if (sd->version < 3)
     126           0 :                 sd->version = 3;
     127             :         }
     128             :     }
     129             : 
     130           0 :     for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
     131           0 :         rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
     132           0 :         if (rch->type == CMS_REVCHOICE_OTHER) {
     133           0 :             if (sd->version < 5)
     134           0 :                 sd->version = 5;
     135             :         }
     136             :     }
     137             : 
     138           0 :     if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
     139           0 :         && (sd->version < 3))
     140           0 :         sd->version = 3;
     141             : 
     142           0 :     for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
     143           0 :         si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
     144           0 :         if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
     145           0 :             if (si->version < 3)
     146           0 :                 si->version = 3;
     147           0 :             if (sd->version < 3)
     148           0 :                 sd->version = 3;
     149           0 :         } else if (si->version < 1)
     150           0 :             si->version = 1;
     151             :     }
     152             : 
     153           0 :     if (sd->version < 1)
     154           0 :         sd->version = 1;
     155             : 
     156           0 : }
     157             : 
     158             : /* Copy an existing messageDigest value */
     159             : 
     160           0 : static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
     161             : {
     162             :     STACK_OF(CMS_SignerInfo) *sinfos;
     163             :     CMS_SignerInfo *sitmp;
     164             :     int i;
     165             :     sinfos = CMS_get0_SignerInfos(cms);
     166           0 :     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
     167             :         ASN1_OCTET_STRING *messageDigest;
     168           0 :         sitmp = sk_CMS_SignerInfo_value(sinfos, i);
     169           0 :         if (sitmp == si)
     170           0 :             continue;
     171           0 :         if (CMS_signed_get_attr_count(sitmp) < 0)
     172           0 :             continue;
     173           0 :         if (OBJ_cmp(si->digestAlgorithm->algorithm,
     174           0 :                     sitmp->digestAlgorithm->algorithm))
     175           0 :             continue;
     176           0 :         messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
     177             :                                                     OBJ_nid2obj
     178             :                                                     (NID_pkcs9_messageDigest),
     179             :                                                     -3, V_ASN1_OCTET_STRING);
     180           0 :         if (!messageDigest) {
     181           0 :             CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
     182             :                    CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
     183           0 :             return 0;
     184             :         }
     185             : 
     186           0 :         if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
     187             :                                         V_ASN1_OCTET_STRING,
     188             :                                         messageDigest, -1))
     189             :             return 1;
     190             :         else
     191           0 :             return 0;
     192             :     }
     193           0 :     CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
     194           0 :     return 0;
     195             : }
     196             : 
     197           0 : int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
     198             : {
     199           0 :     switch (type) {
     200             :     case CMS_SIGNERINFO_ISSUER_SERIAL:
     201           0 :         if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
     202             :             return 0;
     203             :         break;
     204             : 
     205             :     case CMS_SIGNERINFO_KEYIDENTIFIER:
     206           0 :         if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
     207             :             return 0;
     208             :         break;
     209             : 
     210             :     default:
     211           0 :         CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
     212           0 :         return 0;
     213             :     }
     214             : 
     215           0 :     sid->type = type;
     216             : 
     217           0 :     return 1;
     218             : }
     219             : 
     220           0 : int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
     221             :                                         ASN1_OCTET_STRING **keyid,
     222             :                                         X509_NAME **issuer,
     223             :                                         ASN1_INTEGER **sno)
     224             : {
     225           0 :     if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
     226           0 :         if (issuer)
     227           0 :             *issuer = sid->d.issuerAndSerialNumber->issuer;
     228           0 :         if (sno)
     229           0 :             *sno = sid->d.issuerAndSerialNumber->serialNumber;
     230           0 :     } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
     231           0 :         if (keyid)
     232           0 :             *keyid = sid->d.subjectKeyIdentifier;
     233             :     } else
     234             :         return 0;
     235             :     return 1;
     236             : }
     237             : 
     238           0 : int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
     239             : {
     240           0 :     if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
     241           0 :         return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
     242           0 :     else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
     243           0 :         return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
     244             :     else
     245             :         return -1;
     246             : }
     247             : 
     248           0 : static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
     249             : {
     250           0 :     EVP_PKEY *pkey = si->pkey;
     251             :     int i;
     252           0 :     if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
     253             :         return 1;
     254           0 :     i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
     255           0 :     if (i == -2) {
     256           0 :         CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
     257           0 :         return 0;
     258             :     }
     259           0 :     if (i <= 0) {
     260           0 :         CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
     261           0 :         return 0;
     262             :     }
     263             :     return 1;
     264             : }
     265             : 
     266           0 : CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     267             :                                 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
     268             :                                 unsigned int flags)
     269             : {
     270             :     CMS_SignedData *sd;
     271             :     CMS_SignerInfo *si = NULL;
     272             :     X509_ALGOR *alg;
     273             :     int i, type;
     274           0 :     if (!X509_check_private_key(signer, pk)) {
     275           0 :         CMSerr(CMS_F_CMS_ADD1_SIGNER,
     276             :                CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
     277           0 :         return NULL;
     278             :     }
     279           0 :     sd = cms_signed_data_init(cms);
     280           0 :     if (!sd)
     281             :         goto err;
     282           0 :     si = M_ASN1_new_of(CMS_SignerInfo);
     283           0 :     if (!si)
     284             :         goto merr;
     285           0 :     X509_check_purpose(signer, -1, -1);
     286             : 
     287           0 :     CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
     288           0 :     CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
     289             : 
     290           0 :     si->pkey = pk;
     291           0 :     si->signer = signer;
     292           0 :     EVP_MD_CTX_init(&si->mctx);
     293           0 :     si->pctx = NULL;
     294             : 
     295           0 :     if (flags & CMS_USE_KEYID) {
     296           0 :         si->version = 3;
     297           0 :         if (sd->version < 3)
     298           0 :             sd->version = 3;
     299             :         type = CMS_SIGNERINFO_KEYIDENTIFIER;
     300             :     } else {
     301             :         type = CMS_SIGNERINFO_ISSUER_SERIAL;
     302           0 :         si->version = 1;
     303             :     }
     304             : 
     305           0 :     if (!cms_set1_SignerIdentifier(si->sid, signer, type))
     306             :         goto err;
     307             : 
     308           0 :     if (md == NULL) {
     309             :         int def_nid;
     310           0 :         if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
     311             :             goto err;
     312           0 :         md = EVP_get_digestbynid(def_nid);
     313           0 :         if (md == NULL) {
     314           0 :             CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
     315           0 :             goto err;
     316             :         }
     317             :     }
     318             : 
     319           0 :     if (!md) {
     320           0 :         CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
     321           0 :         goto err;
     322             :     }
     323             : 
     324           0 :     cms_DigestAlgorithm_set(si->digestAlgorithm, md);
     325             : 
     326             :     /* See if digest is present in digestAlgorithms */
     327           0 :     for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
     328             :         ASN1_OBJECT *aoid;
     329           0 :         alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
     330           0 :         X509_ALGOR_get0(&aoid, NULL, NULL, alg);
     331           0 :         if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
     332             :             break;
     333             :     }
     334             : 
     335           0 :     if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
     336           0 :         alg = X509_ALGOR_new();
     337           0 :         if (!alg)
     338             :             goto merr;
     339           0 :         cms_DigestAlgorithm_set(alg, md);
     340           0 :         if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
     341           0 :             X509_ALGOR_free(alg);
     342           0 :             goto merr;
     343             :         }
     344             :     }
     345             : 
     346           0 :     if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
     347             :         goto err;
     348           0 :     if (!(flags & CMS_NOATTR)) {
     349             :         /*
     350             :          * Initialialize signed attributes strutucture so other attributes
     351             :          * such as signing time etc are added later even if we add none here.
     352             :          */
     353           0 :         if (!si->signedAttrs) {
     354           0 :             si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
     355           0 :             if (!si->signedAttrs)
     356             :                 goto merr;
     357             :         }
     358             : 
     359           0 :         if (!(flags & CMS_NOSMIMECAP)) {
     360           0 :             STACK_OF(X509_ALGOR) *smcap = NULL;
     361           0 :             i = CMS_add_standard_smimecap(&smcap);
     362           0 :             if (i)
     363           0 :                 i = CMS_add_smimecap(si, smcap);
     364           0 :             sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
     365           0 :             if (!i)
     366             :                 goto merr;
     367             :         }
     368           0 :         if (flags & CMS_REUSE_DIGEST) {
     369           0 :             if (!cms_copy_messageDigest(cms, si))
     370             :                 goto err;
     371           0 :             if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
     372           0 :                 !CMS_SignerInfo_sign(si))
     373             :                 goto err;
     374             :         }
     375             :     }
     376             : 
     377           0 :     if (!(flags & CMS_NOCERTS)) {
     378             :         /* NB ignore -1 return for duplicate cert */
     379           0 :         if (!CMS_add1_cert(cms, signer))
     380             :             goto merr;
     381             :     }
     382             : 
     383           0 :     if (flags & CMS_KEY_PARAM) {
     384           0 :         if (flags & CMS_NOATTR) {
     385           0 :             si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
     386           0 :             if (!si->pctx)
     387             :                 goto err;
     388           0 :             if (EVP_PKEY_sign_init(si->pctx) <= 0)
     389             :                 goto err;
     390           0 :             if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
     391             :                 goto err;
     392           0 :         } else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <=
     393             :                    0)
     394             :             goto err;
     395             :     }
     396             : 
     397           0 :     if (!sd->signerInfos)
     398           0 :         sd->signerInfos = sk_CMS_SignerInfo_new_null();
     399           0 :     if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
     400             :         goto merr;
     401             : 
     402             :     return si;
     403             : 
     404             :  merr:
     405           0 :     CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
     406             :  err:
     407           0 :     if (si)
     408           0 :         M_ASN1_free_of(si, CMS_SignerInfo);
     409             :     return NULL;
     410             : 
     411             : }
     412             : 
     413           0 : static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
     414             : {
     415             :     ASN1_TIME *tt;
     416             :     int r = 0;
     417           0 :     if (t)
     418             :         tt = t;
     419             :     else
     420           0 :         tt = X509_gmtime_adj(NULL, 0);
     421             : 
     422           0 :     if (!tt)
     423             :         goto merr;
     424             : 
     425           0 :     if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
     426             :                                     tt->type, tt, -1) <= 0)
     427             :         goto merr;
     428             : 
     429             :     r = 1;
     430             : 
     431             :  merr:
     432             : 
     433           0 :     if (!t)
     434           0 :         ASN1_TIME_free(tt);
     435             : 
     436           0 :     if (!r)
     437           0 :         CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
     438             : 
     439           0 :     return r;
     440             : 
     441             : }
     442             : 
     443           0 : EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
     444             : {
     445           0 :     return si->pctx;
     446             : }
     447             : 
     448           0 : EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
     449             : {
     450           0 :     return &si->mctx;
     451             : }
     452             : 
     453           0 : STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
     454             : {
     455             :     CMS_SignedData *sd;
     456           0 :     sd = cms_get0_signed(cms);
     457           0 :     if (!sd)
     458             :         return NULL;
     459           0 :     return sd->signerInfos;
     460             : }
     461             : 
     462           0 : STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
     463             : {
     464             :     STACK_OF(X509) *signers = NULL;
     465             :     STACK_OF(CMS_SignerInfo) *sinfos;
     466             :     CMS_SignerInfo *si;
     467             :     int i;
     468             :     sinfos = CMS_get0_SignerInfos(cms);
     469           0 :     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
     470           0 :         si = sk_CMS_SignerInfo_value(sinfos, i);
     471           0 :         if (si->signer) {
     472           0 :             if (!signers) {
     473           0 :                 signers = sk_X509_new_null();
     474           0 :                 if (!signers)
     475             :                     return NULL;
     476             :             }
     477           0 :             if (!sk_X509_push(signers, si->signer)) {
     478           0 :                 sk_X509_free(signers);
     479           0 :                 return NULL;
     480             :             }
     481             :         }
     482             :     }
     483             :     return signers;
     484             : }
     485             : 
     486           0 : void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
     487             : {
     488           0 :     if (signer) {
     489           0 :         CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
     490           0 :         if (si->pkey)
     491           0 :             EVP_PKEY_free(si->pkey);
     492           0 :         si->pkey = X509_get_pubkey(signer);
     493             :     }
     494           0 :     if (si->signer)
     495           0 :         X509_free(si->signer);
     496           0 :     si->signer = signer;
     497           0 : }
     498             : 
     499           0 : int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
     500             :                                   ASN1_OCTET_STRING **keyid,
     501             :                                   X509_NAME **issuer, ASN1_INTEGER **sno)
     502             : {
     503           0 :     return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
     504             : }
     505             : 
     506           0 : int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
     507             : {
     508           0 :     return cms_SignerIdentifier_cert_cmp(si->sid, cert);
     509             : }
     510             : 
     511           0 : int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
     512             :                            unsigned int flags)
     513             : {
     514             :     CMS_SignedData *sd;
     515             :     CMS_SignerInfo *si;
     516             :     CMS_CertificateChoices *cch;
     517             :     STACK_OF(CMS_CertificateChoices) *certs;
     518             :     X509 *x;
     519             :     int i, j;
     520             :     int ret = 0;
     521           0 :     sd = cms_get0_signed(cms);
     522           0 :     if (!sd)
     523             :         return -1;
     524           0 :     certs = sd->certificates;
     525           0 :     for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
     526           0 :         si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
     527           0 :         if (si->signer)
     528           0 :             continue;
     529             : 
     530           0 :         for (j = 0; j < sk_X509_num(scerts); j++) {
     531           0 :             x = sk_X509_value(scerts, j);
     532           0 :             if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
     533           0 :                 CMS_SignerInfo_set1_signer_cert(si, x);
     534           0 :                 ret++;
     535           0 :                 break;
     536             :             }
     537             :         }
     538             : 
     539           0 :         if (si->signer || (flags & CMS_NOINTERN))
     540           0 :             continue;
     541             : 
     542           0 :         for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
     543           0 :             cch = sk_CMS_CertificateChoices_value(certs, j);
     544           0 :             if (cch->type != 0)
     545           0 :                 continue;
     546           0 :             x = cch->d.certificate;
     547           0 :             if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
     548           0 :                 CMS_SignerInfo_set1_signer_cert(si, x);
     549           0 :                 ret++;
     550           0 :                 break;
     551             :             }
     552             :         }
     553             :     }
     554             :     return ret;
     555             : }
     556             : 
     557           0 : void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
     558             :                               X509 **signer, X509_ALGOR **pdig,
     559             :                               X509_ALGOR **psig)
     560             : {
     561           0 :     if (pk)
     562           0 :         *pk = si->pkey;
     563           0 :     if (signer)
     564           0 :         *signer = si->signer;
     565           0 :     if (pdig)
     566           0 :         *pdig = si->digestAlgorithm;
     567           0 :     if (psig)
     568           0 :         *psig = si->signatureAlgorithm;
     569           0 : }
     570             : 
     571           0 : ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
     572             : {
     573           0 :     return si->signature;
     574             : }
     575             : 
     576           0 : static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
     577             :                                        CMS_SignerInfo *si, BIO *chain)
     578             : {
     579             :     EVP_MD_CTX mctx;
     580             :     int r = 0;
     581             :     EVP_PKEY_CTX *pctx = NULL;
     582           0 :     EVP_MD_CTX_init(&mctx);
     583             : 
     584           0 :     if (!si->pkey) {
     585           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
     586             :         return 0;
     587             :     }
     588             : 
     589           0 :     if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
     590             :         goto err;
     591             :     /* Set SignerInfo algortihm details if we used custom parametsr */
     592           0 :     if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
     593             :         goto err;
     594             : 
     595             :     /*
     596             :      * If any signed attributes calculate and add messageDigest attribute
     597             :      */
     598             : 
     599           0 :     if (CMS_signed_get_attr_count(si) >= 0) {
     600           0 :         ASN1_OBJECT *ctype =
     601           0 :             cms->d.signedData->encapContentInfo->eContentType;
     602             :         unsigned char md[EVP_MAX_MD_SIZE];
     603             :         unsigned int mdlen;
     604           0 :         if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
     605             :             goto err;
     606           0 :         if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
     607             :                                          V_ASN1_OCTET_STRING, md, mdlen))
     608             :             goto err;
     609             :         /* Copy content type across */
     610           0 :         if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
     611             :                                         V_ASN1_OBJECT, ctype, -1) <= 0)
     612             :             goto err;
     613           0 :         if (!CMS_SignerInfo_sign(si))
     614             :             goto err;
     615           0 :     } else if (si->pctx) {
     616             :         unsigned char *sig;
     617             :         size_t siglen;
     618             :         unsigned char md[EVP_MAX_MD_SIZE];
     619             :         unsigned int mdlen;
     620             :         pctx = si->pctx;
     621           0 :         if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
     622             :             goto err;
     623           0 :         siglen = EVP_PKEY_size(si->pkey);
     624           0 :         sig = OPENSSL_malloc(siglen);
     625           0 :         if (!sig) {
     626           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
     627             :             goto err;
     628             :         }
     629           0 :         if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0)
     630             :             goto err;
     631           0 :         ASN1_STRING_set0(si->signature, sig, siglen);
     632             :     } else {
     633             :         unsigned char *sig;
     634             :         unsigned int siglen;
     635           0 :         sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
     636           0 :         if (!sig) {
     637           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
     638           0 :             goto err;
     639             :         }
     640           0 :         if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) {
     641           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
     642           0 :             OPENSSL_free(sig);
     643             :             goto err;
     644             :         }
     645           0 :         ASN1_STRING_set0(si->signature, sig, siglen);
     646             :     }
     647             : 
     648             :     r = 1;
     649             : 
     650             :  err:
     651           0 :     EVP_MD_CTX_cleanup(&mctx);
     652           0 :     if (pctx)
     653           0 :         EVP_PKEY_CTX_free(pctx);
     654             :     return r;
     655             : 
     656             : }
     657             : 
     658           0 : int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
     659             : {
     660             :     STACK_OF(CMS_SignerInfo) *sinfos;
     661             :     CMS_SignerInfo *si;
     662             :     int i;
     663             :     sinfos = CMS_get0_SignerInfos(cms);
     664           0 :     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
     665           0 :         si = sk_CMS_SignerInfo_value(sinfos, i);
     666           0 :         if (!cms_SignerInfo_content_sign(cms, si, chain))
     667             :             return 0;
     668             :     }
     669           0 :     cms->d.signedData->encapContentInfo->partial = 0;
     670           0 :     return 1;
     671             : }
     672             : 
     673           0 : int CMS_SignerInfo_sign(CMS_SignerInfo *si)
     674             : {
     675           0 :     EVP_MD_CTX *mctx = &si->mctx;
     676             :     EVP_PKEY_CTX *pctx;
     677           0 :     unsigned char *abuf = NULL;
     678             :     int alen;
     679             :     size_t siglen;
     680             :     const EVP_MD *md = NULL;
     681             : 
     682           0 :     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
     683           0 :     if (md == NULL)
     684             :         return 0;
     685             : 
     686           0 :     if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
     687           0 :         if (!cms_add1_signingTime(si, NULL))
     688             :             goto err;
     689             :     }
     690             : 
     691           0 :     if (si->pctx)
     692           0 :         pctx = si->pctx;
     693             :     else {
     694           0 :         EVP_MD_CTX_init(mctx);
     695           0 :         if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
     696             :             goto err;
     697             :     }
     698             : 
     699           0 :     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
     700             :                           EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
     701           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
     702           0 :         goto err;
     703             :     }
     704             : 
     705           0 :     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
     706             :                          ASN1_ITEM_rptr(CMS_Attributes_Sign));
     707           0 :     if (!abuf)
     708             :         goto err;
     709           0 :     if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
     710             :         goto err;
     711           0 :     if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
     712             :         goto err;
     713           0 :     OPENSSL_free(abuf);
     714           0 :     abuf = OPENSSL_malloc(siglen);
     715           0 :     if (!abuf)
     716             :         goto err;
     717           0 :     if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
     718             :         goto err;
     719             : 
     720           0 :     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
     721             :                           EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
     722           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
     723           0 :         goto err;
     724             :     }
     725             : 
     726           0 :     EVP_MD_CTX_cleanup(mctx);
     727             : 
     728           0 :     ASN1_STRING_set0(si->signature, abuf, siglen);
     729             : 
     730           0 :     return 1;
     731             : 
     732             :  err:
     733           0 :     if (abuf)
     734           0 :         OPENSSL_free(abuf);
     735           0 :     EVP_MD_CTX_cleanup(mctx);
     736           0 :     return 0;
     737             : 
     738             : }
     739             : 
     740           0 : int CMS_SignerInfo_verify(CMS_SignerInfo *si)
     741             : {
     742           0 :     EVP_MD_CTX *mctx = &si->mctx;
     743           0 :     unsigned char *abuf = NULL;
     744             :     int alen, r = -1;
     745             :     const EVP_MD *md = NULL;
     746             : 
     747           0 :     if (!si->pkey) {
     748           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
     749           0 :         return -1;
     750             :     }
     751             : 
     752           0 :     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
     753           0 :     if (md == NULL)
     754             :         return -1;
     755           0 :     EVP_MD_CTX_init(mctx);
     756           0 :     if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
     757             :         goto err;
     758             : 
     759           0 :     if (!cms_sd_asn1_ctrl(si, 1))
     760             :         goto err;
     761             : 
     762           0 :     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
     763             :                          ASN1_ITEM_rptr(CMS_Attributes_Verify));
     764           0 :     if (!abuf)
     765             :         goto err;
     766           0 :     r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
     767           0 :     OPENSSL_free(abuf);
     768           0 :     if (r <= 0) {
     769             :         r = -1;
     770             :         goto err;
     771             :     }
     772           0 :     r = EVP_DigestVerifyFinal(mctx,
     773           0 :                               si->signature->data, si->signature->length);
     774           0 :     if (r <= 0)
     775           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
     776             :  err:
     777           0 :     EVP_MD_CTX_cleanup(mctx);
     778           0 :     return r;
     779             : }
     780             : 
     781             : /* Create a chain of digest BIOs from a CMS ContentInfo */
     782             : 
     783           0 : BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
     784             : {
     785             :     int i;
     786             :     CMS_SignedData *sd;
     787             :     BIO *chain = NULL;
     788           0 :     sd = cms_get0_signed(cms);
     789           0 :     if (!sd)
     790             :         return NULL;
     791           0 :     if (cms->d.signedData->encapContentInfo->partial)
     792           0 :         cms_sd_set_version(sd);
     793           0 :     for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
     794             :         X509_ALGOR *digestAlgorithm;
     795             :         BIO *mdbio;
     796           0 :         digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
     797           0 :         mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
     798           0 :         if (!mdbio)
     799             :             goto err;
     800           0 :         if (chain)
     801           0 :             BIO_push(chain, mdbio);
     802             :         else
     803             :             chain = mdbio;
     804             :     }
     805             :     return chain;
     806             :  err:
     807           0 :     if (chain)
     808           0 :         BIO_free_all(chain);
     809             :     return NULL;
     810             : }
     811             : 
     812           0 : int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
     813             : {
     814             :     ASN1_OCTET_STRING *os = NULL;
     815             :     EVP_MD_CTX mctx;
     816             :     EVP_PKEY_CTX *pkctx = NULL;
     817             :     int r = -1;
     818             :     unsigned char mval[EVP_MAX_MD_SIZE];
     819             :     unsigned int mlen;
     820           0 :     EVP_MD_CTX_init(&mctx);
     821             :     /* If we have any signed attributes look for messageDigest value */
     822           0 :     if (CMS_signed_get_attr_count(si) >= 0) {
     823           0 :         os = CMS_signed_get0_data_by_OBJ(si,
     824             :                                          OBJ_nid2obj(NID_pkcs9_messageDigest),
     825             :                                          -3, V_ASN1_OCTET_STRING);
     826           0 :         if (!os) {
     827           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
     828             :                    CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
     829           0 :             goto err;
     830             :         }
     831             :     }
     832             : 
     833           0 :     if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
     834             :         goto err;
     835             : 
     836           0 :     if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) {
     837           0 :         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
     838             :                CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
     839           0 :         goto err;
     840             :     }
     841             : 
     842             :     /* If messageDigest found compare it */
     843             : 
     844           0 :     if (os) {
     845           0 :         if (mlen != (unsigned int)os->length) {
     846           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
     847             :                    CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
     848           0 :             goto err;
     849             :         }
     850             : 
     851           0 :         if (memcmp(mval, os->data, mlen)) {
     852           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
     853             :                    CMS_R_VERIFICATION_FAILURE);
     854             :             r = 0;
     855             :         } else
     856             :             r = 1;
     857             :     } else {
     858           0 :         const EVP_MD *md = EVP_MD_CTX_md(&mctx);
     859           0 :         pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
     860           0 :         if (EVP_PKEY_verify_init(pkctx) <= 0)
     861             :             goto err;
     862           0 :         if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
     863             :             goto err;
     864           0 :         si->pctx = pkctx;
     865           0 :         if (!cms_sd_asn1_ctrl(si, 1))
     866             :             goto err;
     867           0 :         r = EVP_PKEY_verify(pkctx, si->signature->data,
     868           0 :                             si->signature->length, mval, mlen);
     869           0 :         if (r <= 0) {
     870           0 :             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
     871             :                    CMS_R_VERIFICATION_FAILURE);
     872             :             r = 0;
     873             :         }
     874             :     }
     875             : 
     876             :  err:
     877           0 :     if (pkctx)
     878           0 :         EVP_PKEY_CTX_free(pkctx);
     879           0 :     EVP_MD_CTX_cleanup(&mctx);
     880           0 :     return r;
     881             : 
     882             : }
     883             : 
     884           0 : int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
     885             : {
     886           0 :     unsigned char *smder = NULL;
     887             :     int smderlen, r;
     888           0 :     smderlen = i2d_X509_ALGORS(algs, &smder);
     889           0 :     if (smderlen <= 0)
     890             :         return 0;
     891           0 :     r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
     892             :                                     V_ASN1_SEQUENCE, smder, smderlen);
     893           0 :     OPENSSL_free(smder);
     894           0 :     return r;
     895             : }
     896             : 
     897           0 : int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
     898             :                             int algnid, int keysize)
     899             : {
     900             :     X509_ALGOR *alg;
     901             :     ASN1_INTEGER *key = NULL;
     902           0 :     if (keysize > 0) {
     903           0 :         key = ASN1_INTEGER_new();
     904           0 :         if (!key || !ASN1_INTEGER_set(key, keysize))
     905             :             return 0;
     906             :     }
     907           0 :     alg = X509_ALGOR_new();
     908           0 :     if (!alg) {
     909           0 :         if (key)
     910           0 :             ASN1_INTEGER_free(key);
     911             :         return 0;
     912             :     }
     913             : 
     914           0 :     X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
     915             :                     key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
     916           0 :     if (!*algs)
     917           0 :         *algs = sk_X509_ALGOR_new_null();
     918           0 :     if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) {
     919           0 :         X509_ALGOR_free(alg);
     920           0 :         return 0;
     921             :     }
     922             :     return 1;
     923             : }
     924             : 
     925             : /* Check to see if a cipher exists and if so add S/MIME capabilities */
     926             : 
     927           0 : static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
     928             : {
     929           0 :     if (EVP_get_cipherbynid(nid))
     930           0 :         return CMS_add_simple_smimecap(sk, nid, arg);
     931             :     return 1;
     932             : }
     933             : 
     934           0 : static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
     935             : {
     936           0 :     if (EVP_get_digestbynid(nid))
     937           0 :         return CMS_add_simple_smimecap(sk, nid, arg);
     938             :     return 1;
     939             : }
     940             : 
     941           0 : int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
     942             : {
     943           0 :     if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
     944           0 :         || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
     945           0 :         || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
     946           0 :         || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
     947           0 :         || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
     948           0 :         || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
     949           0 :         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
     950           0 :         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
     951           0 :         || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
     952           0 :         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
     953             :         return 0;
     954             :     return 1;
     955             : }

Generated by: LCOV version 1.10