PKCS7_FINAL(3)
π PKCS7_FINAL β¨
okay so bestie, this is a page from libcrypto β like, the OpenSSL library manual, third section, the function-calls one. Pull up a chair, we're learning about PKCS7_final() π
πΈ NAME πΈ
PKCS7_final β read data from a BIO into a ContentInfo object. that's literally it, that's the whole vibe π¦
β¨ SYNOPSIS β¨
bestie it lives in libcrypto, so you're gonna want this include:
#include <openssl/pkcs7.h>
and here's the signature, character for character, no cap:
int
PKCS7_final(PKCS7 *p7, BIO *data, int flags);
π DESCRIPTION π
okay so PKCS7_final() reads data and puts it into the appropriate content field of p7 itself β or of its appropriate substructure. and that substructure can be SignedData, EnvelopedData, SignedAndEnvelopedData, DigestedData, or just arbitrary data. which field exactly? the PKCS7_dataFinal(3) manual spills all that tea, go read it π
here are the flags it actually recognizes (the rest are just... there, being decorative):
PKCS7_BINARYβ copies the data verbatim, no byte-changing whatsoever. by default tho, line endings get replaced with two-byte"\r\n"sequences (that's ASCII CR+LF, periodt). and heads up: if this flag is set,PKCS7_TEXTis ignored. like, fully ignored. don't even try it πPKCS7_TEXTβ prepends"Content-Type: text/plain"followed by a blank line to the data. but ifPKCS7_BINARYis also set, this one gets ignored instead. choose your fighter π
and if any other bits are set in flags β for example PKCS7_STREAM or PKCS7_PARTIAL β they're ignored. which is honestly a serve, because it means you can pass the same flags argument that you already passed to PKCS7_sign(3) or PKCS7_encrypt(3). no extra work, no notes π₯
now for the main-character use case: PKCS7_final() is most commonly used to finalize a p7 object returned from a call to PKCS7_sign(3) that used flags including PKCS7_PARTIAL or PKCS7_STREAM. with those flags, PKCS7_sign(3) ignores its data argument (yes, really, it's giving uninterested π). the partial p7 object you get back can then be customized β like setting up multiple signers, or non-default digest algorithms with PKCS7_sign_add_signer(3) β before you call PKCS7_final(). obsessed with that workflow honestly π
similarly (see what I did there), PKCS7_final() can be used to finalize a p7 object returned from a call to PKCS7_encrypt(3) that used flags including PKCS7_STREAM.
here's the catch tho, bestie π«Ά β since PKCS7_final() starts by calling PKCS7_dataInit(3) internally, using it to finalize a p7 object containing SignedAndEnvelopedData, DigestedData, or arbitrary data requires the setup described in the PKCS7_dataInit(3) manual. for SignedData and EnvelopedData, such manual setup is also feasible, but it is more easily performed with PKCS7_sign(3) or PKCS7_encrypt(3), respectively. so like... you can do it the hard way, but why would you π
and finally: PKCS7_final() is only one among several functions that can be used to finalize p7. alternatives include SMIME_write_PKCS7(3), PEM_write_bio_PKCS7_stream(3), and i2d_PKCS7_bio_stream(3). options, options, options π
β RETURN VALUES β
PKCS7_final() returns 1 on success or 0 on failure. that's the whole scale, binary, iconic π
possible reasons for failure include:
p7isNULL.- The content field of
p7is empty. - The
contentTypeofp7is unsupported. - Signing or digesting is requested and
p7is not configured to store a detached signature, but does not contain the required field to store the content either. - At least one signer lacks a usable digest algorithm.
- A cipher is required but none is configured.
- Any required operation fails, for example signing or digesting.
- Memory allocation fails.
and a lil note: signers lacking private keys do not cause failure β they're silently skipped. quiet quitting, but make it cryptography π
π¦ SEE ALSO π¦
BIO_new(3), i2d_PKCS7_bio_stream(3), PEM_write_bio_PKCS7_stream(3), PKCS7_add_attribute(3), PKCS7_dataFinal(3), PKCS7_dataInit(3), PKCS7_encrypt(3), PKCS7_new(3), PKCS7_sign(3), SMIME_write_PKCS7(3)
go read them all, i believe in you π
πΈ HISTORY πΈ
PKCS7_final() first appeared in OpenSSL 1.0.0 and has been available since OpenBSD 4.9. she's been around a minute, and she ate every single year π
π CAVEATS π
This function does not support EncryptedData. like, at all. don't come for her about it π«Ά
and that's the page bestie!! β¨ this one's from Debian, dated June 8, 2025 β read it, love it, run man PKCS7_final when you forget, mwah ππ§ββοΈπ
π¦ where this page comes from
- alpine 3.24: libressl-doc 4.3.1-r0 Β· custom
- arch rolling: libressl 4.4.0-1 Β· ISC AND custom:OpenSSL
- Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms