CMS_SIGN(3ossl)
π
CMS_SIGN β create a CMS SignedData structure (this is the 3ossl one, bestie, OpenSSL's own β¨)
Okay so picture this: you've got a cert, you've got a key, you've got some data, and you want the whole world to know it's yours and nobody touched it. That's the entire gig here. Let's go π«Ά
πΈ SYNOPSIS πΈ
#include <openssl/cms.h>
CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey,
STACK_OF(X509) *certs, BIO *data,
unsigned int flags, OSSL_LIB_CTX *ctx,
const char *propq);
CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
BIO *data, unsigned int flags);
π DESCRIPTION π
So CMS_sign_ex() creates a CMS SignedData structure and hands it right back to you. Iconic behavior honestly.
signcertβ the certificate you're signing with.pkeyβ the matching private key (yes, the corresponding one, don't try anything cute).certsβ an optional extra set of certificates to bundle into the CMS structure, like any intermediate CAs hanging out in the chain.ctx(the library context,libctxin the prose) andpropq(property query) β these get used when algorithms are being retrieved from providers.dataβ the actual data getting signed, read from thisBIO.
Any or all of these parameters can be NULL β check the NOTES section below, no cap π
And flags? Optional set of flags. We'll get to those.
CMS_sign() is literally the same vibe as CMS_sign_ex() except it uses default values of NULL for the library context libctx and the property query propq. Easy.
β¨ NOTES β¨
Any of the following flags (ored together β yes, ored, stack 'em) can be passed in the flags parameter. Buckle up, there's a bunch π
CMS_TEXTβ so many S/MIME clients expect the signed content to include valid MIME headers. Set this and MIME headers for typetext/plainget prepended to the data.CMS_NOCERTSβ the signer's certificate will not be included in theCMS_ContentInfostructure. Important: the signer's certificate still has to be supplied in thesigncertparameter though, no skipping that. Why bother? It can shrink the signature if the signer's cert can be obtained another way β like from a previously signed message.CMS_DETACHEDβ the data being signed is normally included in theCMS_ContentInfostructure, but set this and it's omitted. This is the detached-signature life, used for S/MIME plaintext signed messages for example.CMS_BINARYβ normally the supplied content gets translated into MIME canonical format (as required by the S/MIME specifications). Set this and no translation occurs. Use this if your data is binary, otherwise the translation will corrupt it. Dead serious about that one πCMS_NOATTRβ the SignedData structure includes several CMS signedAttributes: the signing time, the CMS content type, and the supported list of ciphers in an SMIMECapabilities attribute. Set this flag and no signedAttributes will be used at all. Zero. None.CMS_NOSMIMECAPβ the SMIMECapabilities get omitted.CMS_NO_SIGNING_TIMEβ the signing time gets omitted.CMS_USE_KEYIDβ OpenSSL by default identifies signing certificates using issuer name and serial number. Set this and it uses the subject key identifier value instead. β οΈ If the signing certificate doesn't have a subject key identifier extension, you get an error.CMS_STREAMβ the returnedCMS_ContentInfostructure is just initialized, ready to perform the signing operation. The signing is however not performed, and the data to be signed is not read from thedataparameter. Signing is deferred until after the data has been written. The upside? Data can be signed in a single pass. Slay.CMS_PARTIALβ a partialCMS_ContentInfostructure is output, to which additional signers and capabilities can be added before finalization.
π¨ Real talk: if the flagCMS_STREAMis set, the returnedCMS_ContentInfostructure is not complete, and outputting its contents via a function that doesn't properly finalize theCMS_ContentInfostructure will give unpredictable results. Not a vibe. Finalize your stuff.
Several functions finalize the structure, including SMIME_write_CMS(), i2d_CMS_bio_stream(), and PEM_write_bio_CMS_stream(). Alternatively, finalization can be performed by obtaining the streaming ASN1 BIO directly using BIO_new_CMS().
So about SMIMECapabilities: if present, that attribute indicates support for the following algorithms, in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192 bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of these algorithms isn't available then it won't be included β for example, the GOST algorithms won't be included if the GOST ENGINE is not loaded. Makes sense, she's not gonna advertise what she can't do π
If a signer is specified, it will use the default digest for the signing algorithm. That's SHA1 for both RSA and DSA keys. (Yes, SHA1, we know, it's giving vintage.)
If signcert and pkey are NULL, then a certificates-only CMS structure is output. Cute, minimal, no key needed.
CMS_sign() is a basic CMS signing function whose output will be suitable for many purposes. But for finer control of the output format, the certs, signcert and pkey parameters can all be NULL and the CMS_PARTIAL flag set. Then:
- one or more signers can be added using the function
CMS_add1_signer(), - non-default digests can be used,
- and custom attributes added.
CMS_final() must then be called to finalize the structure if streaming is not enabled. Periodt.
π BUGS π
Some attributes such as counter signatures are not supported. That's it, that's the bug note. We're humble about it π
π₯ RETURN VALUES π₯
CMS_sign_ex() and CMS_sign() return either a valid CMS_ContentInfo structure or NULL if an error occurred. The error can be obtained from ERR_get_error(3).
π¦ SEE ALSO π¦
ERR_get_error(3), CMS_verify(3)
π HISTORY π
- The
CMS_STREAMflag is only supported for detached data in OpenSSL 0.9.8 β it's supported for embedded data in OpenSSL 1.0.0 and later. - The
CMS_sign_ex()method was added in OpenSSL 3.0. - Since OpenSSL 3.2,
CMS_sign_ex()andCMS_sign()ignore any duplicate certificates in theircertsargument and no longer throw an error for them. Glow-up fr fr β¨
π COPYRIGHT π
Copyright 2008-2023 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 bestie, that's the whole page π Version 3.5.0, dated 2026-09-25 β go sign something and make it iconic π
π¦ where this page comes from
- opensuse-leap 16.0: openssl-3-doc 3.5.0-160000.11.1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms