Home | History | Annotate | Line # | Download | only in cms
      1 /*
      2  * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the OpenSSL license (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/pem.h>
     13 #include <openssl/x509v3.h>
     14 #include <openssl/err.h>
     15 #include <openssl/cms.h>
     16 #include "cms_local.h"
     17 
     18 /* CMS DigestedData Utilities */
     19 
     20 CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
     21 {
     22     CMS_ContentInfo *cms;
     23     CMS_DigestedData *dd;
     24     cms = CMS_ContentInfo_new();
     25     if (cms == NULL)
     26         return NULL;
     27 
     28     dd = M_ASN1_new_of(CMS_DigestedData);
     29 
     30     if (dd == NULL)
     31         goto err;
     32 
     33     cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
     34     cms->d.digestedData = dd;
     35 
     36     dd->version = 0;
     37     dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
     38 
     39     X509_ALGOR_set_md(dd->digestAlgorithm, md);
     40 
     41     return cms;
     42 
     43  err:
     44     CMS_ContentInfo_free(cms);
     45     return NULL;
     46 }
     47 
     48 BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
     49 {
     50     CMS_DigestedData *dd;
     51     dd = cms->d.digestedData;
     52     return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
     53 }
     54 
     55 int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
     56 {
     57     EVP_MD_CTX *mctx = EVP_MD_CTX_new();
     58     unsigned char md[EVP_MAX_MD_SIZE];
     59     unsigned int mdlen;
     60     int r = 0;
     61     CMS_DigestedData *dd;
     62 
     63     if (mctx == NULL) {
     64         CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, ERR_R_MALLOC_FAILURE);
     65         goto err;
     66     }
     67 
     68     dd = cms->d.digestedData;
     69 
     70     if (!cms_DigestAlgorithm_find_ctx(mctx, chain, dd->digestAlgorithm))
     71         goto err;
     72 
     73     if (EVP_DigestFinal_ex(mctx, md, &mdlen) <= 0)
     74         goto err;
     75 
     76     if (verify) {
     77         if (mdlen != (unsigned int)dd->digest->length) {
     78             CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
     79                    CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
     80             goto err;
     81         }
     82 
     83         if (memcmp(md, dd->digest->data, mdlen))
     84             CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
     85                    CMS_R_VERIFICATION_FAILURE);
     86         else
     87             r = 1;
     88     } else {
     89         if (!ASN1_STRING_set(dd->digest, md, mdlen))
     90             goto err;
     91         r = 1;
     92     }
     93 
     94  err:
     95     EVP_MD_CTX_free(mctx);
     96 
     97     return r;
     98 
     99 }
    100