Absolute File Name: | /home/opencoverage/opencoverage/guest-scripts/libressl/src/crypto/pkcs7/pk7_smime.c |
Source code | Switch to Preprocessed file |
Line | Source | Count | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | /* $OpenBSD: pk7_smime.c,v 1.22 2017/01/29 17:49:23 beck Exp $ */ | - | ||||||||||||||||||
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | - | ||||||||||||||||||
3 | * project. | - | ||||||||||||||||||
4 | */ | - | ||||||||||||||||||
5 | /* ==================================================================== | - | ||||||||||||||||||
6 | * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. | - | ||||||||||||||||||
7 | * | - | ||||||||||||||||||
8 | * Redistribution and use in source and binary forms, with or without | - | ||||||||||||||||||
9 | * modification, are permitted provided that the following conditions | - | ||||||||||||||||||
10 | * are met: | - | ||||||||||||||||||
11 | * | - | ||||||||||||||||||
12 | * 1. Redistributions of source code must retain the above copyright | - | ||||||||||||||||||
13 | * notice, this list of conditions and the following disclaimer. | - | ||||||||||||||||||
14 | * | - | ||||||||||||||||||
15 | * 2. Redistributions in binary form must reproduce the above copyright | - | ||||||||||||||||||
16 | * notice, this list of conditions and the following disclaimer in | - | ||||||||||||||||||
17 | * the documentation and/or other materials provided with the | - | ||||||||||||||||||
18 | * distribution. | - | ||||||||||||||||||
19 | * | - | ||||||||||||||||||
20 | * 3. All advertising materials mentioning features or use of this | - | ||||||||||||||||||
21 | * software must display the following acknowledgment: | - | ||||||||||||||||||
22 | * "This product includes software developed by the OpenSSL Project | - | ||||||||||||||||||
23 | * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" | - | ||||||||||||||||||
24 | * | - | ||||||||||||||||||
25 | * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to | - | ||||||||||||||||||
26 | * endorse or promote products derived from this software without | - | ||||||||||||||||||
27 | * prior written permission. For written permission, please contact | - | ||||||||||||||||||
28 | * licensing@OpenSSL.org. | - | ||||||||||||||||||
29 | * | - | ||||||||||||||||||
30 | * 5. Products derived from this software may not be called "OpenSSL" | - | ||||||||||||||||||
31 | * nor may "OpenSSL" appear in their names without prior written | - | ||||||||||||||||||
32 | * permission of the OpenSSL Project. | - | ||||||||||||||||||
33 | * | - | ||||||||||||||||||
34 | * 6. Redistributions of any form whatsoever must retain the following | - | ||||||||||||||||||
35 | * acknowledgment: | - | ||||||||||||||||||
36 | * "This product includes software developed by the OpenSSL Project | - | ||||||||||||||||||
37 | * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" | - | ||||||||||||||||||
38 | * | - | ||||||||||||||||||
39 | * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY | - | ||||||||||||||||||
40 | * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | - | ||||||||||||||||||
41 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | - | ||||||||||||||||||
42 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR | - | ||||||||||||||||||
43 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | - | ||||||||||||||||||
44 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | - | ||||||||||||||||||
45 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | - | ||||||||||||||||||
46 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | - | ||||||||||||||||||
47 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | - | ||||||||||||||||||
48 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | - | ||||||||||||||||||
49 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | - | ||||||||||||||||||
50 | * OF THE POSSIBILITY OF SUCH DAMAGE. | - | ||||||||||||||||||
51 | * ==================================================================== | - | ||||||||||||||||||
52 | * | - | ||||||||||||||||||
53 | * This product includes cryptographic software written by Eric Young | - | ||||||||||||||||||
54 | * (eay@cryptsoft.com). This product includes software written by Tim | - | ||||||||||||||||||
55 | * Hudson (tjh@cryptsoft.com). | - | ||||||||||||||||||
56 | * | - | ||||||||||||||||||
57 | */ | - | ||||||||||||||||||
58 | - | |||||||||||||||||||
59 | /* Simple PKCS#7 processing functions */ | - | ||||||||||||||||||
60 | - | |||||||||||||||||||
61 | #include <stdio.h> | - | ||||||||||||||||||
62 | - | |||||||||||||||||||
63 | #include <openssl/err.h> | - | ||||||||||||||||||
64 | #include <openssl/x509.h> | - | ||||||||||||||||||
65 | #include <openssl/x509v3.h> | - | ||||||||||||||||||
66 | - | |||||||||||||||||||
67 | static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); | - | ||||||||||||||||||
68 | - | |||||||||||||||||||
69 | PKCS7 * | - | ||||||||||||||||||
70 | PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data, | - | ||||||||||||||||||
71 | int flags) | - | ||||||||||||||||||
72 | { | - | ||||||||||||||||||
73 | PKCS7 *p7; | - | ||||||||||||||||||
74 | int i; | - | ||||||||||||||||||
75 | - | |||||||||||||||||||
76 | if (!(p7 = PKCS7_new())) {
| 0-2 | ||||||||||||||||||
77 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
78 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
79 | } | - | ||||||||||||||||||
80 | - | |||||||||||||||||||
81 | if (!PKCS7_set_type(p7, NID_pkcs7_signed))
| 0-2 | ||||||||||||||||||
82 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
83 | - | |||||||||||||||||||
84 | if (!PKCS7_content_new(p7, NID_pkcs7_data))
| 0-2 | ||||||||||||||||||
85 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
86 | - | |||||||||||||||||||
87 | if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
| 0-1 | ||||||||||||||||||
88 | PKCS7error(PKCS7_R_PKCS7_ADD_SIGNER_ERROR); | - | ||||||||||||||||||
89 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
90 | } | - | ||||||||||||||||||
91 | - | |||||||||||||||||||
92 | if (!(flags & PKCS7_NOCERTS)) {
| 0-2 | ||||||||||||||||||
93 | for (i = 0; i < sk_X509_num(certs); i++) {
| 1-2 | ||||||||||||||||||
94 | if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
| 0-1 | ||||||||||||||||||
95 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
96 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
97 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
98 | - | |||||||||||||||||||
99 | if (flags & PKCS7_DETACHED)
| 1 | ||||||||||||||||||
100 | PKCS7_set_detached(p7, 1); executed 1 time by 1 test: PKCS7_ctrl(p7,1,1, ((void *)0) ); Executed by:
| 1 | ||||||||||||||||||
101 | - | |||||||||||||||||||
102 | if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
| 1 | ||||||||||||||||||
103 | return p7; executed 1 time by 1 test: return p7; Executed by:
| 1 | ||||||||||||||||||
104 | - | |||||||||||||||||||
105 | if (PKCS7_final(p7, data, flags))
| 0-1 | ||||||||||||||||||
106 | return p7; executed 1 time by 1 test: return p7; Executed by:
| 1 | ||||||||||||||||||
107 | - | |||||||||||||||||||
108 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||
109 | PKCS7_free(p7); | - | ||||||||||||||||||
110 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
111 | } | - | ||||||||||||||||||
112 | - | |||||||||||||||||||
113 | int | - | ||||||||||||||||||
114 | PKCS7_final(PKCS7 *p7, BIO *data, int flags) | - | ||||||||||||||||||
115 | { | - | ||||||||||||||||||
116 | BIO *p7bio; | - | ||||||||||||||||||
117 | int ret = 0; | - | ||||||||||||||||||
118 | - | |||||||||||||||||||
119 | if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
| 0-3 | ||||||||||||||||||
120 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
121 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
122 | } | - | ||||||||||||||||||
123 | - | |||||||||||||||||||
124 | SMIME_crlf_copy(data, p7bio, flags); | - | ||||||||||||||||||
125 | - | |||||||||||||||||||
126 | (void)BIO_flush(p7bio); | - | ||||||||||||||||||
127 | - | |||||||||||||||||||
128 | if (!PKCS7_dataFinal(p7, p7bio)) {
| 0-3 | ||||||||||||||||||
129 | PKCS7error(PKCS7_R_PKCS7_DATASIGN); | - | ||||||||||||||||||
130 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
131 | } | - | ||||||||||||||||||
132 | - | |||||||||||||||||||
133 | ret = 1; | - | ||||||||||||||||||
134 | - | |||||||||||||||||||
135 | err: code before this statement executed 3 times by 1 test: err: Executed by:
| 3 | ||||||||||||||||||
136 | BIO_free_all(p7bio); | - | ||||||||||||||||||
137 | - | |||||||||||||||||||
138 | return ret; executed 3 times by 1 test: return ret; Executed by:
| 3 | ||||||||||||||||||
139 | } | - | ||||||||||||||||||
140 | - | |||||||||||||||||||
141 | /* Check to see if a cipher exists and if so add S/MIME capabilities */ | - | ||||||||||||||||||
142 | - | |||||||||||||||||||
143 | static int | - | ||||||||||||||||||
144 | add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) | - | ||||||||||||||||||
145 | { | - | ||||||||||||||||||
146 | if (EVP_get_cipherbynid(nid))
| 0-18 | ||||||||||||||||||
147 | return PKCS7_simple_smimecap(sk, nid, arg); executed 18 times by 1 test: return PKCS7_simple_smimecap(sk, nid, arg); Executed by:
| 18 | ||||||||||||||||||
148 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
149 | } | - | ||||||||||||||||||
150 | - | |||||||||||||||||||
151 | static int | - | ||||||||||||||||||
152 | add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) | - | ||||||||||||||||||
153 | { | - | ||||||||||||||||||
154 | if (EVP_get_digestbynid(nid))
| 0-6 | ||||||||||||||||||
155 | return PKCS7_simple_smimecap(sk, nid, arg); executed 6 times by 1 test: return PKCS7_simple_smimecap(sk, nid, arg); Executed by:
| 6 | ||||||||||||||||||
156 | return 1; never executed: return 1; | 0 | ||||||||||||||||||
157 | } | - | ||||||||||||||||||
158 | - | |||||||||||||||||||
159 | PKCS7_SIGNER_INFO * | - | ||||||||||||||||||
160 | PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey, | - | ||||||||||||||||||
161 | const EVP_MD *md, int flags) | - | ||||||||||||||||||
162 | { | - | ||||||||||||||||||
163 | PKCS7_SIGNER_INFO *si = NULL; | - | ||||||||||||||||||
164 | STACK_OF(X509_ALGOR) *smcap = NULL; | - | ||||||||||||||||||
165 | - | |||||||||||||||||||
166 | if (!X509_check_private_key(signcert, pkey)) {
| 0-2 | ||||||||||||||||||
167 | PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | - | ||||||||||||||||||
168 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
169 | } | - | ||||||||||||||||||
170 | - | |||||||||||||||||||
171 | if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) {
| 0-2 | ||||||||||||||||||
172 | PKCS7error(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); | - | ||||||||||||||||||
173 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
174 | } | - | ||||||||||||||||||
175 | - | |||||||||||||||||||
176 | if (!(flags & PKCS7_NOCERTS)) {
| 0-2 | ||||||||||||||||||
177 | if (!PKCS7_add_certificate(p7, signcert))
| 0-2 | ||||||||||||||||||
178 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
179 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
180 | - | |||||||||||||||||||
181 | if (!(flags & PKCS7_NOATTR)) {
| 0-2 | ||||||||||||||||||
182 | if (!PKCS7_add_attrib_content_type(si, NULL))
| 0-2 | ||||||||||||||||||
183 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
184 | /* Add SMIMECapabilities */ | - | ||||||||||||||||||
185 | if (!(flags & PKCS7_NOSMIMECAP)) {
| 0-2 | ||||||||||||||||||
186 | if (!(smcap = sk_X509_ALGOR_new_null())) {
| 0-2 | ||||||||||||||||||
187 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
188 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
189 | } | - | ||||||||||||||||||
190 | if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
| 0-2 | ||||||||||||||||||
191 | !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) ||
| 0-2 | ||||||||||||||||||
192 | !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_256, -1) ||
| 0-2 | ||||||||||||||||||
193 | !add_digest_smcap(smcap, NID_id_tc26_gost3411_2012_512, -1) ||
| 0-2 | ||||||||||||||||||
194 | !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) ||
| 0-2 | ||||||||||||||||||
195 | !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
| 0-2 | ||||||||||||||||||
196 | !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) ||
| 0-2 | ||||||||||||||||||
197 | !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) ||
| 0-2 | ||||||||||||||||||
198 | !add_cipher_smcap(smcap, NID_rc2_cbc, 128) ||
| 0-2 | ||||||||||||||||||
199 | !add_cipher_smcap(smcap, NID_rc2_cbc, 64) ||
| 0-2 | ||||||||||||||||||
200 | !add_cipher_smcap(smcap, NID_des_cbc, -1) ||
| 0-2 | ||||||||||||||||||
201 | !add_cipher_smcap(smcap, NID_rc2_cbc, 40) ||
| 0-2 | ||||||||||||||||||
202 | !PKCS7_add_attrib_smimecap(si, smcap))
| 0-2 | ||||||||||||||||||
203 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
204 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); | - | ||||||||||||||||||
205 | smcap = NULL; | - | ||||||||||||||||||
206 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
207 | if (flags & PKCS7_REUSE_DIGEST) {
| 0-2 | ||||||||||||||||||
208 | if (!pkcs7_copy_existing_digest(p7, si))
| 0 | ||||||||||||||||||
209 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
210 | if (!(flags & PKCS7_PARTIAL) &&
| 0 | ||||||||||||||||||
211 | !PKCS7_SIGNER_INFO_sign(si))
| 0 | ||||||||||||||||||
212 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
213 | } never executed: end of block | 0 | ||||||||||||||||||
214 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
215 | return si; executed 2 times by 1 test: return si; Executed by:
| 2 | ||||||||||||||||||
216 | - | |||||||||||||||||||
217 | err: | - | ||||||||||||||||||
218 | if (smcap)
| 0 | ||||||||||||||||||
219 | sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); never executed: sk_pop_free(((_STACK*) (1 ? (smcap) : (struct stack_st_X509_ALGOR*)0)), ((void (*)(void *)) ((1 ? (X509_ALGOR_free) : (void (*)(X509_ALGOR *))0)))); | 0 | ||||||||||||||||||
220 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
221 | } | - | ||||||||||||||||||
222 | - | |||||||||||||||||||
223 | /* Search for a digest matching SignerInfo digest type and if found | - | ||||||||||||||||||
224 | * copy across. | - | ||||||||||||||||||
225 | */ | - | ||||||||||||||||||
226 | - | |||||||||||||||||||
227 | static int | - | ||||||||||||||||||
228 | pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) | - | ||||||||||||||||||
229 | { | - | ||||||||||||||||||
230 | int i; | - | ||||||||||||||||||
231 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | - | ||||||||||||||||||
232 | PKCS7_SIGNER_INFO *sitmp; | - | ||||||||||||||||||
233 | ASN1_OCTET_STRING *osdig = NULL; | - | ||||||||||||||||||
234 | - | |||||||||||||||||||
235 | sinfos = PKCS7_get_signer_info(p7); | - | ||||||||||||||||||
236 | for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
| 0 | ||||||||||||||||||
237 | sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); | - | ||||||||||||||||||
238 | if (si == sitmp)
| 0 | ||||||||||||||||||
239 | break; never executed: break; | 0 | ||||||||||||||||||
240 | if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
| 0 | ||||||||||||||||||
241 | continue; never executed: continue; | 0 | ||||||||||||||||||
242 | if (!OBJ_cmp(si->digest_alg->algorithm,
| 0 | ||||||||||||||||||
243 | sitmp->digest_alg->algorithm)) {
| 0 | ||||||||||||||||||
244 | osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); | - | ||||||||||||||||||
245 | break; never executed: break; | 0 | ||||||||||||||||||
246 | } | - | ||||||||||||||||||
247 | - | |||||||||||||||||||
248 | } never executed: end of block | 0 | ||||||||||||||||||
249 | - | |||||||||||||||||||
250 | if (osdig)
| 0 | ||||||||||||||||||
251 | return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); never executed: return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); | 0 | ||||||||||||||||||
252 | - | |||||||||||||||||||
253 | PKCS7error(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); | - | ||||||||||||||||||
254 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
255 | } | - | ||||||||||||||||||
256 | - | |||||||||||||||||||
257 | int | - | ||||||||||||||||||
258 | PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, | - | ||||||||||||||||||
259 | BIO *out, int flags) | - | ||||||||||||||||||
260 | { | - | ||||||||||||||||||
261 | STACK_OF(X509) *signers; | - | ||||||||||||||||||
262 | X509 *signer; | - | ||||||||||||||||||
263 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | - | ||||||||||||||||||
264 | PKCS7_SIGNER_INFO *si; | - | ||||||||||||||||||
265 | X509_STORE_CTX cert_ctx; | - | ||||||||||||||||||
266 | char buf[4096]; | - | ||||||||||||||||||
267 | int i, j = 0, k, ret = 0; | - | ||||||||||||||||||
268 | BIO *p7bio; | - | ||||||||||||||||||
269 | BIO *tmpin, *tmpout; | - | ||||||||||||||||||
270 | - | |||||||||||||||||||
271 | if (!p7) {
| 0-2 | ||||||||||||||||||
272 | PKCS7error(PKCS7_R_INVALID_NULL_POINTER); | - | ||||||||||||||||||
273 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
274 | } | - | ||||||||||||||||||
275 | - | |||||||||||||||||||
276 | if (!PKCS7_type_is_signed(p7)) {
| 0-2 | ||||||||||||||||||
277 | PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); | - | ||||||||||||||||||
278 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
279 | } | - | ||||||||||||||||||
280 | - | |||||||||||||||||||
281 | /* Check for no data and no content: no data to verify signature */ | - | ||||||||||||||||||
282 | if (PKCS7_get_detached(p7) && !indata) {
| 0-1 | ||||||||||||||||||
283 | PKCS7error(PKCS7_R_NO_CONTENT); | - | ||||||||||||||||||
284 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
285 | } | - | ||||||||||||||||||
286 | - | |||||||||||||||||||
287 | /* | - | ||||||||||||||||||
288 | * Very old Netscape illegally included empty content with | - | ||||||||||||||||||
289 | * a detached signature. Very old users should upgrade. | - | ||||||||||||||||||
290 | */ | - | ||||||||||||||||||
291 | /* Check for data and content: two sets of data */ | - | ||||||||||||||||||
292 | if (!PKCS7_get_detached(p7) && indata) {
| 0-1 | ||||||||||||||||||
293 | PKCS7error(PKCS7_R_CONTENT_AND_DATA_PRESENT); | - | ||||||||||||||||||
294 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
295 | } | - | ||||||||||||||||||
296 | - | |||||||||||||||||||
297 | sinfos = PKCS7_get_signer_info(p7); | - | ||||||||||||||||||
298 | - | |||||||||||||||||||
299 | if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
| 0-2 | ||||||||||||||||||
300 | PKCS7error(PKCS7_R_NO_SIGNATURES_ON_DATA); | - | ||||||||||||||||||
301 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
302 | } | - | ||||||||||||||||||
303 | - | |||||||||||||||||||
304 | - | |||||||||||||||||||
305 | signers = PKCS7_get0_signers(p7, certs, flags); | - | ||||||||||||||||||
306 | - | |||||||||||||||||||
307 | if (!signers)
| 0-2 | ||||||||||||||||||
308 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
309 | - | |||||||||||||||||||
310 | /* Now verify the certificates */ | - | ||||||||||||||||||
311 | - | |||||||||||||||||||
312 | if (!(flags & PKCS7_NOVERIFY))
| 0-2 | ||||||||||||||||||
313 | for (k = 0; k < sk_X509_num(signers); k++) {
| 2 | ||||||||||||||||||
314 | signer = sk_X509_value (signers, k); | - | ||||||||||||||||||
315 | if (!(flags & PKCS7_NOCHAIN)) {
| 0-2 | ||||||||||||||||||
316 | if (!X509_STORE_CTX_init(&cert_ctx, store,
| 0-2 | ||||||||||||||||||
317 | signer, p7->d.sign->cert)) {
| 0-2 | ||||||||||||||||||
318 | PKCS7error(ERR_R_X509_LIB); | - | ||||||||||||||||||
319 | sk_X509_free(signers); | - | ||||||||||||||||||
320 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
321 | } | - | ||||||||||||||||||
322 | if (X509_STORE_CTX_set_default(&cert_ctx,
| 0-2 | ||||||||||||||||||
323 | "smime_sign") == 0) {
| 0-2 | ||||||||||||||||||
324 | sk_X509_free(signers); | - | ||||||||||||||||||
325 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
326 | } | - | ||||||||||||||||||
327 | } else if (!X509_STORE_CTX_init(&cert_ctx, store, executed 2 times by 1 test: end of block Executed by:
| 0-2 | ||||||||||||||||||
328 | signer, NULL)) {
| 0 | ||||||||||||||||||
329 | PKCS7error(ERR_R_X509_LIB); | - | ||||||||||||||||||
330 | sk_X509_free(signers); | - | ||||||||||||||||||
331 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
332 | } | - | ||||||||||||||||||
333 | if (!(flags & PKCS7_NOCRL))
| 0-2 | ||||||||||||||||||
334 | X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); executed 2 times by 1 test: X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); Executed by:
| 2 | ||||||||||||||||||
335 | i = X509_verify_cert(&cert_ctx); | - | ||||||||||||||||||
336 | if (i <= 0)
| 0-2 | ||||||||||||||||||
337 | j = X509_STORE_CTX_get_error(&cert_ctx); never executed: j = X509_STORE_CTX_get_error(&cert_ctx); | 0 | ||||||||||||||||||
338 | X509_STORE_CTX_cleanup(&cert_ctx); | - | ||||||||||||||||||
339 | if (i <= 0) {
| 0-2 | ||||||||||||||||||
340 | PKCS7error(PKCS7_R_CERTIFICATE_VERIFY_ERROR); | - | ||||||||||||||||||
341 | ERR_asprintf_error_data("Verify error:%s", | - | ||||||||||||||||||
342 | X509_verify_cert_error_string(j)); | - | ||||||||||||||||||
343 | sk_X509_free(signers); | - | ||||||||||||||||||
344 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
345 | } | - | ||||||||||||||||||
346 | /* Check for revocation status here */ | - | ||||||||||||||||||
347 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
348 | - | |||||||||||||||||||
349 | /* | - | ||||||||||||||||||
350 | * Performance optimization: if the content is a memory BIO then | - | ||||||||||||||||||
351 | * store its contents in a temporary read only memory BIO. This | - | ||||||||||||||||||
352 | * avoids potentially large numbers of slow copies of data which will | - | ||||||||||||||||||
353 | * occur when reading from a read write memory BIO when signatures | - | ||||||||||||||||||
354 | * are calculated. | - | ||||||||||||||||||
355 | */ | - | ||||||||||||||||||
356 | if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
| 0-1 | ||||||||||||||||||
357 | char *ptr; | - | ||||||||||||||||||
358 | long len; | - | ||||||||||||||||||
359 | - | |||||||||||||||||||
360 | len = BIO_get_mem_data(indata, &ptr); | - | ||||||||||||||||||
361 | tmpin = BIO_new_mem_buf(ptr, len); | - | ||||||||||||||||||
362 | if (tmpin == NULL) {
| 0-1 | ||||||||||||||||||
363 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
364 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
365 | } | - | ||||||||||||||||||
366 | } else executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
367 | tmpin = indata; executed 1 time by 1 test: tmpin = indata; Executed by:
| 1 | ||||||||||||||||||
368 | - | |||||||||||||||||||
369 | - | |||||||||||||||||||
370 | if (!(p7bio = PKCS7_dataInit(p7, tmpin)))
| 0-2 | ||||||||||||||||||
371 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
372 | - | |||||||||||||||||||
373 | if (flags & PKCS7_TEXT) {
| 0-2 | ||||||||||||||||||
374 | if (!(tmpout = BIO_new(BIO_s_mem()))) {
| 0 | ||||||||||||||||||
375 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
376 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
377 | } | - | ||||||||||||||||||
378 | BIO_set_mem_eof_return(tmpout, 0); | - | ||||||||||||||||||
379 | } else never executed: end of block | 0 | ||||||||||||||||||
380 | tmpout = out; executed 2 times by 1 test: tmpout = out; Executed by:
| 2 | ||||||||||||||||||
381 | - | |||||||||||||||||||
382 | /* We now have to 'read' from p7bio to calculate digests etc. */ | - | ||||||||||||||||||
383 | for (;;) { | - | ||||||||||||||||||
384 | i = BIO_read(p7bio, buf, sizeof(buf)); | - | ||||||||||||||||||
385 | if (i <= 0)
| 2 | ||||||||||||||||||
386 | break; executed 2 times by 1 test: break; Executed by:
| 2 | ||||||||||||||||||
387 | if (tmpout)
| 0-2 | ||||||||||||||||||
388 | BIO_write(tmpout, buf, i); executed 2 times by 1 test: BIO_write(tmpout, buf, i); Executed by:
| 2 | ||||||||||||||||||
389 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
390 | - | |||||||||||||||||||
391 | if (flags & PKCS7_TEXT) {
| 0-2 | ||||||||||||||||||
392 | if (!SMIME_text(tmpout, out)) {
| 0 | ||||||||||||||||||
393 | PKCS7error(PKCS7_R_SMIME_TEXT_ERROR); | - | ||||||||||||||||||
394 | BIO_free(tmpout); | - | ||||||||||||||||||
395 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
396 | } | - | ||||||||||||||||||
397 | BIO_free(tmpout); | - | ||||||||||||||||||
398 | } never executed: end of block | 0 | ||||||||||||||||||
399 | - | |||||||||||||||||||
400 | /* Now Verify All Signatures */ | - | ||||||||||||||||||
401 | if (!(flags & PKCS7_NOSIGS))
| 0-2 | ||||||||||||||||||
402 | for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
| 2 | ||||||||||||||||||
403 | si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); | - | ||||||||||||||||||
404 | signer = sk_X509_value (signers, i); | - | ||||||||||||||||||
405 | j = PKCS7_signatureVerify(p7bio, p7, si, signer); | - | ||||||||||||||||||
406 | if (j <= 0) {
| 0-2 | ||||||||||||||||||
407 | PKCS7error(PKCS7_R_SIGNATURE_FAILURE); | - | ||||||||||||||||||
408 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
409 | } | - | ||||||||||||||||||
410 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
411 | - | |||||||||||||||||||
412 | ret = 1; | - | ||||||||||||||||||
413 | - | |||||||||||||||||||
414 | err: code before this statement executed 2 times by 1 test: err: Executed by:
| 2 | ||||||||||||||||||
415 | if (tmpin == indata) {
| 1 | ||||||||||||||||||
416 | if (indata)
| 0-1 | ||||||||||||||||||
417 | BIO_pop(p7bio); never executed: BIO_pop(p7bio); | 0 | ||||||||||||||||||
418 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
419 | BIO_free_all(p7bio); | - | ||||||||||||||||||
420 | sk_X509_free(signers); | - | ||||||||||||||||||
421 | - | |||||||||||||||||||
422 | return ret; executed 2 times by 1 test: return ret; Executed by:
| 2 | ||||||||||||||||||
423 | } | - | ||||||||||||||||||
424 | - | |||||||||||||||||||
425 | STACK_OF(X509) * | - | ||||||||||||||||||
426 | PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags) | - | ||||||||||||||||||
427 | { | - | ||||||||||||||||||
428 | STACK_OF(X509) *signers; | - | ||||||||||||||||||
429 | STACK_OF(PKCS7_SIGNER_INFO) *sinfos; | - | ||||||||||||||||||
430 | PKCS7_SIGNER_INFO *si; | - | ||||||||||||||||||
431 | PKCS7_ISSUER_AND_SERIAL *ias; | - | ||||||||||||||||||
432 | X509 *signer; | - | ||||||||||||||||||
433 | int i; | - | ||||||||||||||||||
434 | - | |||||||||||||||||||
435 | if (!p7) {
| 0-2 | ||||||||||||||||||
436 | PKCS7error(PKCS7_R_INVALID_NULL_POINTER); | - | ||||||||||||||||||
437 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
438 | } | - | ||||||||||||||||||
439 | - | |||||||||||||||||||
440 | if (!PKCS7_type_is_signed(p7)) {
| 0-2 | ||||||||||||||||||
441 | PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); | - | ||||||||||||||||||
442 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
443 | } | - | ||||||||||||||||||
444 | - | |||||||||||||||||||
445 | /* Collect all the signers together */ | - | ||||||||||||||||||
446 | sinfos = PKCS7_get_signer_info(p7); | - | ||||||||||||||||||
447 | if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
| 0-2 | ||||||||||||||||||
448 | PKCS7error(PKCS7_R_NO_SIGNERS); | - | ||||||||||||||||||
449 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
450 | } | - | ||||||||||||||||||
451 | - | |||||||||||||||||||
452 | if (!(signers = sk_X509_new_null())) {
| 0-2 | ||||||||||||||||||
453 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
454 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
455 | } | - | ||||||||||||||||||
456 | - | |||||||||||||||||||
457 | for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
| 2 | ||||||||||||||||||
458 | si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); | - | ||||||||||||||||||
459 | ias = si->issuer_and_serial; | - | ||||||||||||||||||
460 | signer = NULL; | - | ||||||||||||||||||
461 | /* If any certificates passed they take priority */ | - | ||||||||||||||||||
462 | if (certs)
| 0-2 | ||||||||||||||||||
463 | signer = X509_find_by_issuer_and_serial (certs, executed 2 times by 1 test: signer = X509_find_by_issuer_and_serial (certs, ias->issuer, ias->serial); Executed by:
| 2 | ||||||||||||||||||
464 | ias->issuer, ias->serial); executed 2 times by 1 test: signer = X509_find_by_issuer_and_serial (certs, ias->issuer, ias->serial); Executed by:
| 2 | ||||||||||||||||||
465 | if (!signer && !(flags & PKCS7_NOINTERN) && p7->d.sign->cert)
| 0-2 | ||||||||||||||||||
466 | signer = never executed: signer = X509_find_by_issuer_and_serial(p7->d.sign->cert, ias->issuer, ias->serial); | 0 | ||||||||||||||||||
467 | X509_find_by_issuer_and_serial(p7->d.sign->cert, never executed: signer = X509_find_by_issuer_and_serial(p7->d.sign->cert, ias->issuer, ias->serial); | 0 | ||||||||||||||||||
468 | ias->issuer, ias->serial); never executed: signer = X509_find_by_issuer_and_serial(p7->d.sign->cert, ias->issuer, ias->serial); | 0 | ||||||||||||||||||
469 | if (!signer) {
| 0-2 | ||||||||||||||||||
470 | PKCS7error(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); | - | ||||||||||||||||||
471 | sk_X509_free(signers); | - | ||||||||||||||||||
472 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
473 | } | - | ||||||||||||||||||
474 | - | |||||||||||||||||||
475 | if (!sk_X509_push(signers, signer)) {
| 0-2 | ||||||||||||||||||
476 | sk_X509_free(signers); | - | ||||||||||||||||||
477 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
478 | } | - | ||||||||||||||||||
479 | } executed 2 times by 1 test: end of block Executed by:
| 2 | ||||||||||||||||||
480 | return signers; executed 2 times by 1 test: return signers; Executed by:
| 2 | ||||||||||||||||||
481 | } | - | ||||||||||||||||||
482 | - | |||||||||||||||||||
483 | /* Build a complete PKCS#7 enveloped data */ | - | ||||||||||||||||||
484 | - | |||||||||||||||||||
485 | PKCS7 * | - | ||||||||||||||||||
486 | PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, | - | ||||||||||||||||||
487 | int flags) | - | ||||||||||||||||||
488 | { | - | ||||||||||||||||||
489 | PKCS7 *p7; | - | ||||||||||||||||||
490 | BIO *p7bio = NULL; | - | ||||||||||||||||||
491 | int i; | - | ||||||||||||||||||
492 | X509 *x509; | - | ||||||||||||||||||
493 | - | |||||||||||||||||||
494 | if (!(p7 = PKCS7_new())) {
| 0-1 | ||||||||||||||||||
495 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
496 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
497 | } | - | ||||||||||||||||||
498 | - | |||||||||||||||||||
499 | if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
| 0-1 | ||||||||||||||||||
500 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
501 | if (!PKCS7_set_cipher(p7, cipher)) {
| 0-1 | ||||||||||||||||||
502 | PKCS7error(PKCS7_R_ERROR_SETTING_CIPHER); | - | ||||||||||||||||||
503 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
504 | } | - | ||||||||||||||||||
505 | - | |||||||||||||||||||
506 | for (i = 0; i < sk_X509_num(certs); i++) {
| 1 | ||||||||||||||||||
507 | x509 = sk_X509_value(certs, i); | - | ||||||||||||||||||
508 | if (!PKCS7_add_recipient(p7, x509)) {
| 0-1 | ||||||||||||||||||
509 | PKCS7error(PKCS7_R_ERROR_ADDING_RECIPIENT); | - | ||||||||||||||||||
510 | goto err; never executed: goto err; | 0 | ||||||||||||||||||
511 | } | - | ||||||||||||||||||
512 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
513 | - | |||||||||||||||||||
514 | if (flags & PKCS7_STREAM)
| 0-1 | ||||||||||||||||||
515 | return p7; never executed: return p7; | 0 | ||||||||||||||||||
516 | - | |||||||||||||||||||
517 | if (PKCS7_final(p7, in, flags))
| 0-1 | ||||||||||||||||||
518 | return p7; executed 1 time by 1 test: return p7; Executed by:
| 1 | ||||||||||||||||||
519 | - | |||||||||||||||||||
520 | err: code before this statement never executed: err: | 0 | ||||||||||||||||||
521 | BIO_free_all(p7bio); | - | ||||||||||||||||||
522 | PKCS7_free(p7); | - | ||||||||||||||||||
523 | return NULL; never executed: return ((void *)0) ; | 0 | ||||||||||||||||||
524 | } | - | ||||||||||||||||||
525 | - | |||||||||||||||||||
526 | int | - | ||||||||||||||||||
527 | PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) | - | ||||||||||||||||||
528 | { | - | ||||||||||||||||||
529 | BIO *tmpmem; | - | ||||||||||||||||||
530 | int ret, i; | - | ||||||||||||||||||
531 | char buf[4096]; | - | ||||||||||||||||||
532 | - | |||||||||||||||||||
533 | if (!p7) {
| 0-1 | ||||||||||||||||||
534 | PKCS7error(PKCS7_R_INVALID_NULL_POINTER); | - | ||||||||||||||||||
535 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
536 | } | - | ||||||||||||||||||
537 | - | |||||||||||||||||||
538 | if (!PKCS7_type_is_enveloped(p7)) {
| 0-1 | ||||||||||||||||||
539 | PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE); | - | ||||||||||||||||||
540 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
541 | } | - | ||||||||||||||||||
542 | - | |||||||||||||||||||
543 | if (cert && !X509_check_private_key(cert, pkey)) {
| 0-1 | ||||||||||||||||||
544 | PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); | - | ||||||||||||||||||
545 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
546 | } | - | ||||||||||||||||||
547 | - | |||||||||||||||||||
548 | if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
| 0-1 | ||||||||||||||||||
549 | PKCS7error(PKCS7_R_DECRYPT_ERROR); | - | ||||||||||||||||||
550 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
551 | } | - | ||||||||||||||||||
552 | - | |||||||||||||||||||
553 | if (flags & PKCS7_TEXT) {
| 0-1 | ||||||||||||||||||
554 | BIO *tmpbuf; | - | ||||||||||||||||||
555 | - | |||||||||||||||||||
556 | /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ | - | ||||||||||||||||||
557 | if (!(tmpbuf = BIO_new(BIO_f_buffer()))) {
| 0 | ||||||||||||||||||
558 | PKCS7error(ERR_R_MALLOC_FAILURE); | - | ||||||||||||||||||
559 | BIO_free_all(tmpmem); | - | ||||||||||||||||||
560 | return 0; never executed: return 0; | 0 | ||||||||||||||||||
561 | } | - | ||||||||||||||||||
562 | BIO_push(tmpbuf, tmpmem); | - | ||||||||||||||||||
563 | ret = SMIME_text(tmpbuf, data); | - | ||||||||||||||||||
564 | if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
| 0 | ||||||||||||||||||
565 | if (!BIO_get_cipher_status(tmpmem))
| 0 | ||||||||||||||||||
566 | ret = 0; never executed: ret = 0; | 0 | ||||||||||||||||||
567 | } never executed: end of block | 0 | ||||||||||||||||||
568 | BIO_free_all(tmpbuf); | - | ||||||||||||||||||
569 | return ret; never executed: return ret; | 0 | ||||||||||||||||||
570 | } else { | - | ||||||||||||||||||
571 | for (;;) { | - | ||||||||||||||||||
572 | i = BIO_read(tmpmem, buf, sizeof(buf)); | - | ||||||||||||||||||
573 | if (i <= 0) {
| 1 | ||||||||||||||||||
574 | ret = 1; | - | ||||||||||||||||||
575 | if (BIO_method_type(tmpmem) ==
| 0-1 | ||||||||||||||||||
576 | BIO_TYPE_CIPHER) {
| 0-1 | ||||||||||||||||||
577 | if (!BIO_get_cipher_status(tmpmem))
| 0-1 | ||||||||||||||||||
578 | ret = 0; never executed: ret = 0; | 0 | ||||||||||||||||||
579 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
580 | break; executed 1 time by 1 test: break; Executed by:
| 1 | ||||||||||||||||||
581 | } | - | ||||||||||||||||||
582 | if (BIO_write(data, buf, i) != i) {
| 0-1 | ||||||||||||||||||
583 | ret = 0; | - | ||||||||||||||||||
584 | break; never executed: break; | 0 | ||||||||||||||||||
585 | } | - | ||||||||||||||||||
586 | } executed 1 time by 1 test: end of block Executed by:
| 1 | ||||||||||||||||||
587 | BIO_free_all(tmpmem); | - | ||||||||||||||||||
588 | return ret; executed 1 time by 1 test: return ret; Executed by:
| 1 | ||||||||||||||||||
589 | } | - | ||||||||||||||||||
590 | } | - | ||||||||||||||||||
Source code | Switch to Preprocessed file |