Home | History | Annotate | Line # | Download | only in cms
      1 /*
      2  * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include "internal/cryptlib.h"
     11 #include <openssl/asn1t.h>
     12 #include <openssl/x509.h>
     13 #include <openssl/x509v3.h>
     14 #include <openssl/err.h>
     15 #include <openssl/cms.h>
     16 #include "cms_local.h"
     17 #include "crypto/asn1.h"
     18 #include "crypto/x509.h"
     19 
     20 static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
     21 {
     22     BIO *rbio;
     23 
     24     if (out == NULL)
     25         rbio = BIO_new(BIO_s_null());
     26     else if (flags & CMS_TEXT) {
     27         rbio = BIO_new(BIO_s_mem());
     28         BIO_set_mem_eof_return(rbio, 0);
     29     } else
     30         rbio = out;
     31     return rbio;
     32 }
     33 
     34 static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
     35 {
     36     unsigned char buf[4096];
     37     int r = 0, i;
     38     BIO *tmpout;
     39 
     40     tmpout = cms_get_text_bio(out, flags);
     41 
     42     if (tmpout == NULL) {
     43         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
     44         goto err;
     45     }
     46 
     47     /* Read all content through chain to process digest, decrypt etc */
     48     for (;;) {
     49         i = BIO_read(in, buf, sizeof(buf));
     50         if (i <= 0) {
     51             if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
     52                 if (BIO_get_cipher_status(in) <= 0)
     53                     goto err;
     54             }
     55             if (i < 0)
     56                 goto err;
     57             break;
     58         }
     59 
     60         if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i))
     61             goto err;
     62     }
     63 
     64     if (flags & CMS_TEXT) {
     65         if (!SMIME_text(tmpout, out)) {
     66             ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR);
     67             goto err;
     68         }
     69     }
     70 
     71     r = 1;
     72 err:
     73     if (tmpout != out)
     74         BIO_free(tmpout);
     75     return r;
     76 }
     77 
     78 static int check_content(CMS_ContentInfo *cms)
     79 {
     80     ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
     81 
     82     if (pos == NULL || *pos == NULL) {
     83         ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT);
     84         return 0;
     85     }
     86     return 1;
     87 }
     88 
     89 static void do_free_upto(BIO *f, BIO *upto)
     90 {
     91     if (upto != NULL) {
     92         BIO *tbio;
     93 
     94         do {
     95             tbio = BIO_pop(f);
     96             BIO_free(f);
     97             f = tbio;
     98         } while (f != NULL && f != upto);
     99     } else {
    100         BIO_free_all(f);
    101     }
    102 }
    103 
    104 int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
    105 {
    106     BIO *cont;
    107     int r;
    108 
    109     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
    110         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA);
    111         return 0;
    112     }
    113     cont = CMS_dataInit(cms, NULL);
    114     if (cont == NULL)
    115         return 0;
    116     r = cms_copy_content(out, cont, flags);
    117     BIO_free_all(cont);
    118     return r;
    119 }
    120 
    121 CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags,
    122     OSSL_LIB_CTX *libctx, const char *propq)
    123 {
    124     CMS_ContentInfo *cms = ossl_cms_Data_create(libctx, propq);
    125 
    126     if (cms == NULL)
    127         return NULL;
    128 
    129     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
    130         return cms;
    131 
    132     CMS_ContentInfo_free(cms);
    133     return NULL;
    134 }
    135 
    136 CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
    137 {
    138     return CMS_data_create_ex(in, flags, NULL, NULL);
    139 }
    140 
    141 int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
    142     unsigned int flags)
    143 {
    144     BIO *cont;
    145     int r;
    146 
    147     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
    148         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA);
    149         return 0;
    150     }
    151 
    152     if (dcont == NULL && !check_content(cms))
    153         return 0;
    154 
    155     cont = CMS_dataInit(cms, dcont);
    156     if (cont == NULL)
    157         return 0;
    158 
    159     r = cms_copy_content(out, cont, flags);
    160     if (r)
    161         r = ossl_cms_DigestedData_do_final(cms, cont, 1);
    162     do_free_upto(cont, dcont);
    163     return r;
    164 }
    165 
    166 CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md,
    167     unsigned int flags, OSSL_LIB_CTX *ctx,
    168     const char *propq)
    169 {
    170     CMS_ContentInfo *cms;
    171 
    172     /*
    173      * Because the EVP_MD is cached and can be a legacy algorithm, we
    174      * cannot fetch the algorithm if it isn't supplied.
    175      */
    176     if (md == NULL)
    177         md = EVP_sha1();
    178     cms = ossl_cms_DigestedData_create(md, ctx, propq);
    179     if (cms == NULL)
    180         return NULL;
    181 
    182     if (!(flags & CMS_DETACHED))
    183         CMS_set_detached(cms, 0);
    184 
    185     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
    186         return cms;
    187 
    188     CMS_ContentInfo_free(cms);
    189     return NULL;
    190 }
    191 
    192 CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
    193     unsigned int flags)
    194 {
    195     return CMS_digest_create_ex(in, md, flags, NULL, NULL);
    196 }
    197 
    198 int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
    199     const unsigned char *key, size_t keylen,
    200     BIO *dcont, BIO *out, unsigned int flags)
    201 {
    202     BIO *cont;
    203     int r;
    204 
    205     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
    206         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA);
    207         return 0;
    208     }
    209 
    210     if (dcont == NULL && !check_content(cms))
    211         return 0;
    212 
    213     if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
    214         return 0;
    215     cont = CMS_dataInit(cms, dcont);
    216     if (cont == NULL)
    217         return 0;
    218     r = cms_copy_content(out, cont, flags);
    219     do_free_upto(cont, dcont);
    220     return r;
    221 }
    222 
    223 CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher,
    224     const unsigned char *key,
    225     size_t keylen, unsigned int flags,
    226     OSSL_LIB_CTX *libctx,
    227     const char *propq)
    228 {
    229     CMS_ContentInfo *cms;
    230 
    231     if (cipher == NULL) {
    232         ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER);
    233         return NULL;
    234     }
    235     cms = CMS_ContentInfo_new_ex(libctx, propq);
    236     if (cms == NULL)
    237         return NULL;
    238     if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
    239         goto err;
    240 
    241     if (!(flags & CMS_DETACHED))
    242         CMS_set_detached(cms, 0);
    243 
    244     if ((flags & (CMS_STREAM | CMS_PARTIAL))
    245         || CMS_final(cms, in, NULL, flags))
    246         return cms;
    247 
    248 err:
    249     CMS_ContentInfo_free(cms);
    250     return NULL;
    251 }
    252 
    253 CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
    254     const unsigned char *key,
    255     size_t keylen, unsigned int flags)
    256 {
    257     return CMS_EncryptedData_encrypt_ex(in, cipher, key, keylen, flags, NULL,
    258         NULL);
    259 }
    260 
    261 static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
    262     X509_STORE *store,
    263     STACK_OF(X509) *untrusted,
    264     STACK_OF(X509_CRL) *crls,
    265     STACK_OF(X509) **chain,
    266     const CMS_CTX *cms_ctx)
    267 {
    268     X509_STORE_CTX *ctx;
    269     X509 *signer;
    270     int i, j, r = 0;
    271 
    272     ctx = X509_STORE_CTX_new_ex(ossl_cms_ctx_get0_libctx(cms_ctx),
    273         ossl_cms_ctx_get0_propq(cms_ctx));
    274     if (ctx == NULL) {
    275         ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB);
    276         goto err;
    277     }
    278     CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
    279     if (!X509_STORE_CTX_init(ctx, store, signer, untrusted)) {
    280         ERR_raise(ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR);
    281         goto err;
    282     }
    283     X509_STORE_CTX_set_default(ctx, "smime_sign");
    284     if (crls != NULL)
    285         X509_STORE_CTX_set0_crls(ctx, crls);
    286 
    287     i = X509_verify_cert(ctx);
    288     if (i <= 0) {
    289         j = X509_STORE_CTX_get_error(ctx);
    290         ERR_raise_data(ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR,
    291             "Verify error: %s", X509_verify_cert_error_string(j));
    292         goto err;
    293     }
    294     r = 1;
    295 
    296     /* also send back the trust chain when required */
    297     if (chain != NULL)
    298         *chain = X509_STORE_CTX_get1_chain(ctx);
    299 err:
    300     X509_STORE_CTX_free(ctx);
    301     return r;
    302 }
    303 
    304 /* This strongly overlaps with PKCS7_verify() */
    305 int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
    306     X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
    307 {
    308     CMS_SignerInfo *si;
    309     STACK_OF(CMS_SignerInfo) *sinfos;
    310     STACK_OF(X509) *untrusted = NULL;
    311     STACK_OF(X509_CRL) *crls = NULL;
    312     STACK_OF(X509) **si_chains = NULL;
    313     X509 *signer;
    314     int i, scount = 0, ret = 0;
    315     BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
    316     int cadesVerify = (flags & CMS_CADES) != 0;
    317     const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
    318 
    319     if (dcont == NULL && !check_content(cms))
    320         return 0;
    321     if (dcont != NULL && !(flags & CMS_BINARY)) {
    322         const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
    323 
    324         if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
    325             flags |= CMS_ASCIICRLF;
    326     }
    327 
    328     /* Attempt to find all signer certificates */
    329 
    330     sinfos = CMS_get0_SignerInfos(cms);
    331 
    332     if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
    333         ERR_raise(ERR_LIB_CMS, CMS_R_NO_SIGNERS);
    334         goto err;
    335     }
    336 
    337     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
    338         si = sk_CMS_SignerInfo_value(sinfos, i);
    339         CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
    340         if (signer != NULL)
    341             scount++;
    342     }
    343 
    344     if (scount != sk_CMS_SignerInfo_num(sinfos))
    345         scount += CMS_set1_signers_certs(cms, certs, flags);
    346 
    347     if (scount != sk_CMS_SignerInfo_num(sinfos)) {
    348         ERR_raise(ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
    349         goto err;
    350     }
    351 
    352     /* Attempt to verify all signers certs */
    353     /* at this point scount == sk_CMS_SignerInfo_num(sinfos) */
    354 
    355     if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) {
    356         if (cadesVerify) {
    357             /* Certificate trust chain is required to check CAdES signature */
    358             si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0]));
    359             if (si_chains == NULL)
    360                 goto err;
    361         }
    362         if (!ossl_cms_get1_certs_ex(cms, &untrusted))
    363             goto err;
    364         if (sk_X509_num(certs) > 0
    365             && !ossl_x509_add_certs_new(&untrusted, certs,
    366                 X509_ADD_FLAG_UP_REF | X509_ADD_FLAG_NO_DUP))
    367             goto err;
    368 
    369         if ((flags & CMS_NOCRL) == 0
    370             && !ossl_cms_get1_crls_ex(cms, &crls))
    371             goto err;
    372         for (i = 0; i < scount; i++) {
    373             si = sk_CMS_SignerInfo_value(sinfos, i);
    374 
    375             if (!cms_signerinfo_verify_cert(si, store, untrusted, crls,
    376                     si_chains ? &si_chains[i] : NULL,
    377                     ctx))
    378                 goto err;
    379         }
    380     }
    381 
    382     /* Attempt to verify all SignerInfo signed attribute signatures */
    383 
    384     if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) {
    385         for (i = 0; i < scount; i++) {
    386             si = sk_CMS_SignerInfo_value(sinfos, i);
    387             if (CMS_signed_get_attr_count(si) < 0)
    388                 continue;
    389             if (CMS_SignerInfo_verify(si) <= 0)
    390                 goto err;
    391             if (cadesVerify) {
    392                 STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL;
    393 
    394                 if (ossl_cms_check_signing_certs(si, si_chain) <= 0)
    395                     goto err;
    396             }
    397         }
    398     }
    399 
    400     /*
    401      * Performance optimization: if the content is a memory BIO then store
    402      * its contents in a temporary read only memory BIO. This avoids
    403      * potentially large numbers of slow copies of data which will occur when
    404      * reading from a read write memory BIO when signatures are calculated.
    405      */
    406 
    407     if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
    408         char *ptr;
    409         long len;
    410 
    411         len = BIO_get_mem_data(dcont, &ptr);
    412         tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len);
    413         if (tmpin == NULL) {
    414             ERR_raise(ERR_LIB_CMS, ERR_R_BIO_LIB);
    415             goto err2;
    416         }
    417     } else {
    418         tmpin = dcont;
    419     }
    420     /*
    421      * If not binary mode and detached generate digests by *writing* through
    422      * the BIO. That makes it possible to canonicalise the input.
    423      */
    424     if (!(flags & SMIME_BINARY) && dcont) {
    425         /*
    426          * Create output BIO so we can either handle text or to ensure
    427          * included content doesn't override detached content.
    428          */
    429         tmpout = cms_get_text_bio(out, flags);
    430         if (tmpout == NULL) {
    431             ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    432             goto err;
    433         }
    434         cmsbio = CMS_dataInit(cms, tmpout);
    435         if (cmsbio == NULL)
    436             goto err;
    437         /*
    438          * Don't use SMIME_TEXT for verify: it adds headers and we want to
    439          * remove them.
    440          */
    441         if (!SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT))
    442             goto err;
    443 
    444         if (flags & CMS_TEXT) {
    445             if (!SMIME_text(tmpout, out)) {
    446                 ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR);
    447                 goto err;
    448             }
    449         }
    450     } else {
    451         cmsbio = CMS_dataInit(cms, tmpin);
    452         if (cmsbio == NULL)
    453             goto err;
    454 
    455         if (!cms_copy_content(out, cmsbio, flags))
    456             goto err;
    457     }
    458     if (!(flags & CMS_NO_CONTENT_VERIFY)) {
    459         for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
    460             si = sk_CMS_SignerInfo_value(sinfos, i);
    461             if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
    462                 ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR);
    463                 goto err;
    464             }
    465         }
    466     }
    467 
    468     ret = 1;
    469 err:
    470     if (!(flags & SMIME_BINARY) && dcont) {
    471         do_free_upto(cmsbio, tmpout);
    472         if (tmpin != dcont)
    473             BIO_free(tmpin);
    474     } else {
    475         if (dcont && (tmpin == dcont))
    476             do_free_upto(cmsbio, dcont);
    477         else
    478             BIO_free_all(cmsbio);
    479     }
    480 
    481     if (out != tmpout)
    482         BIO_free_all(tmpout);
    483 
    484 err2:
    485     if (si_chains != NULL) {
    486         for (i = 0; i < scount; ++i)
    487             OSSL_STACK_OF_X509_free(si_chains[i]);
    488         OPENSSL_free(si_chains);
    489     }
    490     sk_X509_pop_free(untrusted, X509_free);
    491     sk_X509_CRL_pop_free(crls, X509_CRL_free);
    492 
    493     return ret;
    494 }
    495 
    496 int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
    497     STACK_OF(X509) *certs,
    498     X509_STORE *store, unsigned int flags)
    499 {
    500     int r;
    501 
    502     flags &= ~(CMS_DETACHED | CMS_TEXT);
    503     r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
    504     if (r <= 0)
    505         return r;
    506     return ossl_cms_Receipt_verify(rcms, ocms);
    507 }
    508 
    509 CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey,
    510     STACK_OF(X509) *certs, BIO *data,
    511     unsigned int flags, OSSL_LIB_CTX *libctx,
    512     const char *propq)
    513 {
    514     CMS_ContentInfo *cms;
    515     int i;
    516 
    517     cms = CMS_ContentInfo_new_ex(libctx, propq);
    518     if (cms == NULL || !CMS_SignedData_init(cms)) {
    519         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    520         goto err;
    521     }
    522     if (flags & CMS_ASCIICRLF
    523         && !CMS_set1_eContentType(cms,
    524             OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) {
    525         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    526         goto err;
    527     }
    528 
    529     if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
    530         ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR);
    531         goto err;
    532     }
    533 
    534     for (i = 0; i < sk_X509_num(certs); i++) {
    535         X509 *x = sk_X509_value(certs, i);
    536 
    537         if (!CMS_add1_cert(cms, x)) {
    538             ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    539             goto err;
    540         }
    541     }
    542 
    543     if (!(flags & CMS_DETACHED))
    544         CMS_set_detached(cms, 0);
    545 
    546     if ((flags & (CMS_STREAM | CMS_PARTIAL))
    547         || CMS_final(cms, data, NULL, flags))
    548         return cms;
    549     else
    550         goto err;
    551 
    552 err:
    553     CMS_ContentInfo_free(cms);
    554     return NULL;
    555 }
    556 
    557 CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
    558     BIO *data, unsigned int flags)
    559 {
    560     return CMS_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL);
    561 }
    562 
    563 CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
    564     X509 *signcert, EVP_PKEY *pkey,
    565     STACK_OF(X509) *certs, unsigned int flags)
    566 {
    567     CMS_SignerInfo *rct_si;
    568     CMS_ContentInfo *cms = NULL;
    569     ASN1_OCTET_STRING **pos, *os = NULL;
    570     BIO *rct_cont = NULL;
    571     int r = 0;
    572     const CMS_CTX *ctx = si->cms_ctx;
    573 
    574     flags &= ~(CMS_STREAM | CMS_TEXT);
    575     /* Not really detached but avoids content being allocated */
    576     flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
    577     if (pkey == NULL || signcert == NULL) {
    578         ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT);
    579         return NULL;
    580     }
    581 
    582     /* Initialize signed data */
    583 
    584     cms = CMS_sign_ex(NULL, NULL, certs, NULL, flags,
    585         ossl_cms_ctx_get0_libctx(ctx),
    586         ossl_cms_ctx_get0_propq(ctx));
    587     if (cms == NULL)
    588         goto err;
    589 
    590     /* Set inner content type to signed receipt */
    591     if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
    592         goto err;
    593 
    594     rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
    595     if (!rct_si) {
    596         ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR);
    597         goto err;
    598     }
    599 
    600     os = ossl_cms_encode_Receipt(si);
    601     if (os == NULL)
    602         goto err;
    603 
    604     /* Set content to digest */
    605     rct_cont = BIO_new_mem_buf(os->data, os->length);
    606     if (rct_cont == NULL)
    607         goto err;
    608 
    609     /* Add msgSigDigest attribute */
    610 
    611     if (!ossl_cms_msgSigDigest_add1(rct_si, si))
    612         goto err;
    613 
    614     /* Finalize structure */
    615     if (!CMS_final(cms, rct_cont, NULL, flags))
    616         goto err;
    617 
    618     /* Set embedded content */
    619     pos = CMS_get0_content(cms);
    620     if (pos == NULL)
    621         goto err;
    622     *pos = os;
    623 
    624     r = 1;
    625 
    626 err:
    627     BIO_free(rct_cont);
    628     if (r)
    629         return cms;
    630     CMS_ContentInfo_free(cms);
    631     ASN1_OCTET_STRING_free(os);
    632     return NULL;
    633 }
    634 
    635 CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data,
    636     const EVP_CIPHER *cipher, unsigned int flags,
    637     OSSL_LIB_CTX *libctx, const char *propq)
    638 {
    639     CMS_ContentInfo *cms;
    640     int i;
    641     X509 *recip;
    642 
    643     cms = (EVP_CIPHER_get_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER)
    644         ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq)
    645         : CMS_EnvelopedData_create_ex(cipher, libctx, propq);
    646     if (cms == NULL) {
    647         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    648         goto err;
    649     }
    650     for (i = 0; i < sk_X509_num(certs); i++) {
    651         recip = sk_X509_value(certs, i);
    652         if (!CMS_add1_recipient_cert(cms, recip, flags)) {
    653             ERR_raise(ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR);
    654             goto err;
    655         }
    656     }
    657 
    658     if (!(flags & CMS_DETACHED))
    659         CMS_set_detached(cms, 0);
    660 
    661     if ((flags & (CMS_STREAM | CMS_PARTIAL))
    662         || CMS_final(cms, data, NULL, flags))
    663         return cms;
    664     else
    665         ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
    666 
    667 err:
    668     CMS_ContentInfo_free(cms);
    669     return NULL;
    670 }
    671 
    672 CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
    673     const EVP_CIPHER *cipher, unsigned int flags)
    674 {
    675     return CMS_encrypt_ex(certs, data, cipher, flags, NULL, NULL);
    676 }
    677 
    678 static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms,
    679     CMS_RecipientInfo *ri,
    680     EVP_PKEY *pk, X509 *cert, X509 *peer)
    681 {
    682     int i;
    683     STACK_OF(CMS_RecipientEncryptedKey) *reks;
    684     CMS_RecipientEncryptedKey *rek;
    685 
    686     reks = CMS_RecipientInfo_kari_get0_reks(ri);
    687     for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
    688         int rv;
    689 
    690         rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
    691         if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
    692             continue;
    693         CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer);
    694         rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
    695         CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
    696         if (rv > 0)
    697             return 1;
    698         return cert == NULL ? 0 : -1;
    699     }
    700     return 0;
    701 }
    702 
    703 int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
    704 {
    705     return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL);
    706 }
    707 
    708 int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
    709     X509 *cert, X509 *peer)
    710 {
    711     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
    712     CMS_RecipientInfo *ri;
    713     int i, r, cms_pkey_ri_type;
    714     int debug = 0, match_ri = 0;
    715     CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
    716 
    717     /* Prevent mem leak on earlier CMS_decrypt_set1_{pkey_and_peer,password} */
    718     if (ec != NULL) {
    719         OPENSSL_clear_free(ec->key, ec->keylen);
    720         ec->key = NULL;
    721         ec->keylen = 0;
    722     }
    723 
    724     if (ris != NULL && ec != NULL)
    725         debug = ec->debug;
    726 
    727     cms_pkey_ri_type = ossl_cms_pkey_get_ri_type(pk);
    728     if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) {
    729         ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
    730         return 0;
    731     }
    732 
    733     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
    734         int ri_type;
    735 
    736         ri = sk_CMS_RecipientInfo_value(ris, i);
    737         ri_type = CMS_RecipientInfo_type(ri);
    738         if (!ossl_cms_pkey_is_ri_type_supported(pk, ri_type))
    739             continue;
    740         match_ri = 1;
    741         if (ri_type == CMS_RECIPINFO_AGREE) {
    742             r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer);
    743             if (r > 0)
    744                 return 1;
    745             if (r < 0)
    746                 return 0;
    747         }
    748         /* If we have a cert, try matching RecipientInfo, else try them all */
    749         else if (cert == NULL || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
    750             if (!EVP_PKEY_up_ref(pk))
    751                 return 0;
    752             CMS_RecipientInfo_set0_pkey(ri, pk);
    753             r = CMS_RecipientInfo_decrypt(cms, ri);
    754             CMS_RecipientInfo_set0_pkey(ri, NULL);
    755             if (cert != NULL) {
    756                 /*
    757                  * If not debugging clear any error and return success to
    758                  * avoid leaking of information useful to MMA
    759                  */
    760                 if (!debug) {
    761                     ERR_clear_error();
    762                     return 1;
    763                 }
    764                 if (r > 0)
    765                     return 1;
    766                 ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR);
    767                 return 0;
    768             }
    769             /*
    770              * If no cert and not debugging don't leave loop after first
    771              * successful decrypt. Always attempt to decrypt all recipients
    772              * to avoid leaking timing of a successful decrypt.
    773              */
    774             else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS))
    775                 return 1;
    776         }
    777     }
    778     /* If no cert, key transport and not debugging always return success */
    779     if (cert == NULL
    780         && cms_pkey_ri_type == CMS_RECIPINFO_TRANS
    781         && match_ri
    782         && !debug) {
    783         ERR_clear_error();
    784         return 1;
    785     }
    786 
    787     if (!match_ri)
    788         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
    789     return 0;
    790 }
    791 
    792 int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
    793     unsigned char *key, size_t keylen,
    794     const unsigned char *id, size_t idlen)
    795 {
    796     STACK_OF(CMS_RecipientInfo) *ris;
    797     CMS_RecipientInfo *ri;
    798     int i, r, match_ri = 0;
    799 
    800     ris = CMS_get0_RecipientInfos(cms);
    801     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
    802         ri = sk_CMS_RecipientInfo_value(ris, i);
    803         if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
    804             continue;
    805 
    806         /* If we have an id, try matching RecipientInfo, else try them all */
    807         if (id == NULL
    808             || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
    809             match_ri = 1;
    810             CMS_RecipientInfo_set0_key(ri, key, keylen);
    811             r = CMS_RecipientInfo_decrypt(cms, ri);
    812             CMS_RecipientInfo_set0_key(ri, NULL, 0);
    813             if (r > 0)
    814                 return 1;
    815             if (id != NULL) {
    816                 ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR);
    817                 return 0;
    818             }
    819             ERR_clear_error();
    820         }
    821     }
    822 
    823     if (!match_ri)
    824         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
    825     return 0;
    826 }
    827 
    828 int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
    829     unsigned char *pass, ossl_ssize_t passlen)
    830 {
    831     STACK_OF(CMS_RecipientInfo) *ris = CMS_get0_RecipientInfos(cms);
    832     CMS_RecipientInfo *ri;
    833     int i, r, match_ri = 0;
    834     CMS_EncryptedContentInfo *ec = ossl_cms_get0_env_enc_content(cms);
    835 
    836     /* Prevent mem leak on earlier CMS_decrypt_set1_{pkey_and_peer,password} */
    837     if (ec != NULL) {
    838         OPENSSL_clear_free(ec->key, ec->keylen);
    839         ec->key = NULL;
    840         ec->keylen = 0;
    841     }
    842 
    843     for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
    844         ri = sk_CMS_RecipientInfo_value(ris, i);
    845         if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
    846             continue;
    847 
    848         /* Must try each PasswordRecipientInfo */
    849         match_ri = 1;
    850         CMS_RecipientInfo_set0_password(ri, pass, passlen);
    851         r = CMS_RecipientInfo_decrypt(cms, ri);
    852         CMS_RecipientInfo_set0_password(ri, NULL, 0);
    853         if (r > 0)
    854             return 1;
    855     }
    856 
    857     if (!match_ri)
    858         ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT);
    859     return 0;
    860 }
    861 
    862 int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
    863     BIO *dcont, BIO *out, unsigned int flags)
    864 {
    865     int r;
    866     BIO *cont;
    867     CMS_EncryptedContentInfo *ec;
    868     int nid = OBJ_obj2nid(CMS_get0_type(cms));
    869 
    870     if (nid != NID_pkcs7_enveloped
    871         && nid != NID_id_smime_ct_authEnvelopedData) {
    872         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA);
    873         return 0;
    874     }
    875     if (dcont == NULL && !check_content(cms))
    876         return 0;
    877     ec = ossl_cms_get0_env_enc_content(cms);
    878     ec->debug = (flags & CMS_DEBUG_DECRYPT) != 0;
    879     ec->havenocert = cert == NULL;
    880     if (pk == NULL && cert == NULL && dcont == NULL && out == NULL)
    881         return 1;
    882     if (pk != NULL && !CMS_decrypt_set1_pkey(cms, pk, cert))
    883         return 0;
    884     cont = CMS_dataInit(cms, dcont);
    885     if (cont == NULL)
    886         return 0;
    887     r = cms_copy_content(out, cont, flags);
    888     do_free_upto(cont, dcont);
    889     return r;
    890 }
    891 
    892 int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
    893 {
    894     BIO *cmsbio;
    895     int ret = 0;
    896 
    897     if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
    898         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
    899         return 0;
    900     }
    901 
    902     if (!SMIME_crlf_copy(data, cmsbio, flags)) {
    903         goto err;
    904     }
    905 
    906     (void)BIO_flush(cmsbio);
    907 
    908     if (!CMS_dataFinal(cms, cmsbio)) {
    909         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR);
    910         goto err;
    911     }
    912 
    913     ret = 1;
    914 
    915 err:
    916     do_free_upto(cmsbio, dcont);
    917 
    918     return ret;
    919 }
    920 
    921 int CMS_final_digest(CMS_ContentInfo *cms,
    922     const unsigned char *md, unsigned int mdlen,
    923     BIO *dcont, unsigned int flags)
    924 {
    925     BIO *cmsbio;
    926     int ret = 0;
    927 
    928     if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
    929         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
    930         return 0;
    931     }
    932 
    933     (void)BIO_flush(cmsbio);
    934 
    935     if (!ossl_cms_DataFinal(cms, cmsbio, md, mdlen)) {
    936         ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR);
    937         goto err;
    938     }
    939     ret = 1;
    940 
    941 err:
    942     do_free_upto(cmsbio, dcont);
    943     return ret;
    944 }
    945 
    946 #ifndef OPENSSL_NO_ZLIB
    947 
    948 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
    949     unsigned int flags)
    950 {
    951     BIO *cont;
    952     int r;
    953 
    954     if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
    955         ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
    956         return 0;
    957     }
    958 
    959     if (dcont == NULL && !check_content(cms))
    960         return 0;
    961 
    962     cont = CMS_dataInit(cms, dcont);
    963     if (cont == NULL)
    964         return 0;
    965     r = cms_copy_content(out, cont, flags);
    966     do_free_upto(cont, dcont);
    967     return r;
    968 }
    969 
    970 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
    971 {
    972     CMS_ContentInfo *cms;
    973 
    974     if (comp_nid <= 0)
    975         comp_nid = NID_zlib_compression;
    976     cms = ossl_cms_CompressedData_create(comp_nid, NULL, NULL);
    977     if (cms == NULL)
    978         return NULL;
    979 
    980     if (!(flags & CMS_DETACHED))
    981         CMS_set_detached(cms, 0);
    982 
    983     if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
    984         return cms;
    985 
    986     CMS_ContentInfo_free(cms);
    987     return NULL;
    988 }
    989 
    990 #else
    991 
    992 int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
    993     unsigned int flags)
    994 {
    995     ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
    996     return 0;
    997 }
    998 
    999 CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
   1000 {
   1001     ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
   1002     return NULL;
   1003 }
   1004 
   1005 #endif
   1006