CMS_ENCRYPT(3SSL)
π CMS_ENCRYPT β bestie edition π
okay so you found yourself in the CMS_ENCRYPT(3SSL) manpage, welcome, pull up a chair π«Ά this one is basically "how do I wrap up some content so only certain people can open it" and honestly? it's giving cryptography main character energy.
NAME β¨
CMS_encrypt_ex, CMS_encrypt β these two make you a CMS envelopedData structure. that's the whole job bestie π
SYNOPSIS π
#include <openssl/cms.h>
CMS_ContentInfo *CMS_encrypt_ex(const STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags,
OSSL_LIB_CTX *libctx, const char *propq);
CMS_ContentInfo *CMS_encrypt(const STACK_OF(X509) *certs, BIO *in,
const EVP_CIPHER *cipher, unsigned int flags);
like look at those signatures. so clean. so demure. β¨
DESCRIPTION πΈ
CMS_encrypt_ex() builds you a CMS EnvelopedData or AuthEnvelopedData structure and hands it back to you. let's break down the lil squad of arguments:
certsβ a list of recipient certificates. these are the people allowed in the group chat πinβ the content that's getting encryptedcipherβ the symmetric cipher we're usingflagsβ an optional set of flags (we'll get to those, don't worry)libctxβ the library contextpropqβ the property query
the libctx and propq are used internally when retrieving algorithms from providers. iykyk. π§
ngl there's a limitation here: only certificates carrying RSA, Diffie-Hellman or EC keys are supported by this function. if yours doesn't, that's a no from her.
EVP_des_ede3_cbc() (triple DES) is literally the algorithm of choice for S/MIME use because most clients will support it. it's the universal love language of mail clients fr fr.
the algorithm you pass in the cipher parameter must support ASN1 encoding of its parameters β that's non-negotiable bestie. and here's the tea: if the cipher mode is GCM, then an AuthEnvelopedData structure containing a MAC is used. otherwise an EnvelopedData structure is used. currently the AES variants with GCM mode are the only supported AEAD algorithms. iconic β¨
okay so, many browsers implement a "sign and encrypt" option which is simply an S/MIME envelopedData containing an S/MIME signed message. want that? so easy β store the S/MIME signed message in a memory BIO and pass it to CMS_encrypt(). slay π
OPTIONS π₯ (the flags, bestie)
the following flags can be passed in the flags parameter:
CMS_TEXTβ if set, MIME headers for typetext/plainare prepended to the data. cute lil header moment πCMS_BINARYβ normally the supplied content is translated into MIME canonical format (as required by the S/MIME specifications). ifCMS_BINARYis set, no translation occurs. use this if your data is in binary format, otherwise the translation will corrupt it π. also, ifCMS_BINARYis set thenCMS_TEXTis ignored. she said pick one.CMS_USE_KEYIDβ OpenSSL will by default identify recipient certificates using issuer name and serial number. set this flag and it'll use the subject key identifier value instead. heads up tho: an error occurs if all recipient certificates do not have a subject key identifier extension. so make sure everybody's got one or the whole thing falls apart πCMS_STREAMβ set this and a partialCMS_ContentInfostructure is returned suitable for streaming I/O: no data is read from the BIO in. lazy girl math, no reading, obsessed β¨CMS_PARTIALβ set this and a partialCMS_ContentInfostructure is returned to which additional recipients and attributes can be added before finalization. build-your-own-adventure vibes π¦CMS_DETACHEDβ the data being encrypted is included in theCMS_ContentInfostructure, unless this is set, in which case it is omitted. this is rarely used in practice and is not supported bySMIME_write_CMS(). noted, moving on π
m o r e d e t a i l s π
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. read that again. unpredictable. results. π
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().
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(). KEMRecipientInfo is also supported using the flag CMS_PARTIAL and CMS_add1_recipient(). so many recipient-info girlies, we love range π
the parameter certs may be NULL if CMS_PARTIAL is set and recipients are added later using CMS_add1_recipient() or CMS_add1_recipient_cert() with CMS_add0_recipient_key().
and finally β CMS_encrypt() is similar to CMS_encrypt_ex() but uses default values of NULL for the library context libctx and the property query propq. the chill version. the "i don't wanna think about it" version. valid. π«Ά
RETURN VALUES β
CMS_encrypt_ex() and CMS_encrypt() return either a CMS_ContentInfo structure, or NULL if an error occurred. the error can be obtained from ERR_get_error(3). so if you get NULL, don't panic, just go check the error π
SEE ALSO π
HISTORY π
- the function
CMS_encrypt_ex()was added in OpenSSL 3.0. - the
CMS_STREAMflag was first supported in OpenSSL 1.0.0.
COPYRIGHT βοΈ
Copyright 2008-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 thing bestie, you're officially a CMS encryption girlie now π β¨
this has been CMS_ENCRYPT(3SSL), OpenSSL version 4.0.3, dated 2026-09-29 β mwah, go encrypt something iconic ππ
π¦ 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