Update copyright year
[openssl.git] / crypto / pkcs7 / pk7_lib.c
1 /*
2  * Copyright 1995-2022 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 "internal/cryptlib.h"
12 #include <openssl/objects.h>
13 #include <openssl/x509.h>
14 #include <openssl/pkcs7.h>
15 #include "crypto/asn1.h"
16 #include "crypto/evp.h"
17 #include "crypto/x509.h" /* for sk_X509_add1_cert() */
18 #include "pk7_local.h"
19
20 long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
21 {
22     int nid;
23     long ret;
24
25     nid = OBJ_obj2nid(p7->type);
26
27     switch (cmd) {
28     /* NOTE(emilia): does not support detached digested data. */
29     case PKCS7_OP_SET_DETACHED_SIGNATURE:
30         if (nid == NID_pkcs7_signed) {
31             ret = p7->detached = (int)larg;
32             if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
33                 ASN1_OCTET_STRING *os;
34                 os = p7->d.sign->contents->d.data;
35                 ASN1_OCTET_STRING_free(os);
36                 p7->d.sign->contents->d.data = NULL;
37             }
38         } else {
39             ERR_raise(ERR_LIB_PKCS7,
40                       PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
41             ret = 0;
42         }
43         break;
44     case PKCS7_OP_GET_DETACHED_SIGNATURE:
45         if (nid == NID_pkcs7_signed) {
46             if (p7->d.sign == NULL || p7->d.sign->contents->d.ptr == NULL)
47                 ret = 1;
48             else
49                 ret = 0;
50
51             p7->detached = ret;
52         } else {
53             ERR_raise(ERR_LIB_PKCS7,
54                       PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
55             ret = 0;
56         }
57
58         break;
59     default:
60         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION);
61         ret = 0;
62     }
63     return ret;
64 }
65
66 int PKCS7_content_new(PKCS7 *p7, int type)
67 {
68     PKCS7 *ret = NULL;
69
70     if ((ret = PKCS7_new()) == NULL)
71         goto err;
72     if (!PKCS7_set_type(ret, type))
73         goto err;
74     if (!PKCS7_set_content(p7, ret))
75         goto err;
76
77     return 1;
78  err:
79     PKCS7_free(ret);
80     return 0;
81 }
82
83 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
84 {
85     int i;
86
87     i = OBJ_obj2nid(p7->type);
88     switch (i) {
89     case NID_pkcs7_signed:
90         PKCS7_free(p7->d.sign->contents);
91         p7->d.sign->contents = p7_data;
92         break;
93     case NID_pkcs7_digest:
94         PKCS7_free(p7->d.digest->contents);
95         p7->d.digest->contents = p7_data;
96         break;
97     case NID_pkcs7_data:
98     case NID_pkcs7_enveloped:
99     case NID_pkcs7_signedAndEnveloped:
100     case NID_pkcs7_encrypted:
101     default:
102         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
103         goto err;
104     }
105     return 1;
106  err:
107     return 0;
108 }
109
110 int PKCS7_set_type(PKCS7 *p7, int type)
111 {
112     ASN1_OBJECT *obj;
113
114     /*
115      * PKCS7_content_free(p7);
116      */
117     obj = OBJ_nid2obj(type);    /* will not fail */
118
119     switch (type) {
120     case NID_pkcs7_signed:
121         p7->type = obj;
122         if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
123             goto err;
124         if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
125             PKCS7_SIGNED_free(p7->d.sign);
126             p7->d.sign = NULL;
127             goto err;
128         }
129         break;
130     case NID_pkcs7_data:
131         p7->type = obj;
132         if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
133             goto err;
134         break;
135     case NID_pkcs7_signedAndEnveloped:
136         p7->type = obj;
137         if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
138             == NULL)
139             goto err;
140         if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
141             goto err;
142         p7->d.signed_and_enveloped->enc_data->content_type
143             = OBJ_nid2obj(NID_pkcs7_data);
144         break;
145     case NID_pkcs7_enveloped:
146         p7->type = obj;
147         if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
148             == NULL)
149             goto err;
150         if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
151             goto err;
152         p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
153         break;
154     case NID_pkcs7_encrypted:
155         p7->type = obj;
156         if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
157             == NULL)
158             goto err;
159         if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
160             goto err;
161         p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
162         break;
163
164     case NID_pkcs7_digest:
165         p7->type = obj;
166         if ((p7->d.digest = PKCS7_DIGEST_new())
167             == NULL)
168             goto err;
169         if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
170             goto err;
171         break;
172     default:
173         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
174         goto err;
175     }
176     return 1;
177  err:
178     return 0;
179 }
180
181 int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
182 {
183     p7->type = OBJ_nid2obj(type);
184     p7->d.other = other;
185     return 1;
186 }
187
188 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
189 {
190     int i, j;
191     ASN1_OBJECT *obj;
192     X509_ALGOR *alg;
193     STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
194     STACK_OF(X509_ALGOR) *md_sk;
195
196     i = OBJ_obj2nid(p7->type);
197     switch (i) {
198     case NID_pkcs7_signed:
199         signer_sk = p7->d.sign->signer_info;
200         md_sk = p7->d.sign->md_algs;
201         break;
202     case NID_pkcs7_signedAndEnveloped:
203         signer_sk = p7->d.signed_and_enveloped->signer_info;
204         md_sk = p7->d.signed_and_enveloped->md_algs;
205         break;
206     default:
207         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
208         return 0;
209     }
210
211     obj = psi->digest_alg->algorithm;
212     /* If the digest is not currently listed, add it */
213     j = 0;
214     for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
215         alg = sk_X509_ALGOR_value(md_sk, i);
216         if (OBJ_cmp(obj, alg->algorithm) == 0) {
217             j = 1;
218             break;
219         }
220     }
221     if (!j) {                   /* we need to add another algorithm */
222         int nid;
223
224         if ((alg = X509_ALGOR_new()) == NULL
225             || (alg->parameter = ASN1_TYPE_new()) == NULL) {
226             X509_ALGOR_free(alg);
227             ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
228             return 0;
229         }
230         /*
231          * If there is a constant copy of the ASN1 OBJECT in libcrypto, then
232          * use that.  Otherwise, use a dynamically duplicated copy
233          */
234         if ((nid = OBJ_obj2nid(obj)) != NID_undef)
235             alg->algorithm = OBJ_nid2obj(nid);
236         else
237             alg->algorithm = OBJ_dup(obj);
238         alg->parameter->type = V_ASN1_NULL;
239         if (alg->algorithm == NULL || !sk_X509_ALGOR_push(md_sk, alg)) {
240             X509_ALGOR_free(alg);
241             return 0;
242         }
243     }
244
245     psi->ctx = ossl_pkcs7_get0_ctx(p7);
246     if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
247         return 0;
248     return 1;
249 }
250
251 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
252 {
253     int i;
254     STACK_OF(X509) **sk;
255
256     i = OBJ_obj2nid(p7->type);
257     switch (i) {
258     case NID_pkcs7_signed:
259         sk = &(p7->d.sign->cert);
260         break;
261     case NID_pkcs7_signedAndEnveloped:
262         sk = &(p7->d.signed_and_enveloped->cert);
263         break;
264     default:
265         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
266         return 0;
267     }
268
269     return ossl_x509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF);
270 }
271
272 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
273 {
274     int i;
275     STACK_OF(X509_CRL) **sk;
276
277     i = OBJ_obj2nid(p7->type);
278     switch (i) {
279     case NID_pkcs7_signed:
280         sk = &(p7->d.sign->crl);
281         break;
282     case NID_pkcs7_signedAndEnveloped:
283         sk = &(p7->d.signed_and_enveloped->crl);
284         break;
285     default:
286         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
287         return 0;
288     }
289
290     if (*sk == NULL)
291         *sk = sk_X509_CRL_new_null();
292     if (*sk == NULL) {
293         ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
294         return 0;
295     }
296
297     X509_CRL_up_ref(crl);
298     if (!sk_X509_CRL_push(*sk, crl)) {
299         X509_CRL_free(crl);
300         return 0;
301     }
302     return 1;
303 }
304
305 static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si,
306                                                 int verify)
307 {
308     if (!verify) {
309         int snid, hnid;
310         X509_ALGOR *alg1, *alg2;
311         EVP_PKEY *pkey = si->pkey;
312
313         PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2);
314         if (alg1 == NULL || alg1->algorithm == NULL)
315             return -1;
316         hnid = OBJ_obj2nid(alg1->algorithm);
317         if (hnid == NID_undef)
318             return -1;
319         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey)))
320             return -1;
321         return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
322     }
323     return 1;
324 }
325
326 static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify)
327 {
328     if (!verify) {
329         X509_ALGOR *alg = NULL;
330
331         PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg);
332         if (alg != NULL)
333             return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
334                                    V_ASN1_NULL, NULL);
335     }
336     return 1;
337 }
338
339 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
340                           const EVP_MD *dgst)
341 {
342     int ret;
343
344     /* We now need to add another PKCS7_SIGNER_INFO entry */
345     if (!ASN1_INTEGER_set(p7i->version, 1))
346         return 0;
347     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
348                        X509_get_issuer_name(x509)))
349         return 0;
350
351     /*
352      * because ASN1_INTEGER_set is used to set a 'long' we will do things the
353      * ugly way.
354      */
355     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
356     if (!(p7i->issuer_and_serial->serial =
357           ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
358         return 0;
359
360     /* lets keep the pkey around for a while */
361     EVP_PKEY_up_ref(pkey);
362     p7i->pkey = pkey;
363
364     /* Set the algorithms */
365
366     if (!X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)),
367                          V_ASN1_NULL, NULL))
368         return 0;
369
370     if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA"))
371         return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0);
372     if (EVP_PKEY_is_a(pkey, "RSA"))
373         return pkcs7_rsa_sign_verify_setup(p7i, 0);
374
375     if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) {
376         ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
377         if (ret > 0)
378             return 1;
379         if (ret != -2) {
380             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE);
381             return 0;
382         }
383     }
384     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
385     return 0;
386 }
387
388 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
389                                        const EVP_MD *dgst)
390 {
391     PKCS7_SIGNER_INFO *si = NULL;
392
393     if (dgst == NULL) {
394         int def_nid;
395         if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
396             goto err;
397         dgst = EVP_get_digestbynid(def_nid);
398         if (dgst == NULL) {
399             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST);
400             goto err;
401         }
402     }
403
404     if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
405         goto err;
406     if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
407         goto err;
408     if (!PKCS7_add_signer(p7, si))
409         goto err;
410     return si;
411  err:
412     PKCS7_SIGNER_INFO_free(si);
413     return NULL;
414 }
415
416 static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
417 {
418     if (PKCS7_type_is_signed(p7))
419         return p7->d.sign->cert;
420     if (PKCS7_type_is_signedAndEnveloped(p7))
421         return p7->d.signed_and_enveloped->cert;
422     return NULL;
423 }
424
425 static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
426 {
427     if (PKCS7_type_is_signedAndEnveloped(p7))
428         return p7->d.signed_and_enveloped->recipientinfo;
429     if (PKCS7_type_is_enveloped(p7))
430         return p7->d.enveloped->recipientinfo;
431     return NULL;
432 }
433
434 /*
435  * Set up the library context into any loaded structure that needs it.
436  * i.e loaded X509 objects.
437  */
438 void ossl_pkcs7_resolve_libctx(PKCS7 *p7)
439 {
440     int i;
441     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
442     OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
443     const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
444     STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7);
445     STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
446     STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7);
447
448     if (ctx == NULL)
449         return;
450
451     for (i = 0; i < sk_X509_num(certs); i++)
452         ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
453
454     for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
455         PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
456
457         ossl_x509_set0_libctx(ri->cert, libctx, propq);
458     }
459
460     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
461         PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
462
463         if (si != NULL)
464             si->ctx = ctx;
465     }
466 }
467
468 const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
469 {
470     return p7 != NULL ? &p7->ctx : NULL;
471 }
472
473 void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
474 {
475     p7->ctx.libctx = ctx;
476 }
477
478 int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
479 {
480     if (p7->ctx.propq != NULL) {
481         OPENSSL_free(p7->ctx.propq);
482         p7->ctx.propq = NULL;
483     }
484     if (propq != NULL) {
485         p7->ctx.propq = OPENSSL_strdup(propq);
486         if (p7->ctx.propq == NULL) {
487             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
488             return 0;
489         }
490     }
491     return 1;
492 }
493
494 int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
495 {
496     ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
497     if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
498         return 0;
499
500     ossl_pkcs7_resolve_libctx(to);
501     return 1;
502 }
503
504 OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
505 {
506     return ctx != NULL ? ctx->libctx : NULL;
507 }
508 const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
509 {
510     return ctx != NULL ? ctx->propq : NULL;
511 }
512
513 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
514 {
515     if (PKCS7_type_is_digest(p7)) {
516         if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
517             ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
518             return 0;
519         }
520         p7->d.digest->md->parameter->type = V_ASN1_NULL;
521         p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
522         return 1;
523     }
524
525     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
526     return 1;
527 }
528
529 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
530 {
531     if (p7 == NULL || p7->d.ptr == NULL)
532         return NULL;
533     if (PKCS7_type_is_signed(p7)) {
534         return p7->d.sign->signer_info;
535     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
536         return p7->d.signed_and_enveloped->signer_info;
537     } else
538         return NULL;
539 }
540
541 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
542                                  X509_ALGOR **pdig, X509_ALGOR **psig)
543 {
544     if (pk)
545         *pk = si->pkey;
546     if (pdig)
547         *pdig = si->digest_alg;
548     if (psig)
549         *psig = si->digest_enc_alg;
550 }
551
552 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
553 {
554     if (penc)
555         *penc = ri->key_enc_algor;
556 }
557
558 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
559 {
560     PKCS7_RECIP_INFO *ri;
561
562     if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
563         goto err;
564     if (!PKCS7_RECIP_INFO_set(ri, x509))
565         goto err;
566     if (!PKCS7_add_recipient_info(p7, ri))
567         goto err;
568     ri->ctx = ossl_pkcs7_get0_ctx(p7);
569     return ri;
570  err:
571     PKCS7_RECIP_INFO_free(ri);
572     return NULL;
573 }
574
575 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
576 {
577     int i;
578     STACK_OF(PKCS7_RECIP_INFO) *sk;
579
580     i = OBJ_obj2nid(p7->type);
581     switch (i) {
582     case NID_pkcs7_signedAndEnveloped:
583         sk = p7->d.signed_and_enveloped->recipientinfo;
584         break;
585     case NID_pkcs7_enveloped:
586         sk = p7->d.enveloped->recipientinfo;
587         break;
588     default:
589         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
590         return 0;
591     }
592
593     if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
594         return 0;
595     return 1;
596 }
597
598 static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt)
599 {
600     X509_ALGOR *alg = NULL;
601
602     if (!decrypt) {
603         PKCS7_RECIP_INFO_get0_alg(ri, &alg);
604         if (alg != NULL)
605             return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
606                                    V_ASN1_NULL, NULL);
607     }
608     return 1;
609 }
610
611 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
612 {
613     int ret;
614     EVP_PKEY *pkey = NULL;
615     if (!ASN1_INTEGER_set(p7i->version, 0))
616         return 0;
617     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
618                        X509_get_issuer_name(x509)))
619         return 0;
620
621     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
622     if (!(p7i->issuer_and_serial->serial =
623           ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
624         return 0;
625
626     pkey = X509_get0_pubkey(x509);
627     if (pkey == NULL)
628         return 0;
629
630     if (EVP_PKEY_is_a(pkey, "RSA-PSS"))
631         return -2;
632     if (EVP_PKEY_is_a(pkey, "RSA")) {
633         if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0)
634             goto err;
635         goto finished;
636     }
637
638     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) {
639         ERR_raise(ERR_LIB_PKCS7,
640                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
641         goto err;
642     }
643
644     ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
645     if (ret == -2) {
646         ERR_raise(ERR_LIB_PKCS7,
647                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
648         goto err;
649     }
650     if (ret <= 0) {
651         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE);
652         goto err;
653     }
654 finished:
655     X509_up_ref(x509);
656     p7i->cert = x509;
657
658     return 1;
659
660  err:
661     return 0;
662 }
663
664 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
665 {
666     if (PKCS7_type_is_signed(p7))
667         return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
668                                                si->issuer_and_serial->issuer,
669                                                si->
670                                                issuer_and_serial->serial));
671     else
672         return NULL;
673 }
674
675 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
676 {
677     int i;
678     PKCS7_ENC_CONTENT *ec;
679
680     i = OBJ_obj2nid(p7->type);
681     switch (i) {
682     case NID_pkcs7_signedAndEnveloped:
683         ec = p7->d.signed_and_enveloped->enc_data;
684         break;
685     case NID_pkcs7_enveloped:
686         ec = p7->d.enveloped->enc_data;
687         break;
688     default:
689         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
690         return 0;
691     }
692
693     /* Check cipher OID exists and has data in it */
694     i = EVP_CIPHER_get_type(cipher);
695     if (i == NID_undef) {
696         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
697         return 0;
698     }
699
700     ec->cipher = cipher;
701     ec->ctx = ossl_pkcs7_get0_ctx(p7);
702     return 1;
703 }
704
705 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
706 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
707 {
708     ASN1_OCTET_STRING *os = NULL;
709
710     switch (OBJ_obj2nid(p7->type)) {
711     case NID_pkcs7_data:
712         os = p7->d.data;
713         break;
714
715     case NID_pkcs7_signedAndEnveloped:
716         os = p7->d.signed_and_enveloped->enc_data->enc_data;
717         if (os == NULL) {
718             os = ASN1_OCTET_STRING_new();
719             p7->d.signed_and_enveloped->enc_data->enc_data = os;
720         }
721         break;
722
723     case NID_pkcs7_enveloped:
724         os = p7->d.enveloped->enc_data->enc_data;
725         if (os == NULL) {
726             os = ASN1_OCTET_STRING_new();
727             p7->d.enveloped->enc_data->enc_data = os;
728         }
729         break;
730
731     case NID_pkcs7_signed:
732         os = p7->d.sign->contents->d.data;
733         break;
734
735     default:
736         os = NULL;
737         break;
738     }
739
740     if (os == NULL)
741         return 0;
742
743     os->flags |= ASN1_STRING_FLAG_NDEF;
744     *boundary = &os->data;
745
746     return 1;
747 }