]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/pkcs7/pk7_doit.c
Run util/openssl-format-source -v -c .
[thirdparty/openssl.git] / crypto / pkcs7 / pk7_doit.c
1 /* crypto/pkcs7/pk7_doit.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59 #include <stdio.h>
60 #include "cryptlib.h"
61 #include <openssl/rand.h>
62 #include <openssl/objects.h>
63 #include <openssl/x509.h>
64 #include <openssl/x509v3.h>
65 #include <openssl/err.h>
66
67 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
68 void *value);
69 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
70
71 static int PKCS7_type_is_other(PKCS7 *p7)
72 {
73 int isOther = 1;
74
75 int nid = OBJ_obj2nid(p7->type);
76
77 switch (nid) {
78 case NID_pkcs7_data:
79 case NID_pkcs7_signed:
80 case NID_pkcs7_enveloped:
81 case NID_pkcs7_signedAndEnveloped:
82 case NID_pkcs7_digest:
83 case NID_pkcs7_encrypted:
84 isOther = 0;
85 break;
86 default:
87 isOther = 1;
88 }
89
90 return isOther;
91
92 }
93
94 static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
95 {
96 if (PKCS7_type_is_data(p7))
97 return p7->d.data;
98 if (PKCS7_type_is_other(p7) && p7->d.other
99 && (p7->d.other->type == V_ASN1_OCTET_STRING))
100 return p7->d.other->value.octet_string;
101 return NULL;
102 }
103
104 static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
105 {
106 BIO *btmp;
107 const EVP_MD *md;
108 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
109 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
110 goto err;
111 }
112
113 md = EVP_get_digestbyobj(alg->algorithm);
114 if (md == NULL) {
115 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
116 goto err;
117 }
118
119 BIO_set_md(btmp, md);
120 if (*pbio == NULL)
121 *pbio = btmp;
122 else if (!BIO_push(*pbio, btmp)) {
123 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
124 goto err;
125 }
126 btmp = NULL;
127
128 return 1;
129
130 err:
131 if (btmp)
132 BIO_free(btmp);
133 return 0;
134
135 }
136
137 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
138 {
139 int i;
140 BIO *out = NULL, *btmp = NULL;
141 X509_ALGOR *xa = NULL;
142 const EVP_CIPHER *evp_cipher = NULL;
143 STACK_OF(X509_ALGOR) *md_sk = NULL;
144 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
145 X509_ALGOR *xalg = NULL;
146 PKCS7_RECIP_INFO *ri = NULL;
147 EVP_PKEY *pkey;
148 ASN1_OCTET_STRING *os = NULL;
149
150 i = OBJ_obj2nid(p7->type);
151 p7->state = PKCS7_S_HEADER;
152
153 switch (i) {
154 case NID_pkcs7_signed:
155 md_sk = p7->d.sign->md_algs;
156 os = PKCS7_get_octet_string(p7->d.sign->contents);
157 break;
158 case NID_pkcs7_signedAndEnveloped:
159 rsk = p7->d.signed_and_enveloped->recipientinfo;
160 md_sk = p7->d.signed_and_enveloped->md_algs;
161 xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
162 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
163 if (evp_cipher == NULL) {
164 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
165 goto err;
166 }
167 break;
168 case NID_pkcs7_enveloped:
169 rsk = p7->d.enveloped->recipientinfo;
170 xalg = p7->d.enveloped->enc_data->algorithm;
171 evp_cipher = p7->d.enveloped->enc_data->cipher;
172 if (evp_cipher == NULL) {
173 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
174 goto err;
175 }
176 break;
177 case NID_pkcs7_digest:
178 xa = p7->d.digest->md;
179 os = PKCS7_get_octet_string(p7->d.digest->contents);
180 break;
181 default:
182 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
183 goto err;
184 }
185
186 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
187 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
188 goto err;
189
190 if (xa && !PKCS7_bio_add_digest(&out, xa))
191 goto err;
192
193 if (evp_cipher != NULL) {
194 unsigned char key[EVP_MAX_KEY_LENGTH];
195 unsigned char iv[EVP_MAX_IV_LENGTH];
196 int keylen, ivlen;
197 int jj, max;
198 unsigned char *tmp;
199 EVP_CIPHER_CTX *ctx;
200
201 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
202 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
203 goto err;
204 }
205 BIO_get_cipher_ctx(btmp, &ctx);
206 keylen = EVP_CIPHER_key_length(evp_cipher);
207 ivlen = EVP_CIPHER_iv_length(evp_cipher);
208 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
209 if (ivlen > 0)
210 if (RAND_pseudo_bytes(iv, ivlen) <= 0)
211 goto err;
212 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
213 goto err;
214 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
215 goto err;
216 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
217 goto err;
218
219 if (ivlen > 0) {
220 if (xalg->parameter == NULL) {
221 xalg->parameter = ASN1_TYPE_new();
222 if (xalg->parameter == NULL)
223 goto err;
224 }
225 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
226 goto err;
227 }
228
229 /* Lets do the pub key stuff :-) */
230 max = 0;
231 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
232 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
233 if (ri->cert == NULL) {
234 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
235 PKCS7_R_MISSING_CERIPEND_INFO);
236 goto err;
237 }
238 if ((pkey = X509_get_pubkey(ri->cert)) == NULL)
239 goto err;
240 jj = EVP_PKEY_size(pkey);
241 EVP_PKEY_free(pkey);
242 if (max < jj)
243 max = jj;
244 }
245 if ((tmp = (unsigned char *)OPENSSL_malloc(max)) == NULL) {
246 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE);
247 goto err;
248 }
249 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
250 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
251 if ((pkey = X509_get_pubkey(ri->cert)) == NULL)
252 goto err;
253 jj = EVP_PKEY_encrypt(tmp, key, keylen, pkey);
254 EVP_PKEY_free(pkey);
255 if (jj <= 0) {
256 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_EVP_LIB);
257 OPENSSL_free(tmp);
258 goto err;
259 }
260 if (!M_ASN1_OCTET_STRING_set(ri->enc_key, tmp, jj)) {
261 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE);
262 OPENSSL_free(tmp);
263 goto err;
264 }
265 }
266 OPENSSL_free(tmp);
267 OPENSSL_cleanse(key, keylen);
268
269 if (out == NULL)
270 out = btmp;
271 else
272 BIO_push(out, btmp);
273 btmp = NULL;
274 }
275
276 if (bio == NULL) {
277 if (PKCS7_is_detached(p7))
278 bio = BIO_new(BIO_s_null());
279 else if (os && os->length > 0)
280 bio = BIO_new_mem_buf(os->data, os->length);
281 if (bio == NULL) {
282 bio = BIO_new(BIO_s_mem());
283 if (bio == NULL)
284 goto err;
285 BIO_set_mem_eof_return(bio, 0);
286 }
287 }
288 BIO_push(out, bio);
289 bio = NULL;
290 if (0) {
291 err:
292 if (out != NULL)
293 BIO_free_all(out);
294 if (btmp != NULL)
295 BIO_free_all(btmp);
296 out = NULL;
297 }
298 return (out);
299 }
300
301 static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
302 {
303 int ret;
304 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
305 pcert->cert_info->issuer);
306 if (ret)
307 return ret;
308 return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
309 ri->issuer_and_serial->serial);
310 }
311
312 /* int */
313 BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
314 {
315 int i, j;
316 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
317 unsigned char *tmp = NULL;
318 X509_ALGOR *xa;
319 ASN1_OCTET_STRING *data_body = NULL;
320 const EVP_MD *evp_md;
321 const EVP_CIPHER *evp_cipher = NULL;
322 EVP_CIPHER_CTX *evp_ctx = NULL;
323 X509_ALGOR *enc_alg = NULL;
324 STACK_OF(X509_ALGOR) *md_sk = NULL;
325 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
326 PKCS7_RECIP_INFO *ri = NULL;
327
328 i = OBJ_obj2nid(p7->type);
329 p7->state = PKCS7_S_HEADER;
330
331 switch (i) {
332 case NID_pkcs7_signed:
333 data_body = PKCS7_get_octet_string(p7->d.sign->contents);
334 md_sk = p7->d.sign->md_algs;
335 break;
336 case NID_pkcs7_signedAndEnveloped:
337 rsk = p7->d.signed_and_enveloped->recipientinfo;
338 md_sk = p7->d.signed_and_enveloped->md_algs;
339 data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
340 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
341 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
342 if (evp_cipher == NULL) {
343 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
344 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
345 goto err;
346 }
347 break;
348 case NID_pkcs7_enveloped:
349 rsk = p7->d.enveloped->recipientinfo;
350 enc_alg = p7->d.enveloped->enc_data->algorithm;
351 data_body = p7->d.enveloped->enc_data->enc_data;
352 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
353 if (evp_cipher == NULL) {
354 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
355 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
356 goto err;
357 }
358 break;
359 default:
360 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
361 goto err;
362 }
363
364 /* We will be checking the signature */
365 if (md_sk != NULL) {
366 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
367 xa = sk_X509_ALGOR_value(md_sk, i);
368 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
369 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
370 goto err;
371 }
372
373 j = OBJ_obj2nid(xa->algorithm);
374 evp_md = EVP_get_digestbynid(j);
375 if (evp_md == NULL) {
376 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
377 PKCS7_R_UNKNOWN_DIGEST_TYPE);
378 goto err;
379 }
380
381 BIO_set_md(btmp, evp_md);
382 if (out == NULL)
383 out = btmp;
384 else
385 BIO_push(out, btmp);
386 btmp = NULL;
387 }
388 }
389
390 if (evp_cipher != NULL) {
391 #if 0
392 unsigned char key[EVP_MAX_KEY_LENGTH];
393 unsigned char iv[EVP_MAX_IV_LENGTH];
394 unsigned char *p;
395 int keylen, ivlen;
396 int max;
397 X509_OBJECT ret;
398 #endif
399 unsigned char *tkey = NULL;
400 int tkeylen;
401 int jj;
402
403 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
404 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
405 goto err;
406 }
407
408 /*
409 * It was encrypted, we need to decrypt the secret key with the
410 * private key
411 */
412
413 /*
414 * Find the recipientInfo which matches the passed certificate (if
415 * any)
416 */
417
418 if (pcert) {
419 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
420 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
421 if (!pkcs7_cmp_ri(ri, pcert))
422 break;
423 ri = NULL;
424 }
425 if (ri == NULL) {
426 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
427 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
428 goto err;
429 }
430 }
431
432 jj = EVP_PKEY_size(pkey);
433 tmp = (unsigned char *)OPENSSL_malloc(jj + 10);
434 if (tmp == NULL) {
435 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_MALLOC_FAILURE);
436 goto err;
437 }
438
439 /* If we haven't got a certificate try each ri in turn */
440
441 if (pcert == NULL) {
442 /*
443 * Temporary storage in case EVP_PKEY_decrypt overwrites output
444 * buffer on error.
445 */
446 unsigned char *tmp2;
447 tmp2 = OPENSSL_malloc(jj);
448 if (!tmp2)
449 goto err;
450 jj = -1;
451 /*
452 * Always attempt to decrypt all cases to avoid leaking timing
453 * information about a successful decrypt.
454 */
455 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
456 int tret;
457 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
458 tret = EVP_PKEY_decrypt(tmp2,
459 M_ASN1_STRING_data(ri->enc_key),
460 M_ASN1_STRING_length(ri->enc_key),
461 pkey);
462 if (tret > 0) {
463 memcpy(tmp, tmp2, tret);
464 OPENSSL_cleanse(tmp2, tret);
465 jj = tret;
466 }
467 ERR_clear_error();
468 }
469 OPENSSL_free(tmp2);
470 } else {
471 jj = EVP_PKEY_decrypt(tmp,
472 M_ASN1_STRING_data(ri->enc_key),
473 M_ASN1_STRING_length(ri->enc_key), pkey);
474 ERR_clear_error();
475 }
476
477 evp_ctx = NULL;
478 BIO_get_cipher_ctx(etmp, &evp_ctx);
479 if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
480 goto err;
481 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
482 goto err;
483 /* Generate random key to counter MMA */
484 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
485 tkey = OPENSSL_malloc(tkeylen);
486 if (!tkey)
487 goto err;
488 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
489 goto err;
490 /* If we have no key use random key */
491 if (jj <= 0) {
492 OPENSSL_free(tmp);
493 jj = tkeylen;
494 tmp = tkey;
495 tkey = NULL;
496 }
497
498 if (jj != tkeylen) {
499 /*
500 * Some S/MIME clients don't use the same key and effective key
501 * length. The key length is determined by the size of the
502 * decrypted RSA key.
503 */
504 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) {
505 /* As MMA defence use random key instead */
506 OPENSSL_cleanse(tmp, jj);
507 OPENSSL_free(tmp);
508 jj = tkeylen;
509 tmp = tkey;
510 tkey = NULL;
511 }
512 }
513 ERR_clear_error();
514 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, tmp, NULL, 0) <= 0)
515 goto err;
516
517 OPENSSL_cleanse(tmp, jj);
518
519 if (tkey) {
520 OPENSSL_cleanse(tkey, tkeylen);
521 OPENSSL_free(tkey);
522 }
523
524 if (out == NULL)
525 out = etmp;
526 else
527 BIO_push(out, etmp);
528 etmp = NULL;
529 }
530 #if 1
531 if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
532 bio = in_bio;
533 } else {
534 # if 0
535 bio = BIO_new(BIO_s_mem());
536 /*
537 * We need to set this so that when we have read all the data, the
538 * encrypt BIO, if present, will read EOF and encode the last few
539 * bytes
540 */
541 BIO_set_mem_eof_return(bio, 0);
542
543 if (data_body->length > 0)
544 BIO_write(bio, (char *)data_body->data, data_body->length);
545 # else
546 if (data_body->length > 0)
547 bio = BIO_new_mem_buf(data_body->data, data_body->length);
548 else {
549 bio = BIO_new(BIO_s_mem());
550 BIO_set_mem_eof_return(bio, 0);
551 }
552 if (bio == NULL)
553 goto err;
554 # endif
555 }
556 BIO_push(out, bio);
557 bio = NULL;
558 #endif
559 if (0) {
560 err:
561 if (out != NULL)
562 BIO_free_all(out);
563 if (btmp != NULL)
564 BIO_free_all(btmp);
565 if (etmp != NULL)
566 BIO_free_all(etmp);
567 if (bio != NULL)
568 BIO_free_all(bio);
569 out = NULL;
570 }
571 if (tmp != NULL)
572 OPENSSL_free(tmp);
573 return (out);
574 }
575
576 static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
577 {
578 for (;;) {
579 bio = BIO_find_type(bio, BIO_TYPE_MD);
580 if (bio == NULL) {
581 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
582 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
583 return NULL;
584 }
585 BIO_get_md_ctx(bio, pmd);
586 if (*pmd == NULL) {
587 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
588 return NULL;
589 }
590 if (EVP_MD_CTX_type(*pmd) == nid)
591 return bio;
592 bio = BIO_next(bio);
593 }
594 return NULL;
595 }
596
597 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
598 {
599 int ret = 0;
600 int i, j;
601 BIO *btmp;
602 BUF_MEM *buf_mem = NULL;
603 BUF_MEM *buf = NULL;
604 PKCS7_SIGNER_INFO *si;
605 EVP_MD_CTX *mdc, ctx_tmp;
606 STACK_OF(X509_ATTRIBUTE) *sk;
607 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
608 ASN1_OCTET_STRING *os = NULL;
609
610 EVP_MD_CTX_init(&ctx_tmp);
611 i = OBJ_obj2nid(p7->type);
612 p7->state = PKCS7_S_HEADER;
613
614 switch (i) {
615 case NID_pkcs7_signedAndEnveloped:
616 /* XXXXXXXXXXXXXXXX */
617 si_sk = p7->d.signed_and_enveloped->signer_info;
618 if (!(os = M_ASN1_OCTET_STRING_new())) {
619 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
620 goto err;
621 }
622 p7->d.signed_and_enveloped->enc_data->enc_data = os;
623 break;
624 case NID_pkcs7_enveloped:
625 /* XXXXXXXXXXXXXXXX */
626 if (!(os = M_ASN1_OCTET_STRING_new())) {
627 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
628 goto err;
629 }
630 p7->d.enveloped->enc_data->enc_data = os;
631 break;
632 case NID_pkcs7_signed:
633 si_sk = p7->d.sign->signer_info;
634 os = PKCS7_get_octet_string(p7->d.sign->contents);
635 /* If detached data then the content is excluded */
636 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
637 M_ASN1_OCTET_STRING_free(os);
638 p7->d.sign->contents->d.data = NULL;
639 }
640 break;
641
642 case NID_pkcs7_digest:
643 os = PKCS7_get_octet_string(p7->d.digest->contents);
644 /* If detached data then the content is excluded */
645 if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
646 M_ASN1_OCTET_STRING_free(os);
647 p7->d.digest->contents->d.data = NULL;
648 }
649 break;
650
651 }
652
653 if (si_sk != NULL) {
654 if ((buf = BUF_MEM_new()) == NULL) {
655 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_BIO_LIB);
656 goto err;
657 }
658 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
659 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
660 if (si->pkey == NULL)
661 continue;
662
663 j = OBJ_obj2nid(si->digest_alg->algorithm);
664
665 btmp = bio;
666
667 btmp = PKCS7_find_digest(&mdc, btmp, j);
668
669 if (btmp == NULL)
670 goto err;
671
672 /*
673 * We now have the EVP_MD_CTX, lets do the signing.
674 */
675 EVP_MD_CTX_copy_ex(&ctx_tmp, mdc);
676 if (!BUF_MEM_grow_clean(buf, EVP_PKEY_size(si->pkey))) {
677 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_BIO_LIB);
678 goto err;
679 }
680
681 sk = si->auth_attr;
682
683 /*
684 * If there are attributes, we add the digest attribute and only
685 * sign the attributes
686 */
687 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
688 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf = NULL;
689 unsigned int md_len, alen;
690 ASN1_OCTET_STRING *digest;
691 ASN1_UTCTIME *sign_time;
692 const EVP_MD *md_tmp;
693
694 /* Add signing time if not already present */
695 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
696 if (!(sign_time = X509_gmtime_adj(NULL, 0))) {
697 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
698 ERR_R_MALLOC_FAILURE);
699 goto err;
700 }
701 if (!PKCS7_add_signed_attribute(si,
702 NID_pkcs9_signingTime,
703 V_ASN1_UTCTIME,
704 sign_time)) {
705 M_ASN1_UTCTIME_free(sign_time);
706 goto err;
707 }
708 }
709
710 /* Add digest */
711 md_tmp = EVP_MD_CTX_md(&ctx_tmp);
712 EVP_DigestFinal_ex(&ctx_tmp, md_data, &md_len);
713 if (!(digest = M_ASN1_OCTET_STRING_new())) {
714 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
715 goto err;
716 }
717 if (!M_ASN1_OCTET_STRING_set(digest, md_data, md_len)) {
718 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
719 M_ASN1_OCTET_STRING_free(digest);
720 goto err;
721 }
722 if (!PKCS7_add_signed_attribute(si,
723 NID_pkcs9_messageDigest,
724 V_ASN1_OCTET_STRING, digest))
725 {
726 M_ASN1_OCTET_STRING_free(digest);
727 goto err;
728 }
729
730 /* Now sign the attributes */
731 EVP_SignInit_ex(&ctx_tmp, md_tmp, NULL);
732 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
733 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
734 if (!abuf)
735 goto err;
736 EVP_SignUpdate(&ctx_tmp, abuf, alen);
737 OPENSSL_free(abuf);
738 }
739 #ifndef OPENSSL_NO_DSA
740 if (si->pkey->type == EVP_PKEY_DSA)
741 ctx_tmp.digest = EVP_dss1();
742 #endif
743 #ifndef OPENSSL_NO_ECDSA
744 if (si->pkey->type == EVP_PKEY_EC)
745 ctx_tmp.digest = EVP_ecdsa();
746 #endif
747
748 if (!EVP_SignFinal(&ctx_tmp, (unsigned char *)buf->data,
749 (unsigned int *)&buf->length, si->pkey)) {
750 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
751 goto err;
752 }
753 if (!ASN1_STRING_set(si->enc_digest,
754 (unsigned char *)buf->data, buf->length)) {
755 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_ASN1_LIB);
756 goto err;
757 }
758 }
759 } else if (i == NID_pkcs7_digest) {
760 unsigned char md_data[EVP_MAX_MD_SIZE];
761 unsigned int md_len;
762 if (!PKCS7_find_digest(&mdc, bio,
763 OBJ_obj2nid(p7->d.digest->md->algorithm)))
764 goto err;
765 EVP_DigestFinal_ex(mdc, md_data, &md_len);
766 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
767 }
768
769 if (!PKCS7_is_detached(p7)) {
770 btmp = BIO_find_type(bio, BIO_TYPE_MEM);
771 if (btmp == NULL) {
772 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
773 goto err;
774 }
775 BIO_get_mem_ptr(btmp, &buf_mem);
776 /*
777 * Mark the BIO read only then we can use its copy of the data
778 * instead of making an extra copy.
779 */
780 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
781 BIO_set_mem_eof_return(btmp, 0);
782 os->data = (unsigned char *)buf_mem->data;
783 os->length = buf_mem->length;
784 #if 0
785 M_ASN1_OCTET_STRING_set(os,
786 (unsigned char *)buf_mem->data,
787 buf_mem->length);
788 #endif
789 }
790 ret = 1;
791 err:
792 EVP_MD_CTX_cleanup(&ctx_tmp);
793 if (buf != NULL)
794 BUF_MEM_free(buf);
795 return (ret);
796 }
797
798 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
799 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
800 {
801 PKCS7_ISSUER_AND_SERIAL *ias;
802 int ret = 0, i;
803 STACK_OF(X509) *cert;
804 X509 *x509;
805
806 if (PKCS7_type_is_signed(p7)) {
807 cert = p7->d.sign->cert;
808 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
809 cert = p7->d.signed_and_enveloped->cert;
810 } else {
811 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
812 goto err;
813 }
814 /* XXXXXXXXXXXXXXXXXXXXXXX */
815 ias = si->issuer_and_serial;
816
817 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
818
819 /* were we able to find the cert in passed to us */
820 if (x509 == NULL) {
821 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
822 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
823 goto err;
824 }
825
826 /* Lets verify */
827 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
828 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
829 goto err;
830 }
831 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
832 i = X509_verify_cert(ctx);
833 if (i <= 0) {
834 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
835 X509_STORE_CTX_cleanup(ctx);
836 goto err;
837 }
838 X509_STORE_CTX_cleanup(ctx);
839
840 return PKCS7_signatureVerify(bio, p7, si, x509);
841 err:
842 return ret;
843 }
844
845 int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
846 X509 *x509)
847 {
848 ASN1_OCTET_STRING *os;
849 EVP_MD_CTX mdc_tmp, *mdc;
850 int ret = 0, i;
851 int md_type;
852 STACK_OF(X509_ATTRIBUTE) *sk;
853 BIO *btmp;
854 EVP_PKEY *pkey;
855
856 EVP_MD_CTX_init(&mdc_tmp);
857
858 if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
859 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
860 goto err;
861 }
862
863 md_type = OBJ_obj2nid(si->digest_alg->algorithm);
864
865 btmp = bio;
866 for (;;) {
867 if ((btmp == NULL) ||
868 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
869 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
870 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
871 goto err;
872 }
873 BIO_get_md_ctx(btmp, &mdc);
874 if (mdc == NULL) {
875 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
876 goto err;
877 }
878 if (EVP_MD_CTX_type(mdc) == md_type)
879 break;
880 /*
881 * Workaround for some broken clients that put the signature OID
882 * instead of the digest OID in digest_alg->algorithm
883 */
884 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
885 break;
886 btmp = BIO_next(btmp);
887 }
888
889 /*
890 * mdc is the digest ctx that we want, unless there are attributes, in
891 * which case the digest is the signed attributes
892 */
893 EVP_MD_CTX_copy_ex(&mdc_tmp, mdc);
894
895 sk = si->auth_attr;
896 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
897 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
898 unsigned int md_len, alen;
899 ASN1_OCTET_STRING *message_digest;
900
901 EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len);
902 message_digest = PKCS7_digest_from_attributes(sk);
903 if (!message_digest) {
904 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
905 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
906 goto err;
907 }
908 if ((message_digest->length != (int)md_len) ||
909 (memcmp(message_digest->data, md_dat, md_len))) {
910 #if 0
911 {
912 int ii;
913 for (ii = 0; ii < message_digest->length; ii++)
914 printf("%02X", message_digest->data[ii]);
915 printf(" sent\n");
916 for (ii = 0; ii < md_len; ii++)
917 printf("%02X", md_dat[ii]);
918 printf(" calc\n");
919 }
920 #endif
921 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
922 ret = -1;
923 goto err;
924 }
925
926 EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL);
927
928 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
929 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
930 EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
931
932 OPENSSL_free(abuf);
933 }
934
935 os = si->enc_digest;
936 pkey = X509_get_pubkey(x509);
937 if (!pkey) {
938 ret = -1;
939 goto err;
940 }
941 #ifndef OPENSSL_NO_DSA
942 if (pkey->type == EVP_PKEY_DSA)
943 mdc_tmp.digest = EVP_dss1();
944 #endif
945 #ifndef OPENSSL_NO_ECDSA
946 if (pkey->type == EVP_PKEY_EC)
947 mdc_tmp.digest = EVP_ecdsa();
948 #endif
949
950 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
951 EVP_PKEY_free(pkey);
952 if (i <= 0) {
953 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
954 ret = -1;
955 goto err;
956 } else
957 ret = 1;
958 err:
959 EVP_MD_CTX_cleanup(&mdc_tmp);
960 return (ret);
961 }
962
963 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
964 {
965 STACK_OF(PKCS7_RECIP_INFO) *rsk;
966 PKCS7_RECIP_INFO *ri;
967 int i;
968
969 i = OBJ_obj2nid(p7->type);
970 if (i != NID_pkcs7_signedAndEnveloped)
971 return NULL;
972 if (p7->d.signed_and_enveloped == NULL)
973 return NULL;
974 rsk = p7->d.signed_and_enveloped->recipientinfo;
975 if (rsk == NULL)
976 return NULL;
977 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0);
978 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
979 return (NULL);
980 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
981 return (ri->issuer_and_serial);
982 }
983
984 ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
985 {
986 return (get_attribute(si->auth_attr, nid));
987 }
988
989 ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
990 {
991 return (get_attribute(si->unauth_attr, nid));
992 }
993
994 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
995 {
996 int i;
997 X509_ATTRIBUTE *xa;
998 ASN1_OBJECT *o;
999
1000 o = OBJ_nid2obj(nid);
1001 if (!o || !sk)
1002 return (NULL);
1003 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1004 xa = sk_X509_ATTRIBUTE_value(sk, i);
1005 if (OBJ_cmp(xa->object, o) == 0) {
1006 if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
1007 return (sk_ASN1_TYPE_value(xa->value.set, 0));
1008 else
1009 return (NULL);
1010 }
1011 }
1012 return (NULL);
1013 }
1014
1015 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
1016 {
1017 ASN1_TYPE *astype;
1018 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
1019 return NULL;
1020 return astype->value.octet_string;
1021 }
1022
1023 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
1024 STACK_OF(X509_ATTRIBUTE) *sk)
1025 {
1026 int i;
1027
1028 if (p7si->auth_attr != NULL)
1029 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
1030 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
1031 if (p7si->auth_attr == NULL)
1032 return 0;
1033 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1034 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
1035 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1036 (sk, i))))
1037 == NULL)
1038 return (0);
1039 }
1040 return (1);
1041 }
1042
1043 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
1044 STACK_OF(X509_ATTRIBUTE) *sk)
1045 {
1046 int i;
1047
1048 if (p7si->unauth_attr != NULL)
1049 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
1050 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
1051 if (p7si->unauth_attr == NULL)
1052 return 0;
1053 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1054 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
1055 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1056 (sk, i))))
1057 == NULL)
1058 return (0);
1059 }
1060 return (1);
1061 }
1062
1063 int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1064 void *value)
1065 {
1066 return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
1067 }
1068
1069 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1070 void *value)
1071 {
1072 return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
1073 }
1074
1075 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1076 void *value)
1077 {
1078 X509_ATTRIBUTE *attr = NULL;
1079
1080 if (*sk == NULL) {
1081 if (!(*sk = sk_X509_ATTRIBUTE_new_null()))
1082 return 0;
1083 new_attrib:
1084 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
1085 return 0;
1086 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
1087 X509_ATTRIBUTE_free(attr);
1088 return 0;
1089 }
1090 } else {
1091 int i;
1092
1093 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
1094 attr = sk_X509_ATTRIBUTE_value(*sk, i);
1095 if (OBJ_obj2nid(attr->object) == nid) {
1096 X509_ATTRIBUTE_free(attr);
1097 attr = X509_ATTRIBUTE_create(nid, atrtype, value);
1098 if (attr == NULL)
1099 return 0;
1100 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
1101 X509_ATTRIBUTE_free(attr);
1102 return 0;
1103 }
1104 goto end;
1105 }
1106 }
1107 goto new_attrib;
1108 }
1109 end:
1110 return (1);
1111 }