fips module header inclusion fine-tunning
[openssl.git] / crypto / pkcs7 / pk7_lib.c
1 /*
2  * Copyright 1995-2021 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 == 0) {
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         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
322     }
323     return 1;
324 }
325
326 static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify)
327 {
328     if (verify == 0) {
329         X509_ALGOR *alg = NULL;
330
331         PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg);
332         if (alg != NULL)
333             X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
334     }
335     return 1;
336 }
337
338 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
339                           const EVP_MD *dgst)
340 {
341     int ret;
342
343     /* We now need to add another PKCS7_SIGNER_INFO entry */
344     if (!ASN1_INTEGER_set(p7i->version, 1))
345         goto err;
346     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
347                        X509_get_issuer_name(x509)))
348         goto err;
349
350     /*
351      * because ASN1_INTEGER_set is used to set a 'long' we will do things the
352      * ugly way.
353      */
354     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
355     if (!(p7i->issuer_and_serial->serial =
356           ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
357         goto err;
358
359     /* lets keep the pkey around for a while */
360     EVP_PKEY_up_ref(pkey);
361     p7i->pkey = pkey;
362
363     /* Set the algorithms */
364
365     X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_get_type(dgst)),
366                     V_ASN1_NULL, NULL);
367
368     if (EVP_PKEY_is_a(pkey, "EC") || EVP_PKEY_is_a(pkey, "DSA"))
369         return pkcs7_ecdsa_or_dsa_sign_verify_setup(p7i, 0);
370     if (EVP_PKEY_is_a(pkey, "RSA"))
371         return pkcs7_rsa_sign_verify_setup(p7i, 0);
372
373     if (pkey->ameth != NULL && pkey->ameth->pkey_ctrl != NULL) {
374         ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
375         if (ret > 0)
376             return 1;
377         if (ret != -2) {
378             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_CTRL_FAILURE);
379             return 0;
380         }
381     }
382     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
383  err:
384     return 0;
385 }
386
387 PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
388                                        const EVP_MD *dgst)
389 {
390     PKCS7_SIGNER_INFO *si = NULL;
391
392     if (dgst == NULL) {
393         int def_nid;
394         if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
395             goto err;
396         dgst = EVP_get_digestbynid(def_nid);
397         if (dgst == NULL) {
398             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_DEFAULT_DIGEST);
399             goto err;
400         }
401     }
402
403     if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
404         goto err;
405     if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
406         goto err;
407     if (!PKCS7_add_signer(p7, si))
408         goto err;
409     return si;
410  err:
411     PKCS7_SIGNER_INFO_free(si);
412     return NULL;
413 }
414
415 static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
416 {
417     if (PKCS7_type_is_signed(p7))
418         return p7->d.sign->cert;
419     if (PKCS7_type_is_signedAndEnveloped(p7))
420         return p7->d.signed_and_enveloped->cert;
421     return NULL;
422 }
423
424 static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
425 {
426     if (PKCS7_type_is_signedAndEnveloped(p7))
427         return p7->d.signed_and_enveloped->recipientinfo;
428     if (PKCS7_type_is_enveloped(p7))
429         return p7->d.enveloped->recipientinfo;
430     return NULL;
431 }
432
433 /*
434  * Set up the library context into any loaded structure that needs it.
435  * i.e loaded X509 objects.
436  */
437 void ossl_pkcs7_resolve_libctx(PKCS7 *p7)
438 {
439     int i;
440     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
441     OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
442     const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
443     STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7);
444     STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
445     STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7);
446
447     if (ctx == NULL)
448         return;
449
450     for (i = 0; i < sk_X509_num(certs); i++)
451         ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
452
453     for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
454         PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
455
456         ossl_x509_set0_libctx(ri->cert, libctx, propq);
457     }
458
459     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
460         PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
461
462         if (si != NULL)
463             si->ctx = ctx;
464     }
465 }
466
467 const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
468 {
469     return p7 != NULL ? &p7->ctx : NULL;
470 }
471
472 void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
473 {
474     p7->ctx.libctx = ctx;
475 }
476
477 int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
478 {
479     if (p7->ctx.propq != NULL) {
480         OPENSSL_free(p7->ctx.propq);
481         p7->ctx.propq = NULL;
482     }
483     if (propq != NULL) {
484         p7->ctx.propq = OPENSSL_strdup(propq);
485         if (p7->ctx.propq == NULL) {
486             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
487             return 0;
488         }
489     }
490     return 1;
491 }
492
493 int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
494 {
495     ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
496     if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
497         return 0;
498
499     ossl_pkcs7_resolve_libctx(to);
500     return 1;
501 }
502
503 OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
504 {
505     return ctx != NULL ? ctx->libctx : NULL;
506 }
507 const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
508 {
509     return ctx != NULL ? ctx->propq : NULL;
510 }
511
512 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
513 {
514     if (PKCS7_type_is_digest(p7)) {
515         if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
516             ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
517             return 0;
518         }
519         p7->d.digest->md->parameter->type = V_ASN1_NULL;
520         p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
521         return 1;
522     }
523
524     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
525     return 1;
526 }
527
528 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
529 {
530     if (p7 == NULL || p7->d.ptr == NULL)
531         return NULL;
532     if (PKCS7_type_is_signed(p7)) {
533         return p7->d.sign->signer_info;
534     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
535         return p7->d.signed_and_enveloped->signer_info;
536     } else
537         return NULL;
538 }
539
540 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
541                                  X509_ALGOR **pdig, X509_ALGOR **psig)
542 {
543     if (pk)
544         *pk = si->pkey;
545     if (pdig)
546         *pdig = si->digest_alg;
547     if (psig)
548         *psig = si->digest_enc_alg;
549 }
550
551 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
552 {
553     if (penc)
554         *penc = ri->key_enc_algor;
555 }
556
557 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
558 {
559     PKCS7_RECIP_INFO *ri;
560
561     if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
562         goto err;
563     if (!PKCS7_RECIP_INFO_set(ri, x509))
564         goto err;
565     if (!PKCS7_add_recipient_info(p7, ri))
566         goto err;
567     ri->ctx = ossl_pkcs7_get0_ctx(p7);
568     return ri;
569  err:
570     PKCS7_RECIP_INFO_free(ri);
571     return NULL;
572 }
573
574 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
575 {
576     int i;
577     STACK_OF(PKCS7_RECIP_INFO) *sk;
578
579     i = OBJ_obj2nid(p7->type);
580     switch (i) {
581     case NID_pkcs7_signedAndEnveloped:
582         sk = p7->d.signed_and_enveloped->recipientinfo;
583         break;
584     case NID_pkcs7_enveloped:
585         sk = p7->d.enveloped->recipientinfo;
586         break;
587     default:
588         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
589         return 0;
590     }
591
592     if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
593         return 0;
594     return 1;
595 }
596
597 static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt)
598 {
599     X509_ALGOR *alg = NULL;
600
601     if (decrypt == 0) {
602         PKCS7_RECIP_INFO_get0_alg(ri, &alg);
603         if (alg != NULL)
604             X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
605     }
606     return 1;
607 }
608
609 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
610 {
611     int ret;
612     EVP_PKEY *pkey = NULL;
613     if (!ASN1_INTEGER_set(p7i->version, 0))
614         return 0;
615     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
616                        X509_get_issuer_name(x509)))
617         return 0;
618
619     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
620     if (!(p7i->issuer_and_serial->serial =
621           ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
622         return 0;
623
624     pkey = X509_get0_pubkey(x509);
625     if (pkey == NULL)
626         return 0;
627
628     if (EVP_PKEY_is_a(pkey, "RSA-PSS"))
629         return -2;
630     if (EVP_PKEY_is_a(pkey, "RSA")) {
631         if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0)
632             goto err;
633         goto finished;
634     }
635
636     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) {
637         ERR_raise(ERR_LIB_PKCS7,
638                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
639         goto err;
640     }
641
642     ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
643     if (ret == -2) {
644         ERR_raise(ERR_LIB_PKCS7,
645                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
646         goto err;
647     }
648     if (ret <= 0) {
649         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE);
650         goto err;
651     }
652 finished:
653     X509_up_ref(x509);
654     p7i->cert = x509;
655
656     return 1;
657
658  err:
659     return 0;
660 }
661
662 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
663 {
664     if (PKCS7_type_is_signed(p7))
665         return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
666                                                si->issuer_and_serial->issuer,
667                                                si->
668                                                issuer_and_serial->serial));
669     else
670         return NULL;
671 }
672
673 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
674 {
675     int i;
676     PKCS7_ENC_CONTENT *ec;
677
678     i = OBJ_obj2nid(p7->type);
679     switch (i) {
680     case NID_pkcs7_signedAndEnveloped:
681         ec = p7->d.signed_and_enveloped->enc_data;
682         break;
683     case NID_pkcs7_enveloped:
684         ec = p7->d.enveloped->enc_data;
685         break;
686     default:
687         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
688         return 0;
689     }
690
691     /* Check cipher OID exists and has data in it */
692     i = EVP_CIPHER_get_type(cipher);
693     if (i == NID_undef) {
694         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
695         return 0;
696     }
697
698     ec->cipher = cipher;
699     ec->ctx = ossl_pkcs7_get0_ctx(p7);
700     return 1;
701 }
702
703 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
704 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
705 {
706     ASN1_OCTET_STRING *os = NULL;
707
708     switch (OBJ_obj2nid(p7->type)) {
709     case NID_pkcs7_data:
710         os = p7->d.data;
711         break;
712
713     case NID_pkcs7_signedAndEnveloped:
714         os = p7->d.signed_and_enveloped->enc_data->enc_data;
715         if (os == NULL) {
716             os = ASN1_OCTET_STRING_new();
717             p7->d.signed_and_enveloped->enc_data->enc_data = os;
718         }
719         break;
720
721     case NID_pkcs7_enveloped:
722         os = p7->d.enveloped->enc_data->enc_data;
723         if (os == NULL) {
724             os = ASN1_OCTET_STRING_new();
725             p7->d.enveloped->enc_data->enc_data = os;
726         }
727         break;
728
729     case NID_pkcs7_signed:
730         os = p7->d.sign->contents->d.data;
731         break;
732
733     default:
734         os = NULL;
735         break;
736     }
737
738     if (os == NULL)
739         return 0;
740
741     os->flags |= ASN1_STRING_FLAG_NDEF;
742     *boundary = &os->data;
743
744     return 1;
745 }