CMS_ENCRYPT(3ossl)

πŸ’Œ CMS_ENCRYPT β€” create a CMS envelopedData structure πŸ’Œ

ok so. bestie. this is the page for CMS_encrypt_ex and CMS_encrypt, and it lives in the 3ossl manual for OpenSSL. it's giving cryptography. it's giving "your secrets are safe with me." let's GO 🫢


✨ SYNOPSIS ✨

#include <openssl/cms.h>

CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *in,
                                const EVP_CIPHER *cipher, unsigned int flags,
                                OSSL_LIB_CTX *libctx, const char *propq);
CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
                             const EVP_CIPHER *cipher, unsigned int flags);

🌸 DESCRIPTION 🌸

CMS_encrypt_ex() creates and returns a CMS EnvelopedData or AuthEnvelopedData structure. literally it's a little envelope for your data. so cute. πŸ’–

here's the tea on the args:

  • certs β€” a list of recipient certificates. like, who's allowed in the group chat.
  • in β€” the content to be encrypted. the message itself.
  • cipher β€” the symmetric cipher to use. the lock on the envelope.
  • flags β€” an optional set of flags. we'll get to those, don't worry.
  • libctx and propq β€” the library context and the property query. these are used internally when retrieving algorithms from providers. behind the scenes stuff, iykyk.

okay important: only certificates carrying RSA, Diffie-Hellman or EC keys are supported by this function. that's it. no others. periodt.

EVP_des_ede3_cbc() (triple DES) is the algorithm of choice for S/MIME use because most clients will support it. yes, triple DES. it's the algorithm equivalent of a reliable older sister. she shows up, she works. πŸ‘‘

the algorithm passed in the cipher parameter must support ASN1 encoding of its parameters. that's a requirement, not a suggestion, bestie. πŸ’… and if the cipher mode is GCM, then an AuthEnvelopedData structure containing MAC is used. otherwise, an EnvelopedData structure is used. currently the AES variants with GCM mode are the only supported AEAD algorithms. the only ones. iconic behavior honestly.

ngl this next bit is kinda cool: many browsers implement a "sign and encrypt" option, which is simply an S/MIME envelopedData containing an S/MIME signed message. you can readily produce this by storing the S/MIME signed message in a memory BIO and passing it to CMS_encrypt(). look at you, doing browser things. ✨

πŸŽ€ the flags πŸŽ€

the following flags can be passed in the flags parameter:

  • CMS_TEXT β€” if set, MIME headers for type text/plain are prepended to the data. a little name tag on your data. 🏷️
  • CMS_BINARY β€” normally the supplied content is translated into MIME canonical format (as required by the S/MIME specifications). if CMS_BINARY is set, no translation occurs. you should use this option if the supplied data is in binary format, otherwise the translation will corrupt it. 😭 and heads up: if CMS_BINARY is set, then CMS_TEXT is ignored. sorry to CMS_TEXT. it's not personal.
  • CMS_USE_KEYID β€” OpenSSL will by default identify recipient certificates using issuer name and serial number. if this flag is set, it will use the subject key identifier value instead. ⚠️ an error occurs if all recipient certificates do not have a subject key identifier extension. all of them. no stragglers.
  • CMS_STREAM β€” if set, a partial CMS_ContentInfo structure is returned suitable for streaming I/O: no data is read from the BIO in. she's not ready yet, she's still loading.
  • CMS_PARTIAL β€” if set, a partial CMS_ContentInfo structure is returned, to which additional recipients and attributes can be added before finalization. build-a-bear energy. 🧸
  • CMS_DETACHED β€” the data being encrypted is included in the CMS_ContentInfo structure, unless this is set, in which case it is omitted. this is rarely used in practice and is not supported by SMIME_write_CMS(). noted. πŸ“
⚠️ okay so this one's important. if the flag CMS_STREAM is set, the returned CMS_ContentInfo structure is not complete, and outputting its contents via a function that does not properly finalize the CMS_ContentInfo structure will give unpredictable results. do not do this. i'm begging. πŸ™

several functions β€” including SMIME_write_CMS(), i2d_CMS_bio_stream(), PEM_write_bio_CMS_stream() β€” finalize the structure. alternatively, finalization can be performed by obtaining the streaming ASN1 BIO directly using BIO_new_CMS(). so many options, all valid, pick your fave. πŸ’

the recipients specified in certs use a CMS KeyTransRecipientInfo info structure. KEKRecipientInfo is also supported, using the flag CMS_PARTIAL and CMS_add0_recipient_key(). two paths, both slay.

the parameter certs may be NULL if CMS_PARTIAL is set and recipients added later using CMS_add1_recipient_cert() or CMS_add0_recipient_key(). so you can do it in stages. no pressure. 🌈

CMS_encrypt() is similar to CMS_encrypt_ex() but uses default values of NULL for the library context libctx and the property query propq. it's the chill, no-frills version. lowkey the same girl, just less setup.


πŸ’« RETURN VALUES πŸ’«

CMS_encrypt_ex() and CMS_encrypt() return either a CMS_ContentInfo structure, or NULL if an error occurred. and if you get NULL, the error can be obtained from ERR_get_error(3). don't panic, just go read the error. 🫢


πŸ‘€ SEE ALSO πŸ‘€

ERR_get_error(3), CMS_decrypt(3)

like, go read those too. they're in the same friend group.


πŸ•°οΈ HISTORY πŸ•°οΈ

  • the function CMS_encrypt_ex() was added in OpenSSL 3.0.
  • the CMS_STREAM flag was first supported in OpenSSL 1.0.0.

glow-up timeline. πŸ“ˆ


Copyright 2008-2020 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>.


ok that's the whole page bestie, you ate that πŸ’… this was the CMS_ENCRYPT(3ossl) page from OpenSSL version 3.5.9, dated 2026-09-29. go encrypt something cute. mwah! πŸ’–βœ¨πŸŽ€πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from