SMIME_READ_CMS(3ossl)

πŸ“¦
version 15.1 Β· 2 versions
, in freebsd 15.1

✨ SMIME_READ_CMS πŸ’Œ

okay so bestie, welcome to SMIME_read_CMS(3ossl) β€” the OpenSSL page about parsing S/MIME messages, and honestly? she's doing the most so you don't have to 🫢


🌸 NAME 🌸

SMIME_read_CMS_ex, SMIME_read_CMS β€” the duo that parses S/MIME messages for you, no cap πŸ’…


⭐ SYNOPSIS ⭐

like, here's the vibe check on how you call her:

#include <openssl/cms.h>

CMS_ContentInfo *SMIME_read_CMS_ex(BIO *bio, int flags, BIO **bcont,
                                   CMS_ContentInfo **cms);
CMS_ContentInfo *SMIME_read_CMS(BIO *in, BIO **bcont);

πŸŽ€ DESCRIPTION πŸŽ€

So SMIME_read_CMS() parses a message that's in S/MIME format. That's the whole job. Iconic behaviour, honestly.

in is a BIO you read the message from β€” that's the source, bestie, the main character.

If cleartext signing is used, then the content gets saved in a memory bio which is written to *bcont. If that's not happening? Then *bcont is set to NULL. Simple as that πŸ’β€β™€οΈ

The parsed CMS_ContentInfo structure is returned β€” or NULL if something went wrong 😭. Yeah. Errors happen.

Now, SMIME_read_CMS_ex() is literally SMIME_read_CMS()'s cooler older sister β€” she's similar, but optionally you can hand her a previously created cms CMS_ContentInfo object, plus some flags. To create a cms object, use CMS_ContentInfo_new_ex(3) β€” that's the move πŸ”₯

If the flags argument contains CMS_BINARY, then the input is assumed to be in binary format and is not translated to canonical form. And if SMIME_ASCIICRLF is set on top of that, then the binary input is assumed to be followed by CR and LF characters β€” otherwise, it's followed by only an LF character. tiny detail, huge consequences, iykyk.

And if flags is 0 and cms is NULL? Then she's literally identical to SMIME_read_CMS(). Same girl, different font πŸ’…


πŸ¦‹ NOTES πŸ¦‹

If *bcont is not NULL, then the message is clear text signed πŸ’–. You can then pass *bcont to CMS_verify() with the CMS_DETACHED flag set β€” slay.

Otherwise, you can figure out the type of the returned structure using CMS_get0_type().

To support future functionality, if bcont is not NULL, then *bcont should be initialized to NULL. Like, please. Do it for future-you πŸ™ˆ

For example:

BIO *cont = NULL;
CMS_ContentInfo *cms;

cms = SMIME_read_CMS(in, &cont);

πŸ’€ BUGS πŸ’€

ngl, this part is a little rough, so buckle up:

  • The MIME parser used by SMIME_read_CMS() is somewhat primitive. She'll handle most S/MIME messages, but more complex compound formats may just... not work 😭.
  • The parser assumes that the CMS_ContentInfo structure is always base64 encoded β€” and she will not handle the case where it's in binary format or uses quoted printable format. not her era, apparently.
  • Using a memory BIO to hold the signed content limits the size of the message which can be processed, due to memory restraints. A streaming single pass option should be available. (should be. isn't. we cope 🫠)

🌈 RETURN VALUES 🌈

SMIME_read_CMS_ex() and SMIME_read_CMS() both return a valid CMS_ContentInfo structure β€” or NULL if an error occurred. If you got NULL, you can grab the error from ERR_get_error(3) πŸ”


πŸ‘‘ SEE ALSO πŸ‘‘

ERR_get_error(3), CMS_sign(3), CMS_verify(3), CMS_encrypt(3), CMS_decrypt(3) β€” go read the whole friend group, they're all iconic ✨


🧚 HISTORY 🧚

The function SMIME_read_CMS_ex() was added in OpenSSL 3.0. a legend was born πŸ’œ


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


and that's the whole page, bestie πŸŽ€ β€” this was OpenSSL 3.5.6, dated 2026-04-07, signing off from SMIME_read_CMS(3ossl). mwah πŸ’‹πŸŒΈ

πŸ“¦ where this page comes from