summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2021-04-28 10:54:57 +0200
committerTodd Short <todd.short@me.com>2022-04-02 10:42:16 -0400
commit07342bad1bf850657e1a1f21188ee9a8a75e3a19 (patch)
treef9b918931dd10d5a1e58a3a7c039eb29b1e39a7c /crypto
parente4cdcb8bc44250aa4e0893dc4a7d64668f0fb949 (diff)
CMS sign digest
CLI changes: New parameter -digest to CLI command openssl cms, to provide pre-computed digest for use with -sign. API changes: New function CMS_final_digest(), like CMS_final() but uses a pre-computed digest instead of computing it from the data. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> Reviewed-by: Todd Short <todd.short@me.com> (Merged from https://github.com/openssl/openssl/pull/15348)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/cms/cms_err.c4
-rw-r--r--crypto/cms/cms_lib.c9
-rw-r--r--crypto/cms/cms_local.h7
-rw-r--r--crypto/cms/cms_sd.c34
-rw-r--r--crypto/cms/cms_smime.c25
-rw-r--r--crypto/err/openssl.txt1
6 files changed, 66 insertions, 14 deletions
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c
index 1fba9d8502..293b65a1f4 100644
--- a/crypto/cms/cms_err.c
+++ b/crypto/cms/cms_err.c
@@ -1,6 +1,6 @@
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -109,6 +109,8 @@ static const ERR_STRING_DATA CMS_str_reasons[] = {
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers"},
+ {ERR_PACK(ERR_LIB_CMS, 0, CMS_R_OPERATION_UNSUPPORTED),
+ "operation unsupported"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error"},
{ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
"private key does not match certificate"},
diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c
index 0b25bc234e..4d5a11624f 100644
--- a/crypto/cms/cms_lib.c
+++ b/crypto/cms/cms_lib.c
@@ -208,6 +208,13 @@ err:
/* unfortunately cannot constify SMIME_write_ASN1() due to this function */
int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
{
+ return ossl_cms_DataFinal(cms, cmsbio, NULL, 0);
+}
+
+int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio,
+ const unsigned char *precomp_md,
+ unsigned int precomp_mdlen)
+{
ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
if (pos == NULL)
@@ -245,7 +252,7 @@ int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
return ossl_cms_AuthEnvelopedData_final(cms, cmsbio);
case NID_pkcs7_signed:
- return ossl_cms_SignedData_final(cms, cmsbio);
+ return ossl_cms_SignedData_final(cms, cmsbio, precomp_md, precomp_mdlen);
case NID_pkcs7_digest:
return ossl_cms_DigestedData_do_final(cms, cmsbio, 0);
diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h
index e9fb43715a..d44bf3b0a1 100644
--- a/crypto/cms/cms_local.h
+++ b/crypto/cms/cms_local.h
@@ -395,6 +395,9 @@ const char *ossl_cms_ctx_get0_propq(const CMS_CTX *ctx);
void ossl_cms_resolve_libctx(CMS_ContentInfo *ci);
CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *ctx, const char *propq);
+int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio,
+ const unsigned char *precomp_md,
+ unsigned int precomp_mdlen);
CMS_ContentInfo *ossl_cms_DigestedData_create(const EVP_MD *md,
OSSL_LIB_CTX *libctx,
@@ -404,7 +407,9 @@ int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms,
BIO *chain, int verify);
BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms);
-int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
+int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain,
+ const unsigned char *precomp_md,
+ unsigned int precomp_mdlen);
int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
int type, const CMS_CTX *ctx);
int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c
index d1e5ec8b4e..ee210eab29 100644
--- a/crypto/cms/cms_sd.c
+++ b/crypto/cms/cms_sd.c
@@ -694,7 +694,9 @@ ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
}
static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
- CMS_SignerInfo *si, BIO *chain)
+ CMS_SignerInfo *si, BIO *chain,
+ const unsigned char *md,
+ unsigned int mdlen)
{
EVP_MD_CTX *mctx = EVP_MD_CTX_new();
int r = 0;
@@ -722,11 +724,13 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
*/
if (CMS_signed_get_attr_count(si) >= 0) {
- unsigned char md[EVP_MAX_MD_SIZE];
- unsigned int mdlen;
+ unsigned char computed_md[EVP_MAX_MD_SIZE];
- if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
- goto err;
+ if (md == NULL) {
+ if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen))
+ goto err;
+ md = computed_md;
+ }
if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
V_ASN1_OCTET_STRING, md, mdlen))
goto err;
@@ -739,12 +743,14 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
} else if (si->pctx) {
unsigned char *sig;
size_t siglen;
- unsigned char md[EVP_MAX_MD_SIZE];
- unsigned int mdlen;
+ unsigned char computed_md[EVP_MAX_MD_SIZE];
pctx = si->pctx;
- if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
- goto err;
+ if (md == NULL) {
+ if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen))
+ goto err;
+ md = computed_md;
+ }
siglen = EVP_PKEY_get_size(si->pkey);
sig = OPENSSL_malloc(siglen);
if (sig == NULL) {
@@ -760,6 +766,10 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
unsigned char *sig;
unsigned int siglen;
+ if (md != NULL) {
+ ERR_raise(ERR_LIB_CMS, CMS_R_OPERATION_UNSUPPORTED);
+ goto err;
+ }
sig = OPENSSL_malloc(EVP_PKEY_get_size(si->pkey));
if (sig == NULL) {
ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE);
@@ -784,7 +794,9 @@ static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
}
-int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
+int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain,
+ const unsigned char *precomp_md,
+ unsigned int precomp_mdlen)
{
STACK_OF(CMS_SignerInfo) *sinfos;
CMS_SignerInfo *si;
@@ -793,7 +805,7 @@ int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
sinfos = CMS_get0_SignerInfos(cms);
for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
si = sk_CMS_SignerInfo_value(sinfos, i);
- if (!cms_SignerInfo_content_sign(cms, si, chain))
+ if (!cms_SignerInfo_content_sign(cms, si, chain, precomp_md, precomp_mdlen))
return 0;
}
cms->d.signedData->encapContentInfo->partial = 0;
diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c
index b82eee32cb..690ea3291b 100644
--- a/crypto/cms/cms_smime.c
+++ b/crypto/cms/cms_smime.c
@@ -897,6 +897,31 @@ err:
}
+int CMS_final_digest(CMS_ContentInfo *cms,
+ const unsigned char *md, unsigned int mdlen,
+ BIO *dcont, unsigned int flags)
+{
+ BIO *cmsbio;
+ int ret = 0;
+
+ if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
+ ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB);
+ return 0;
+ }
+
+ (void)BIO_flush(cmsbio);
+
+ if (!ossl_cms_DataFinal(cms, cmsbio, md, mdlen)) {
+ ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR);
+ goto err;
+ }
+ ret = 1;
+
+err:
+ do_free_upto(cmsbio, dcont);
+ return ret;
+}
+
#ifdef ZLIB
int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index c4a94f9559..27f7247235 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -343,6 +343,7 @@ CMS_R_NO_PRIVATE_KEY:133:no private key
CMS_R_NO_PUBLIC_KEY:134:no public key
CMS_R_NO_RECEIPT_REQUEST:168:no receipt request
CMS_R_NO_SIGNERS:135:no signers
+CMS_R_OPERATION_UNSUPPORTED:182:operation unsupported
CMS_R_PEER_KEY_ERROR:188:peer key error
CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE:136:\
private key does not match certificate