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