Skip to content

Commit e85d19c

Browse files
opensignaturemspncp
authored andcommitted
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 #7893)
1 parent 9f5a87f commit e85d19c

File tree

30 files changed

+852
-478
lines changed

30 files changed

+852
-478
lines changed

apps/cms.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
2+
* Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
33
*
44
* Licensed under the Apache License 2.0 (the "License"). You may not use
55
* this file except in compliance with the License. You can obtain a copy
@@ -65,7 +65,7 @@ struct cms_key_param_st {
6565
typedef enum OPTION_choice {
6666
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
6767
OPT_INFORM, OPT_OUTFORM, OPT_IN, OPT_OUT, OPT_ENCRYPT,
68-
OPT_DECRYPT, OPT_SIGN, OPT_SIGN_RECEIPT, OPT_RESIGN,
68+
OPT_DECRYPT, OPT_SIGN, OPT_CADES, OPT_SIGN_RECEIPT, OPT_RESIGN,
6969
OPT_VERIFY, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT,
7070
OPT_CMSOUT, OPT_DATA_OUT, OPT_DATA_CREATE, OPT_DIGEST_VERIFY,
7171
OPT_DIGEST_CREATE, OPT_COMPRESS, OPT_UNCOMPRESS,
@@ -102,6 +102,7 @@ const OPTIONS cms_options[] = {
102102
{"sign", OPT_SIGN, '-', "Sign message"},
103103
{"sign_receipt", OPT_SIGN_RECEIPT, '-', "Generate a signed receipt for the message"},
104104
{"resign", OPT_RESIGN, '-', "Resign a signed message"},
105+
{"cades", OPT_CADES, '-', "Include signer certificate digest"},
105106
{"verify", OPT_VERIFY, '-', "Verify signed message"},
106107
{"verify_retcode", OPT_VERIFY_RETCODE, '-'},
107108
{"verify_receipt", OPT_VERIFY_RECEIPT, '<'},
@@ -326,6 +327,9 @@ int cms_main(int argc, char **argv)
326327
case OPT_BINARY:
327328
flags |= CMS_BINARY;
328329
break;
330+
case OPT_CADES:
331+
flags |= CMS_CADES;
332+
break;
329333
case OPT_KEYID:
330334
flags |= CMS_USE_KEYID;
331335
break;

crypto/build.info

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
55
md2 md4 md5 sha mdc2 gmac hmac ripemd whrlpool poly1305 blake2 \
66
siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \
77
seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \
8-
err comp ocsp cms ts srp cmac ct async kmac
8+
err comp ocsp cms ts srp cmac ct async kmac ess
99

1010
LIBS=../libcrypto
1111
SOURCE[../libcrypto]=\

crypto/cms/cms_err.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ static const ERR_STRING_DATA CMS_str_functs[] = {
2727
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNER, 0), "CMS_add1_signer"},
2828
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNINGTIME, 0),
2929
"cms_add1_signingTime"},
30+
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT, 0),
31+
"CMS_add1_signing_cert"},
32+
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_ADD1_SIGNING_CERT_V2, 0),
33+
"CMS_add1_signing_cert_v2"},
3034
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESS, 0), "CMS_compress"},
3135
{ERR_PACK(ERR_LIB_CMS, CMS_F_CMS_COMPRESSEDDATA_CREATE, 0),
3236
"cms_CompressedData_create"},

crypto/cms/cms_ess.c

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved.
2+
* Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
33
*
44
* Licensed under the Apache License 2.0 (the "License"). You may not use
55
* this file except in compliance with the License. You can obtain a copy
@@ -14,11 +14,13 @@
1414
#include <openssl/x509v3.h>
1515
#include <openssl/err.h>
1616
#include <openssl/cms.h>
17+
#include <openssl/ess.h>
1718
#include "cms_lcl.h"
19+
#include "internal/ess_int.h"
1820

1921
IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
2022

21-
/* ESS services: for now just Signed Receipt related */
23+
/* ESS services */
2224

2325
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
2426
{
@@ -335,3 +337,70 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
335337
CMS_ReceiptRequest_free(rr);
336338
return os;
337339
}
340+
341+
/*
342+
* Add signer certificate's V2 digest to a SignerInfo
343+
* structure
344+
*/
345+
346+
int CMS_add1_signing_cert_v2(CMS_SignerInfo *si,
347+
ESS_SIGNING_CERT_V2 *sc)
348+
{
349+
ASN1_STRING *seq = NULL;
350+
unsigned char *p, *pp;
351+
int len;
352+
353+
/* Add SigningCertificateV2 signed attribute to the signer info. */
354+
len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
355+
if ((pp = OPENSSL_malloc(len)) == NULL)
356+
goto err;
357+
p = pp;
358+
i2d_ESS_SIGNING_CERT_V2(sc, &p);
359+
if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
360+
goto err;
361+
OPENSSL_free(pp);
362+
pp = NULL;
363+
if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificateV2,
364+
V_ASN1_SEQUENCE, seq, -1))
365+
goto err;
366+
ASN1_STRING_free(seq);
367+
return 1;
368+
err:
369+
CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT_V2, ERR_R_MALLOC_FAILURE);
370+
ASN1_STRING_free(seq);
371+
OPENSSL_free(pp);
372+
return 0;
373+
}
374+
375+
/*
376+
* Add signer certificate's digest to a SignerInfo
377+
* structure
378+
*/
379+
380+
int CMS_add1_signing_cert(CMS_SignerInfo *si, ESS_SIGNING_CERT *sc)
381+
{
382+
ASN1_STRING *seq = NULL;
383+
unsigned char *p, *pp;
384+
int len;
385+
386+
/* Add SigningCertificate signed attribute to the signer info. */
387+
len = i2d_ESS_SIGNING_CERT(sc, NULL);
388+
if ((pp = OPENSSL_malloc(len)) == NULL)
389+
goto err;
390+
p = pp;
391+
i2d_ESS_SIGNING_CERT(sc, &p);
392+
if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len))
393+
goto err;
394+
OPENSSL_free(pp);
395+
pp = NULL;
396+
if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificate,
397+
V_ASN1_SEQUENCE, seq, -1))
398+
goto err;
399+
ASN1_STRING_free(seq);
400+
return 1;
401+
err:
402+
CMSerr(CMS_F_CMS_ADD1_SIGNING_CERT, ERR_R_MALLOC_FAILURE);
403+
ASN1_STRING_free(seq);
404+
OPENSSL_free(pp);
405+
return 0;
406+
}

crypto/cms/cms_sd.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,27 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
332332
!CMS_SignerInfo_sign(si))
333333
goto err;
334334
}
335+
if (flags & CMS_CADES) {
336+
ESS_SIGNING_CERT *sc = NULL;
337+
ESS_SIGNING_CERT_V2 *sc2 = NULL;
338+
int add_sc;
339+
340+
if (md == EVP_sha1() || md == NULL) {
341+
if ((sc = ESS_SIGNING_CERT_new_init(signer,
342+
NULL, 1)) == NULL)
343+
goto err;
344+
add_sc = CMS_add1_signing_cert(si, sc);
345+
ESS_SIGNING_CERT_free(sc);
346+
} else {
347+
if ((sc2 = ESS_SIGNING_CERT_V2_new_init(md, signer,
348+
NULL, 1)) == NULL)
349+
goto err;
350+
add_sc = CMS_add1_signing_cert_v2(si, sc2);
351+
ESS_SIGNING_CERT_V2_free(sc2);
352+
}
353+
if (!add_sc)
354+
goto err;
355+
}
335356
}
336357

337358
if (!(flags & CMS_NOCERTS)) {

crypto/err/err.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ static ERR_STRING_DATA ERR_str_libraries[] = {
6464
{ERR_PACK(ERR_LIB_KDF, 0, 0), "KDF routines"},
6565
{ERR_PACK(ERR_LIB_OSSL_STORE, 0, 0), "STORE routines"},
6666
{ERR_PACK(ERR_LIB_SM2, 0, 0), "SM2 routines"},
67+
{ERR_PACK(ERR_LIB_ESS, 0, 0), "ESS routines"},
6768
{0, NULL},
6869
};
6970

crypto/err/err_all.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <openssl/asyncerr.h>
3939
#include <openssl/kdferr.h>
4040
#include <openssl/storeerr.h>
41+
#include <openssl/esserr.h>
4142

4243
int err_load_crypto_strings_int(void)
4344
{
@@ -91,6 +92,7 @@ int err_load_crypto_strings_int(void)
9192
# ifndef OPENSSL_NO_CT
9293
ERR_load_CT_strings() == 0 ||
9394
# endif
95+
ERR_load_ESS_strings() == 0 ||
9496
ERR_load_ASYNC_strings() == 0 ||
9597
#endif
9698
ERR_load_KDF_strings() == 0 ||

crypto/err/openssl.ec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ L ASYNC include/openssl/async.h crypto/async/async_err.c
3434
L KDF include/openssl/kdf.h crypto/kdf/kdf_err.c
3535
L SM2 crypto/include/internal/sm2.h crypto/sm2/sm2_err.c
3636
L OSSL_STORE include/openssl/store.h crypto/store/store_err.c
37+
L ESS include/openssl/ess.h crypto/ess/ess_err.c
3738

3839
# additional header files to be scanned for function names
3940
L NONE include/openssl/x509_vfy.h NONE

crypto/err/openssl.txt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
1+
# Copyright 1999-2019 The OpenSSL Project Authors. All Rights Reserved.
22
#
33
# Licensed under the Apache License 2.0 (the "License"). You may not use
44
# this file except in compliance with the License. You can obtain a copy
@@ -242,6 +242,8 @@ CMS_F_CMS_ADD1_RECEIPTREQUEST:158:CMS_add1_ReceiptRequest
242242
CMS_F_CMS_ADD1_RECIPIENT_CERT:101:CMS_add1_recipient_cert
243243
CMS_F_CMS_ADD1_SIGNER:102:CMS_add1_signer
244244
CMS_F_CMS_ADD1_SIGNINGTIME:103:cms_add1_signingTime
245+
CMS_F_CMS_ADD1_SIGNING_CERT:181:CMS_add1_signing_cert
246+
CMS_F_CMS_ADD1_SIGNING_CERT_V2:182:CMS_add1_signing_cert_v2
245247
CMS_F_CMS_COMPRESS:104:CMS_compress
246248
CMS_F_CMS_COMPRESSEDDATA_CREATE:105:cms_CompressedData_create
247249
CMS_F_CMS_COMPRESSEDDATA_INIT_BIO:106:cms_CompressedData_init_bio
@@ -709,6 +711,12 @@ ENGINE_F_INT_CTRL_HELPER:172:int_ctrl_helper
709711
ENGINE_F_INT_ENGINE_CONFIGURE:188:int_engine_configure
710712
ENGINE_F_INT_ENGINE_MODULE_INIT:187:int_engine_module_init
711713
ENGINE_F_OSSL_HMAC_INIT:200:ossl_hmac_init
714+
ESS_F_ESS_CERT_ID_NEW_INIT:100:ESS_CERT_ID_new_init
715+
ESS_F_ESS_CERT_ID_V2_NEW_INIT:101:ESS_CERT_ID_V2_new_init
716+
ESS_F_ESS_SIGNING_CERT_ADD:104:ESS_SIGNING_CERT_add
717+
ESS_F_ESS_SIGNING_CERT_NEW_INIT:102:ESS_SIGNING_CERT_new_init
718+
ESS_F_ESS_SIGNING_CERT_V2_ADD:105:ESS_SIGNING_CERT_V2_add
719+
ESS_F_ESS_SIGNING_CERT_V2_NEW_INIT:103:ESS_SIGNING_CERT_V2_new_init
712720
EVP_F_AESNI_INIT_KEY:165:aesni_init_key
713721
EVP_F_AES_GCM_CTRL:196:aes_gcm_ctrl
714722
EVP_F_AES_GCM_TLS_CIPHER:207:aes_gcm_tls_cipher
@@ -1558,12 +1566,6 @@ SSL_F_WPACKET_START_SUB_PACKET_LEN__:634:WPACKET_start_sub_packet_len__
15581566
SSL_F_WRITE_STATE_MACHINE:586:write_state_machine
15591567
TS_F_DEF_SERIAL_CB:110:def_serial_cb
15601568
TS_F_DEF_TIME_CB:111:def_time_cb
1561-
TS_F_ESS_ADD_SIGNING_CERT:112:ess_add_signing_cert
1562-
TS_F_ESS_ADD_SIGNING_CERT_V2:147:ess_add_signing_cert_v2
1563-
TS_F_ESS_CERT_ID_NEW_INIT:113:ess_CERT_ID_new_init
1564-
TS_F_ESS_CERT_ID_V2_NEW_INIT:156:ess_cert_id_v2_new_init
1565-
TS_F_ESS_SIGNING_CERT_NEW_INIT:114:ess_SIGNING_CERT_new_init
1566-
TS_F_ESS_SIGNING_CERT_V2_NEW_INIT:157:ess_signing_cert_v2_new_init
15671569
TS_F_INT_TS_RESP_VERIFY_TOKEN:149:int_ts_RESP_verify_token
15681570
TS_F_PKCS7_TO_TS_TST_INFO:148:PKCS7_to_TS_TST_INFO
15691571
TS_F_TS_ACCURACY_SET_MICROS:115:TS_ACCURACY_set_micros
@@ -2223,6 +2225,9 @@ ENGINE_R_UNIMPLEMENTED_CIPHER:146:unimplemented cipher
22232225
ENGINE_R_UNIMPLEMENTED_DIGEST:147:unimplemented digest
22242226
ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD:101:unimplemented public key method
22252227
ENGINE_R_VERSION_INCOMPATIBILITY:145:version incompatibility
2228+
ESS_R_ESS_SIGNING_CERTIFICATE_ERROR:102:ess signing certificate error
2229+
ESS_R_ESS_SIGNING_CERT_ADD_ERROR:100:ess signing cert add error
2230+
ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR:101:ess signing cert v2 add error
22262231
EVP_R_AES_KEY_SETUP_FAILED:143:aes key setup failed
22272232
EVP_R_ARIA_KEY_SETUP_FAILED:176:aria key setup failed
22282233
EVP_R_BAD_DECRYPT:100:bad decrypt

crypto/ess/build.info

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
LIBS=../../libcrypto
2+
SOURCE[../../libcrypto]= \
3+
ess_lib.c ess_asn1.c ess_err.c

0 commit comments

Comments
 (0)