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