PKCS7_SIGN(3SSL)
π PKCS7_SIGN π (that's the PKCS7_SIGN(3SSL) page from the OpenSSL manual, bestie)
okay so. you want to make a PKCS#7 signedData structure. iconic. let's go π
β¨ NAME β¨
PKCS7_sign_ex, PKCS7_sign β create a PKCS#7 signedData structure π
πΈ SYNOPSIS πΈ
#include <openssl/pkcs7.h>
PKCS7 *PKCS7_sign_ex(X509 *signcert, EVP_PKEY *pkey,
const STACK_OF(X509) *certs,
BIO *data, int flags, OSSL_LIB_CTX *libctx,
const char *propq);
PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, const STACK_OF(X509) *certs,
BIO *data, int flags);
π¦ DESCRIPTION π¦
so PKCS7_sign_ex() makes a PKCS#7 signedData structure and hands it back to you. literally that's the whole job. π
signcertβ the certificate you're signing with, bestie.pkeyβ the matching private key for that cert. they're a set, don't split them up πcertsβ an optional stack of extra certificates to shove into the PKCS#7 structure (think: any intermediate CAs hanging out in the chain).libctxβ the library context, andpropqβ the property query. these two get used when we're retrieving algorithms from providers. provider stuff, iykyk.
the actual data being signed? read straight out of the BIO data. π₯
flags is optional, a bunch of flags, and you can OR them together like it's a friendship bracelet.
okay here come the flags, this is the main character section, stay with me π«Ά
- If you set
PKCS7_TEXT, MIME headers for type"text/plain"get prepended to the data. why? because many S/MIME clients expect the signed content to have valid MIME headers. they're needy like that but we love them. - If you set
PKCS7_NOCERTS, the signer's certificate AND the extra certs will not be included in the PKCS7 structure. π« but β and this is important β the signer's certificate still has to be supplied in thesigncertparameter. no skipping that. this flag can shrink your signatures if the signer's certs are obtainable some other way (like, say, a previously signed message that already has them). slay, smaller output. - The data being signed gets included in the PKCS7 structure... unless
PKCS7_DETACHEDis set, in which case nope, it's omitted. this is the ~detached signature~ moment, and it's what S/MIME plaintext signed messages use, for example. very smooth, very "the data is right there, we just don't carry it around". - Normally the content you hand over gets translated into MIME canonical format (the S/MIME specs demand it). but if
PKCS7_BINARYis set, no translation happens at all. π use this if your data is binary, otherwise that translation will corrupt it. corruption is NOT the vibe. do not do it. - The signedData structure comes with several PKCS#7
authenticatedAttributes, including:- the signing time β°
- the PKCS#7 content type
- the supported list of ciphers in an
SMIMECapabilitiesattribute
if PKCS7_NOATTR is set β no authenticatedAttributes at all. if PKCS7_NOSMIMECAP is set β just the SMIMECapabilities get omitted. cherry-picking, we love options.
- If the
SMIMECapabilitiesattribute is present, it's saying "hey, I support these algorithms": triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. and if any of those algorithms is disabled, it just won't be included. it knows when it's not wanted π PKCS7_STREAMgang rise up: if this flag is set, the returned PKCS7 structure is just initialized, ready to perform the signing operation β but the signing hasn't happened yet, and the data to be signed is not read from thedataparameter. signing gets deferred until after the data has been written. this is how you sign data in a single pass. one pass. efficient. queen behavior. π- If
PKCS7_PARTIALis set, you get a partial PKCS7 structure out, and you can add more signers and capabilities to it before finalization. build-a-bear but for signatures π§Έ
β οΈ real talk: if the flag PKCS7_STREAM is set, the returned PKCS7 structure is not complete, and outputting its contents through a function that doesn't properly finalize the PKCS7 structure will give unpredictable results. not cute. not slay. finalize properly, bestie.
Several functions do finalize the structure, including SMIME_write_PKCS7(), i2d_PKCS7_bio_stream(), and PEM_write_bio_PKCS7_stream(). alternatively you can finalize by getting the streaming ASN1 BIO directly with BIO_new_PKCS7(). your choice, both are valid π
If a signer is specified, it uses the default digest for the signing algorithm. that's SHA256 for both RSA and DSA keys. periodt.
Now, the fun part. The certs, signcert and pkey parameters can all be NULL β but only if the PKCS7_PARTIAL flag is set. then you can add one or more signers with PKCS7_sign_add_signer(). if streaming is not enabled you also must call PKCS7_final() to finalize the structure. and pssst β you can also specify alternative signing digests through this method β¨
And if signcert and pkey are both NULL? you get a certificates-only PKCS#7 structure out. no signing, just vibes.
π lore drop: in versions of OpenSSL before 1.0.0, thesigncertandpkeyparameters must not beNULL. so if you're time traveling, watch out.
PKCS7_sign() is like PKCS7_sign_ex() except it uses default values of NULL for the library context libctx and the property query propq. it's still here for API backward compatibility. legacy but still iconic π«Ά
π BUGS π
Some advanced attributes, like counter signatures, are not supported. yeah. that one. we know. π
β RETURN VALUES β
PKCS7_sign_ex() and PKCS7_sign() return either a valid PKCS7 structure, or NULL if an error happened. if you got NULL, you can go get the error from ERR_get_error(3). go get it, it's waiting for you.
π SEE ALSO π
ERR_get_error(3), PKCS7_verify(3)
π HISTORY π
- The function
PKCS7_sign_ex()was added in OpenSSL 3.0. - The
PKCS7_PARTIALflag, plus the ability forcerts,signcert, andpkeyparameters to beNULL, were added in OpenSSL 1.0.0. - The
PKCS7_STREAMflag was added in OpenSSL 1.0.0.
π COPYRIGHT π
Copyright 2002-2026 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 ate it up fr fr π
β¨ this was the PKCS7_SIGN(3SSL) manpage from OpenSSL 4.0.3, dated 2026-09-29 β mwah, go sign something gorgeous ππ¦π
π¦ where this page comes from
- ubuntu stonking: libssl-doc 4.0.3-1ubuntu1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms