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