PKCS7_ENCRYPT(3)

πŸ“¦ version 4.4.0, in alpine 3.24, arch rolling

πŸ’Œ PKCS7_ENCRYPT(3) β€” the envelopedData glow-up πŸ’Œ

okay bestie, welcome to the libcrypto manual page for PKCS7_encrypt(). yes, that libcrypto. the crypto one. buckle up πŸŽ€


✨ NAME ✨

PKCS7_encrypt β€” create a PKCS#7 envelopedData structure πŸ’… (yes that's the whole job, and she does it gorgeously)


🌸 SYNOPSIS 🌸

library β€œlibcrypto” #include <openssl/pkcs7.h>

PKCS7 *
PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
    int flags);

πŸ¦‹ DESCRIPTION πŸ¦‹

So PKCS7_encrypt() literally creates and returns a PKCS#7 envelopedData structure. that's it, that's the vibe ✨ here's the cast:

  • certs β€” the list of recipient certificates 🫢
  • in β€” the content that's getting encrypted πŸ”
  • cipher β€” the symmetric cipher to use 🧚
  • flags β€” an optional set of flags 🚩
⚠️ important!! Only RSA keys are supported in PKCS#7 and envelopedData. so every single recipient certificate you hand this function must contain an RSA public key. ngl they don't have to be signed using the RSA algorithm though β€” just gotta have the RSA public key. iykyk πŸ’€

And the algorithm you pass in cipher? it has to support ASN.1 encoding of its parameters. no exceptions bestie βœ‹

okay so here's a fun one: many browsers implement a "sign and encrypt" option which is honestly just an S/MIME envelopedData containing an S/MIME signed message. main character energy honestly πŸ‘‘ you can produce that easily by storing the S/MIME signed message in a memory BIO and passing it to PKCS7_encrypt(). slay 🌈

πŸŽ€ the flags, one by one πŸŽ€

these go in the flags parameter, bestie:

  • PKCS7_TEXT β€” if set, MIME headers for type text/plain get prepended to the data πŸ’Œ
  • PKCS7_BINARY β€” normally the supplied content gets translated into MIME canonical format (as required by the S/MIME specifications, periodt). if this flag is set, no translation occurs. 🚨 use this if your supplied data is in binary format β€” otherwise the translation will literally corrupt it 😭. and heads up: if PKCS7_BINARY is set, then PKCS7_TEXT is ignored.
  • PKCS7_STREAM β€” if set, a partial PKCS7 structure is output suitable for streaming I/O: no data is read from in. iconic for streaming, but see the warning below πŸ‘‡
πŸ’€ BIG WARNING: if the flag PKCS7_STREAM is set, the returned PKCS7 structure is not complete, and outputting its contents via a function that does not properly finalize the PKCS7 structure will give unpredictable results. like, actually unpredictable. not cute unpredictable. πŸ™ˆ

so how do you finalize it? several functions do the job:

alternatively, finalization can be performed by obtaining the streaming ASN.1 BIO directly using BIO_new_PKCS7(). options, we love options 🫢


⭐ RETURN VALUES ⭐

PKCS7_encrypt() returns either a PKCS7 structure, or NULL if an error occurred 😭 if it's NULL, you can grab the error from ERR_get_error(3). go get your diagnostics bestie πŸ”


🌟 SEE ALSO 🌟

(the whole PKCS7 friend group honestly πŸ’–)


πŸ‘‘ HISTORY πŸ‘‘

PKCS7_encrypt() first appeared in OpenSSL 0.9.5 and has been available since OpenBSD 2.7. a true veteran, we stan 🫑

The PKCS7_STREAM flag was first supported in OpenSSL 1.0.0. she's newer but she's that girl πŸ’…


kisses and good luck with your envelopedData πŸ“ β€” this page came straight from the Debian libcrypto docs, dated June 8, 2025. bye bestie, go encrypt something gorgeous πŸ’œβœ¨

πŸ“¦ where this page comes from