]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - crypto/openssl/crypto/pkcs7/pk7_doit.c
Merge OpenSSL 0.9.8zf.
[FreeBSD/stable/9.git] / crypto / openssl / 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     if (p7 == NULL) {
151         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
152         return NULL;
153     }
154     /*
155      * The content field in the PKCS7 ContentInfo is optional, but that really
156      * only applies to inner content (precisely, detached signatures).
157      *
158      * When reading content, missing outer content is therefore treated as an
159      * error.
160      *
161      * When creating content, PKCS7_content_new() must be called before
162      * calling this method, so a NULL p7->d is always an error.
163      */
164     if (p7->d.ptr == NULL) {
165         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
166         return NULL;
167     }
168
169     i = OBJ_obj2nid(p7->type);
170     p7->state = PKCS7_S_HEADER;
171
172     switch (i) {
173     case NID_pkcs7_signed:
174         md_sk = p7->d.sign->md_algs;
175         os = PKCS7_get_octet_string(p7->d.sign->contents);
176         break;
177     case NID_pkcs7_signedAndEnveloped:
178         rsk = p7->d.signed_and_enveloped->recipientinfo;
179         md_sk = p7->d.signed_and_enveloped->md_algs;
180         xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
181         evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
182         if (evp_cipher == NULL) {
183             PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
184             goto err;
185         }
186         break;
187     case NID_pkcs7_enveloped:
188         rsk = p7->d.enveloped->recipientinfo;
189         xalg = p7->d.enveloped->enc_data->algorithm;
190         evp_cipher = p7->d.enveloped->enc_data->cipher;
191         if (evp_cipher == NULL) {
192             PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
193             goto err;
194         }
195         break;
196     case NID_pkcs7_digest:
197         xa = p7->d.digest->md;
198         os = PKCS7_get_octet_string(p7->d.digest->contents);
199         break;
200     default:
201         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
202         goto err;
203     }
204
205     for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
206         if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
207             goto err;
208
209     if (xa && !PKCS7_bio_add_digest(&out, xa))
210         goto err;
211
212     if (evp_cipher != NULL) {
213         unsigned char key[EVP_MAX_KEY_LENGTH];
214         unsigned char iv[EVP_MAX_IV_LENGTH];
215         int keylen, ivlen;
216         int jj, max;
217         unsigned char *tmp;
218         EVP_CIPHER_CTX *ctx;
219
220         if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
221             PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
222             goto err;
223         }
224         BIO_get_cipher_ctx(btmp, &ctx);
225         keylen = EVP_CIPHER_key_length(evp_cipher);
226         ivlen = EVP_CIPHER_iv_length(evp_cipher);
227         xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
228         if (ivlen > 0)
229             if (RAND_pseudo_bytes(iv, ivlen) <= 0)
230                 goto err;
231         if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
232             goto err;
233         if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
234             goto err;
235         if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
236             goto err;
237
238         if (ivlen > 0) {
239             if (xalg->parameter == NULL) {
240                 xalg->parameter = ASN1_TYPE_new();
241                 if (xalg->parameter == NULL)
242                     goto err;
243             }
244             if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
245                 goto err;
246         }
247
248         /* Lets do the pub key stuff :-) */
249         max = 0;
250         for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
251             ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
252             if (ri->cert == NULL) {
253                 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
254                          PKCS7_R_MISSING_CERIPEND_INFO);
255                 goto err;
256             }
257             if ((pkey = X509_get_pubkey(ri->cert)) == NULL)
258                 goto err;
259             jj = EVP_PKEY_size(pkey);
260             EVP_PKEY_free(pkey);
261             if (max < jj)
262                 max = jj;
263         }
264         if ((tmp = (unsigned char *)OPENSSL_malloc(max)) == NULL) {
265             PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE);
266             goto err;
267         }
268         for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
269             ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
270             if ((pkey = X509_get_pubkey(ri->cert)) == NULL)
271                 goto err;
272             jj = EVP_PKEY_encrypt(tmp, key, keylen, pkey);
273             EVP_PKEY_free(pkey);
274             if (jj <= 0) {
275                 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_EVP_LIB);
276                 OPENSSL_free(tmp);
277                 goto err;
278             }
279             if (!M_ASN1_OCTET_STRING_set(ri->enc_key, tmp, jj)) {
280                 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_MALLOC_FAILURE);
281                 OPENSSL_free(tmp);
282                 goto err;
283             }
284         }
285         OPENSSL_free(tmp);
286         OPENSSL_cleanse(key, keylen);
287
288         if (out == NULL)
289             out = btmp;
290         else
291             BIO_push(out, btmp);
292         btmp = NULL;
293     }
294
295     if (bio == NULL) {
296         if (PKCS7_is_detached(p7))
297             bio = BIO_new(BIO_s_null());
298         else if (os && os->length > 0)
299             bio = BIO_new_mem_buf(os->data, os->length);
300         if (bio == NULL) {
301             bio = BIO_new(BIO_s_mem());
302             if (bio == NULL)
303                 goto err;
304             BIO_set_mem_eof_return(bio, 0);
305         }
306     }
307     BIO_push(out, bio);
308     bio = NULL;
309     if (0) {
310  err:
311         if (out != NULL)
312             BIO_free_all(out);
313         if (btmp != NULL)
314             BIO_free_all(btmp);
315         out = NULL;
316     }
317     return (out);
318 }
319
320 static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
321 {
322     int ret;
323     ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
324                         pcert->cert_info->issuer);
325     if (ret)
326         return ret;
327     return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
328                               ri->issuer_and_serial->serial);
329 }
330
331 /* int */
332 BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
333 {
334     int i, j;
335     BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
336     unsigned char *tmp = NULL;
337     X509_ALGOR *xa;
338     ASN1_OCTET_STRING *data_body = NULL;
339     const EVP_MD *evp_md;
340     const EVP_CIPHER *evp_cipher = NULL;
341     EVP_CIPHER_CTX *evp_ctx = NULL;
342     X509_ALGOR *enc_alg = NULL;
343     STACK_OF(X509_ALGOR) *md_sk = NULL;
344     STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
345     PKCS7_RECIP_INFO *ri = NULL;
346
347     if (p7 == NULL) {
348         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
349         return NULL;
350     }
351
352     if (p7->d.ptr == NULL) {
353         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
354         return NULL;
355     }
356
357     i = OBJ_obj2nid(p7->type);
358     p7->state = PKCS7_S_HEADER;
359
360     switch (i) {
361     case NID_pkcs7_signed:
362         data_body = PKCS7_get_octet_string(p7->d.sign->contents);
363         md_sk = p7->d.sign->md_algs;
364         break;
365     case NID_pkcs7_signedAndEnveloped:
366         rsk = p7->d.signed_and_enveloped->recipientinfo;
367         md_sk = p7->d.signed_and_enveloped->md_algs;
368         data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
369         enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
370         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
371         if (evp_cipher == NULL) {
372             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
373                      PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
374             goto err;
375         }
376         break;
377     case NID_pkcs7_enveloped:
378         rsk = p7->d.enveloped->recipientinfo;
379         enc_alg = p7->d.enveloped->enc_data->algorithm;
380         data_body = p7->d.enveloped->enc_data->enc_data;
381         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
382         if (evp_cipher == NULL) {
383             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
384                      PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
385             goto err;
386         }
387         break;
388     default:
389         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
390         goto err;
391     }
392
393     /* We will be checking the signature */
394     if (md_sk != NULL) {
395         for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
396             xa = sk_X509_ALGOR_value(md_sk, i);
397             if ((btmp = BIO_new(BIO_f_md())) == NULL) {
398                 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
399                 goto err;
400             }
401
402             j = OBJ_obj2nid(xa->algorithm);
403             evp_md = EVP_get_digestbynid(j);
404             if (evp_md == NULL) {
405                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
406                          PKCS7_R_UNKNOWN_DIGEST_TYPE);
407                 goto err;
408             }
409
410             BIO_set_md(btmp, evp_md);
411             if (out == NULL)
412                 out = btmp;
413             else
414                 BIO_push(out, btmp);
415             btmp = NULL;
416         }
417     }
418
419     if (evp_cipher != NULL) {
420 #if 0
421         unsigned char key[EVP_MAX_KEY_LENGTH];
422         unsigned char iv[EVP_MAX_IV_LENGTH];
423         unsigned char *p;
424         int keylen, ivlen;
425         int max;
426         X509_OBJECT ret;
427 #endif
428         unsigned char *tkey = NULL;
429         int tkeylen;
430         int jj;
431
432         if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
433             PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
434             goto err;
435         }
436
437         /*
438          * It was encrypted, we need to decrypt the secret key with the
439          * private key
440          */
441
442         /*
443          * Find the recipientInfo which matches the passed certificate (if
444          * any)
445          */
446
447         if (pcert) {
448             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
449                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
450                 if (!pkcs7_cmp_ri(ri, pcert))
451                     break;
452                 ri = NULL;
453             }
454             if (ri == NULL) {
455                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
456                          PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
457                 goto err;
458             }
459         }
460
461         jj = EVP_PKEY_size(pkey);
462         tmp = (unsigned char *)OPENSSL_malloc(jj + 10);
463         if (tmp == NULL) {
464             PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_MALLOC_FAILURE);
465             goto err;
466         }
467
468         /* If we haven't got a certificate try each ri in turn */
469
470         if (pcert == NULL) {
471             /*
472              * Temporary storage in case EVP_PKEY_decrypt overwrites output
473              * buffer on error.
474              */
475             unsigned char *tmp2;
476             tmp2 = OPENSSL_malloc(jj);
477             if (!tmp2)
478                 goto err;
479             jj = -1;
480             /*
481              * Always attempt to decrypt all cases to avoid leaking timing
482              * information about a successful decrypt.
483              */
484             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
485                 int tret;
486                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
487                 tret = EVP_PKEY_decrypt(tmp2,
488                                         M_ASN1_STRING_data(ri->enc_key),
489                                         M_ASN1_STRING_length(ri->enc_key),
490                                         pkey);
491                 if (tret > 0) {
492                     memcpy(tmp, tmp2, tret);
493                     OPENSSL_cleanse(tmp2, tret);
494                     jj = tret;
495                 }
496                 ERR_clear_error();
497             }
498             OPENSSL_free(tmp2);
499         } else {
500             jj = EVP_PKEY_decrypt(tmp,
501                                   M_ASN1_STRING_data(ri->enc_key),
502                                   M_ASN1_STRING_length(ri->enc_key), pkey);
503             ERR_clear_error();
504         }
505
506         evp_ctx = NULL;
507         BIO_get_cipher_ctx(etmp, &evp_ctx);
508         if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
509             goto err;
510         if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
511             goto err;
512         /* Generate random key to counter MMA */
513         tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
514         tkey = OPENSSL_malloc(tkeylen);
515         if (!tkey)
516             goto err;
517         if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
518             goto err;
519         /* If we have no key use random key */
520         if (jj <= 0) {
521             OPENSSL_free(tmp);
522             jj = tkeylen;
523             tmp = tkey;
524             tkey = NULL;
525         }
526
527         if (jj != tkeylen) {
528             /*
529              * Some S/MIME clients don't use the same key and effective key
530              * length. The key length is determined by the size of the
531              * decrypted RSA key.
532              */
533             if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) {
534                 /* As MMA defence use random key instead */
535                 OPENSSL_cleanse(tmp, jj);
536                 OPENSSL_free(tmp);
537                 jj = tkeylen;
538                 tmp = tkey;
539                 tkey = NULL;
540             }
541         }
542         ERR_clear_error();
543         if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, tmp, NULL, 0) <= 0)
544             goto err;
545
546         OPENSSL_cleanse(tmp, jj);
547
548         if (tkey) {
549             OPENSSL_cleanse(tkey, tkeylen);
550             OPENSSL_free(tkey);
551         }
552
553         if (out == NULL)
554             out = etmp;
555         else
556             BIO_push(out, etmp);
557         etmp = NULL;
558     }
559 #if 1
560     if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
561         bio = in_bio;
562     } else {
563 # if 0
564         bio = BIO_new(BIO_s_mem());
565         /*
566          * We need to set this so that when we have read all the data, the
567          * encrypt BIO, if present, will read EOF and encode the last few
568          * bytes
569          */
570         BIO_set_mem_eof_return(bio, 0);
571
572         if (data_body->length > 0)
573             BIO_write(bio, (char *)data_body->data, data_body->length);
574 # else
575         if (data_body->length > 0)
576             bio = BIO_new_mem_buf(data_body->data, data_body->length);
577         else {
578             bio = BIO_new(BIO_s_mem());
579             BIO_set_mem_eof_return(bio, 0);
580         }
581         if (bio == NULL)
582             goto err;
583 # endif
584     }
585     BIO_push(out, bio);
586     bio = NULL;
587 #endif
588     if (0) {
589  err:
590         if (out != NULL)
591             BIO_free_all(out);
592         if (btmp != NULL)
593             BIO_free_all(btmp);
594         if (etmp != NULL)
595             BIO_free_all(etmp);
596         if (bio != NULL)
597             BIO_free_all(bio);
598         out = NULL;
599     }
600     if (tmp != NULL)
601         OPENSSL_free(tmp);
602     return (out);
603 }
604
605 static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
606 {
607     for (;;) {
608         bio = BIO_find_type(bio, BIO_TYPE_MD);
609         if (bio == NULL) {
610             PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
611                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
612             return NULL;
613         }
614         BIO_get_md_ctx(bio, pmd);
615         if (*pmd == NULL) {
616             PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
617             return NULL;
618         }
619         if (EVP_MD_CTX_type(*pmd) == nid)
620             return bio;
621         bio = BIO_next(bio);
622     }
623     return NULL;
624 }
625
626 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
627 {
628     int ret = 0;
629     int i, j;
630     BIO *btmp;
631     BUF_MEM *buf_mem = NULL;
632     BUF_MEM *buf = NULL;
633     PKCS7_SIGNER_INFO *si;
634     EVP_MD_CTX *mdc, ctx_tmp;
635     STACK_OF(X509_ATTRIBUTE) *sk;
636     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
637     ASN1_OCTET_STRING *os = NULL;
638
639     if (p7 == NULL) {
640         PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
641         return 0;
642     }
643
644     if (p7->d.ptr == NULL) {
645         PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
646         return 0;
647     }
648
649     EVP_MD_CTX_init(&ctx_tmp);
650     i = OBJ_obj2nid(p7->type);
651     p7->state = PKCS7_S_HEADER;
652
653     switch (i) {
654     case NID_pkcs7_signedAndEnveloped:
655         /* XXXXXXXXXXXXXXXX */
656         si_sk = p7->d.signed_and_enveloped->signer_info;
657         if (!(os = M_ASN1_OCTET_STRING_new())) {
658             PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
659             goto err;
660         }
661         p7->d.signed_and_enveloped->enc_data->enc_data = os;
662         break;
663     case NID_pkcs7_enveloped:
664         /* XXXXXXXXXXXXXXXX */
665         if (!(os = M_ASN1_OCTET_STRING_new())) {
666             PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
667             goto err;
668         }
669         p7->d.enveloped->enc_data->enc_data = os;
670         break;
671     case NID_pkcs7_signed:
672         si_sk = p7->d.sign->signer_info;
673         os = PKCS7_get_octet_string(p7->d.sign->contents);
674         /* If detached data then the content is excluded */
675         if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
676             M_ASN1_OCTET_STRING_free(os);
677             os = NULL;
678             p7->d.sign->contents->d.data = NULL;
679         }
680         break;
681
682     case NID_pkcs7_digest:
683         os = PKCS7_get_octet_string(p7->d.digest->contents);
684         /* If detached data then the content is excluded */
685         if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
686             M_ASN1_OCTET_STRING_free(os);
687             os = NULL;
688             p7->d.digest->contents->d.data = NULL;
689         }
690         break;
691
692     }
693
694     if (si_sk != NULL) {
695         if ((buf = BUF_MEM_new()) == NULL) {
696             PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_BIO_LIB);
697             goto err;
698         }
699         for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
700             si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
701             if (si->pkey == NULL)
702                 continue;
703
704             j = OBJ_obj2nid(si->digest_alg->algorithm);
705
706             btmp = bio;
707
708             btmp = PKCS7_find_digest(&mdc, btmp, j);
709
710             if (btmp == NULL)
711                 goto err;
712
713             /*
714              * We now have the EVP_MD_CTX, lets do the signing.
715              */
716             EVP_MD_CTX_copy_ex(&ctx_tmp, mdc);
717             if (!BUF_MEM_grow_clean(buf, EVP_PKEY_size(si->pkey))) {
718                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_BIO_LIB);
719                 goto err;
720             }
721
722             sk = si->auth_attr;
723
724             /*
725              * If there are attributes, we add the digest attribute and only
726              * sign the attributes
727              */
728             if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
729                 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf = NULL;
730                 unsigned int md_len, alen;
731                 ASN1_OCTET_STRING *digest;
732                 ASN1_UTCTIME *sign_time;
733                 const EVP_MD *md_tmp;
734
735                 /* Add signing time if not already present */
736                 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
737                     if (!(sign_time = X509_gmtime_adj(NULL, 0))) {
738                         PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
739                                  ERR_R_MALLOC_FAILURE);
740                         goto err;
741                     }
742                     if (!PKCS7_add_signed_attribute(si,
743                                                     NID_pkcs9_signingTime,
744                                                     V_ASN1_UTCTIME,
745                                                     sign_time)) {
746                         M_ASN1_UTCTIME_free(sign_time);
747                         goto err;
748                     }
749                 }
750
751                 /* Add digest */
752                 md_tmp = EVP_MD_CTX_md(&ctx_tmp);
753                 EVP_DigestFinal_ex(&ctx_tmp, md_data, &md_len);
754                 if (!(digest = M_ASN1_OCTET_STRING_new())) {
755                     PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
756                     goto err;
757                 }
758                 if (!M_ASN1_OCTET_STRING_set(digest, md_data, md_len)) {
759                     PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
760                     M_ASN1_OCTET_STRING_free(digest);
761                     goto err;
762                 }
763                 if (!PKCS7_add_signed_attribute(si,
764                                                 NID_pkcs9_messageDigest,
765                                                 V_ASN1_OCTET_STRING, digest))
766                 {
767                     M_ASN1_OCTET_STRING_free(digest);
768                     goto err;
769                 }
770
771                 /* Now sign the attributes */
772                 EVP_SignInit_ex(&ctx_tmp, md_tmp, NULL);
773                 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
774                                      ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
775                 if (!abuf)
776                     goto err;
777                 EVP_SignUpdate(&ctx_tmp, abuf, alen);
778                 OPENSSL_free(abuf);
779             }
780 #ifndef OPENSSL_NO_DSA
781             if (si->pkey->type == EVP_PKEY_DSA)
782                 ctx_tmp.digest = EVP_dss1();
783 #endif
784 #ifndef OPENSSL_NO_ECDSA
785             if (si->pkey->type == EVP_PKEY_EC)
786                 ctx_tmp.digest = EVP_ecdsa();
787 #endif
788
789             if (!EVP_SignFinal(&ctx_tmp, (unsigned char *)buf->data,
790                                (unsigned int *)&buf->length, si->pkey)) {
791                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
792                 goto err;
793             }
794             if (!ASN1_STRING_set(si->enc_digest,
795                                  (unsigned char *)buf->data, buf->length)) {
796                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_ASN1_LIB);
797                 goto err;
798             }
799         }
800     } else if (i == NID_pkcs7_digest) {
801         unsigned char md_data[EVP_MAX_MD_SIZE];
802         unsigned int md_len;
803         if (!PKCS7_find_digest(&mdc, bio,
804                                OBJ_obj2nid(p7->d.digest->md->algorithm)))
805             goto err;
806         EVP_DigestFinal_ex(mdc, md_data, &md_len);
807         M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
808     }
809
810     if (!PKCS7_is_detached(p7)) {
811         /*
812          * NOTE(emilia): I think we only reach os == NULL here because detached
813          * digested data support is broken.
814          */
815         if (os == NULL)
816             goto err;
817         btmp = BIO_find_type(bio, BIO_TYPE_MEM);
818         if (btmp == NULL) {
819             PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
820             goto err;
821         }
822         BIO_get_mem_ptr(btmp, &buf_mem);
823         /*
824          * Mark the BIO read only then we can use its copy of the data
825          * instead of making an extra copy.
826          */
827         BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
828         BIO_set_mem_eof_return(btmp, 0);
829         os->data = (unsigned char *)buf_mem->data;
830         os->length = buf_mem->length;
831 #if 0
832         M_ASN1_OCTET_STRING_set(os,
833                                 (unsigned char *)buf_mem->data,
834                                 buf_mem->length);
835 #endif
836     }
837     ret = 1;
838  err:
839     EVP_MD_CTX_cleanup(&ctx_tmp);
840     if (buf != NULL)
841         BUF_MEM_free(buf);
842     return (ret);
843 }
844
845 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
846                      PKCS7 *p7, PKCS7_SIGNER_INFO *si)
847 {
848     PKCS7_ISSUER_AND_SERIAL *ias;
849     int ret = 0, i;
850     STACK_OF(X509) *cert;
851     X509 *x509;
852
853     if (p7 == NULL) {
854         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
855         return 0;
856     }
857
858     if (p7->d.ptr == NULL) {
859         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
860         return 0;
861     }
862
863     if (PKCS7_type_is_signed(p7)) {
864         cert = p7->d.sign->cert;
865     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
866         cert = p7->d.signed_and_enveloped->cert;
867     } else {
868         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
869         goto err;
870     }
871     /* XXXXXXXXXXXXXXXXXXXXXXX */
872     ias = si->issuer_and_serial;
873
874     x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
875
876     /* were we able to find the cert in passed to us */
877     if (x509 == NULL) {
878         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
879                  PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
880         goto err;
881     }
882
883     /* Lets verify */
884     if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
885         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
886         goto err;
887     }
888     X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
889     i = X509_verify_cert(ctx);
890     if (i <= 0) {
891         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
892         X509_STORE_CTX_cleanup(ctx);
893         goto err;
894     }
895     X509_STORE_CTX_cleanup(ctx);
896
897     return PKCS7_signatureVerify(bio, p7, si, x509);
898  err:
899     return ret;
900 }
901
902 int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
903                           X509 *x509)
904 {
905     ASN1_OCTET_STRING *os;
906     EVP_MD_CTX mdc_tmp, *mdc;
907     int ret = 0, i;
908     int md_type;
909     STACK_OF(X509_ATTRIBUTE) *sk;
910     BIO *btmp;
911     EVP_PKEY *pkey;
912
913     EVP_MD_CTX_init(&mdc_tmp);
914
915     if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
916         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
917         goto err;
918     }
919
920     md_type = OBJ_obj2nid(si->digest_alg->algorithm);
921
922     btmp = bio;
923     for (;;) {
924         if ((btmp == NULL) ||
925             ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
926             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
927                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
928             goto err;
929         }
930         BIO_get_md_ctx(btmp, &mdc);
931         if (mdc == NULL) {
932             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
933             goto err;
934         }
935         if (EVP_MD_CTX_type(mdc) == md_type)
936             break;
937         /*
938          * Workaround for some broken clients that put the signature OID
939          * instead of the digest OID in digest_alg->algorithm
940          */
941         if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
942             break;
943         btmp = BIO_next(btmp);
944     }
945
946     /*
947      * mdc is the digest ctx that we want, unless there are attributes, in
948      * which case the digest is the signed attributes
949      */
950     EVP_MD_CTX_copy_ex(&mdc_tmp, mdc);
951
952     sk = si->auth_attr;
953     if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
954         unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
955         unsigned int md_len, alen;
956         ASN1_OCTET_STRING *message_digest;
957
958         EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len);
959         message_digest = PKCS7_digest_from_attributes(sk);
960         if (!message_digest) {
961             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
962                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
963             goto err;
964         }
965         if ((message_digest->length != (int)md_len) ||
966             (memcmp(message_digest->data, md_dat, md_len))) {
967 #if 0
968             {
969                 int ii;
970                 for (ii = 0; ii < message_digest->length; ii++)
971                     printf("%02X", message_digest->data[ii]);
972                 printf(" sent\n");
973                 for (ii = 0; ii < md_len; ii++)
974                     printf("%02X", md_dat[ii]);
975                 printf(" calc\n");
976             }
977 #endif
978             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
979             ret = -1;
980             goto err;
981         }
982
983         EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL);
984
985         alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
986                              ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
987         EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
988
989         OPENSSL_free(abuf);
990     }
991
992     os = si->enc_digest;
993     pkey = X509_get_pubkey(x509);
994     if (!pkey) {
995         ret = -1;
996         goto err;
997     }
998 #ifndef OPENSSL_NO_DSA
999     if (pkey->type == EVP_PKEY_DSA)
1000         mdc_tmp.digest = EVP_dss1();
1001 #endif
1002 #ifndef OPENSSL_NO_ECDSA
1003     if (pkey->type == EVP_PKEY_EC)
1004         mdc_tmp.digest = EVP_ecdsa();
1005 #endif
1006
1007     i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
1008     EVP_PKEY_free(pkey);
1009     if (i <= 0) {
1010         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
1011         ret = -1;
1012         goto err;
1013     } else
1014         ret = 1;
1015  err:
1016     EVP_MD_CTX_cleanup(&mdc_tmp);
1017     return (ret);
1018 }
1019
1020 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
1021 {
1022     STACK_OF(PKCS7_RECIP_INFO) *rsk;
1023     PKCS7_RECIP_INFO *ri;
1024     int i;
1025
1026     i = OBJ_obj2nid(p7->type);
1027     if (i != NID_pkcs7_signedAndEnveloped)
1028         return NULL;
1029     if (p7->d.signed_and_enveloped == NULL)
1030         return NULL;
1031     rsk = p7->d.signed_and_enveloped->recipientinfo;
1032     if (rsk == NULL)
1033         return NULL;
1034     ri = sk_PKCS7_RECIP_INFO_value(rsk, 0);
1035     if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
1036         return (NULL);
1037     ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
1038     return (ri->issuer_and_serial);
1039 }
1040
1041 ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
1042 {
1043     return (get_attribute(si->auth_attr, nid));
1044 }
1045
1046 ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
1047 {
1048     return (get_attribute(si->unauth_attr, nid));
1049 }
1050
1051 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
1052 {
1053     int i;
1054     X509_ATTRIBUTE *xa;
1055     ASN1_OBJECT *o;
1056
1057     o = OBJ_nid2obj(nid);
1058     if (!o || !sk)
1059         return (NULL);
1060     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1061         xa = sk_X509_ATTRIBUTE_value(sk, i);
1062         if (OBJ_cmp(xa->object, o) == 0) {
1063             if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
1064                 return (sk_ASN1_TYPE_value(xa->value.set, 0));
1065             else
1066                 return (NULL);
1067         }
1068     }
1069     return (NULL);
1070 }
1071
1072 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
1073 {
1074     ASN1_TYPE *astype;
1075     if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
1076         return NULL;
1077     return astype->value.octet_string;
1078 }
1079
1080 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
1081                                 STACK_OF(X509_ATTRIBUTE) *sk)
1082 {
1083     int i;
1084
1085     if (p7si->auth_attr != NULL)
1086         sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
1087     p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
1088     if (p7si->auth_attr == NULL)
1089         return 0;
1090     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1091         if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
1092                                    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1093                                                       (sk, i))))
1094             == NULL)
1095             return (0);
1096     }
1097     return (1);
1098 }
1099
1100 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
1101                          STACK_OF(X509_ATTRIBUTE) *sk)
1102 {
1103     int i;
1104
1105     if (p7si->unauth_attr != NULL)
1106         sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
1107     p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
1108     if (p7si->unauth_attr == NULL)
1109         return 0;
1110     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1111         if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
1112                                    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1113                                                       (sk, i))))
1114             == NULL)
1115             return (0);
1116     }
1117     return (1);
1118 }
1119
1120 int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1121                                void *value)
1122 {
1123     return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
1124 }
1125
1126 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1127                         void *value)
1128 {
1129     return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
1130 }
1131
1132 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1133                          void *value)
1134 {
1135     X509_ATTRIBUTE *attr = NULL;
1136
1137     if (*sk == NULL) {
1138         if (!(*sk = sk_X509_ATTRIBUTE_new_null()))
1139             return 0;
1140  new_attrib:
1141         if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
1142             return 0;
1143         if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
1144             X509_ATTRIBUTE_free(attr);
1145             return 0;
1146         }
1147     } else {
1148         int i;
1149
1150         for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
1151             attr = sk_X509_ATTRIBUTE_value(*sk, i);
1152             if (OBJ_obj2nid(attr->object) == nid) {
1153                 X509_ATTRIBUTE_free(attr);
1154                 attr = X509_ATTRIBUTE_create(nid, atrtype, value);
1155                 if (attr == NULL)
1156                     return 0;
1157                 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
1158                     X509_ATTRIBUTE_free(attr);
1159                     return 0;
1160                 }
1161                 goto end;
1162             }
1163         }
1164         goto new_attrib;
1165     }
1166  end:
1167     return (1);
1168 }