xref: /freebsd/crypto/openssl/crypto/pkcs7/pk7_lib.c (revision 10a428653ee7216475f1ddce3fb4cbf1200319f8)
1 /*
2  * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include "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 == NULL
52                 || p7->d.sign->contents->d.ptr == NULL)
53                 ret = 1;
54             else
55                 ret = 0;
56 
57             p7->detached = ret;
58         } else {
59             ERR_raise(ERR_LIB_PKCS7,
60                 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
61             ret = 0;
62         }
63 
64         break;
65     default:
66         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNKNOWN_OPERATION);
67         ret = 0;
68     }
69     return ret;
70 }
71 
PKCS7_content_new(PKCS7 * p7,int type)72 int PKCS7_content_new(PKCS7 *p7, int type)
73 {
74     PKCS7 *ret = NULL;
75 
76     if ((ret = PKCS7_new()) == NULL)
77         goto err;
78     if (!PKCS7_set_type(ret, type))
79         goto err;
80     if (!PKCS7_set_content(p7, ret))
81         goto err;
82 
83     return 1;
84 err:
85     PKCS7_free(ret);
86     return 0;
87 }
88 
PKCS7_set_content(PKCS7 * p7,PKCS7 * p7_data)89 int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
90 {
91     int i;
92 
93     i = OBJ_obj2nid(p7->type);
94     switch (i) {
95     case NID_pkcs7_signed:
96         PKCS7_free(p7->d.sign->contents);
97         p7->d.sign->contents = p7_data;
98         break;
99     case NID_pkcs7_digest:
100         PKCS7_free(p7->d.digest->contents);
101         p7->d.digest->contents = p7_data;
102         break;
103     case NID_pkcs7_data:
104     case NID_pkcs7_enveloped:
105     case NID_pkcs7_signedAndEnveloped:
106     case NID_pkcs7_encrypted:
107     default:
108         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
109         goto err;
110     }
111     return 1;
112 err:
113     return 0;
114 }
115 
PKCS7_set_type(PKCS7 * p7,int type)116 int PKCS7_set_type(PKCS7 *p7, int type)
117 {
118     ASN1_OBJECT *obj;
119 
120     /*
121      * PKCS7_content_free(p7);
122      */
123     obj = OBJ_nid2obj(type); /* will not fail */
124 
125     switch (type) {
126     case NID_pkcs7_signed:
127         p7->type = obj;
128         if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
129             goto err;
130         if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
131             PKCS7_SIGNED_free(p7->d.sign);
132             p7->d.sign = NULL;
133             goto err;
134         }
135         break;
136     case NID_pkcs7_data:
137         p7->type = obj;
138         if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
139             goto err;
140         break;
141     case NID_pkcs7_signedAndEnveloped:
142         p7->type = obj;
143         if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
144             == NULL)
145             goto err;
146         if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
147             goto err;
148         p7->d.signed_and_enveloped->enc_data->content_type
149             = OBJ_nid2obj(NID_pkcs7_data);
150         break;
151     case NID_pkcs7_enveloped:
152         p7->type = obj;
153         if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
154             == NULL)
155             goto err;
156         if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
157             goto err;
158         p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
159         break;
160     case NID_pkcs7_encrypted:
161         p7->type = obj;
162         if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
163             == NULL)
164             goto err;
165         if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
166             goto err;
167         p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
168         break;
169 
170     case NID_pkcs7_digest:
171         p7->type = obj;
172         if ((p7->d.digest = PKCS7_DIGEST_new())
173             == NULL)
174             goto err;
175         if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
176             goto err;
177         break;
178     default:
179         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
180         goto err;
181     }
182     return 1;
183 err:
184     return 0;
185 }
186 
PKCS7_set0_type_other(PKCS7 * p7,int type,ASN1_TYPE * other)187 int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
188 {
189     p7->type = OBJ_nid2obj(type);
190     p7->d.other = other;
191     return 1;
192 }
193 
PKCS7_add_signer(PKCS7 * p7,PKCS7_SIGNER_INFO * psi)194 int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
195 {
196     int i, j;
197     ASN1_OBJECT *obj;
198     X509_ALGOR *alg;
199     STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
200     STACK_OF(X509_ALGOR) *md_sk;
201 
202     i = OBJ_obj2nid(p7->type);
203     switch (i) {
204     case NID_pkcs7_signed:
205         signer_sk = p7->d.sign->signer_info;
206         md_sk = p7->d.sign->md_algs;
207         break;
208     case NID_pkcs7_signedAndEnveloped:
209         signer_sk = p7->d.signed_and_enveloped->signer_info;
210         md_sk = p7->d.signed_and_enveloped->md_algs;
211         break;
212     default:
213         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
214         return 0;
215     }
216 
217     obj = psi->digest_alg->algorithm;
218     /* If the digest is not currently listed, add it */
219     j = 0;
220     for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
221         alg = sk_X509_ALGOR_value(md_sk, i);
222         if (OBJ_cmp(obj, alg->algorithm) == 0) {
223             j = 1;
224             break;
225         }
226     }
227     if (!j) { /* we need to add another algorithm */
228         int nid;
229 
230         if ((alg = X509_ALGOR_new()) == NULL
231             || (alg->parameter = ASN1_TYPE_new()) == NULL) {
232             X509_ALGOR_free(alg);
233             ERR_raise(ERR_LIB_PKCS7, ERR_R_ASN1_LIB);
234             return 0;
235         }
236         /*
237          * If there is a constant copy of the ASN1 OBJECT in libcrypto, then
238          * use that.  Otherwise, use a dynamically duplicated copy
239          */
240         if ((nid = OBJ_obj2nid(obj)) != NID_undef)
241             alg->algorithm = OBJ_nid2obj(nid);
242         else
243             alg->algorithm = OBJ_dup(obj);
244         alg->parameter->type = V_ASN1_NULL;
245         if (alg->algorithm == NULL || !sk_X509_ALGOR_push(md_sk, alg)) {
246             X509_ALGOR_free(alg);
247             return 0;
248         }
249     }
250 
251     psi->ctx = ossl_pkcs7_get0_ctx(p7);
252     if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
253         return 0;
254     return 1;
255 }
256 
PKCS7_add_certificate(PKCS7 * p7,X509 * x509)257 int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
258 {
259     int i;
260     STACK_OF(X509) **sk;
261 
262     i = OBJ_obj2nid(p7->type);
263     switch (i) {
264     case NID_pkcs7_signed:
265         sk = &(p7->d.sign->cert);
266         break;
267     case NID_pkcs7_signedAndEnveloped:
268         sk = &(p7->d.signed_and_enveloped->cert);
269         break;
270     default:
271         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
272         return 0;
273     }
274 
275     return ossl_x509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF);
276 }
277 
PKCS7_add_crl(PKCS7 * p7,X509_CRL * crl)278 int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
279 {
280     int i;
281     STACK_OF(X509_CRL) **sk;
282 
283     i = OBJ_obj2nid(p7->type);
284     switch (i) {
285     case NID_pkcs7_signed:
286         sk = &(p7->d.sign->crl);
287         break;
288     case NID_pkcs7_signedAndEnveloped:
289         sk = &(p7->d.signed_and_enveloped->crl);
290         break;
291     default:
292         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
293         return 0;
294     }
295 
296     if (*sk == NULL)
297         *sk = sk_X509_CRL_new_null();
298     if (*sk == NULL) {
299         ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB);
300         return 0;
301     }
302 
303     if (!X509_CRL_up_ref(crl))
304         return 0;
305     if (!sk_X509_CRL_push(*sk, crl)) {
306         X509_CRL_free(crl);
307         return 0;
308     }
309     return 1;
310 }
311 
pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO * si,int verify)312 static int pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO *si,
313     int verify)
314 {
315     if (!verify) {
316         int snid, hnid;
317         X509_ALGOR *alg1, *alg2;
318         EVP_PKEY *pkey = si->pkey;
319 
320         PKCS7_SIGNER_INFO_get0_algs(si, NULL, &alg1, &alg2);
321         if (alg1 == NULL || alg1->algorithm == NULL)
322             return -1;
323         hnid = OBJ_obj2nid(alg1->algorithm);
324         if (hnid == NID_undef)
325             return -1;
326         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_get_id(pkey)))
327             return -1;
328         return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
329     }
330     return 1;
331 }
332 
pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO * si,int verify)333 static int pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO *si, int verify)
334 {
335     if (!verify) {
336         X509_ALGOR *alg = NULL;
337 
338         PKCS7_SIGNER_INFO_get0_algs(si, NULL, NULL, &alg);
339         if (alg != NULL)
340             return X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
341                 V_ASN1_NULL, NULL);
342     }
343     return 1;
344 }
345 
PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO * p7i,X509 * x509,EVP_PKEY * pkey,const EVP_MD * dgst)346 int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
347     const EVP_MD *dgst)
348 {
349     int ret;
350 
351     /* We now need to add another PKCS7_SIGNER_INFO entry */
352     if (!ASN1_INTEGER_set(p7i->version, 1))
353         return 0;
354     if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
355             X509_get_issuer_name(x509)))
356         return 0;
357 
358     /*
359      * because ASN1_INTEGER_set is used to set a 'long' we will do things the
360      * ugly way.
361      */
362     ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
363     if (!(p7i->issuer_and_serial->serial = 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 = ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
637         return 0;
638 
639     pkey = X509_get0_pubkey(x509);
640     if (pkey == NULL)
641         return 0;
642 
643     if (EVP_PKEY_is_a(pkey, "RSA-PSS"))
644         return -2;
645     if (EVP_PKEY_is_a(pkey, "RSA")) {
646         if (pkcs7_rsa_encrypt_decrypt_setup(p7i, 0) <= 0)
647             goto err;
648         goto finished;
649     }
650 
651     if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL) {
652         ERR_raise(ERR_LIB_PKCS7,
653             PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
654         goto err;
655     }
656 
657     ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
658     if (ret == -2) {
659         ERR_raise(ERR_LIB_PKCS7,
660             PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
661         goto err;
662     }
663     if (ret <= 0) {
664         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_ENCRYPTION_CTRL_FAILURE);
665         goto err;
666     }
667 finished:
668     if (!X509_up_ref(x509))
669         goto err;
670 
671     p7i->cert = x509;
672 
673     return 1;
674 
675 err:
676     return 0;
677 }
678 
PKCS7_cert_from_signer_info(PKCS7 * p7,PKCS7_SIGNER_INFO * si)679 X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
680 {
681     if (PKCS7_type_is_signed(p7))
682         return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
683             si->issuer_and_serial->issuer,
684             si->issuer_and_serial->serial));
685     else
686         return NULL;
687 }
688 
PKCS7_set_cipher(PKCS7 * p7,const EVP_CIPHER * cipher)689 int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
690 {
691     int i;
692     PKCS7_ENC_CONTENT *ec;
693 
694     i = OBJ_obj2nid(p7->type);
695     switch (i) {
696     case NID_pkcs7_signedAndEnveloped:
697         ec = p7->d.signed_and_enveloped->enc_data;
698         break;
699     case NID_pkcs7_enveloped:
700         ec = p7->d.enveloped->enc_data;
701         break;
702     default:
703         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
704         return 0;
705     }
706 
707     /* Check cipher OID exists and has data in it */
708     i = EVP_CIPHER_get_type(cipher);
709     if (i == NID_undef) {
710         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
711         return 0;
712     }
713 
714     ec->cipher = cipher;
715     ec->ctx = ossl_pkcs7_get0_ctx(p7);
716     return 1;
717 }
718 
719 /* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
PKCS7_stream(unsigned char *** boundary,PKCS7 * p7)720 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
721 {
722     ASN1_OCTET_STRING *os = NULL;
723 
724     switch (OBJ_obj2nid(p7->type)) {
725     case NID_pkcs7_data:
726         os = p7->d.data;
727         break;
728 
729     case NID_pkcs7_signedAndEnveloped:
730         os = p7->d.signed_and_enveloped->enc_data->enc_data;
731         if (os == NULL) {
732             os = ASN1_OCTET_STRING_new();
733             p7->d.signed_and_enveloped->enc_data->enc_data = os;
734         }
735         break;
736 
737     case NID_pkcs7_enveloped:
738         os = p7->d.enveloped->enc_data->enc_data;
739         if (os == NULL) {
740             os = ASN1_OCTET_STRING_new();
741             p7->d.enveloped->enc_data->enc_data = os;
742         }
743         break;
744 
745     case NID_pkcs7_signed:
746         if (p7->d.sign == NULL || p7->d.sign->contents == NULL) {
747             ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT);
748             break;
749         }
750         os = p7->d.sign->contents->d.data;
751         break;
752 
753     default:
754         os = NULL;
755         break;
756     }
757 
758     if (os == NULL)
759         return 0;
760 
761     os->flags |= ASN1_STRING_FLAG_NDEF;
762     *boundary = &os->data;
763 
764     return 1;
765 }
766