diff options
Diffstat (limited to 'crypto/cms/cms_ess.c')
| -rw-r--r-- | crypto/cms/cms_ess.c | 188 |
1 files changed, 134 insertions, 54 deletions
diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index a21c443ae85e..6c43dd102a91 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -1,7 +1,7 @@ /* - * Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 * in the file LICENSE in the source distribution or at * https://www.openssl.org/source/license.html @@ -14,42 +14,111 @@ #include <openssl/x509v3.h> #include <openssl/err.h> #include <openssl/cms.h> +#include <openssl/ess.h> +#include "crypto/ess.h" +#include "crypto/x509.h" #include "cms_local.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) { ASN1_STRING *str; - CMS_ReceiptRequest *rr = NULL; - if (prr) + CMS_ReceiptRequest *rr; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_receiptRequest); + + if (prr != NULL) *prr = NULL; - str = CMS_signed_get0_data_by_OBJ(si, - OBJ_nid2obj - (NID_id_smime_aa_receiptRequest), -3, - V_ASN1_SEQUENCE); - if (!str) + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) return 0; rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); - if (!rr) + if (rr == NULL) return -1; - if (prr) + if (prr != NULL) *prr = rr; else CMS_ReceiptRequest_free(rr); return 1; } -CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, - int allorfirst, - STACK_OF(GENERAL_NAMES) - *receiptList, STACK_OF(GENERAL_NAMES) - *receiptsTo) +/* + * Returns 0 if attribute is not found, 1 if found, + * or -1 on attribute parsing failure. + */ +static int ossl_cms_signerinfo_get_signing_cert(const CMS_SignerInfo *si, + ESS_SIGNING_CERT **psc) { - CMS_ReceiptRequest *rr = NULL; + ASN1_STRING *str; + ESS_SIGNING_CERT *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificate); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_free(sc); + return 1; +} + +/* + * Returns 0 if attribute is not found, 1 if found, + * or -1 on attribute parsing failure. + */ +static int ossl_cms_signerinfo_get_signing_cert_v2(const CMS_SignerInfo *si, + ESS_SIGNING_CERT_V2 **psc) +{ + ASN1_STRING *str; + ESS_SIGNING_CERT_V2 *sc; + ASN1_OBJECT *obj = OBJ_nid2obj(NID_id_smime_aa_signingCertificateV2); + + if (psc != NULL) + *psc = NULL; + str = CMS_signed_get0_data_by_OBJ(si, obj, -3, V_ASN1_SEQUENCE); + if (str == NULL) + return 0; + + sc = ASN1_item_unpack(str, ASN1_ITEM_rptr(ESS_SIGNING_CERT_V2)); + if (sc == NULL) + return -1; + if (psc != NULL) + *psc = sc; + else + ESS_SIGNING_CERT_V2_free(sc); + return 1; +} + +int ossl_cms_check_signing_certs(const CMS_SignerInfo *si, + const STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = NULL; + ESS_SIGNING_CERT_V2 *ssv2 = NULL; + int ret = ossl_cms_signerinfo_get_signing_cert(si, &ss) >= 0 + && ossl_cms_signerinfo_get_signing_cert_v2(si, &ssv2) >= 0 + && OSSL_ESS_check_signing_certs(ss, ssv2, chain, 1) > 0; + + ESS_SIGNING_CERT_free(ss); + ESS_SIGNING_CERT_V2_free(ssv2); + return ret; +} + +CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo, + OSSL_LIB_CTX *libctx) +{ + CMS_ReceiptRequest *rr; rr = CMS_ReceiptRequest_new(); if (rr == NULL) @@ -59,14 +128,15 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, else { if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) goto merr; - if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0) + if (RAND_bytes_ex(libctx, rr->signedContentIdentifier->data, 32, + 0) <= 0) goto err; } sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); rr->receiptsTo = receiptsTo; - if (receiptList) { + if (receiptList != NULL) { rr->receiptsFrom->type = 1; rr->receiptsFrom->d.receiptList = receiptList; } else { @@ -77,7 +147,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, return rr; merr: - CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); err: CMS_ReceiptRequest_free(rr); @@ -85,6 +155,14 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, } +CMS_ReceiptRequest *CMS_ReceiptRequest_create0( + unsigned char *id, int idlen, int allorfirst, + STACK_OF(GENERAL_NAMES) *receiptList, STACK_OF(GENERAL_NAMES) *receiptsTo) +{ + return CMS_ReceiptRequest_create0_ex(id, idlen, allorfirst, receiptList, + receiptsTo, NULL); +} + int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) { unsigned char *rrder = NULL; @@ -102,7 +180,7 @@ int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) merr: if (!r) - CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); OPENSSL_free(rrder); @@ -116,20 +194,20 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, STACK_OF(GENERAL_NAMES) **plist, STACK_OF(GENERAL_NAMES) **prto) { - if (pcid) + if (pcid != NULL) *pcid = rr->signedContentIdentifier; if (rr->receiptsFrom->type == 0) { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; - if (plist) + if (plist != NULL) *plist = NULL; } else { - if (pallorfirst) + if (pallorfirst != NULL) *pallorfirst = -1; - if (plist) + if (plist != NULL) *plist = rr->receiptsFrom->d.receiptList; } - if (prto) + if (prto != NULL) *prto = rr->receiptsTo; } @@ -138,29 +216,32 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, static int cms_msgSigDigest(CMS_SignerInfo *si, unsigned char *dig, unsigned int *diglen) { - const EVP_MD *md; - md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + const EVP_MD *md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) return 0; - if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, - si->signedAttrs, dig, diglen)) + if (!ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, + si->signedAttrs, dig, diglen, + ossl_cms_ctx_get0_libctx(si->cms_ctx), + ossl_cms_ctx_get0_propq(si->cms_ctx))) return 0; return 1; } /* Add a msgSigDigest attribute to a SignerInfo */ -int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) +int ossl_cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) { unsigned char dig[EVP_MAX_MD_SIZE]; unsigned int diglen; + if (!cms_msgSigDigest(src, dig, &diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR); return 0; } if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, V_ASN1_OCTET_STRING, dig, diglen)) { - CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); return 0; } return 1; @@ -168,7 +249,7 @@ int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) /* Verify signed receipt after it has already passed normal CMS verify */ -int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) +int ossl_cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) { int r = 0, i; CMS_ReceiptRequest *rr = NULL; @@ -187,27 +268,27 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) goto err; if (sk_CMS_SignerInfo_num(sis) != 1) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); + ERR_raise(ERR_LIB_CMS, CMS_R_NEED_ONE_SIGNER); goto err; } /* Check receipt content type */ if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); + ERR_raise(ERR_LIB_CMS, CMS_R_NOT_A_SIGNED_RECEIPT); goto err; } /* Extract and decode receipt content */ pcont = CMS_get0_content(cms); - if (!pcont || !*pcont) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); + if (pcont == NULL || *pcont == NULL) { + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); goto err; } rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); if (!rct) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_RECEIPT_DECODE_ERROR); goto err; } @@ -220,7 +301,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) } if (i == sk_CMS_SignerInfo_num(osis)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_SIGNATURE); goto err; } @@ -234,23 +315,22 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) V_ASN1_OCTET_STRING); if (!msig) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_MSGSIGDIGEST); goto err; } if (!cms_msgSigDigest(osi, dig, &diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_ERROR); goto err; } if (diglen != (unsigned int)msig->length) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); goto err; } if (memcmp(dig, msig->data, diglen)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, - CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); + ERR_raise(ERR_LIB_CMS, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); goto err; } @@ -260,27 +340,27 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); if (!octype) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE); goto err; } /* Compare details in receipt request */ if (OBJ_cmp(octype, rct->contentType)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_MISMATCH); goto err; } /* Get original receipt request details */ if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST); goto err; } if (ASN1_STRING_cmp(rr->signedContentIdentifier, rct->signedContentIdentifier)) { - CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); + ERR_raise(ERR_LIB_CMS, CMS_R_CONTENTIDENTIFIER_MISMATCH); goto err; } @@ -298,7 +378,7 @@ int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) * SignedData ContentInfo. */ -ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) +ASN1_OCTET_STRING *ossl_cms_encode_Receipt(CMS_SignerInfo *si) { CMS_Receipt rct; CMS_ReceiptRequest *rr = NULL; @@ -310,7 +390,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) /* Get original receipt request details */ if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_RECEIPT_REQUEST); goto err; } @@ -320,7 +400,7 @@ ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) OBJ_nid2obj(NID_pkcs9_contentType), -3, V_ASN1_OBJECT); if (!ctype) { - CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); + ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT_TYPE); goto err; } |
