xref: /freebsd/crypto/openssl/crypto/pkcs7/pk7_lib.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
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 
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             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 
PKCS7_content_new(PKCS7 * p7,int type)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 
PKCS7_set_content(PKCS7 * p7,PKCS7 * p7_data)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 
PKCS7_set_type(PKCS7 * p7,int type)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 
PKCS7_set0_type_other(PKCS7 * p7,int type,ASN1_TYPE * other)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 
PKCS7_add_signer(PKCS7 * p7,PKCS7_SIGNER_INFO * psi)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 
PKCS7_add_certificate(PKCS7 * p7,X509 * x509)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 
PKCS7_add_crl(PKCS7 * p7,X509_CRL * crl)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 
pkcs7_ecdsa_or_dsa_sign_verify_setup(PKCS7_SIGNER_INFO * si,int verify)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 
pkcs7_rsa_sign_verify_setup(PKCS7_SIGNER_INFO * si,int verify)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 
PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO * p7i,X509 * x509,EVP_PKEY * pkey,const EVP_MD * dgst)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 
PKCS7_add_signature(PKCS7 * p7,X509 * x509,EVP_PKEY * pkey,const EVP_MD * dgst)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) <= 0)
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 
STACK_OF(X509)415 static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
416 {
417     if (p7->d.ptr == NULL)
418         return NULL;
419     if (PKCS7_type_is_signed(p7))
420         return p7->d.sign->cert;
421     if (PKCS7_type_is_signedAndEnveloped(p7))
422         return p7->d.signed_and_enveloped->cert;
423     return NULL;
424 }
425 
STACK_OF(PKCS7_RECIP_INFO)426 static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
427 {
428     if (p7->d.ptr == NULL)
429         return NULL;
430     if (PKCS7_type_is_signedAndEnveloped(p7))
431         return p7->d.signed_and_enveloped->recipientinfo;
432     if (PKCS7_type_is_enveloped(p7))
433         return p7->d.enveloped->recipientinfo;
434     return NULL;
435 }
436 
437 /*
438  * Set up the library context into any loaded structure that needs it.
439  * i.e loaded X509 objects.
440  */
ossl_pkcs7_resolve_libctx(PKCS7 * p7)441 void ossl_pkcs7_resolve_libctx(PKCS7 *p7)
442 {
443     int i;
444     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
445     OSSL_LIB_CTX *libctx = ossl_pkcs7_ctx_get0_libctx(ctx);
446     const char *propq = ossl_pkcs7_ctx_get0_propq(ctx);
447     STACK_OF(PKCS7_RECIP_INFO) *rinfos;
448     STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
449     STACK_OF(X509) *certs;
450 
451     if (ctx == NULL || p7->d.ptr == NULL)
452         return;
453 
454     rinfos = pkcs7_get_recipient_info(p7);
455     sinfos = PKCS7_get_signer_info(p7);
456     certs = pkcs7_get_signer_certs(p7);
457 
458     for (i = 0; i < sk_X509_num(certs); i++)
459         ossl_x509_set0_libctx(sk_X509_value(certs, i), libctx, propq);
460 
461     for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
462         PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
463 
464         ossl_x509_set0_libctx(ri->cert, libctx, propq);
465     }
466 
467     for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
468         PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
469 
470         if (si != NULL)
471             si->ctx = ctx;
472     }
473 }
474 
ossl_pkcs7_get0_ctx(const PKCS7 * p7)475 const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7)
476 {
477     return p7 != NULL ? &p7->ctx : NULL;
478 }
479 
ossl_pkcs7_set0_libctx(PKCS7 * p7,OSSL_LIB_CTX * ctx)480 void ossl_pkcs7_set0_libctx(PKCS7 *p7, OSSL_LIB_CTX *ctx)
481 {
482     p7->ctx.libctx = ctx;
483 }
484 
ossl_pkcs7_set1_propq(PKCS7 * p7,const char * propq)485 int ossl_pkcs7_set1_propq(PKCS7 *p7, const char *propq)
486 {
487     if (p7->ctx.propq != NULL) {
488         OPENSSL_free(p7->ctx.propq);
489         p7->ctx.propq = NULL;
490     }
491     if (propq != NULL) {
492         p7->ctx.propq = OPENSSL_strdup(propq);
493         if (p7->ctx.propq == NULL) {
494             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
495             return 0;
496         }
497     }
498     return 1;
499 }
500 
ossl_pkcs7_ctx_propagate(const PKCS7 * from,PKCS7 * to)501 int ossl_pkcs7_ctx_propagate(const PKCS7 *from, PKCS7 *to)
502 {
503     ossl_pkcs7_set0_libctx(to, from->ctx.libctx);
504     if (!ossl_pkcs7_set1_propq(to, from->ctx.propq))
505         return 0;
506 
507     ossl_pkcs7_resolve_libctx(to);
508     return 1;
509 }
510 
ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX * ctx)511 OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
512 {
513     return ctx != NULL ? ctx->libctx : NULL;
514 }
ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX * ctx)515 const char *ossl_pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
516 {
517     return ctx != NULL ? ctx->propq : NULL;
518 }
519 
PKCS7_set_digest(PKCS7 * p7,const EVP_MD * md)520 int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
521 {
522     if (PKCS7_type_is_digest(p7)) {
523         if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
524             ERR_raise(ERR_LIB_PKCS7, ERR_R_MALLOC_FAILURE);
525             return 0;
526         }
527         p7->d.digest->md->parameter->type = V_ASN1_NULL;
528         p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
529         return 1;
530     }
531 
532     ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
533     return 1;
534 }
535 
STACK_OF(PKCS7_SIGNER_INFO)536 STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
537 {
538     if (p7 == NULL || p7->d.ptr == NULL)
539         return NULL;
540     if (PKCS7_type_is_signed(p7)) {
541         return p7->d.sign->signer_info;
542     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
543         return p7->d.signed_and_enveloped->signer_info;
544     } else
545         return NULL;
546 }
547 
PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO * si,EVP_PKEY ** pk,X509_ALGOR ** pdig,X509_ALGOR ** psig)548 void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
549                                  X509_ALGOR **pdig, X509_ALGOR **psig)
550 {
551     if (pk)
552         *pk = si->pkey;
553     if (pdig)
554         *pdig = si->digest_alg;
555     if (psig)
556         *psig = si->digest_enc_alg;
557 }
558 
PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO * ri,X509_ALGOR ** penc)559 void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
560 {
561     if (penc)
562         *penc = ri->key_enc_algor;
563 }
564 
PKCS7_add_recipient(PKCS7 * p7,X509 * x509)565 PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
566 {
567     PKCS7_RECIP_INFO *ri;
568 
569     if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
570         goto err;
571     if (PKCS7_RECIP_INFO_set(ri, x509) <= 0)
572         goto err;
573     if (!PKCS7_add_recipient_info(p7, ri))
574         goto err;
575     ri->ctx = ossl_pkcs7_get0_ctx(p7);
576     return ri;
577  err:
578     PKCS7_RECIP_INFO_free(ri);
579     return NULL;
580 }
581 
PKCS7_add_recipient_info(PKCS7 * p7,PKCS7_RECIP_INFO * ri)582 int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
583 {
584     int i;
585     STACK_OF(PKCS7_RECIP_INFO) *sk;
586 
587     i = OBJ_obj2nid(p7->type);
588     switch (i) {
589     case NID_pkcs7_signedAndEnveloped:
590         sk = p7->d.signed_and_enveloped->recipientinfo;
591         break;
592     case NID_pkcs7_enveloped:
593         sk = p7->d.enveloped->recipientinfo;
594         break;
595     default:
596         ERR_raise(ERR_LIB_PKCS7, PKCS7_R_WRONG_CONTENT_TYPE);
597         return 0;
598     }
599 
600     if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
601         return 0;
602     return 1;
603 }
604 
pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO * ri,int decrypt)605 static int pkcs7_rsa_encrypt_decrypt_setup(PKCS7_RECIP_INFO *ri, int decrypt)
606 {
607     X509_ALGOR *alg = NULL;
608 
609     if (decrypt == 0) {
610         PKCS7_RECIP_INFO_get0_alg(ri, &alg);
611         if (alg != NULL)
612             X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0);
613     }
614     return 1;
615 }
616 
PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO * p7i,X509 * x509)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 
PKCS7_cert_from_signer_info(PKCS7 * p7,PKCS7_SIGNER_INFO * si)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 
PKCS7_set_cipher(PKCS7 * p7,const EVP_CIPHER * cipher)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() */
PKCS7_stream(unsigned char *** boundary,PKCS7 * p7)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 }
754