7be292854296445d13ba56bc8e9475c92d6762cc
[openssl.git] / crypto / pkcs7 / pk7_lib.c
1 /*
2  * Copyright 1995-2023 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_ASN1_LIB);
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_CRYPTO_LIB);
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) <= 0)
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 (p7->d.ptr == NULL)
419         return NULL;
420     if (PKCS7_type_is_signed(p7))
421         return p7->d.sign->cert;
422     if (PKCS7_type_is_signedAndEnveloped(p7))
423         return p7->d.signed_and_enveloped->cert;
424     return NULL;
425 }
426
427 static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
428 {
429     if (p7->d.ptr == NULL)
430         return NULL;
431     if (PKCS7_type_is_signedAndEnveloped(p7))
432         return p7->d.signed_and_enveloped->recipientinfo;
433     if (PKCS7_type_is_enveloped(p7))
434         return p7->d.enveloped->recipientinfo;
435     return NULL;
436 }
437
438 /*
439  * Set up the library context into any loaded structure that needs it.
440  * i.e loaded X509 objects.
441  */
442 void ossl_pkcs7_resolve_libctx(PKCS7 *p7)
443 {
444     int i;
445     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
446     OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
447     const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
448     STACK_OF(PKCS7_RECIP_INFO) *rinfos;
449     STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
450     STACK_OF(X509) *certs;
451
452     if (ctx == NULL || p7->d.ptr == NULL)
453         return;
454
455     rinfos = pkcs7_get_recipient_info(p7);
456     sinfos = PKCS7_get_signer_info(p7);
457     certs = pkcs7_get_signer_certs(p7);
458
459     for (i = 0; i < sk_X509_num(certs); i++)
460         ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
461
462     for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
463         PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
464
465         ossl_x509_set0_libctx(ri->cert, libctx, propq);
466     }
467
468     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
469         PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
470
471         if (si != NULL)
472             si->ctx = ctx;
473     }
474 }
475
476 const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
477 {
478     return p7 != NULL ? &p7->ctx : NULL;
479 }
480
481 void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
482 {
483     p7->ctx.libctx = ctx;
484 }
485
486 int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
487 {
488     if (p7->ctx.propq != NULL) {
489         OPENSSL_free(p7->ctx.propq);
490         p7->ctx.propq = NULL;
491     }
492     if (propq != NULL) {
493         p7->ctx.propq = OPENSSL_strdup(propq);
494         if (p7->ctx.propq == NULL)
495             return 0;
496     }
497     return 1;
498 }
499
500 int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
501 {
502     ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
503     if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
504         return 0;
505
506     ossl_pkcs7_resolve_libctx(to);
507     return 1;
508 }
509
510 OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
511 {
512     return ctx != NULL ? ctx->libctx : NULL;
513 }
514 const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
515 {
516     return ctx != NULL ? ctx->propq : NULL;
517 }
518
519 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
520 {
521     if (PKCS7_type_is_digest(p7)) {
522         if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
523             ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB);
524             return 0;
525         }
526         p7->d.digest->md->parameter->type = V_ASN1_NULL;
527         p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
528         return 1;
529     }
530
531     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
532     return 1;
533 }
534
535 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
536 {
537     if (p7 == NULL || p7->d.ptr == NULL)
538         return NULL;
539     if (PKCS7_type_is_signed(p7)) {
540         return p7->d.sign->signer_info;
541     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
542         return p7->d.signed_and_enveloped->signer_info;
543     } else
544         return NULL;
545 }
546
547 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
548                                  X509_ALGOR **pdig, X509_ALGOR **psig)
549 {
550     if (pk)
551         *pk = si->pkey;
552     if (pdig)
553         *pdig = si->digest_alg;
554     if (psig)
555         *psig = si->digest_enc_alg;
556 }
557
558 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
559 {
560     if (penc)
561         *penc = ri->key_enc_algor;
562 }
563
564 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
565 {
566     PKCS7_RECIP_INFO *ri;
567
568     if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
569         goto err;
570     if (PKCS7_RECIP_INFO_set(ri, x509) <= 0)
571         goto err;
572     if (!PKCS7_add_recipient_info(p7, ri))
573         goto err;
574     ri->ctx = ossl_pkcs7_get0_ctx(p7);
575     return ri;
576  err:
577     PKCS7_RECIP_INFO_free(ri);
578     return NULL;
579 }
580
581 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
582 {
583     int i;
584     STACK_OF(PKCS7_RECIP_INFO) *sk;
585
586     i = OBJ_obj2nid(p7->type);
587     switch (i) {
588     case NID_pkcs7_signedAndEnveloped:
589         sk = p7->d.signed_and_enveloped->recipientinfo;
590         break;
591     case NID_pkcs7_enveloped:
592         sk = p7->d.enveloped->recipientinfo;
593         break;
594     default:
595         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
596         return 0;
597     }
598
599     if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
600         return 0;
601     return 1;
602 }
603
604 static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt)
605 {
606     X509_ALGOR *alg = NULL;
607
608     if (!decrypt) {
609         PKCS7_RECIP_INFO_get0_alg(ri, &alg);
610         if (alg != NULL)
611             return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
612                                    V_ASN1_NULL, NULL);
613     }
614     return 1;
615 }
616
617 int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
618 {
619     int ret;
620     EVP_PKEY *pkey = NULL;
621     if (!ASN1_INTEGER_set(p7i->version, 0))
622         return 0;
623     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
624                        X509_get_issuer_name(x509)))
625         return 0;
626
627     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
628     if (!(p7i->issuer_and_serial->serial =
629           ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
630         return 0;
631
632     pkey = X509_get0_pubkey(x509);
633     if (pkey == NULL)
634         return 0;
635
636     if (EVP_PKEY_is_a(pkey, "RSA-PSS"))
637         return -2;
638     if (EVP_PKEY_is_a(pkey, "RSA")) {
639         if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0)
640             goto err;
641         goto finished;
642     }
643
644     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) {
645         ERR_raise(ERR_LIB_PKCS7,
646                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
647         goto err;
648     }
649
650     ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
651     if (ret == -2) {
652         ERR_raise(ERR_LIB_PKCS7,
653                   PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
654         goto err;
655     }
656     if (ret <= 0) {
657         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE);
658         goto err;
659     }
660 finished:
661     X509_up_ref(x509);
662     p7i->cert = x509;
663
664     return 1;
665
666  err:
667     return 0;
668 }
669
670 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
671 {
672     if (PKCS7_type_is_signed(p7))
673         return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
674                                                si->issuer_and_serial->issuer,
675                                                si->
676                                                issuer_and_serial->serial));
677     else
678         return NULL;
679 }
680
681 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
682 {
683     int i;
684     PKCS7_ENC_CONTENT *ec;
685
686     i = OBJ_obj2nid(p7->type);
687     switch (i) {
688     case NID_pkcs7_signedAndEnveloped:
689         ec = p7->d.signed_and_enveloped->enc_data;
690         break;
691     case NID_pkcs7_enveloped:
692         ec = p7->d.enveloped->enc_data;
693         break;
694     default:
695         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
696         return 0;
697     }
698
699     /* Check cipher OID exists and has data in it */
700     i = EVP_CIPHER_get_type(cipher);
701     if (i == NID_undef) {
702         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
703         return 0;
704     }
705
706     ec->cipher = cipher;
707     ec->ctx = ossl_pkcs7_get0_ctx(p7);
708     return 1;
709 }
710
711 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
712 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
713 {
714     ASN1_OCTET_STRING *os = NULL;
715
716     switch (OBJ_obj2nid(p7->type)) {
717     case NID_pkcs7_data:
718         os = p7->d.data;
719         break;
720
721     case NID_pkcs7_signedAndEnveloped:
722         os = p7->d.signed_and_enveloped->enc_data->enc_data;
723         if (os == NULL) {
724             os = ASN1_OCTET_STRING_new();
725             p7->d.signed_and_enveloped->enc_data->enc_data = os;
726         }
727         break;
728
729     case NID_pkcs7_enveloped:
730         os = p7->d.enveloped->enc_data->enc_data;
731         if (os == NULL) {
732             os = ASN1_OCTET_STRING_new();
733             p7->d.enveloped->enc_data->enc_data = os;
734         }
735         break;
736
737     case NID_pkcs7_signed:
738         os = p7->d.sign->contents->d.data;
739         break;
740
741     default:
742         os = NULL;
743         break;
744     }
745
746     if (os == NULL)
747         return 0;
748
749     os->flags |= ASN1_STRING_FLAG_NDEF;
750     *boundary = &os->data;
751
752     return 1;
753 }