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