diff options
author | Antonio Iacono <antiac@gmail.com> | 2018-12-12 23:08:49 +0100 |
---|---|---|
committer | Dr. Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com> | 2019-01-27 23:59:21 +0100 |
commit | e85d19c68e7fb3302410bd72d434793e5c0c23a0 (patch) | |
tree | 748f849bfd79db2cc7b35e5c215f4ed8794cbe62 /crypto/cms | |
parent | add an additional async notification communication method based on callback (diff) | |
download | openssl-e85d19c68e7fb3302410bd72d434793e5c0c23a0.tar.xz openssl-e85d19c68e7fb3302410bd72d434793e5c0c23a0.zip |
crypto/cms: Add support for CAdES Basic Electronic Signatures (CAdES-BES)
A CAdES Basic Electronic Signature (CAdES-BES) contains, among other
specifications, a collection of Signing Certificate reference attributes,
stored in the signedData ether as ESS signing-certificate or as
ESS signing-certificate-v2. These are described in detail in Section 5.7.2
of RFC 5126 - CMS Advanced Electronic Signatures (CAdES).
This patch adds support for adding ESS signing-certificate[-v2] attributes
to CMS signedData. Although it implements only a small part of the RFC, it
is sufficient many cases to enable the `openssl cms` app to create signatures
which comply with legal requirements of some European States (e.g Italy).
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/7893)
Diffstat (limited to 'crypto/cms')
-rw-r--r-- | crypto/cms/cms_err.c | 4 | ||||
-rw-r--r-- | crypto/cms/cms_ess.c | 73 | ||||
-rw-r--r-- | crypto/cms/cms_sd.c | 21 |
3 files changed, 96 insertions, 2 deletions
diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c index 9596fab182..f7d4b7fd96 100644 --- a/crypto/cms/cms_err.c +++ b/crypto/cms/cms_err.c @@ -27,6 +27,10 @@ static const ERR_STRING_DATA CMS_str_functs[] = { {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"}, {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNINGTIME, 0), "cms_add1_signingTime"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT, 0), + "CMS_add1_signing_cert"}, + {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT_V2, 0), + "CMS_add1_signing_cert_v2"}, {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESS, 0), "CMS_compress"}, {ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_CREATE, 0), "cms_CompressedData_create"}, diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index 86e88ffbbe..95e3628d9c 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2019 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 @@ -14,11 +14,13 @@ #include <openssl/x509v3.h> #include <openssl/err.h> #include <openssl/cms.h> +#include <openssl/ess.h> #include "cms_lcl.h" +#include "internal/ess_int.h" IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) -/* ESS services: for now just Signed Receipt related */ +/* ESS services */ int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) { @@ -335,3 +337,70 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) CMS_ReceiptRequest_free(rr); return os; } + +/* + * Add signer certificate's V2 digest to a SignerInfo + * structure + */ + +int CMS_add1_signing_cert_v2(CMS_SignerInfo *si, + ESS_SIGNING_CERT_V2 *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp; + int len; + + /* Add SigningCertificateV2 signed attribute to the signer info. */ + len = i2d_ESS_SIGNING_CERT_V2(sc, NULL); + if ((pp = OPENSSL_malloc(len)) == NULL) + goto err; + p = pp; + i2d_ESS_SIGNING_CERT_V2(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) + goto err; + OPENSSL_free(pp); + pp = NULL; + if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificateV2, + V_ASN1_SEQUENCE, seq, -1)) + goto err; + ASN1_STRING_free(seq); + return 1; + err: + CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; +} + +/* + * Add signer certificate's digest to a SignerInfo + * structure + */ + +int CMS_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp; + int len; + + /* Add SigningCertificate signed attribute to the signer info. */ + len = i2d_ESS_SIGNING_CERT(sc, NULL); + if ((pp = OPENSSL_malloc(len)) == NULL) + goto err; + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) + goto err; + OPENSSL_free(pp); + pp = NULL; + if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq, -1)) + goto err; + ASN1_STRING_free(seq); + return 1; + err: + CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(seq); + OPENSSL_free(pp); + return 0; +} diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index f4f872efe8..71b3041116 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -332,6 +332,27 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, !CMS_SignerInfo_sign(si)) goto err; } + if (flags & CMS_CADES) { + ESS_SIGNING_CERT *sc = NULL; + ESS_SIGNING_CERT_V2 *sc2 = NULL; + int add_sc; + + if (md == EVP_sha1() || md == NULL) { + if ((sc = ESS_SIGNING_CERT_new_init(signer, + NULL, 1)) == NULL) + goto err; + add_sc = CMS_add1_signing_cert(si, sc); + ESS_SIGNING_CERT_free(sc); + } else { + if ((sc2 = ESS_SIGNING_CERT_V2_new_init(md, signer, + NULL, 1)) == NULL) + goto err; + add_sc = CMS_add1_signing_cert_v2(si, sc2); + ESS_SIGNING_CERT_V2_free(sc2); + } + if (!add_sc) + goto err; + } } if (!(flags & CMS_NOCERTS)) { |