diff --git a/crypto/CMakeLists.txt b/crypto/CMakeLists.txt index 23828446a64..6e35414ba79 100644 --- a/crypto/CMakeLists.txt +++ b/crypto/CMakeLists.txt @@ -467,6 +467,7 @@ add_library( pem/pem_x509.c pem/pem_xaux.c pkcs7/pkcs7.c + pkcs7/pkcs7_asn1.c pkcs7/pkcs7_x509.c pkcs8/pkcs8.c pkcs8/pkcs8_x509.c diff --git a/crypto/pkcs7/internal.h b/crypto/pkcs7/internal.h index 5ee8e8a1c33..a8a9a69b87f 100644 --- a/crypto/pkcs7/internal.h +++ b/crypto/pkcs7/internal.h @@ -21,6 +21,55 @@ extern "C" { #endif +struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +}; + +struct pkcs7_signer_info_st { + ASN1_INTEGER *version; + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; + EVP_PKEY *pkey; +}; + +struct pkcs7_recip_info_st { + ASN1_INTEGER *version; + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; +}; + +struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; + const EVP_CIPHER *cipher; +}; + +struct pkcs7_envelope_st { + ASN1_INTEGER *version; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +}; + +struct pkcs7_digest_st { + ASN1_INTEGER *version; + X509_ALGOR *digest_alg; + PKCS7 *contents; + ASN1_OCTET_STRING *digest; + const EVP_MD *md; +}; + +struct pkcs7_encrypt_st { + ASN1_INTEGER *version; + PKCS7_ENC_CONTENT *enc_data; +}; // pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 // SignedData blob from |cbs| and sets |*out| to point to the rest of the diff --git a/crypto/pkcs7/pkcs7_asn1.c b/crypto/pkcs7/pkcs7_asn1.c new file mode 100644 index 00000000000..e6a5aa04b54 --- /dev/null +++ b/crypto/pkcs7/pkcs7_asn1.c @@ -0,0 +1,138 @@ +#include + +#include +#include + +#include "internal.h" +#include "../internal.h" + +ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS7) = { + ADB_ENTRY(NID_pkcs7_data, ASN1_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_pkcs7_signed, ASN1_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), + ADB_ENTRY(NID_pkcs7_enveloped, ASN1_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_digest, ASN1_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), + ADB_ENTRY(NID_pkcs7_encrypted, ASN1_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) +} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); + +ASN1_SEQUENCE(PKCS7) = { + ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS7) +} ASN1_SEQUENCE_END(PKCS7) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7) + +ASN1_SEQUENCE(PKCS7_SIGNED) = { + ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) +} ASN1_SEQUENCE_END(PKCS7_SIGNED) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) + +ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +/* Minor tweak to operation: free up X509 */ +static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; + X509_free(ri->cert); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { + ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), + ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) + +/* Minor tweak to operation: free up EVP_PKEY */ +static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; + if (operation == ASN1_OP_FREE_POST) { + EVP_PKEY_free(si->pkey); + /*} else if (operation == ASN1_OP_NEW_POST) {*/ + /*si->enc_digest = ASN1_OCTET_STRING_new();*/ + /*si->issuer_and_serial = PKCS7_ISSUER_AND_SERIAL_new();*/ + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { + ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), + /* NB this should be a SET OF but we use a SEQUENCE OF so the + * original order * is retained when the structure is reencoded. + * Since the attributes are implicitly tagged this will not affect + * the encoding. + */ + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) +} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) + +ASN1_SEQUENCE(PKCS7_ENC_CONTENT) = { + ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), + ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), + ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) +} ASN1_SEQUENCE_END(PKCS7_ENC_CONTENT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) + +ASN1_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) +} ASN1_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) + +ASN1_SEQUENCE(PKCS7_ENCRYPT) = { + ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) +} ASN1_SEQUENCE_END(PKCS7_ENCRYPT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) + +ASN1_SEQUENCE(PKCS7_DIGEST) = { + ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), + ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), + ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(PKCS7_DIGEST) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) + +ASN1_SEQUENCE(PKCS7_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) +} ASN1_SEQUENCE_END(PKCS7_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) diff --git a/crypto/pkcs7/pkcs7_x509.c b/crypto/pkcs7/pkcs7_x509.c index 7b10f6f239b..3498d881377 100644 --- a/crypto/pkcs7/pkcs7_x509.c +++ b/crypto/pkcs7/pkcs7_x509.c @@ -236,133 +236,41 @@ int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) { /*signer_infos_cb=*/NULL, crls); } -static PKCS7 *pkcs7_new(CBS *cbs) { - PKCS7 *ret = OPENSSL_zalloc(sizeof(PKCS7)); - if (ret == NULL) { - return NULL; - } - ret->type = OBJ_nid2obj(NID_pkcs7_signed); - ret->d.sign = OPENSSL_malloc(sizeof(PKCS7_SIGNED)); - if (ret->d.sign == NULL) { - goto err; - } - ret->d.sign->cert = sk_X509_new_null(); - ret->d.sign->crl = sk_X509_CRL_new_null(); - CBS copy = *cbs, copy2 = *cbs; - if (ret->d.sign->cert == NULL || ret->d.sign->crl == NULL || - !PKCS7_get_certificates(ret->d.sign->cert, ©) || - !PKCS7_get_CRLs(ret->d.sign->crl, cbs)) { - goto err; - } - - if (sk_X509_num(ret->d.sign->cert) == 0) { - sk_X509_free(ret->d.sign->cert); - ret->d.sign->cert = NULL; - } - - if (sk_X509_CRL_num(ret->d.sign->crl) == 0) { - sk_X509_CRL_free(ret->d.sign->crl); - ret->d.sign->crl = NULL; - } - - ret->ber_len = CBS_len(©2) - CBS_len(cbs); - ret->ber_bytes = OPENSSL_memdup(CBS_data(©2), ret->ber_len); - if (ret->ber_bytes == NULL) { - goto err; +PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out) { + if (out == NULL) { + return NULL; } - return ret; - -err: - PKCS7_free(ret); - return NULL; + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bio, (void *) *out); } -PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, - size_t len) { - CBS cbs; - CBS_init(&cbs, *inp, len); - PKCS7 *ret = pkcs7_new(&cbs); - if (ret == NULL) { - return NULL; - } - *inp = CBS_data(&cbs); - if (out != NULL) { - PKCS7_free(*out); - *out = ret; - } - return ret; +int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) { + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bio, (void *) p7); } -PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out) { - // Use a generous bound, to allow for PKCS#7 files containing large root sets. - static const size_t kMaxSize = 4 * 1024 * 1024; - uint8_t *data; - size_t len; - if (!BIO_read_asn1(bio, &data, &len, kMaxSize)) { - return NULL; - } - - CBS cbs; - CBS_init(&cbs, data, len); - PKCS7 *ret = pkcs7_new(&cbs); - OPENSSL_free(data); - if (out != NULL && ret != NULL) { - PKCS7_free(*out); - *out = ret; - } - return ret; +int PKCS7_type_is_data(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_data; } -int i2d_PKCS7(const PKCS7 *p7, uint8_t **out) { - if (p7->ber_len > INT_MAX) { - OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); - return -1; - } - - if (out == NULL) { - return (int)p7->ber_len; - } - - if (*out == NULL) { - *out = OPENSSL_memdup(p7->ber_bytes, p7->ber_len); - if (*out == NULL) { - return -1; - } - } else { - OPENSSL_memcpy(*out, p7->ber_bytes, p7->ber_len); - *out += p7->ber_len; - } - return (int)p7->ber_len; +int PKCS7_type_is_digest(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_digest; } -int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7) { - return BIO_write_all(bio, p7->ber_bytes, p7->ber_len); +int PKCS7_type_is_encrypted(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_encrypted; } -void PKCS7_free(PKCS7 *p7) { - if (p7 == NULL) { - return; - } +int PKCS7_type_is_enveloped(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_enveloped; +} - OPENSSL_free(p7->ber_bytes); - ASN1_OBJECT_free(p7->type); - // We only supported signed data. - if (p7->d.sign != NULL) { - sk_X509_pop_free(p7->d.sign->cert, X509_free); - sk_X509_CRL_pop_free(p7->d.sign->crl, X509_CRL_free); - OPENSSL_free(p7->d.sign); - } - OPENSSL_free(p7); +int PKCS7_type_is_signed(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_signed; } -// We only support signed data, so these getters are no-ops. -int PKCS7_type_is_data(const PKCS7 *p7) { return 0; } -int PKCS7_type_is_digest(const PKCS7 *p7) { return 0; } -int PKCS7_type_is_encrypted(const PKCS7 *p7) { return 0; } -int PKCS7_type_is_enveloped(const PKCS7 *p7) { return 0; } -int PKCS7_type_is_signed(const PKCS7 *p7) { return 1; } -int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7) { return 0; } +int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7) { + return OBJ_obj2nid(p7->type) == NID_pkcs7_signedAndEnveloped; +} // write_sha256_ai writes an AlgorithmIdentifier for SHA-256 to // |digest_algos_set|. @@ -512,9 +420,8 @@ PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, STACK_OF(X509) *certs, goto out; } - CBS cbs; - CBS_init(&cbs, der, len); - ret = pkcs7_new(&cbs); + const uint8_t *const_der = der; + ret = d2i_PKCS7(NULL, &const_der, len); out: CBB_cleanup(&cbb); diff --git a/include/openssl/base.h b/include/openssl/base.h index ae8e510a42b..a11e216f523 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -349,6 +349,13 @@ typedef struct md4_state_st MD4_CTX; typedef struct md5_state_st MD5_CTX; typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; +typedef struct pkcs7_digest_st PKCS7_DIGEST; +typedef struct pkcs7_enc_content_st PKCS7_ENC_CONTENT; +typedef struct pkcs7_encrypt_st PKCS7_ENCRYPT; +typedef struct pkcs7_envelope_st PKCS7_ENVELOPE; +typedef struct pkcs7_issuer_and_serial_st PKCS7_ISSUER_AND_SERIAL; +typedef struct pkcs7_recip_info_st PKCS7_RECIP_INFO; +typedef struct pkcs7_signer_info_st PKCS7_SIGNER_INFO; typedef struct pkcs12_st PKCS12; typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; typedef struct private_key_st X509_PKEY; diff --git a/include/openssl/pkcs7.h b/include/openssl/pkcs7.h index 8244b184f42..94a582d82c9 100644 --- a/include/openssl/pkcs7.h +++ b/include/openssl/pkcs7.h @@ -15,6 +15,7 @@ #ifndef OPENSSL_HEADER_PKCS7_H #define OPENSSL_HEADER_PKCS7_H +#include #include #include @@ -105,27 +106,13 @@ OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, // // These functions are a compatibility layer over a subset of OpenSSL's PKCS#7 // API. It intentionally does not implement the whole thing, only the minimum -// needed to build cryptography.io. +// needed to build cryptography.io and CRuby. -typedef struct { - STACK_OF(X509) *cert; - STACK_OF(X509_CRL) *crl; -} PKCS7_SIGNED; - -typedef struct { - STACK_OF(X509) *cert; - STACK_OF(X509_CRL) *crl; -} PKCS7_SIGN_ENVELOPE; - -typedef void PKCS7_ENVELOPE; -typedef void PKCS7_DIGEST; -typedef void PKCS7_ENCRYPT; -typedef void PKCS7_SIGNER_INFO; - -typedef struct { - uint8_t *ber_bytes; - size_t ber_len; +typedef struct pkcs7_st PKCS7; +typedef struct pkcs7_signed_st PKCS7_SIGNED; +typedef struct pkcs7_sign_envelope_st PKCS7_SIGN_ENVELOPE; +struct pkcs7_st { // Unlike OpenSSL, the following fields are immutable. They filled in when the // object is parsed and ignored in serialization. ASN1_OBJECT *type; @@ -139,11 +126,40 @@ typedef struct { PKCS7_ENCRYPT *encrypted; ASN1_TYPE *other; } d; -} PKCS7; +}; -// d2i_PKCS7 parses a BER-encoded, PKCS#7 signed data ContentInfo structure from -// |len| bytes at |*inp|, as described in |d2i_SAMPLE|. -OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, size_t len); +struct pkcs7_signed_st { + ASN1_INTEGER *version; + STACK_OF(X509_ALGOR) *md_algs; + PKCS7 *contents; + STACK_OF(X509) *cert; + STACK_OF(X509_CRL) *crl; + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; +}; + +struct pkcs7_sign_envelope_st { + ASN1_INTEGER *version; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + STACK_OF(X509_ALGOR) *md_algs; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(X509) *cert; + STACK_OF(X509_CRL) *crl; + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; +}; + +DECLARE_ASN1_FUNCTIONS(PKCS7) +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DEFINE_STACK_OF(PKCS7) +DEFINE_STACK_OF(PKCS7_RECIP_INFO) +DEFINE_STACK_OF(PKCS7_SIGNER_INFO) // d2i_PKCS7_bio behaves like |d2i_PKCS7| but reads the input from |bio|. If // the length of the object is indefinite the full contents of |bio| are read. @@ -152,34 +168,27 @@ OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, size_t len); // from |bio|. OPENSSL_EXPORT PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out); -// i2d_PKCS7 marshals |p7| as a DER-encoded PKCS#7 ContentInfo structure, as -// described in |i2d_SAMPLE|. -OPENSSL_EXPORT int i2d_PKCS7(const PKCS7 *p7, uint8_t **out); - // i2d_PKCS7_bio writes |p7| to |bio|. It returns one on success and zero on // error. OPENSSL_EXPORT int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7); -// PKCS7_free releases memory associated with |p7|. -OPENSSL_EXPORT void PKCS7_free(PKCS7 *p7); - -// PKCS7_type_is_data returns zero. +// PKCS7_type_is_data returns 1 if |p7| is of type data OPENSSL_EXPORT int PKCS7_type_is_data(const PKCS7 *p7); -// PKCS7_type_is_digest returns zero. +// PKCS7_type_is_digest returns 1 if |p7| is of type digest OPENSSL_EXPORT int PKCS7_type_is_digest(const PKCS7 *p7); -// PKCS7_type_is_encrypted returns zero. +// PKCS7_type_is_encrypted returns 1 if |p7| is of type encrypted OPENSSL_EXPORT int PKCS7_type_is_encrypted(const PKCS7 *p7); -// PKCS7_type_is_enveloped returns zero. +// PKCS7_type_is_enveloped returns 1 if |p7| is of type enveloped OPENSSL_EXPORT int PKCS7_type_is_enveloped(const PKCS7 *p7); -// PKCS7_type_is_signed returns one. (We only supporte signed data -// ContentInfos.) +// PKCS7_type_is_signed returns 1 if |p7| is of type signed OPENSSL_EXPORT int PKCS7_type_is_signed(const PKCS7 *p7); -// PKCS7_type_is_signedAndEnveloped returns zero. +// PKCS7_type_is_signedAndEnveloped returns 1 if |p7| is of type +// signedAndEnveloped OPENSSL_EXPORT int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7);