summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7/pk7_smime.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c444
1 files changed, 216 insertions, 228 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
index 692967e72e..5d174f7644 100644
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_smime.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pk7_smime.c,v 1.14 2014/06/12 15:49:30 deraadt Exp $ */ 1/* $OpenBSD: pk7_smime.c,v 1.15 2014/06/29 17:05:36 jsing Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project. 3 * project.
4 */ 4 */
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -65,17 +65,17 @@
65 65
66static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); 66static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
67 67
68PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 68PKCS7 *
69 BIO *data, int flags) 69PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data,
70 int flags)
70{ 71{
71 PKCS7 *p7; 72 PKCS7 *p7;
72 int i; 73 int i;
73 74
74 if(!(p7 = PKCS7_new())) 75 if (!(p7 = PKCS7_new())) {
75 { 76 PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE);
76 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
77 return NULL; 77 return NULL;
78 } 78 }
79 79
80 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 80 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
81 goto err; 81 goto err;
@@ -83,22 +83,19 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
83 if (!PKCS7_content_new(p7, NID_pkcs7_data)) 83 if (!PKCS7_content_new(p7, NID_pkcs7_data))
84 goto err; 84 goto err;
85 85
86 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) 86 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
87 { 87 PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
88 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
89 goto err; 88 goto err;
90 } 89 }
91 90
92 if(!(flags & PKCS7_NOCERTS)) 91 if (!(flags & PKCS7_NOCERTS)) {
93 { 92 for (i = 0; i < sk_X509_num(certs); i++) {
94 for(i = 0; i < sk_X509_num(certs); i++)
95 {
96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 93 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
97 goto err; 94 goto err;
98 }
99 } 95 }
96 }
100 97
101 if(flags & PKCS7_DETACHED) 98 if (flags & PKCS7_DETACHED)
102 PKCS7_set_detached(p7, 1); 99 PKCS7_set_detached(p7, 1);
103 100
104 if (flags & (PKCS7_STREAM|PKCS7_PARTIAL)) 101 if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
@@ -107,164 +104,160 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
107 if (PKCS7_final(p7, data, flags)) 104 if (PKCS7_final(p7, data, flags))
108 return p7; 105 return p7;
109 106
110 err: 107err:
111 PKCS7_free(p7); 108 PKCS7_free(p7);
112 return NULL; 109 return NULL;
113} 110}
114 111
115int PKCS7_final(PKCS7 *p7, BIO *data, int flags) 112int
116 { 113PKCS7_final(PKCS7 *p7, BIO *data, int flags)
114{
117 BIO *p7bio; 115 BIO *p7bio;
118 int ret = 0; 116 int ret = 0;
119 if (!(p7bio = PKCS7_dataInit(p7, NULL))) 117
120 { 118 if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
121 PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE); 119 PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE);
122 return 0; 120 return 0;
123 } 121 }
124 122
125 SMIME_crlf_copy(data, p7bio, flags); 123 SMIME_crlf_copy(data, p7bio, flags);
126 124
127 (void)BIO_flush(p7bio); 125 (void)BIO_flush(p7bio);
128 126
129 127 if (!PKCS7_dataFinal(p7, p7bio)) {
130 if (!PKCS7_dataFinal(p7,p7bio)) 128 PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN);
131 {
132 PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
133 goto err; 129 goto err;
134 } 130 }
135 131
136 ret = 1; 132 ret = 1;
137 133
138 err: 134err:
139 BIO_free_all(p7bio); 135 BIO_free_all(p7bio);
140 136
141 return ret; 137 return ret;
142 138}
143 }
144 139
145/* Check to see if a cipher exists and if so add S/MIME capabilities */ 140/* Check to see if a cipher exists and if so add S/MIME capabilities */
146 141
147static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 142static int
148 { 143add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
144{
149 if (EVP_get_cipherbynid(nid)) 145 if (EVP_get_cipherbynid(nid))
150 return PKCS7_simple_smimecap(sk, nid, arg); 146 return PKCS7_simple_smimecap(sk, nid, arg);
151 return 1; 147 return 1;
152 } 148}
153 149
154static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) 150static int
155 { 151add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
152{
156 if (EVP_get_digestbynid(nid)) 153 if (EVP_get_digestbynid(nid))
157 return PKCS7_simple_smimecap(sk, nid, arg); 154 return PKCS7_simple_smimecap(sk, nid, arg);
158 return 1; 155 return 1;
159 } 156}
160 157
161PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, 158PKCS7_SIGNER_INFO *
162 EVP_PKEY *pkey, const EVP_MD *md, 159PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey,
163 int flags) 160 const EVP_MD *md, int flags)
164 { 161{
165 PKCS7_SIGNER_INFO *si = NULL; 162 PKCS7_SIGNER_INFO *si = NULL;
166 STACK_OF(X509_ALGOR) *smcap = NULL; 163 STACK_OF(X509_ALGOR) *smcap = NULL;
167 if(!X509_check_private_key(signcert, pkey)) 164
168 { 165 if (!X509_check_private_key(signcert, pkey)) {
169 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 166 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
170 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 167 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
171 return NULL; 168 return NULL;
172 } 169 }
173 170
174 if (!(si = PKCS7_add_signature(p7,signcert,pkey, md))) 171 if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) {
175 {
176 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 172 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
177 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 173 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
178 return NULL; 174 return NULL;
179 } 175 }
180 176
181 if(!(flags & PKCS7_NOCERTS)) 177 if (!(flags & PKCS7_NOCERTS)) {
182 {
183 if (!PKCS7_add_certificate(p7, signcert)) 178 if (!PKCS7_add_certificate(p7, signcert))
184 goto err; 179 goto err;
185 } 180 }
186 181
187 if(!(flags & PKCS7_NOATTR)) 182 if (!(flags & PKCS7_NOATTR)) {
188 {
189 if (!PKCS7_add_attrib_content_type(si, NULL)) 183 if (!PKCS7_add_attrib_content_type(si, NULL))
190 goto err; 184 goto err;
191 /* Add SMIMECapabilities */ 185 /* Add SMIMECapabilities */
192 if(!(flags & PKCS7_NOSMIMECAP)) 186 if (!(flags & PKCS7_NOSMIMECAP)) {
193 { 187 if (!(smcap = sk_X509_ALGOR_new_null())) {
194 if(!(smcap = sk_X509_ALGOR_new_null()))
195 {
196 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, 188 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
197 ERR_R_MALLOC_FAILURE); 189 ERR_R_MALLOC_FAILURE);
198 goto err; 190 goto err;
199 } 191 }
200 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) 192 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
201 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) 193 !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) ||
202 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) 194 !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) ||
203 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) 195 !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
204 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) 196 !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) ||
205 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) 197 !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) ||
206 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) 198 !add_cipher_smcap(smcap, NID_rc2_cbc, 128) ||
207 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) 199 !add_cipher_smcap(smcap, NID_rc2_cbc, 64) ||
208 || !add_cipher_smcap(smcap, NID_des_cbc, -1) 200 !add_cipher_smcap(smcap, NID_des_cbc, -1) ||
209 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) 201 !add_cipher_smcap(smcap, NID_rc2_cbc, 40) ||
210 || !PKCS7_add_attrib_smimecap (si, smcap)) 202 !PKCS7_add_attrib_smimecap (si, smcap))
211 goto err; 203 goto err;
212 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 204 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
213 smcap = NULL; 205 smcap = NULL;
214 } 206 }
215 if (flags & PKCS7_REUSE_DIGEST) 207 if (flags & PKCS7_REUSE_DIGEST) {
216 {
217 if (!pkcs7_copy_existing_digest(p7, si)) 208 if (!pkcs7_copy_existing_digest(p7, si))
218 goto err; 209 goto err;
219 if (!(flags & PKCS7_PARTIAL) && 210 if (!(flags & PKCS7_PARTIAL) &&
220 !PKCS7_SIGNER_INFO_sign(si)) 211 !PKCS7_SIGNER_INFO_sign(si))
221 goto err; 212 goto err;
222 }
223 } 213 }
214 }
224 return si; 215 return si;
225 err: 216
217err:
226 if (smcap) 218 if (smcap)
227 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 219 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
228 return NULL; 220 return NULL;
229 } 221}
230 222
231/* Search for a digest matching SignerInfo digest type and if found 223/* Search for a digest matching SignerInfo digest type and if found
232 * copy across. 224 * copy across.
233 */ 225 */
234 226
235static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 227static int
236 { 228pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
229{
237 int i; 230 int i;
238 STACK_OF(PKCS7_SIGNER_INFO) *sinfos; 231 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
239 PKCS7_SIGNER_INFO *sitmp; 232 PKCS7_SIGNER_INFO *sitmp;
240 ASN1_OCTET_STRING *osdig = NULL; 233 ASN1_OCTET_STRING *osdig = NULL;
234
241 sinfos = PKCS7_get_signer_info(p7); 235 sinfos = PKCS7_get_signer_info(p7);
242 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 236 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
243 {
244 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 237 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
245 if (si == sitmp) 238 if (si == sitmp)
246 break; 239 break;
247 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) 240 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
248 continue; 241 continue;
249 if (!OBJ_cmp(si->digest_alg->algorithm, 242 if (!OBJ_cmp(si->digest_alg->algorithm,
250 sitmp->digest_alg->algorithm)) 243 sitmp->digest_alg->algorithm)) {
251 {
252 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); 244 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
253 break; 245 break;
254 }
255
256 } 246 }
257 247
248 }
249
258 if (osdig) 250 if (osdig)
259 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); 251 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
260 252
261 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, 253 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
262 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); 254 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
263 return 0; 255 return 0;
264 } 256}
265 257
266int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 258int
267 BIO *indata, BIO *out, int flags) 259PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata,
260 BIO *out, int flags)
268{ 261{
269 STACK_OF(X509) *signers; 262 STACK_OF(X509) *signers;
270 X509 *signer; 263 X509 *signer;
@@ -272,23 +265,23 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
272 PKCS7_SIGNER_INFO *si; 265 PKCS7_SIGNER_INFO *si;
273 X509_STORE_CTX cert_ctx; 266 X509_STORE_CTX cert_ctx;
274 char buf[4096]; 267 char buf[4096];
275 int i, j=0, k, ret = 0; 268 int i, j = 0, k, ret = 0;
276 BIO *p7bio; 269 BIO *p7bio;
277 BIO *tmpin, *tmpout; 270 BIO *tmpin, *tmpout;
278 271
279 if(!p7) { 272 if (!p7) {
280 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_INVALID_NULL_POINTER); 273 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER);
281 return 0; 274 return 0;
282 } 275 }
283 276
284 if(!PKCS7_type_is_signed(p7)) { 277 if (!PKCS7_type_is_signed(p7)) {
285 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_WRONG_CONTENT_TYPE); 278 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE);
286 return 0; 279 return 0;
287 } 280 }
288 281
289 /* Check for no data and no content: no data to verify signature */ 282 /* Check for no data and no content: no data to verify signature */
290 if(PKCS7_get_detached(p7) && !indata) { 283 if (PKCS7_get_detached(p7) && !indata) {
291 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_CONTENT); 284 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT);
292 return 0; 285 return 0;
293 } 286 }
294#if 0 287#if 0
@@ -297,56 +290,58 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
297 */ 290 */
298 291
299 /* Check for data and content: two sets of data */ 292 /* Check for data and content: two sets of data */
300 if(!PKCS7_get_detached(p7) && indata) { 293 if (!PKCS7_get_detached(p7) && indata) {
301 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CONTENT_AND_DATA_PRESENT); 294 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT);
302 return 0; 295 return 0;
303 } 296 }
304#endif 297#endif
305 298
306 sinfos = PKCS7_get_signer_info(p7); 299 sinfos = PKCS7_get_signer_info(p7);
307 300
308 if(!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { 301 if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
309 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_NO_SIGNATURES_ON_DATA); 302 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA);
310 return 0; 303 return 0;
311 } 304 }
312 305
313 306
314 signers = PKCS7_get0_signers(p7, certs, flags); 307 signers = PKCS7_get0_signers(p7, certs, flags);
315 308
316 if(!signers) return 0; 309 if (!signers)
310 return 0;
317 311
318 /* Now verify the certificates */ 312 /* Now verify the certificates */
319 313
320 if (!(flags & PKCS7_NOVERIFY)) for (k = 0; k < sk_X509_num(signers); k++) { 314 if (!(flags & PKCS7_NOVERIFY))
321 signer = sk_X509_value (signers, k); 315 for (k = 0; k < sk_X509_num(signers); k++) {
322 if (!(flags & PKCS7_NOCHAIN)) { 316 signer = sk_X509_value (signers, k);
323 if(!X509_STORE_CTX_init(&cert_ctx, store, signer, 317 if (!(flags & PKCS7_NOCHAIN)) {
324 p7->d.sign->cert)) 318 if (!X509_STORE_CTX_init(&cert_ctx, store, signer,
325 { 319 p7->d.sign->cert)) {
326 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB); 320 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
321 sk_X509_free(signers);
322 return 0;
323 }
324 X509_STORE_CTX_set_default(&cert_ctx, "smime_sign");
325 } else if (!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) {
326 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB);
327 sk_X509_free(signers); 327 sk_X509_free(signers);
328 return 0; 328 return 0;
329 } 329 }
330 X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); 330 if (!(flags & PKCS7_NOCRL))
331 } else if(!X509_STORE_CTX_init (&cert_ctx, store, signer, NULL)) { 331 X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
332 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_X509_LIB); 332 i = X509_verify_cert(&cert_ctx);
333 sk_X509_free(signers); 333 if (i <= 0)
334 return 0; 334 j = X509_STORE_CTX_get_error(&cert_ctx);
335 } 335 X509_STORE_CTX_cleanup(&cert_ctx);
336 if (!(flags & PKCS7_NOCRL)) 336 if (i <= 0) {
337 X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); 337 PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CERTIFICATE_VERIFY_ERROR);
338 i = X509_verify_cert(&cert_ctx); 338 ERR_asprintf_error_data("Verify error:%s",
339 if (i <= 0) j = X509_STORE_CTX_get_error(&cert_ctx); 339 X509_verify_cert_error_string(j));
340 X509_STORE_CTX_cleanup(&cert_ctx); 340 sk_X509_free(signers);
341 if (i <= 0) { 341 return 0;
342 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_CERTIFICATE_VERIFY_ERROR); 342 }
343 ERR_asprintf_error_data("Verify error:%s", 343 /* Check for revocation status here */
344 X509_verify_cert_error_string(j));
345 sk_X509_free(signers);
346 return 0;
347 } 344 }
348 /* Check for revocation status here */
349 }
350 345
351 /* Performance optimization: if the content is a memory BIO then 346 /* Performance optimization: if the content is a memory BIO then
352 * store its contents in a temporary read only memory BIO. This 347 * store its contents in a temporary read only memory BIO. This
@@ -354,45 +349,43 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
354 * occur when reading from a read write memory BIO when signatures 349 * occur when reading from a read write memory BIO when signatures
355 * are calculated. 350 * are calculated.
356 */ 351 */
357 352 if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
358 if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM))
359 {
360 char *ptr; 353 char *ptr;
361 long len; 354 long len;
362 len = BIO_get_mem_data(indata, &ptr); 355 len = BIO_get_mem_data(indata, &ptr);
363 tmpin = BIO_new_mem_buf(ptr, len); 356 tmpin = BIO_new_mem_buf(ptr, len);
364 if (tmpin == NULL) 357 if (tmpin == NULL) {
365 { 358 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
366 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE);
367 return 0; 359 return 0;
368 }
369 } 360 }
370 else 361 } else
371 tmpin = indata; 362 tmpin = indata;
372
373 363
374 if (!(p7bio=PKCS7_dataInit(p7,tmpin))) 364
365 if (!(p7bio = PKCS7_dataInit(p7, tmpin)))
375 goto err; 366 goto err;
376 367
377 if(flags & PKCS7_TEXT) { 368 if (flags & PKCS7_TEXT) {
378 if(!(tmpout = BIO_new(BIO_s_mem()))) { 369 if (!(tmpout = BIO_new(BIO_s_mem()))) {
379 PKCS7err(PKCS7_F_PKCS7_VERIFY,ERR_R_MALLOC_FAILURE); 370 PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE);
380 goto err; 371 goto err;
381 } 372 }
382 BIO_set_mem_eof_return(tmpout, 0); 373 BIO_set_mem_eof_return(tmpout, 0);
383 } else tmpout = out; 374 } else tmpout = out;
384 375
385 /* We now have to 'read' from p7bio to calculate digests etc. */ 376 /* We now have to 'read' from p7bio to calculate digests etc. */
386 for (;;) 377 for (;;) {
387 { 378 i = BIO_read(p7bio, buf, sizeof(buf));
388 i=BIO_read(p7bio,buf,sizeof(buf)); 379 if (i <= 0)
389 if (i <= 0) break; 380 break;
390 if (tmpout) BIO_write(tmpout, buf, i); 381 if (tmpout)
382 BIO_write(tmpout, buf, i);
391 } 383 }
392 384
393 if(flags & PKCS7_TEXT) { 385 if (flags & PKCS7_TEXT) {
394 if(!SMIME_text(tmpout, out)) { 386 if (!SMIME_text(tmpout, out)) {
395 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SMIME_TEXT_ERROR); 387 PKCS7err(PKCS7_F_PKCS7_VERIFY,
388 PKCS7_R_SMIME_TEXT_ERROR);
396 BIO_free(tmpout); 389 BIO_free(tmpout);
397 goto err; 390 goto err;
398 } 391 }
@@ -401,25 +394,24 @@ int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
401 394
402 /* Now Verify All Signatures */ 395 /* Now Verify All Signatures */
403 if (!(flags & PKCS7_NOSIGS)) 396 if (!(flags & PKCS7_NOSIGS))
404 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 397 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
405 { 398 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
406 si=sk_PKCS7_SIGNER_INFO_value(sinfos,i);
407 signer = sk_X509_value (signers, i); 399 signer = sk_X509_value (signers, i);
408 j=PKCS7_signatureVerify(p7bio,p7,si, signer); 400 j = PKCS7_signatureVerify(p7bio, p7, si, signer);
409 if (j <= 0) { 401 if (j <= 0) {
410 PKCS7err(PKCS7_F_PKCS7_VERIFY,PKCS7_R_SIGNATURE_FAILURE); 402 PKCS7err(PKCS7_F_PKCS7_VERIFY,
403 PKCS7_R_SIGNATURE_FAILURE);
411 goto err; 404 goto err;
412 } 405 }
413 } 406 }
414 407
415 ret = 1; 408 ret = 1;
416 409
417 err: 410err:
418 411 if (tmpin == indata) {
419 if (tmpin == indata) 412 if (indata)
420 { 413 BIO_pop(p7bio);
421 if (indata) BIO_pop(p7bio); 414 }
422 }
423 BIO_free_all(p7bio); 415 BIO_free_all(p7bio);
424 416
425 sk_X509_free(signers); 417 sk_X509_free(signers);
@@ -436,83 +428,84 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
436 X509 *signer; 428 X509 *signer;
437 int i; 429 int i;
438 430
439 if(!p7) { 431 if (!p7) {
440 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_INVALID_NULL_POINTER); 432 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
433 PKCS7_R_INVALID_NULL_POINTER);
441 return NULL; 434 return NULL;
442 } 435 }
443 436
444 if(!PKCS7_type_is_signed(p7)) { 437 if (!PKCS7_type_is_signed(p7)) {
445 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_WRONG_CONTENT_TYPE); 438 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
439 PKCS7_R_WRONG_CONTENT_TYPE);
446 return NULL; 440 return NULL;
447 } 441 }
448 442
449 /* Collect all the signers together */ 443 /* Collect all the signers together */
450
451 sinfos = PKCS7_get_signer_info(p7); 444 sinfos = PKCS7_get_signer_info(p7);
452 445 if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
453 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 446 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS);
454 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
455 return 0; 447 return 0;
456 } 448 }
457 449
458 if(!(signers = sk_X509_new_null())) { 450 if (!(signers = sk_X509_new_null())) {
459 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,ERR_R_MALLOC_FAILURE); 451 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE);
460 return NULL; 452 return NULL;
461 } 453 }
462 454
463 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) 455 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
464 { 456 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
465 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); 457 ias = si->issuer_and_serial;
466 ias = si->issuer_and_serial; 458 signer = NULL;
467 signer = NULL;
468 /* If any certificates passed they take priority */ 459 /* If any certificates passed they take priority */
469 if (certs) signer = X509_find_by_issuer_and_serial (certs, 460 if (certs) signer = X509_find_by_issuer_and_serial (certs,
470 ias->issuer, ias->serial); 461 ias->issuer, ias->serial);
471 if (!signer && !(flags & PKCS7_NOINTERN) 462 if (!signer && !(flags & PKCS7_NOINTERN) &&
472 && p7->d.sign->cert) signer = 463 p7->d.sign->cert) signer =
473 X509_find_by_issuer_and_serial (p7->d.sign->cert, 464 X509_find_by_issuer_and_serial (p7->d.sign->cert,
474 ias->issuer, ias->serial); 465 ias->issuer, ias->serial);
475 if (!signer) { 466 if (!signer) {
476 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); 467 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,
468 PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
477 sk_X509_free(signers); 469 sk_X509_free(signers);
478 return 0; 470 return 0;
479 } 471 }
480 472
481 if (!sk_X509_push(signers, signer)) { 473 if (!sk_X509_push(signers, signer)) {
482 sk_X509_free(signers); 474 sk_X509_free(signers);
483 return NULL; 475 return NULL;
484 } 476 }
485 } 477 }
486 return signers; 478 return signers;
487} 479}
488 480
489
490/* Build a complete PKCS#7 enveloped data */ 481/* Build a complete PKCS#7 enveloped data */
491 482
492PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, 483PKCS7 *
493 int flags) 484PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
485 int flags)
494{ 486{
495 PKCS7 *p7; 487 PKCS7 *p7;
496 BIO *p7bio = NULL; 488 BIO *p7bio = NULL;
497 int i; 489 int i;
498 X509 *x509; 490 X509 *x509;
499 if(!(p7 = PKCS7_new())) { 491
500 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 492 if (!(p7 = PKCS7_new())) {
493 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE);
501 return NULL; 494 return NULL;
502 } 495 }
503 496
504 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 497 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
505 goto err; 498 goto err;
506 if (!PKCS7_set_cipher(p7, cipher)) { 499 if (!PKCS7_set_cipher(p7, cipher)) {
507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); 500 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER);
508 goto err; 501 goto err;
509 } 502 }
510 503
511 for(i = 0; i < sk_X509_num(certs); i++) { 504 for (i = 0; i < sk_X509_num(certs); i++) {
512 x509 = sk_X509_value(certs, i); 505 x509 = sk_X509_value(certs, i);
513 if(!PKCS7_add_recipient(p7, x509)) { 506 if (!PKCS7_add_recipient(p7, x509)) {
514 PKCS7err(PKCS7_F_PKCS7_ENCRYPT, 507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,
515 PKCS7_R_ERROR_ADDING_RECIPIENT); 508 PKCS7_R_ERROR_ADDING_RECIPIENT);
516 goto err; 509 goto err;
517 } 510 }
518 } 511 }
@@ -523,37 +516,36 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
523 if (PKCS7_final(p7, in, flags)) 516 if (PKCS7_final(p7, in, flags))
524 return p7; 517 return p7;
525 518
526 err: 519err:
527
528 BIO_free_all(p7bio); 520 BIO_free_all(p7bio);
529 PKCS7_free(p7); 521 PKCS7_free(p7);
530 return NULL; 522 return NULL;
531
532} 523}
533 524
534int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) 525int
526PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
535{ 527{
536 BIO *tmpmem; 528 BIO *tmpmem;
537 int ret, i; 529 int ret, i;
538 char buf[4096]; 530 char buf[4096];
539 531
540 if(!p7) { 532 if (!p7) {
541 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_INVALID_NULL_POINTER); 533 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER);
542 return 0; 534 return 0;
543 } 535 }
544 536
545 if(!PKCS7_type_is_enveloped(p7)) { 537 if (!PKCS7_type_is_enveloped(p7)) {
546 PKCS7err(PKCS7_F_PKCS7_DECRYPT,PKCS7_R_WRONG_CONTENT_TYPE); 538 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE);
547 return 0; 539 return 0;
548 } 540 }
549 541
550 if(cert && !X509_check_private_key(cert, pkey)) { 542 if (cert && !X509_check_private_key(cert, pkey)) {
551 PKCS7err(PKCS7_F_PKCS7_DECRYPT, 543 PKCS7err(PKCS7_F_PKCS7_DECRYPT,
552 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 544 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
553 return 0; 545 return 0;
554 } 546 }
555 547
556 if(!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { 548 if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
557 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); 549 PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR);
558 return 0; 550 return 0;
559 } 551 }
@@ -561,44 +553,40 @@ int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
561 if (flags & PKCS7_TEXT) { 553 if (flags & PKCS7_TEXT) {
562 BIO *tmpbuf, *bread; 554 BIO *tmpbuf, *bread;
563 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ 555 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
564 if(!(tmpbuf = BIO_new(BIO_f_buffer()))) { 556 if (!(tmpbuf = BIO_new(BIO_f_buffer()))) {
565 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 557 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
566 BIO_free_all(tmpmem); 558 BIO_free_all(tmpmem);
567 return 0; 559 return 0;
568 } 560 }
569 if(!(bread = BIO_push(tmpbuf, tmpmem))) { 561 if (!(bread = BIO_push(tmpbuf, tmpmem))) {
570 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); 562 PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE);
571 BIO_free_all(tmpbuf); 563 BIO_free_all(tmpbuf);
572 BIO_free_all(tmpmem); 564 BIO_free_all(tmpmem);
573 return 0; 565 return 0;
574 } 566 }
575 ret = SMIME_text(bread, data); 567 ret = SMIME_text(bread, data);
576 if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) 568 if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
577 {
578 if (!BIO_get_cipher_status(tmpmem)) 569 if (!BIO_get_cipher_status(tmpmem))
579 ret = 0; 570 ret = 0;
580 } 571 }
581 BIO_free_all(bread); 572 BIO_free_all(bread);
582 return ret; 573 return ret;
583 } else { 574 } else {
584 for(;;) { 575 for (;;) {
585 i = BIO_read(tmpmem, buf, sizeof(buf)); 576 i = BIO_read(tmpmem, buf, sizeof(buf));
586 if(i <= 0) 577 if (i <= 0) {
587 {
588 ret = 1; 578 ret = 1;
589 if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) 579 if (BIO_method_type(tmpmem) ==
590 { 580 BIO_TYPE_CIPHER) {
591 if (!BIO_get_cipher_status(tmpmem)) 581 if (!BIO_get_cipher_status(tmpmem))
592 ret = 0; 582 ret = 0;
593 }
594
595 break;
596 } 583 }
597 if (BIO_write(data, buf, i) != i) 584 break;
598 { 585 }
586 if (BIO_write(data, buf, i) != i) {
599 ret = 0; 587 ret = 0;
600 break; 588 break;
601 } 589 }
602 } 590 }
603 BIO_free_all(tmpmem); 591 BIO_free_all(tmpmem);
604 return ret; 592 return ret;