Adam Langley | d9e397b | 2015-01-22 14:27:53 -0800 | [diff] [blame] | 1 | /* Copyright (c) 2014, Google Inc. |
| 2 | * |
| 3 | * Permission to use, copy, modify, and/or distribute this software for any |
| 4 | * purpose with or without fee is hereby granted, provided that the above |
| 5 | * copyright notice and this permission notice appear in all copies. |
| 6 | * |
| 7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
| 8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
| 9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
| 10 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
| 11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
| 12 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
| 13 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
| 14 | |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 15 | #ifndef OPENSSL_HEADER_PKCS7_H |
| 16 | #define OPENSSL_HEADER_PKCS7_H |
| 17 | |
| 18 | #include <openssl/base.h> |
| 19 | |
| 20 | #include <openssl/stack.h> |
| 21 | |
| 22 | #if defined(__cplusplus) |
| 23 | extern "C" { |
| 24 | #endif |
| 25 | |
| 26 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 27 | // PKCS#7. |
| 28 | // |
| 29 | // This library contains functions for extracting information from PKCS#7 |
| 30 | // structures (RFC 2315). |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 31 | |
| 32 | DECLARE_STACK_OF(CRYPTO_BUFFER) |
| 33 | DECLARE_STACK_OF(X509) |
| 34 | DECLARE_STACK_OF(X509_CRL) |
| 35 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 36 | // PKCS7_get_raw_certificates parses a PKCS#7, SignedData structure from |cbs| |
| 37 | // and appends the included certificates to |out_certs|. It returns one on |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 38 | // success and zero on error. |cbs| is advanced passed the structure. |
| 39 | // |
| 40 | // Note that a SignedData structure may contain no certificates, in which case |
| 41 | // this function succeeds but does not append any certificates. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 42 | OPENSSL_EXPORT int PKCS7_get_raw_certificates( |
| 43 | STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, CRYPTO_BUFFER_POOL *pool); |
| 44 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 45 | // PKCS7_get_certificates behaves like |PKCS7_get_raw_certificates| but parses |
| 46 | // them into |X509| objects. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 47 | OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs); |
| 48 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 49 | // PKCS7_bundle_certificates appends a PKCS#7, SignedData structure containing |
| 50 | // |certs| to |out|. It returns one on success and zero on error. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 51 | OPENSSL_EXPORT int PKCS7_bundle_certificates( |
| 52 | CBB *out, const STACK_OF(X509) *certs); |
| 53 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 54 | // PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 55 | // the included CRLs to |out_crls|. It returns one on success and zero on error. |
| 56 | // |cbs| is advanced passed the structure. |
| 57 | // |
| 58 | // Note that a SignedData structure may contain no CRLs, in which case this |
| 59 | // function succeeds but does not append any CRLs. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 60 | OPENSSL_EXPORT int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs); |
| 61 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 62 | // PKCS7_bundle_CRLs appends a PKCS#7, SignedData structure containing |
| 63 | // |crls| to |out|. It returns one on success and zero on error. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 64 | OPENSSL_EXPORT int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls); |
| 65 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 66 | // PKCS7_get_PEM_certificates reads a PEM-encoded, PKCS#7, SignedData structure |
| 67 | // from |pem_bio| and appends the included certificates to |out_certs|. It |
| 68 | // returns one on success and zero on error. |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 69 | // |
| 70 | // Note that a SignedData structure may contain no certificates, in which case |
| 71 | // this function succeeds but does not append any certificates. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 72 | OPENSSL_EXPORT int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, |
| 73 | BIO *pem_bio); |
| 74 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 75 | // PKCS7_get_PEM_CRLs reads a PEM-encoded, PKCS#7, SignedData structure from |
| 76 | // |pem_bio| and appends the included CRLs to |out_crls|. It returns one on |
| 77 | // success and zero on error. |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 78 | // |
| 79 | // Note that a SignedData structure may contain no CRLs, in which case this |
| 80 | // function succeeds but does not append any CRLs. |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 81 | OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, |
| 82 | BIO *pem_bio); |
| 83 | |
| 84 | |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 85 | // Deprecated functions. |
| 86 | // |
| 87 | // These functions are a compatibility layer over a subset of OpenSSL's PKCS#7 |
| 88 | // API. It intentionally does not implement the whole thing, only the minimum |
| 89 | // needed to build cryptography.io. |
| 90 | |
| 91 | typedef struct { |
| 92 | STACK_OF(X509) *cert; |
| 93 | STACK_OF(X509_CRL) *crl; |
| 94 | } PKCS7_SIGNED; |
| 95 | |
| 96 | typedef struct { |
| 97 | STACK_OF(X509) *cert; |
| 98 | STACK_OF(X509_CRL) *crl; |
| 99 | } PKCS7_SIGN_ENVELOPE; |
| 100 | |
| 101 | typedef void PKCS7_ENVELOPE; |
| 102 | typedef void PKCS7_DIGEST; |
| 103 | typedef void PKCS7_ENCRYPT; |
| 104 | |
| 105 | typedef struct { |
| 106 | uint8_t *ber_bytes; |
| 107 | size_t ber_len; |
| 108 | |
| 109 | // Unlike OpenSSL, the following fields are immutable. They filled in when the |
| 110 | // object is parsed and ignored in serialization. |
| 111 | ASN1_OBJECT *type; |
| 112 | union { |
| 113 | char *ptr; |
| 114 | ASN1_OCTET_STRING *data; |
| 115 | PKCS7_SIGNED *sign; |
| 116 | PKCS7_ENVELOPE *enveloped; |
| 117 | PKCS7_SIGN_ENVELOPE *signed_and_enveloped; |
| 118 | PKCS7_DIGEST *digest; |
| 119 | PKCS7_ENCRYPT *encrypted; |
| 120 | ASN1_TYPE *other; |
| 121 | } d; |
| 122 | } PKCS7; |
| 123 | |
| 124 | // d2i_PKCS7 parses a BER-encoded, PKCS#7 signed data ContentInfo structure from |
| 125 | // |len| bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the |
| 126 | // result is in |*out|. Note that, even if |*out| is already non-NULL on entry, |
| 127 | // it will not be written to. Rather, a fresh |PKCS7| is allocated and the |
| 128 | // previous one is freed. On successful exit, |*inp| is advanced past the BER |
| 129 | // structure. It returns the result or NULL on error. |
| 130 | OPENSSL_EXPORT PKCS7 *d2i_PKCS7(PKCS7 **out, const uint8_t **inp, |
| 131 | size_t len); |
| 132 | |
| 133 | // d2i_PKCS7_bio behaves like |d2i_PKCS7| but reads the input from |bio|. If |
| 134 | // the length of the object is indefinite the full contents of |bio| are read. |
| 135 | // |
| 136 | // If the function fails then some unknown amount of data may have been read |
| 137 | // from |bio|. |
| 138 | OPENSSL_EXPORT PKCS7 *d2i_PKCS7_bio(BIO *bio, PKCS7 **out); |
| 139 | |
| 140 | // i2d_PKCS7 is a dummy function which copies the contents of |p7|. If |out| is |
| 141 | // not NULL then the result is written to |*out| and |*out| is advanced just |
| 142 | // past the output. It returns the number of bytes in the result, whether |
| 143 | // written or not, or a negative value on error. |
| 144 | OPENSSL_EXPORT int i2d_PKCS7(const PKCS7 *p7, uint8_t **out); |
| 145 | |
| 146 | // i2d_PKCS7_bio writes |p7| to |bio|. It returns one on success and zero on |
| 147 | // error. |
| 148 | OPENSSL_EXPORT int i2d_PKCS7_bio(BIO *bio, const PKCS7 *p7); |
| 149 | |
| 150 | // PKCS7_free releases memory associated with |p7|. |
| 151 | OPENSSL_EXPORT void PKCS7_free(PKCS7 *p7); |
| 152 | |
| 153 | // PKCS7_type_is_data returns zero. |
| 154 | OPENSSL_EXPORT int PKCS7_type_is_data(const PKCS7 *p7); |
| 155 | |
| 156 | // PKCS7_type_is_digest returns zero. |
| 157 | OPENSSL_EXPORT int PKCS7_type_is_digest(const PKCS7 *p7); |
| 158 | |
| 159 | // PKCS7_type_is_encrypted returns zero. |
| 160 | OPENSSL_EXPORT int PKCS7_type_is_encrypted(const PKCS7 *p7); |
| 161 | |
| 162 | // PKCS7_type_is_enveloped returns zero. |
| 163 | OPENSSL_EXPORT int PKCS7_type_is_enveloped(const PKCS7 *p7); |
| 164 | |
| 165 | // PKCS7_type_is_signed returns one. (We only supporte signed data |
| 166 | // ContentInfos.) |
| 167 | OPENSSL_EXPORT int PKCS7_type_is_signed(const PKCS7 *p7); |
| 168 | |
| 169 | // PKCS7_type_is_signedAndEnveloped returns zero. |
| 170 | OPENSSL_EXPORT int PKCS7_type_is_signedAndEnveloped(const PKCS7 *p7); |
| 171 | |
| 172 | // PKCS7_DETACHED indicates that the PKCS#7 file specifies its data externally. |
| 173 | #define PKCS7_DETACHED 0x40 |
| 174 | |
| 175 | // The following flags cause |PKCS7_sign| to fail. |
| 176 | #define PKCS7_TEXT 0x1 |
| 177 | #define PKCS7_NOCERTS 0x2 |
| 178 | #define PKCS7_NOSIGS 0x4 |
| 179 | #define PKCS7_NOCHAIN 0x8 |
| 180 | #define PKCS7_NOINTERN 0x10 |
| 181 | #define PKCS7_NOVERIFY 0x20 |
| 182 | #define PKCS7_BINARY 0x80 |
| 183 | #define PKCS7_NOATTR 0x100 |
| 184 | #define PKCS7_NOSMIMECAP 0x200 |
| 185 | #define PKCS7_STREAM 0x1000 |
| 186 | |
| 187 | // PKCS7_sign assembles |certs| into a PKCS#7 signed data ContentInfo with |
| 188 | // external data and no signatures. It returns a newly-allocated |PKCS7| on |
| 189 | // success or NULL on error. |sign_cert| and |pkey| must be NULL. |data| is |
| 190 | // ignored. |flags| must be equal to |PKCS7_DETACHED|. |
| 191 | // |
| 192 | // Note this function only implements a subset of the corresponding OpenSSL |
| 193 | // function. It is provided for backwards compatibility only. |
| 194 | OPENSSL_EXPORT PKCS7 *PKCS7_sign(X509 *sign_cert, EVP_PKEY *pkey, |
| 195 | STACK_OF(X509) *certs, BIO *data, int flags); |
| 196 | |
| 197 | |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 198 | #if defined(__cplusplus) |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 199 | } // extern C |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 200 | |
| 201 | extern "C++" { |
Robert Sloan | 726e9d1 | 2018-09-11 11:45:04 -0700 | [diff] [blame] | 202 | BSSL_NAMESPACE_BEGIN |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 203 | |
| 204 | BORINGSSL_MAKE_DELETER(PKCS7, PKCS7_free) |
| 205 | |
Robert Sloan | 726e9d1 | 2018-09-11 11:45:04 -0700 | [diff] [blame] | 206 | BSSL_NAMESPACE_END |
Adam Vartanian | bfcf3a7 | 2018-08-10 14:55:24 +0100 | [diff] [blame] | 207 | } // extern C++ |
Robert Sloan | 9254e68 | 2017-04-24 09:42:06 -0700 | [diff] [blame] | 208 | #endif |
| 209 | |
| 210 | #define PKCS7_R_BAD_PKCS7_VERSION 100 |
| 211 | #define PKCS7_R_NOT_PKCS7_SIGNED_DATA 101 |
| 212 | #define PKCS7_R_NO_CERTIFICATES_INCLUDED 102 |
| 213 | #define PKCS7_R_NO_CRLS_INCLUDED 103 |
| 214 | |
Robert Sloan | 8f860b1 | 2017-08-28 07:37:06 -0700 | [diff] [blame] | 215 | #endif // OPENSSL_HEADER_PKCS7_H |