PKCS7_dataInit
—
construct a BIO chain for adding or retrieving
content
PKCS7_dataInit
()
constructs a BIO chain in preparation for putting data into or retrieving
data out of p7. Depending on the
contentType of p7, the created
chain starts with:
- for SignedData:
- one or more
BIO_f_md(3)
message digest filters
- for EnvelopedData:
- one
BIO_f_cipher(3)
encryption filter
- for SignedAndEnvelopedData:
- one or more
BIO_f_md(3)
message digest filters followed by one
BIO_f_cipher(3)
encryption filter
- for DigestedData:
- one
BIO_f_md(3)
message digest filter
- for arbitrary data:
- no filter BIO
One additional BIO is appended to the end of the chain, depending
on the first condition that holds in the following list:
- indata
- if the indata argument is not
NULL
. This only makes sense while verifying a
detached signature, in which case indata is expected
to supply the content associated with the detached signature.
- BIO_s_null(3)
- if the contentType of p7 is
SignedData and it is configured to contain a
detached signature. This only makes sense while creating the detached
signature.
- BIO_new_mem_buf(3)
- when reading from a SignedData or
DigestedData object.
PKCS7_dataInit
()
attaches the end of the chain to the nested content of
p7.
- BIO_s_mem(3)
- otherwise. This is the most common case while writing data to
p7.
PKCS7_dataFinal(3)
can later be used to transfer the data from the memory BIO into
p7.
Before calling PKCS7_dataInit
() in order
to add content,
PKCS7_new(3),
PKCS7_set_type(3),
and
PKCS7_content_new(3)
are typically required to create p7, to choose its
desired type, and to allocate the nested ContentInfo
structure. Alternatively, for SignedData,
PKCS7_sign(3)
can be used with the PKCS7_PARTIAL
or
PKCS7_STREAM
flags or for
EnvelopedData,
PKCS7_encrypt(3)
with the PKCS7_STREAM
flag.
After calling
PKCS7_dataInit
(),
the desired data can be written into the returned BIO,
BIO_flush(3)
can be called on it,
PKCS7_dataFinal(3)
can be used to transfer the processed data from the returned memory BIO to
the p7 structure, and the chain can finally be
destroyed with
BIO_free_all(3).
While
PKCS7_dataInit
()
does support the EnvelopedData and
SignedAndEnvelopedData types, using it for these types
is awkward and error prone except when using
PKCS7_encrypt(3)
for the setup because
PKCS7_content_new(3)
does not support these two types. So in addition to creating
p7 itself and setting its type, the nested
ContentInfo structure also needs to be constructed
with
PKCS7_new(3)
and
PKCS7_set_type(3)
and manually inserted into the correct field of the respective sub-structure
of p7.
PKCS7_dataInit
() can also be called on a
fully populated object of type SignedData or
DigestedData. After that,
BIO_read(3)
can be used to retrieve data from it. In this use case, do not call
PKCS7_dataFinal(3);
simply proceed directly to
BIO_free_all(3)
after reading the data.
PKCS7_dataInit
() returns a BIO chain on
success or NULL
on failure. It fails if
p7 is NULL
, if the
content field of p7 is empty, if
the contentType of p7 is
unsupported, if a cipher is required but none is configured, or if any
required operation fails, for example due to lack of memory or for various
other reasons.
PKCS7_dataInit
() first appeared in SSLeay
0.8.1 and has been available since OpenBSD 2.4.
This function does not support
EncryptedData.
If p7 is a fully populated structure
containing EnvelopedData,
SignedAndEnvelopedData, or arbitrary data,
PKCS7_dataInit
() returns a BIO chain that ultimately
reads from an empty memory BIO, so reading from it will instantly return an
end-of-file indication rather than reading the actual data contained in
p7.