xref: /freebsd/crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 88b8b7f0c4e9948667a2279e78e975a784049cba)
1 /*
2  * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include <openssl/rand.h>
12 #include <openssl/objects.h>
13 #include <openssl/x509.h>
14 #include <openssl/x509v3.h>
15 #include <openssl/err.h>
16 #include "internal/cryptlib.h"
17 #include "internal/sizes.h"
18 #include "crypto/evp.h"
19 #include "pk7_local.h"
20 
21 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
22                          void *value);
23 static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid);
24 
25 int PKCS7_type_is_other(PKCS7 *p7)
26 {
27     int isOther = 1;
28 
29     int nid = OBJ_obj2nid(p7->type);
30 
31     switch (nid) {
32     case NID_pkcs7_data:
33     case NID_pkcs7_signed:
34     case NID_pkcs7_enveloped:
35     case NID_pkcs7_signedAndEnveloped:
36     case NID_pkcs7_digest:
37     case NID_pkcs7_encrypted:
38         isOther = 0;
39         break;
40     default:
41         isOther = 1;
42     }
43 
44     return isOther;
45 
46 }
47 
48 ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
49 {
50     if (PKCS7_type_is_data(p7))
51         return p7->d.data;
52     if (PKCS7_type_is_other(p7) && p7->d.other
53         && (p7->d.other->type == V_ASN1_OCTET_STRING))
54         return p7->d.other->value.octet_string;
55     return NULL;
56 }
57 
58 static ASN1_OCTET_STRING *pkcs7_get1_data(PKCS7 *p7)
59 {
60     ASN1_OCTET_STRING *os = PKCS7_get_octet_string(p7);
61 
62     if (os != NULL) {
63         /* Edge case for MIME content, see RFC 5652 section-5.2.1 */
64         ASN1_OCTET_STRING *osdup = ASN1_OCTET_STRING_dup(os);
65 
66         if (osdup != NULL && (os->flags & ASN1_STRING_FLAG_NDEF))
67             /* ASN1_STRING_FLAG_NDEF flag is currently used by openssl-smime */
68             ASN1_STRING_set0(osdup, NULL, 0);
69         return osdup;
70     }
71 
72     /* General case for PKCS#7 content, see RFC 2315 section-7 */
73     if (PKCS7_type_is_other(p7) && (p7->d.other != NULL)
74             && (p7->d.other->type == V_ASN1_SEQUENCE)
75             && (p7->d.other->value.sequence != NULL)
76             && (p7->d.other->value.sequence->length > 0)) {
77         const unsigned char *data = p7->d.other->value.sequence->data;
78         long len;
79         int inf, tag, class;
80 
81         os = ASN1_OCTET_STRING_new();
82         if (os == NULL)
83             return NULL;
84         inf = ASN1_get_object(&data, &len, &tag, &class,
85                               p7->d.other->value.sequence->length);
86         if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE
87                 || !ASN1_OCTET_STRING_set(os, data, len)) {
88             ASN1_OCTET_STRING_free(os);
89             os = NULL;
90         }
91     }
92     return os;
93 }
94 
95 static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg,
96                                 const PKCS7_CTX *ctx)
97 {
98     BIO *btmp;
99     char name[OSSL_MAX_NAME_SIZE];
100     EVP_MD *fetched = NULL;
101     const EVP_MD *md;
102 
103     if ((btmp = BIO_new(BIO_f_md())) == NULL) {
104         ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
105         goto err;
106     }
107 
108     OBJ_obj2txt(name, sizeof(name), alg->algorithm, 0);
109 
110     (void)ERR_set_mark();
111     fetched = EVP_MD_fetch(ossl_pkcs7_ctx_get0_libctx(ctx), name,
112                            ossl_pkcs7_ctx_get0_propq(ctx));
113     if (fetched != NULL)
114         md = fetched;
115     else
116         md = EVP_get_digestbyname(name);
117 
118     if (md == NULL) {
119         (void)ERR_clear_last_mark();
120         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE);
121         goto err;
122     }
123     (void)ERR_pop_to_mark();
124 
125     if (BIO_set_md(btmp, md) <= 0) {
126         ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
127         EVP_MD_free(fetched);
128         goto err;
129     }
130     EVP_MD_free(fetched);
131     if (*pbio == NULL)
132         *pbio = btmp;
133     else if (!BIO_push(*pbio, btmp)) {
134         ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
135         goto err;
136     }
137     btmp = NULL;
138 
139     return 1;
140 
141  err:
142     BIO_free(btmp);
143     return 0;
144 }
145 
146 static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
147                               unsigned char *key, int keylen)
148 {
149     EVP_PKEY_CTX *pctx = NULL;
150     EVP_PKEY *pkey = NULL;
151     unsigned char *ek = NULL;
152     int ret = 0;
153     size_t eklen;
154     const PKCS7_CTX *ctx = ri->ctx;
155 
156     pkey = X509_get0_pubkey(ri->cert);
157     if (pkey == NULL)
158         return 0;
159 
160     pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey,
161                                       ossl_pkcs7_ctx_get0_propq(ctx));
162     if (pctx == NULL)
163         return 0;
164 
165     if (EVP_PKEY_encrypt_init(pctx) <= 0)
166         goto err;
167 
168     if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
169         goto err;
170 
171     ek = OPENSSL_malloc(eklen);
172     if (ek == NULL)
173         goto err;
174 
175     if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
176         goto err;
177 
178     ASN1_STRING_set0(ri->enc_key, ek, eklen);
179     ek = NULL;
180 
181     ret = 1;
182 
183  err:
184     EVP_PKEY_CTX_free(pctx);
185     OPENSSL_free(ek);
186     return ret;
187 
188 }
189 
190 static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
191                                PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
192                                size_t fixlen)
193 {
194     EVP_PKEY_CTX *pctx = NULL;
195     unsigned char *ek = NULL;
196     size_t eklen;
197     int ret = -1;
198     const PKCS7_CTX *ctx = ri->ctx;
199 
200     pctx = EVP_PKEY_CTX_new_from_pkey(ossl_pkcs7_ctx_get0_libctx(ctx), pkey,
201                                       ossl_pkcs7_ctx_get0_propq(ctx));
202     if (pctx == NULL)
203         return -1;
204 
205     if (EVP_PKEY_decrypt_init(pctx) <= 0)
206         goto err;
207 
208     if (EVP_PKEY_is_a(pkey, "RSA"))
209         /* upper layer pkcs7 code incorrectly assumes that a successful RSA
210          * decryption means that the key matches ciphertext (which never
211          * was the case, implicit rejection or not), so to make it work
212          * disable implicit rejection for RSA keys */
213         EVP_PKEY_CTX_ctrl_str(pctx, "rsa_pkcs1_implicit_rejection", "0");
214 
215     ret = evp_pkey_decrypt_alloc(pctx, &ek, &eklen, fixlen,
216                                  ri->enc_key->data, ri->enc_key->length);
217     if (ret <= 0)
218         goto err;
219 
220     ret = 1;
221 
222     OPENSSL_clear_free(*pek, *peklen);
223     *pek = ek;
224     *peklen = eklen;
225 
226  err:
227     EVP_PKEY_CTX_free(pctx);
228     if (!ret)
229         OPENSSL_free(ek);
230 
231     return ret;
232 }
233 
234 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
235 {
236     int i;
237     BIO *out = NULL, *btmp = NULL;
238     X509_ALGOR *xa = NULL;
239     EVP_CIPHER *fetched_cipher = NULL;
240     const EVP_CIPHER *cipher;
241     const EVP_CIPHER *evp_cipher = NULL;
242     STACK_OF(X509_ALGOR) *md_sk = NULL;
243     STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
244     X509_ALGOR *xalg = NULL;
245     PKCS7_RECIP_INFO *ri = NULL;
246     ASN1_OCTET_STRING *os = NULL;
247     const PKCS7_CTX *p7_ctx;
248     OSSL_LIB_CTX *libctx;
249     const char *propq;
250 
251     if (p7 == NULL) {
252         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER);
253         return NULL;
254     }
255     p7_ctx = ossl_pkcs7_get0_ctx(p7);
256     libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx);
257     propq = ossl_pkcs7_ctx_get0_propq(p7_ctx);
258 
259     /*
260      * The content field in the PKCS7 ContentInfo is optional, but that really
261      * only applies to inner content (precisely, detached signatures).
262      *
263      * When reading content, missing outer content is therefore treated as an
264      * error.
265      *
266      * When creating content, PKCS7_content_new() must be called before
267      * calling this method, so a NULL p7->d is always an error.
268      */
269     if (p7->d.ptr == NULL) {
270         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
271         return NULL;
272     }
273 
274     i = OBJ_obj2nid(p7->type);
275     p7->state = PKCS7_S_HEADER;
276 
277     switch (i) {
278     case NID_pkcs7_signed:
279         md_sk = p7->d.sign->md_algs;
280         os = pkcs7_get1_data(p7->d.sign->contents);
281         break;
282     case NID_pkcs7_signedAndEnveloped:
283         rsk = p7->d.signed_and_enveloped->recipientinfo;
284         md_sk = p7->d.signed_and_enveloped->md_algs;
285         xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
286         evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
287         if (evp_cipher == NULL) {
288             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED);
289             goto err;
290         }
291         break;
292     case NID_pkcs7_enveloped:
293         rsk = p7->d.enveloped->recipientinfo;
294         xalg = p7->d.enveloped->enc_data->algorithm;
295         evp_cipher = p7->d.enveloped->enc_data->cipher;
296         if (evp_cipher == NULL) {
297             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_NOT_INITIALIZED);
298             goto err;
299         }
300         break;
301     case NID_pkcs7_digest:
302         xa = p7->d.digest->md;
303         os = pkcs7_get1_data(p7->d.digest->contents);
304         break;
305     case NID_pkcs7_data:
306         break;
307     default:
308         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
309         goto err;
310     }
311 
312     for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
313         if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx))
314             goto err;
315 
316     if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx))
317         goto err;
318 
319     if (evp_cipher != NULL) {
320         unsigned char key[EVP_MAX_KEY_LENGTH];
321         unsigned char iv[EVP_MAX_IV_LENGTH];
322         int keylen, ivlen;
323         EVP_CIPHER_CTX *ctx;
324 
325         if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
326             ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
327             goto err;
328         }
329         BIO_get_cipher_ctx(btmp, &ctx);
330         keylen = EVP_CIPHER_get_key_length(evp_cipher);
331         ivlen = EVP_CIPHER_get_iv_length(evp_cipher);
332         xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_get_type(evp_cipher));
333         if (ivlen > 0)
334             if (RAND_bytes_ex(libctx, iv, ivlen, 0) <= 0)
335                 goto err;
336 
337         (void)ERR_set_mark();
338         fetched_cipher = EVP_CIPHER_fetch(libctx,
339                                           EVP_CIPHER_get0_name(evp_cipher),
340                                           propq);
341         (void)ERR_pop_to_mark();
342         if (fetched_cipher != NULL)
343             cipher = fetched_cipher;
344         else
345             cipher = evp_cipher;
346 
347         if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0)
348             goto err;
349 
350         EVP_CIPHER_free(fetched_cipher);
351         fetched_cipher = NULL;
352 
353         if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
354             goto err;
355         if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
356             goto err;
357 
358         if (ivlen > 0) {
359             if (xalg->parameter == NULL) {
360                 xalg->parameter = ASN1_TYPE_new();
361                 if (xalg->parameter == NULL)
362                     goto err;
363             }
364             if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) <= 0) {
365                 ASN1_TYPE_free(xalg->parameter);
366                 xalg->parameter = NULL;
367                 goto err;
368             }
369         }
370 
371         /* Lets do the pub key stuff :-) */
372         for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
373             ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
374             if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
375                 goto err;
376         }
377         OPENSSL_cleanse(key, keylen);
378 
379         if (out == NULL)
380             out = btmp;
381         else
382             BIO_push(out, btmp);
383         btmp = NULL;
384     }
385 
386     if (bio == NULL) {
387         if (PKCS7_is_detached(p7)) {
388             bio = BIO_new(BIO_s_null());
389         } else if (os != NULL && os->length > 0) {
390             /*
391              * bio needs a copy of os->data instead of a pointer because
392              * the data will be used after os has been freed
393              */
394             bio = BIO_new(BIO_s_mem());
395             if (bio != NULL) {
396                 BIO_set_mem_eof_return(bio, 0);
397                 if (BIO_write(bio, os->data, os->length) != os->length) {
398                     BIO_free_all(bio);
399                     bio = NULL;
400                 }
401             }
402         } else {
403             bio = BIO_new(BIO_s_mem());
404             if (bio == NULL)
405                 goto err;
406             BIO_set_mem_eof_return(bio, 0);
407         }
408         if (bio == NULL)
409             goto err;
410     }
411     if (out)
412         BIO_push(out, bio);
413     else
414         out = bio;
415 
416     ASN1_OCTET_STRING_free(os);
417     return out;
418 
419  err:
420     ASN1_OCTET_STRING_free(os);
421     EVP_CIPHER_free(fetched_cipher);
422     BIO_free_all(out);
423     BIO_free_all(btmp);
424     return NULL;
425 }
426 
427 static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
428 {
429     int ret;
430     ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
431                         X509_get_issuer_name(pcert));
432     if (ret)
433         return ret;
434     return ASN1_INTEGER_cmp(X509_get0_serialNumber(pcert),
435                             ri->issuer_and_serial->serial);
436 }
437 
438 /* int */
439 BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
440 {
441     int i, len;
442     BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
443     X509_ALGOR *xa;
444     ASN1_OCTET_STRING *data_body = NULL;
445     EVP_MD *evp_md = NULL;
446     const EVP_MD *md;
447     EVP_CIPHER *evp_cipher = NULL;
448     const EVP_CIPHER *cipher = NULL;
449     EVP_CIPHER_CTX *evp_ctx = NULL;
450     X509_ALGOR *enc_alg = NULL;
451     STACK_OF(X509_ALGOR) *md_sk = NULL;
452     STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
453     PKCS7_RECIP_INFO *ri = NULL;
454     unsigned char *ek = NULL, *tkey = NULL;
455     int eklen = 0, tkeylen = 0;
456     char name[OSSL_MAX_NAME_SIZE];
457     const PKCS7_CTX *p7_ctx;
458     OSSL_LIB_CTX *libctx;
459     const char *propq;
460 
461     if (p7 == NULL) {
462         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER);
463         return NULL;
464     }
465 
466     p7_ctx = ossl_pkcs7_get0_ctx(p7);
467     libctx = ossl_pkcs7_ctx_get0_libctx(p7_ctx);
468     propq = ossl_pkcs7_ctx_get0_propq(p7_ctx);
469 
470     if (p7->d.ptr == NULL) {
471         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
472         return NULL;
473     }
474 
475     i = OBJ_obj2nid(p7->type);
476     p7->state = PKCS7_S_HEADER;
477 
478     switch (i) {
479     case NID_pkcs7_signed:
480         /*
481          * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
482          * field and optional content.
483          * data_body is NULL if that structure has no (=detached) content
484          * or if the contentType is wrong (i.e., not "data").
485          */
486         data_body = PKCS7_get_octet_string(p7->d.sign->contents);
487         if (!PKCS7_is_detached(p7) && data_body == NULL) {
488             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_SIGNED_DATA_TYPE);
489             goto err;
490         }
491         md_sk = p7->d.sign->md_algs;
492         break;
493     case NID_pkcs7_signedAndEnveloped:
494         rsk = p7->d.signed_and_enveloped->recipientinfo;
495         md_sk = p7->d.signed_and_enveloped->md_algs;
496         /* data_body is NULL if the optional EncryptedContent is missing. */
497         data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
498         enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
499 
500         OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0);
501 
502         (void)ERR_set_mark();
503         evp_cipher = EVP_CIPHER_fetch(libctx, name, propq);
504         if (evp_cipher != NULL)
505             cipher = evp_cipher;
506         else
507             cipher = EVP_get_cipherbyname(name);
508 
509         if (cipher == NULL) {
510             (void)ERR_clear_last_mark();
511             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
512             goto err;
513         }
514         (void)ERR_pop_to_mark();
515         break;
516     case NID_pkcs7_enveloped:
517         rsk = p7->d.enveloped->recipientinfo;
518         enc_alg = p7->d.enveloped->enc_data->algorithm;
519         /* data_body is NULL if the optional EncryptedContent is missing. */
520         data_body = p7->d.enveloped->enc_data->enc_data;
521         OBJ_obj2txt(name, sizeof(name), enc_alg->algorithm, 0);
522 
523         (void)ERR_set_mark();
524         evp_cipher = EVP_CIPHER_fetch(libctx, name, propq);
525         if (evp_cipher != NULL)
526             cipher = evp_cipher;
527         else
528             cipher = EVP_get_cipherbyname(name);
529 
530         if (cipher == NULL) {
531             (void)ERR_clear_last_mark();
532             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
533             goto err;
534         }
535         (void)ERR_pop_to_mark();
536         break;
537     default:
538         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
539         goto err;
540     }
541 
542     /* Detached content must be supplied via in_bio instead. */
543     if (data_body == NULL && in_bio == NULL) {
544         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
545         goto err;
546     }
547 
548     /* We will be checking the signature */
549     if (md_sk != NULL) {
550         for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
551             xa = sk_X509_ALGOR_value(md_sk, i);
552             if ((btmp = BIO_new(BIO_f_md())) == NULL) {
553                 ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
554                 goto err;
555             }
556 
557             OBJ_obj2txt(name, sizeof(name), xa->algorithm, 0);
558 
559             (void)ERR_set_mark();
560             evp_md = EVP_MD_fetch(libctx, name, propq);
561             if (evp_md != NULL)
562                 md = evp_md;
563             else
564                 md = EVP_get_digestbyname(name);
565 
566             if (md == NULL) {
567                 (void)ERR_clear_last_mark();
568                 ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_DIGEST_TYPE);
569                 goto err;
570             }
571             (void)ERR_pop_to_mark();
572 
573             if (BIO_set_md(btmp, md) <= 0) {
574                 EVP_MD_free(evp_md);
575                 ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
576                 goto err;
577             }
578             EVP_MD_free(evp_md);
579             if (out == NULL)
580                 out = btmp;
581             else
582                 BIO_push(out, btmp);
583             btmp = NULL;
584         }
585     }
586 
587     if (cipher != NULL) {
588         if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
589             ERR_raise(ERR_LIB_PKCS7, ERR_R_BIO_LIB);
590             goto err;
591         }
592 
593         /*
594          * It was encrypted, we need to decrypt the secret key with the
595          * private key
596          */
597 
598         /*
599          * Find the recipientInfo which matches the passed certificate (if
600          * any)
601          */
602 
603         if (pcert) {
604             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
605                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
606                 if (!pkcs7_cmp_ri(ri, pcert))
607                     break;
608                 ri = NULL;
609             }
610             if (ri == NULL) {
611                 ERR_raise(ERR_LIB_PKCS7,
612                           PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
613                 goto err;
614             }
615         }
616 
617         /* If we haven't got a certificate try each ri in turn */
618         if (pcert == NULL) {
619             /*
620              * Always attempt to decrypt all rinfo even after success as a
621              * defence against MMA timing attacks.
622              */
623             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
624                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
625                 ri->ctx = p7_ctx;
626                 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
627                         EVP_CIPHER_get_key_length(cipher)) < 0)
628                     goto err;
629                 ERR_clear_error();
630             }
631         } else {
632             ri->ctx = p7_ctx;
633             /* Only exit on fatal errors, not decrypt failure */
634             if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
635                 goto err;
636             ERR_clear_error();
637         }
638 
639         evp_ctx = NULL;
640         BIO_get_cipher_ctx(etmp, &evp_ctx);
641         if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0)
642             goto err;
643         if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) <= 0)
644             goto err;
645         /* Generate random key as MMA defence */
646         len = EVP_CIPHER_CTX_get_key_length(evp_ctx);
647         if (len <= 0)
648             goto err;
649         tkeylen = (size_t)len;
650         tkey = OPENSSL_malloc(tkeylen);
651         if (tkey == NULL)
652             goto err;
653         if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
654             goto err;
655         if (ek == NULL) {
656             ek = tkey;
657             eklen = tkeylen;
658             tkey = NULL;
659         }
660 
661         if (eklen != EVP_CIPHER_CTX_get_key_length(evp_ctx)) {
662             /*
663              * Some S/MIME clients don't use the same key and effective key
664              * length. The key length is determined by the size of the
665              * decrypted RSA key.
666              */
667             if (EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen) <= 0) {
668                 /* Use random key as MMA defence */
669                 OPENSSL_clear_free(ek, eklen);
670                 ek = tkey;
671                 eklen = tkeylen;
672                 tkey = NULL;
673             }
674         }
675         /* Clear errors so we don't leak information useful in MMA */
676         ERR_clear_error();
677         if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
678             goto err;
679 
680         OPENSSL_clear_free(ek, eklen);
681         ek = NULL;
682         OPENSSL_clear_free(tkey, tkeylen);
683         tkey = NULL;
684 
685         if (out == NULL)
686             out = etmp;
687         else
688             BIO_push(out, etmp);
689         etmp = NULL;
690     }
691     if (in_bio != NULL) {
692         bio = in_bio;
693     } else {
694         if (data_body->length > 0)
695             bio = BIO_new_mem_buf(data_body->data, data_body->length);
696         else {
697             bio = BIO_new(BIO_s_mem());
698             if (bio == NULL)
699                 goto err;
700             BIO_set_mem_eof_return(bio, 0);
701         }
702         if (bio == NULL)
703             goto err;
704     }
705     BIO_push(out, bio);
706     bio = NULL;
707     EVP_CIPHER_free(evp_cipher);
708     return out;
709 
710  err:
711     EVP_CIPHER_free(evp_cipher);
712     OPENSSL_clear_free(ek, eklen);
713     OPENSSL_clear_free(tkey, tkeylen);
714     BIO_free_all(out);
715     BIO_free_all(btmp);
716     BIO_free_all(etmp);
717     BIO_free_all(bio);
718     return NULL;
719 }
720 
721 static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
722 {
723     for (;;) {
724         bio = BIO_find_type(bio, BIO_TYPE_MD);
725         if (bio == NULL) {
726             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
727             return NULL;
728         }
729         BIO_get_md_ctx(bio, pmd);
730         if (*pmd == NULL) {
731             ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR);
732             return NULL;
733         }
734         if (EVP_MD_CTX_get_type(*pmd) == nid)
735             return bio;
736         bio = BIO_next(bio);
737     }
738     return NULL;
739 }
740 
741 static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
742 {
743     unsigned char md_data[EVP_MAX_MD_SIZE];
744     unsigned int md_len;
745 
746     /* Add signing time if not already present */
747     if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
748         if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
749             ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB);
750             return 0;
751         }
752     }
753 
754     /* Add digest */
755     if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
756         ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB);
757         return 0;
758     }
759     if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
760         ERR_raise(ERR_LIB_PKCS7, ERR_R_PKCS7_LIB);
761         return 0;
762     }
763 
764     /* Now sign the attributes */
765     if (!PKCS7_SIGNER_INFO_sign(si))
766         return 0;
767 
768     return 1;
769 }
770 
771 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
772 {
773     int ret = 0;
774     int i, j;
775     BIO *btmp;
776     PKCS7_SIGNER_INFO *si;
777     EVP_MD_CTX *mdc, *ctx_tmp;
778     STACK_OF(X509_ATTRIBUTE) *sk;
779     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
780     ASN1_OCTET_STRING *os = NULL;
781     const PKCS7_CTX *p7_ctx;
782 
783     if (p7 == NULL) {
784         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER);
785         return 0;
786     }
787 
788     p7_ctx = ossl_pkcs7_get0_ctx(p7);
789 
790     if (p7->d.ptr == NULL) {
791         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
792         return 0;
793     }
794 
795     ctx_tmp = EVP_MD_CTX_new();
796     if (ctx_tmp == NULL) {
797         ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB);
798         return 0;
799     }
800 
801     i = OBJ_obj2nid(p7->type);
802     p7->state = PKCS7_S_HEADER;
803 
804     switch (i) {
805     case NID_pkcs7_data:
806         os = p7->d.data;
807         break;
808     case NID_pkcs7_signedAndEnveloped:
809         /* XXXXXXXXXXXXXXXX */
810         si_sk = p7->d.signed_and_enveloped->signer_info;
811         os = p7->d.signed_and_enveloped->enc_data->enc_data;
812         if (os == NULL) {
813             os = ASN1_OCTET_STRING_new();
814             if (os == NULL) {
815                 ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB);
816                 goto err;
817             }
818             p7->d.signed_and_enveloped->enc_data->enc_data = os;
819         }
820         break;
821     case NID_pkcs7_enveloped:
822         /* XXXXXXXXXXXXXXXX */
823         os = p7->d.enveloped->enc_data->enc_data;
824         if (os == NULL) {
825             os = ASN1_OCTET_STRING_new();
826             if (os == NULL) {
827                 ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB);
828                 goto err;
829             }
830             p7->d.enveloped->enc_data->enc_data = os;
831         }
832         break;
833     case NID_pkcs7_signed:
834         si_sk = p7->d.sign->signer_info;
835         os = PKCS7_get_octet_string(p7->d.sign->contents);
836         /* If detached data then the content is excluded */
837         if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
838             ASN1_OCTET_STRING_free(os);
839             os = NULL;
840             p7->d.sign->contents->d.data = NULL;
841         }
842         break;
843 
844     case NID_pkcs7_digest:
845         os = PKCS7_get_octet_string(p7->d.digest->contents);
846         /* If detached data then the content is excluded */
847         if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
848             ASN1_OCTET_STRING_free(os);
849             os = NULL;
850             p7->d.digest->contents->d.data = NULL;
851         }
852         break;
853 
854     default:
855         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
856         goto err;
857     }
858 
859     if (si_sk != NULL) {
860         for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
861             si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
862             if (si->pkey == NULL)
863                 continue;
864 
865             j = OBJ_obj2nid(si->digest_alg->algorithm);
866 
867             btmp = bio;
868 
869             btmp = PKCS7_find_digest(&mdc, btmp, j);
870 
871             if (btmp == NULL)
872                 goto err;
873 
874             /*
875              * We now have the EVP_MD_CTX, lets do the signing.
876              */
877             if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
878                 goto err;
879 
880             sk = si->auth_attr;
881 
882             /*
883              * If there are attributes, we add the digest attribute and only
884              * sign the attributes
885              */
886             if (sk_X509_ATTRIBUTE_num(sk) > 0) {
887                 if (!do_pkcs7_signed_attrib(si, ctx_tmp))
888                     goto err;
889             } else {
890                 unsigned char *abuf = NULL;
891                 unsigned int abuflen = EVP_PKEY_get_size(si->pkey);
892 
893                 if (abuflen == 0 || (abuf = OPENSSL_malloc(abuflen)) == NULL)
894                     goto err;
895 
896                 if (!EVP_SignFinal_ex(ctx_tmp, abuf, &abuflen, si->pkey,
897                                       ossl_pkcs7_ctx_get0_libctx(p7_ctx),
898                                       ossl_pkcs7_ctx_get0_propq(p7_ctx))) {
899                     OPENSSL_free(abuf);
900                     ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB);
901                     goto err;
902                 }
903                 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
904             }
905         }
906     } else if (i == NID_pkcs7_digest) {
907         unsigned char md_data[EVP_MAX_MD_SIZE];
908         unsigned int md_len;
909         if (!PKCS7_find_digest(&mdc, bio,
910                                OBJ_obj2nid(p7->d.digest->md->algorithm)))
911             goto err;
912         if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
913             goto err;
914         if (!ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len))
915             goto err;
916     }
917 
918     if (!PKCS7_is_detached(p7)) {
919         /*
920          * NOTE(emilia): I think we only reach os == NULL here because detached
921          * digested data support is broken.
922          */
923         if (os == NULL)
924             goto err;
925         if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
926             char *cont;
927             long contlen;
928             btmp = BIO_find_type(bio, BIO_TYPE_MEM);
929             if (btmp == NULL) {
930                 ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
931                 goto err;
932             }
933             contlen = BIO_get_mem_data(btmp, &cont);
934             /*
935              * Mark the BIO read only then we can use its copy of the data
936              * instead of making an extra copy.
937              */
938             BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
939             BIO_set_mem_eof_return(btmp, 0);
940             ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
941         }
942     }
943     ret = 1;
944  err:
945     EVP_MD_CTX_free(ctx_tmp);
946     return ret;
947 }
948 
949 int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
950 {
951     EVP_MD_CTX *mctx;
952     EVP_PKEY_CTX *pctx = NULL;
953     unsigned char *abuf = NULL;
954     int alen;
955     size_t siglen;
956     const EVP_MD *md = NULL;
957     const PKCS7_CTX *ctx = si->ctx;
958 
959     md = EVP_get_digestbyobj(si->digest_alg->algorithm);
960     if (md == NULL)
961         return 0;
962 
963     mctx = EVP_MD_CTX_new();
964     if (mctx == NULL) {
965         ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB);
966         goto err;
967     }
968 
969     if (EVP_DigestSignInit_ex(mctx, &pctx, EVP_MD_get0_name(md),
970                               ossl_pkcs7_ctx_get0_libctx(ctx),
971                               ossl_pkcs7_ctx_get0_propq(ctx), si->pkey,
972                               NULL) <= 0)
973         goto err;
974 
975     alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
976                          ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
977     if (alen < 0 || abuf == NULL)
978         goto err;
979     if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
980         goto err;
981     OPENSSL_free(abuf);
982     abuf = NULL;
983     if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
984         goto err;
985     abuf = OPENSSL_malloc(siglen);
986     if (abuf == NULL)
987         goto err;
988     if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
989         goto err;
990 
991     EVP_MD_CTX_free(mctx);
992 
993     ASN1_STRING_set0(si->enc_digest, abuf, siglen);
994 
995     return 1;
996 
997  err:
998     OPENSSL_free(abuf);
999     EVP_MD_CTX_free(mctx);
1000     return 0;
1001 }
1002 
1003 /* This partly overlaps with PKCS7_verify(). It does not support flags. */
1004 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
1005                      PKCS7 *p7, PKCS7_SIGNER_INFO *si)
1006 {
1007     PKCS7_ISSUER_AND_SERIAL *ias;
1008     int ret = 0, i;
1009     STACK_OF(X509) *untrusted;
1010     STACK_OF(X509_CRL) *crls;
1011     X509 *signer;
1012 
1013     if (p7 == NULL) {
1014         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_INVALID_NULL_POINTER);
1015         return 0;
1016     }
1017 
1018     if (p7->d.ptr == NULL) {
1019         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
1020         return 0;
1021     }
1022 
1023     if (PKCS7_type_is_signed(p7)) {
1024         untrusted = p7->d.sign->cert;
1025         crls = p7->d.sign->crl;
1026     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
1027         untrusted = p7->d.signed_and_enveloped->cert;
1028         crls = p7->d.signed_and_enveloped->crl;
1029     } else {
1030         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE);
1031         goto err;
1032     }
1033     X509_STORE_CTX_set0_crls(ctx, crls);
1034 
1035     /* XXXXXXXXXXXXXXXXXXXXXXX */
1036     ias = si->issuer_and_serial;
1037 
1038     signer = X509_find_by_issuer_and_serial(untrusted, ias->issuer, ias->serial);
1039 
1040     /* Were we able to find the signer certificate in passed to us? */
1041     if (signer == NULL) {
1042         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
1043         goto err;
1044     }
1045 
1046     /* Lets verify */
1047     if (!X509_STORE_CTX_init(ctx, cert_store, signer, untrusted)) {
1048         ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB);
1049         goto err;
1050     }
1051     X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
1052     i = X509_verify_cert(ctx);
1053     if (i <= 0) {
1054         ERR_raise(ERR_LIB_PKCS7, ERR_R_X509_LIB);
1055         goto err;
1056     }
1057 
1058     return PKCS7_signatureVerify(bio, p7, si, signer);
1059  err:
1060     return ret;
1061 }
1062 
1063 int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
1064                           X509 *signer)
1065 {
1066     ASN1_OCTET_STRING *os;
1067     EVP_MD_CTX *mdc_tmp, *mdc;
1068     const EVP_MD *md;
1069     EVP_MD *fetched_md = NULL;
1070     int ret = 0, i;
1071     int md_type;
1072     STACK_OF(X509_ATTRIBUTE) *sk;
1073     BIO *btmp;
1074     EVP_PKEY *pkey;
1075     unsigned char *abuf = NULL;
1076     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
1077     OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
1078     const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
1079 
1080     mdc_tmp = EVP_MD_CTX_new();
1081     if (mdc_tmp == NULL) {
1082         ERR_raise(ERR_LIB_PKCS7, ERR_R_EVP_LIB);
1083         goto err;
1084     }
1085 
1086     if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
1087         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_PKCS7_TYPE);
1088         goto err;
1089     }
1090 
1091     md_type = OBJ_obj2nid(si->digest_alg->algorithm);
1092 
1093     btmp = bio;
1094     for (;;) {
1095         if ((btmp == NULL) ||
1096             ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
1097             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1098             goto err;
1099         }
1100         BIO_get_md_ctx(btmp, &mdc);
1101         if (mdc == NULL) {
1102             ERR_raise(ERR_LIB_PKCS7, ERR_R_INTERNAL_ERROR);
1103             goto err;
1104         }
1105         if (EVP_MD_CTX_get_type(mdc) == md_type)
1106             break;
1107         /*
1108          * Workaround for some broken clients that put the signature OID
1109          * instead of the digest OID in digest_alg->algorithm
1110          */
1111         if (EVP_MD_get_pkey_type(EVP_MD_CTX_get0_md(mdc)) == md_type)
1112             break;
1113         btmp = BIO_next(btmp);
1114     }
1115 
1116     /*
1117      * mdc is the digest ctx that we want, unless there are attributes, in
1118      * which case the digest is the signed attributes
1119      */
1120     if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
1121         goto err;
1122 
1123     sk = si->auth_attr;
1124     if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
1125         unsigned char md_dat[EVP_MAX_MD_SIZE];
1126         unsigned int md_len;
1127         int alen;
1128         ASN1_OCTET_STRING *message_digest;
1129 
1130         if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
1131             goto err;
1132         message_digest = PKCS7_digest_from_attributes(sk);
1133         if (!message_digest) {
1134             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1135             goto err;
1136         }
1137         if ((message_digest->length != (int)md_len) ||
1138             (memcmp(message_digest->data, md_dat, md_len))) {
1139             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE);
1140             ret = -1;
1141             goto err;
1142         }
1143 
1144         (void)ERR_set_mark();
1145         fetched_md = EVP_MD_fetch(libctx, OBJ_nid2sn(md_type), propq);
1146 
1147         if (fetched_md != NULL)
1148             md = fetched_md;
1149         else
1150             md = EVP_get_digestbynid(md_type);
1151 
1152         if (md == NULL || !EVP_VerifyInit_ex(mdc_tmp, md, NULL)) {
1153             (void)ERR_clear_last_mark();
1154             goto err;
1155         }
1156         (void)ERR_pop_to_mark();
1157 
1158         alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
1159                              ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
1160         if (alen <= 0 || abuf == NULL) {
1161             ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB);
1162             ret = -1;
1163             goto err;
1164         }
1165         if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
1166             goto err;
1167     }
1168 
1169     os = si->enc_digest;
1170     pkey = X509_get0_pubkey(signer);
1171     if (pkey == NULL) {
1172         ret = -1;
1173         goto err;
1174     }
1175 
1176     i = EVP_VerifyFinal_ex(mdc_tmp, os->data, os->length, pkey, libctx, propq);
1177     if (i <= 0) {
1178         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE);
1179         ret = -1;
1180         goto err;
1181     }
1182     ret = 1;
1183  err:
1184     OPENSSL_free(abuf);
1185     EVP_MD_CTX_free(mdc_tmp);
1186     EVP_MD_free(fetched_md);
1187     return ret;
1188 }
1189 
1190 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
1191 {
1192     STACK_OF(PKCS7_RECIP_INFO) *rsk;
1193     PKCS7_RECIP_INFO *ri;
1194     int i;
1195 
1196     i = OBJ_obj2nid(p7->type);
1197     if (i != NID_pkcs7_signedAndEnveloped)
1198         return NULL;
1199     if (p7->d.signed_and_enveloped == NULL)
1200         return NULL;
1201     rsk = p7->d.signed_and_enveloped->recipientinfo;
1202     if (rsk == NULL)
1203         return NULL;
1204     if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
1205         return NULL;
1206     ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
1207     return ri->issuer_and_serial;
1208 }
1209 
1210 ASN1_TYPE *PKCS7_get_signed_attribute(const PKCS7_SIGNER_INFO *si, int nid)
1211 {
1212     return get_attribute(si->auth_attr, nid);
1213 }
1214 
1215 ASN1_TYPE *PKCS7_get_attribute(const PKCS7_SIGNER_INFO *si, int nid)
1216 {
1217     return get_attribute(si->unauth_attr, nid);
1218 }
1219 
1220 static ASN1_TYPE *get_attribute(const STACK_OF(X509_ATTRIBUTE) *sk, int nid)
1221 {
1222     int idx = X509at_get_attr_by_NID(sk, nid, -1);
1223 
1224     if (idx < 0)
1225         return NULL;
1226     return X509_ATTRIBUTE_get0_type(X509at_get_attr(sk, idx), 0);
1227 }
1228 
1229 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
1230 {
1231     ASN1_TYPE *astype;
1232     if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
1233         return NULL;
1234     return astype->value.octet_string;
1235 }
1236 
1237 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
1238                                 STACK_OF(X509_ATTRIBUTE) *sk)
1239 {
1240     sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
1241     p7si->auth_attr = sk_X509_ATTRIBUTE_deep_copy(sk, X509_ATTRIBUTE_dup, X509_ATTRIBUTE_free);
1242     if (p7si->auth_attr == NULL)
1243         return 0;
1244     return 1;
1245 }
1246 
1247 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
1248                          STACK_OF(X509_ATTRIBUTE) *sk)
1249 {
1250     sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
1251     p7si->unauth_attr = sk_X509_ATTRIBUTE_deep_copy(sk, X509_ATTRIBUTE_dup, X509_ATTRIBUTE_free);
1252     if (p7si->unauth_attr == NULL)
1253         return 0;
1254     return 1;
1255 }
1256 
1257 int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1258                                void *value)
1259 {
1260     return add_attribute(&(p7si->auth_attr), nid, atrtype, value);
1261 }
1262 
1263 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1264                         void *value)
1265 {
1266     return add_attribute(&(p7si->unauth_attr), nid, atrtype, value);
1267 }
1268 
1269 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1270                          void *value)
1271 {
1272     X509_ATTRIBUTE *attr = NULL;
1273     int i, n;
1274 
1275     if (*sk == NULL) {
1276         if ((*sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
1277             return 0;
1278     }
1279     n = sk_X509_ATTRIBUTE_num(*sk);
1280     for (i = 0; i < n; i++) {
1281         attr = sk_X509_ATTRIBUTE_value(*sk, i);
1282         if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid)
1283             goto end;
1284     }
1285     if (!sk_X509_ATTRIBUTE_push(*sk, NULL))
1286         return 0;
1287 
1288  end:
1289     attr = X509_ATTRIBUTE_create(nid, atrtype, value);
1290     if (attr == NULL) {
1291         if (i == n)
1292             sk_X509_ATTRIBUTE_pop(*sk);
1293         return 0;
1294     }
1295     X509_ATTRIBUTE_free(sk_X509_ATTRIBUTE_value(*sk, i));
1296     (void) sk_X509_ATTRIBUTE_set(*sk, i, attr);
1297     return 1;
1298 }
1299