CMS_VERIFY(3ossl)
π CMS_VERIFY(3ossl) β bestie's guide to verifying a CMS SignedData π
okay so. hi. welcome to CMS_VERIFY, an OpenSSL manual page, but make it a group chat. we're gonna talk about CMS_verify(), CMS_SignedData_verify() and CMS_get0_signers() β the trio that checks whether a CMS SignedData thing is actually, you know, legit. π₯
β¨ NAME β¨
CMS_verify, CMS_SignedData_verify, CMS_get0_signers β verify a CMS SignedData structure. that's the whole vibe. π«Ά
πΈ SYNOPSIS πΈ
#include <openssl/cms.h>
int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, X509_STORE *store,
BIO *detached_data, BIO *out, unsigned int flags);
BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data,
STACK_OF(X509) *scerts, X509_STORE *store,
STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls,
unsigned int flags,
OSSL_LIB_CTX *libctx, const char *propq);
STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
π¦ DESCRIPTION π¦
CMS_verify() β the classic
CMS_verify() is very similar to PKCS7_verify(3), iykyk. what it does is verify a CMS SignedData structure that lives inside a CMS_ContentInfo-typed struct.
cmsβ points at theCMS_ContentInfostructure we're verifying. the main character, honestly. πcertsβ optional, a set of certificates to search for signing certificates in. it also doubles as a source of untrusted intermediate CA certificates for chain building. multitasking icon. πcmsitself may contain extra untrusted CA certificates that can be used for chain building, plus CRLs that can be used for certificate validation.storeβ may beNULL, or point at the trusted certificate store to use for chain verification.detached_dataβ points at the signed data if the content is detached fromcms. otherwise it should beNULLand the signed data must be incmsitself. no cap, pick one.outβ the content gets written to thisBIOunless it'sNULL.flagsβ an optional set of flags to modify the operation. we'll get to those, bestie, don't worry. π
CMS_SignedData_verify() β the upgraded one
CMS_SignedData_verify() is like CMS_verify() except:
- it operates on CMS SignedData input in the
sdargument, - it has some additional parameters (described next π),
- and on success it returns the verified content as a memory BIO. slay.
the extra deets:
extraβ optional. provides untrusted CA certificates that might help with chain building in certificate validation. β οΈ this list of certificates must not contain duplicates. the way that duplicates will ruin youβ¦ don't.crlsβ optional. provides extra CRLs. also β οΈ this list of CRLs must not contain duplicates. same energy.libctxandpropqβ optional library context and property query, used when retrieving algorithms from providers. providers stay provider-ing. β¨
CMS_get0_signers() β the reveal
CMS_get0_signers() retrieves the signing certificate(s) from cms. but bestie, listen: it may only be called after a successful CMS_verify() or CMS_SignedData_verify() operation. calling it early is giving chaos. π«
π VERIFY PROCESS π
the default storyline
normally, the verify process proceeds like this. (put your phone down, this part matters.)
- initially, some sanity checks are performed on
cms. the type ofcmsmust beSignedData. there must be at least one signature on the data, and if the content is detached thendetached_datacannot beNULL. no exceptions, periodt. - an attempt is made to locate all the signing certificate(s), first looking in the
certsparameter (if it's notNULL) and then looking in any certificates contained in thecmsstructure β unlessCMS_NOINTERNis set. if any signing certificate cannot be located, the operation fails. π - each signing certificate is chain verified using the
smimesignpurpose and using the trusted certificate storestoreif supplied. any internal certificates in the message β which may have been added usingCMS_add1_cert(3)β are used as untrusted CAs. if CRL checking is enabled instoreandCMS_NOCRLis not set, any internal CRLs β which may have been added usingCMS_add1_crl(3)β are used in addition to attempting to look them up instore. ifstoreis notNULLand any chain verify fails, an error code is returned. - finally, the signed content is read (and written to
outunless it'sNULL) and the signature is checked. β¨
if all signatures verify correctly, the function is successful. that's the win. π
the flags (ored together, iconic behaviour)
any of the following flags can be passed in the flags parameter to change the default verify behaviour. they get ored together, because of course they do.
CMS_NOINTERNβ the certificates in the message itself are not searched when locating the signing certificate(s). meaning: all the signing certificates must be in thecertsparameter. no shortcuts. π«CMS_NOCRLβ if set, and CRL checking is enabled instore, then any CRLs in the message itself and any provided via thecrlsparameter are ignored. bye. πCMS_TEXTβ MIME headers for type"text/plain"are deleted from the content. if the content is not of type"text/plain", an error is returned. picky, but valid. πCMS_NO_SIGNER_CERT_VERIFYβ the signing certificates are not chain verifiedβ¦ unlessCMS_CADESis also set. plot twist.CMS_NO_ATTR_VERIFYβ the signed attributes signature is not verifiedβ¦ unlessCMS_CADESis also set. again.CMS_CADESβ each signer certificate is checked against the ESSsigningCertificateor ESSsigningCertificateV2extension that is required in the signed attributes of the signature. mandatory behaviour, no skips. π₯CMS_NO_CONTENT_VERIFYβ the content digest is not checked. yeah. we'll talk about that in NOTES. π
π NOTES π
one application of CMS_NOINTERN is to only accept messages signed by a small number of certificates. the acceptable certificates would be passed in the certs parameter. in that case, if the signer certificate is not one of the certificates supplied in certs, the verify will fail β because the signer cannot be found. that's the whole point, bestie. π
in some cases the standard techniques for looking up and validating certificates are justβ¦ not appropriate? like, an application may wish to look up certificates in a database, or perform customised verification. you can achieve that by setting and verifying the signer certificates manually, using the signed data utility functions. do it yourself, main character energy. π
β οΈ care should be taken when modifying the default verify behaviour. for example, settingCMS_NO_CONTENT_VERIFYwill totally disable all content verification, and any modified content will be considered valid. that's giving "yikes". this combination is however useful if one merely wishes to write the content tooutand its validity is not considered important. know what you're doing, fr fr.
chain verification should arguably be performed using the signing time rather than the current time. however, since the signing time is supplied by the signer, it cannot be trusted without additional evidence (such as a trusted timestamp). shrug. π¦
π RETURN VALUES π
CMS_verify()β returns1for a successful verification, and0if an error occurred. binary, simple, we love her.CMS_SignedData_verify()β returns a memory BIO containing the verified content, orNULLon error.CMS_get0_signers()β returns all signers, orNULLif an error occurred.
the error can be obtained from ERR_get_error(3). go get your error, bestie, it's yours. πΈ
π BUGS π
- the trusted certificate store is not searched for the signing certificate. this is primarily due to the inadequacies of the current
X509_STOREfunctionality. not our fault, we're just reporting. π - the lack of single pass processing means that the signed content must all be held in memory if it is not detached. all of it. in memory. good luck. π
π SEE ALSO π
PKCS7_verify(3), CMS_add1_cert(3), CMS_add1_crl(3), OSSL_ESS_check_signing_certs(3), ERR_get_error(3), CMS_sign(3)
β HISTORY β
CMS_SignedData_verify() was added in OpenSSL 3.2. newer than you think, but she ate. β¨
π COPYRIGHT π
Copyright 2008-2024 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 in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.
okay that's the whole page, you're officially educated. π this was OpenSSL 3.5.9, dated 2026-09-29, and honestly? iconic. go verify something. mwah. π«Άπβ¨
π¦ where this page comes from
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 43: openssl-devel 1:3.5.9-1.fc43 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- fedora 44: openssl-devel 1:3.5.9-1.fc44 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms