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 | |
15 | #ifndef OPENSSL_HEADER_PKCS7_H |
16 | #define |
17 | |
18 | #include <openssl/base.h> |
19 | |
20 | #include <openssl/stack.h> |
21 | |
22 | #if defined(__cplusplus) |
23 | extern "C" { |
24 | #endif |
25 | |
26 | |
27 | // PKCS#7. |
28 | // |
29 | // This library contains functions for extracting information from PKCS#7 |
30 | // structures (RFC 2315). |
31 | |
32 | DECLARE_STACK_OF(CRYPTO_BUFFER) |
33 | DECLARE_STACK_OF(X509) |
34 | DECLARE_STACK_OF(X509_CRL) |
35 | |
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 |
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. |
42 | OPENSSL_EXPORT int PKCS7_get_raw_certificates( |
43 | STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, CRYPTO_BUFFER_POOL *pool); |
44 | |
45 | // PKCS7_get_certificates behaves like |PKCS7_get_raw_certificates| but parses |
46 | // them into |X509| objects. |
47 | OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs); |
48 | |
49 | // PKCS7_bundle_certificates appends a PKCS#7, SignedData structure containing |
50 | // |certs| to |out|. It returns one on success and zero on error. |
51 | OPENSSL_EXPORT int PKCS7_bundle_certificates( |
52 | CBB *out, const STACK_OF(X509) *certs); |
53 | |
54 | // PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends |
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. |
60 | OPENSSL_EXPORT int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs); |
61 | |
62 | // PKCS7_bundle_CRLs appends a PKCS#7, SignedData structure containing |
63 | // |crls| to |out|. It returns one on success and zero on error. |
64 | OPENSSL_EXPORT int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls); |
65 | |
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. |
69 | // |
70 | // Note that a SignedData structure may contain no certificates, in which case |
71 | // this function succeeds but does not append any certificates. |
72 | OPENSSL_EXPORT int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, |
73 | BIO *pem_bio); |
74 | |
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. |
78 | // |
79 | // Note that a SignedData structure may contain no CRLs, in which case this |
80 | // function succeeds but does not append any CRLs. |
81 | OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, |
82 | BIO *pem_bio); |
83 | |
84 | |
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 | |
198 | #if defined(__cplusplus) |
199 | } // extern C |
200 | |
201 | extern "C++" { |
202 | BSSL_NAMESPACE_BEGIN |
203 | |
204 | BORINGSSL_MAKE_DELETER(PKCS7, PKCS7_free) |
205 | |
206 | BSSL_NAMESPACE_END |
207 | } // extern C++ |
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 | |
215 | #endif // OPENSSL_HEADER_PKCS7_H |
216 | |