]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/pkcs7/pk7_lib.c
Introduce X509_add_cert[s] simplifying various additions to cert lists
[thirdparty/openssl.git] / crypto / pkcs7 / pk7_lib.c
CommitLineData
62867571 1/*
454afd98 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
b7617a3a 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
62867571
RS
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
d02b48c6
RE
8 */
9
10#include <stdio.h>
b39fc560 11#include "internal/cryptlib.h"
ec577822
BM
12#include <openssl/objects.h>
13#include <openssl/x509.h>
25f2138b
DMSP
14#include "crypto/asn1.h"
15#include "crypto/evp.h"
eeccc237 16#include "crypto/x509.h" /* for sk_X509_add1_cert() */
90a1f2d7 17#include "pk7_local.h"
d02b48c6 18
852c2ed2
RS
19DEFINE_STACK_OF(X509)
20DEFINE_STACK_OF(X509_CRL)
21DEFINE_STACK_OF(X509_ALGOR)
22DEFINE_STACK_OF(PKCS7_RECIP_INFO)
23DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
24
6b691a5c 25long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
0f113f3e
MC
26{
27 int nid;
28 long ret;
29
30 nid = OBJ_obj2nid(p7->type);
31
32 switch (cmd) {
c225c3cf 33 /* NOTE(emilia): does not support detached digested data. */
0f113f3e
MC
34 case PKCS7_OP_SET_DETACHED_SIGNATURE:
35 if (nid == NID_pkcs7_signed) {
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 PKCS7err(PKCS7_F_PKCS7_CTRL,
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) {
12a765a5 51 if (p7->d.sign == NULL || p7->d.sign->contents->d.ptr == NULL)
0f113f3e
MC
52 ret = 1;
53 else
54 ret = 0;
55
56 p7->detached = ret;
57 } else {
58 PKCS7err(PKCS7_F_PKCS7_CTRL,
59 PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
60 ret = 0;
61 }
62
63 break;
64 default:
65 PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
66 ret = 0;
67 }
26a7d938 68 return ret;
0f113f3e 69}
d02b48c6 70
6b691a5c 71int PKCS7_content_new(PKCS7 *p7, int type)
0f113f3e
MC
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
208fb891 82 return 1;
0f113f3e 83 err:
e0e920b1 84 PKCS7_free(ret);
26a7d938 85 return 0;
0f113f3e 86}
d02b48c6 87
6b691a5c 88int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
0f113f3e
MC
89{
90 int i;
91
92 i = OBJ_obj2nid(p7->type);
93 switch (i) {
94 case NID_pkcs7_signed:
e0e920b1 95 PKCS7_free(p7->d.sign->contents);
0f113f3e
MC
96 p7->d.sign->contents = p7_data;
97 break;
98 case NID_pkcs7_digest:
e0e920b1 99 PKCS7_free(p7->d.digest->contents);
0f113f3e
MC
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 PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
108 goto err;
109 }
208fb891 110 return 1;
0f113f3e 111 err:
26a7d938 112 return 0;
0f113f3e 113}
d02b48c6 114
6b691a5c 115int PKCS7_set_type(PKCS7 *p7, int type)
0f113f3e
MC
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;
f422a514 137 if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
0f113f3e
MC
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;
0f113f3e
MC
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 PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
179 goto err;
180 }
208fb891 181 return 1;
0f113f3e 182 err:
26a7d938 183 return 0;
0f113f3e 184}
d02b48c6 185
8d9086df 186int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
0f113f3e
MC
187{
188 p7->type = OBJ_nid2obj(type);
189 p7->d.other = other;
190 return 1;
191}
8d9086df 192
6b691a5c 193int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
0f113f3e
MC
194{
195 int i, j, nid;
196 X509_ALGOR *alg;
197 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
198 STACK_OF(X509_ALGOR) *md_sk;
199
200 i = OBJ_obj2nid(p7->type);
201 switch (i) {
202 case NID_pkcs7_signed:
203 signer_sk = p7->d.sign->signer_info;
204 md_sk = p7->d.sign->md_algs;
205 break;
206 case NID_pkcs7_signedAndEnveloped:
207 signer_sk = p7->d.signed_and_enveloped->signer_info;
208 md_sk = p7->d.signed_and_enveloped->md_algs;
209 break;
210 default:
211 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
26a7d938 212 return 0;
0f113f3e
MC
213 }
214
215 nid = OBJ_obj2nid(psi->digest_alg->algorithm);
216
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_obj2nid(alg->algorithm) == nid) {
222 j = 1;
223 break;
224 }
225 }
226 if (!j) { /* we need to add another algorithm */
75ebbd9a
RS
227 if ((alg = X509_ALGOR_new()) == NULL
228 || (alg->parameter = ASN1_TYPE_new()) == NULL) {
0f113f3e
MC
229 X509_ALGOR_free(alg);
230 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
26a7d938 231 return 0;
0f113f3e
MC
232 }
233 alg->algorithm = OBJ_nid2obj(nid);
234 alg->parameter->type = V_ASN1_NULL;
235 if (!sk_X509_ALGOR_push(md_sk, alg)) {
236 X509_ALGOR_free(alg);
237 return 0;
238 }
239 }
240
90a1f2d7 241 psi->ctx = pkcs7_get0_ctx(p7);
0f113f3e
MC
242 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
243 return 0;
208fb891 244 return 1;
0f113f3e 245}
d02b48c6 246
6b691a5c 247int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
0f113f3e
MC
248{
249 int i;
250 STACK_OF(X509) **sk;
251
252 i = OBJ_obj2nid(p7->type);
253 switch (i) {
254 case NID_pkcs7_signed:
255 sk = &(p7->d.sign->cert);
256 break;
257 case NID_pkcs7_signedAndEnveloped:
258 sk = &(p7->d.signed_and_enveloped->cert);
259 break;
260 default:
261 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE);
26a7d938 262 return 0;
0f113f3e
MC
263 }
264
eeccc237 265 return X509_add_cert_new(sk, x509, X509_ADD_FLAG_UP_REF);
0f113f3e 266}
d02b48c6 267
6b691a5c 268int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
0f113f3e
MC
269{
270 int i;
271 STACK_OF(X509_CRL) **sk;
272
273 i = OBJ_obj2nid(p7->type);
274 switch (i) {
275 case NID_pkcs7_signed:
276 sk = &(p7->d.sign->crl);
277 break;
278 case NID_pkcs7_signedAndEnveloped:
279 sk = &(p7->d.signed_and_enveloped->crl);
280 break;
281 default:
282 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
26a7d938 283 return 0;
0f113f3e
MC
284 }
285
286 if (*sk == NULL)
287 *sk = sk_X509_CRL_new_null();
288 if (*sk == NULL) {
289 PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
290 return 0;
291 }
292
65cbf983 293 X509_CRL_up_ref(crl);
0f113f3e
MC
294 if (!sk_X509_CRL_push(*sk, crl)) {
295 X509_CRL_free(crl);
296 return 0;
297 }
208fb891 298 return 1;
0f113f3e 299}
d02b48c6 300
6b691a5c 301int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
0f113f3e
MC
302 const EVP_MD *dgst)
303{
304 int ret;
305
306 /* We now need to add another PKCS7_SIGNER_INFO entry */
307 if (!ASN1_INTEGER_set(p7i->version, 1))
308 goto err;
309 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
310 X509_get_issuer_name(x509)))
311 goto err;
312
313 /*
314 * because ASN1_INTEGER_set is used to set a 'long' we will do things the
315 * ugly way.
316 */
f422a514 317 ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
0f113f3e 318 if (!(p7i->issuer_and_serial->serial =
1337a3a9 319 ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
0f113f3e
MC
320 goto err;
321
322 /* lets keep the pkey around for a while */
3aeb9348 323 EVP_PKEY_up_ref(pkey);
0f113f3e
MC
324 p7i->pkey = pkey;
325
326 /* Set the algorithms */
327
328 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
329 V_ASN1_NULL, NULL);
330
331 if (pkey->ameth && pkey->ameth->pkey_ctrl) {
332 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
333 if (ret > 0)
334 return 1;
335 if (ret != -2) {
336 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
337 PKCS7_R_SIGNING_CTRL_FAILURE);
338 return 0;
339 }
340 }
341 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
342 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
343 err:
344 return 0;
345}
d02b48c6 346
6b691a5c 347PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
0f113f3e
MC
348 const EVP_MD *dgst)
349{
350 PKCS7_SIGNER_INFO *si = NULL;
351
352 if (dgst == NULL) {
353 int def_nid;
354 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
355 goto err;
356 dgst = EVP_get_digestbynid(def_nid);
357 if (dgst == NULL) {
358 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST);
359 goto err;
360 }
361 }
362
363 if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
364 goto err;
365 if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
366 goto err;
367 if (!PKCS7_add_signer(p7, si))
368 goto err;
26a7d938 369 return si;
0f113f3e 370 err:
e0e920b1 371 PKCS7_SIGNER_INFO_free(si);
26a7d938 372 return NULL;
0f113f3e 373}
d02b48c6 374
90a1f2d7
SL
375static STACK_OF(X509) *pkcs7_get_signer_certs(const PKCS7 *p7)
376{
377 if (PKCS7_type_is_signed(p7))
378 return p7->d.sign->cert;
379 if (PKCS7_type_is_signedAndEnveloped(p7))
380 return p7->d.signed_and_enveloped->cert;
381 return NULL;
382}
383
384static STACK_OF(PKCS7_RECIP_INFO) *pkcs7_get_recipient_info(const PKCS7 *p7)
385{
386 if (PKCS7_type_is_signedAndEnveloped(p7))
387 return p7->d.signed_and_enveloped->recipientinfo;
388 if (PKCS7_type_is_enveloped(p7))
389 return p7->d.enveloped->recipientinfo;
390 return NULL;
391}
392
393/*
394 * Set up the library context into any loaded structure that needs it.
395 * i.e loaded X509 objects.
396 */
397void pkcs7_resolve_libctx(PKCS7 *p7)
398{
399 int i;
400 const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7);
401 STACK_OF(PKCS7_RECIP_INFO) *rinfos = pkcs7_get_recipient_info(p7);
402 STACK_OF(PKCS7_SIGNER_INFO) *sinfos = PKCS7_get_signer_info(p7);
403 STACK_OF(X509) *certs = pkcs7_get_signer_certs(p7);
404
405 if (ctx == NULL)
406 return;
407
408 for (i = 0; i < sk_X509_num(certs); i++)
409 x509_set0_libctx(sk_X509_value(certs, i), ctx->libctx, ctx->propq);
410
411 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rinfos); i++) {
412 PKCS7_RECIP_INFO *ri = sk_PKCS7_RECIP_INFO_value(rinfos, i);
413
414 x509_set0_libctx(ri->cert, ctx->libctx, ctx->propq);
415 }
416
417 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
418 PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
419
420 if (si != NULL)
421 si->ctx = ctx;
422 }
423}
424
425const PKCS7_CTX *pkcs7_get0_ctx(const PKCS7 *p7)
426{
427 return p7 != NULL ? &p7->ctx : NULL;
428}
429
430OPENSSL_CTX *pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx)
431{
432 return ctx != NULL ? ctx->libctx : NULL;
433}
434const char *pkcs7_ctx_get0_propq(const PKCS7_CTX *ctx)
435{
436 return ctx != NULL ? ctx->propq : NULL;
437}
438
c5a55463 439int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
0f113f3e
MC
440{
441 if (PKCS7_type_is_digest(p7)) {
75ebbd9a 442 if ((p7->d.digest->md->parameter = ASN1_TYPE_new()) == NULL) {
0f113f3e
MC
443 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE);
444 return 0;
445 }
446 p7->d.digest->md->parameter->type = V_ASN1_NULL;
447 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
448 return 1;
449 }
450
451 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
452 return 1;
453}
c5a55463 454
b05b50e6 455STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
0f113f3e 456{
c225c3cf
EK
457 if (p7 == NULL || p7->d.ptr == NULL)
458 return NULL;
0f113f3e 459 if (PKCS7_type_is_signed(p7)) {
26a7d938 460 return p7->d.sign->signer_info;
0f113f3e 461 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
26a7d938 462 return p7->d.signed_and_enveloped->signer_info;
0f113f3e 463 } else
26a7d938 464 return NULL;
0f113f3e 465}
d02b48c6 466
492a9e24 467void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
0f113f3e
MC
468 X509_ALGOR **pdig, X509_ALGOR **psig)
469{
470 if (pk)
471 *pk = si->pkey;
472 if (pdig)
473 *pdig = si->digest_alg;
474 if (psig)
475 *psig = si->digest_enc_alg;
476}
492a9e24 477
e4b21c74 478void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
0f113f3e
MC
479{
480 if (penc)
481 *penc = ri->key_enc_algor;
482}
e4b21c74 483
6b691a5c 484PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
0f113f3e
MC
485{
486 PKCS7_RECIP_INFO *ri;
487
488 if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
489 goto err;
490 if (!PKCS7_RECIP_INFO_set(ri, x509))
491 goto err;
492 if (!PKCS7_add_recipient_info(p7, ri))
493 goto err;
90a1f2d7 494 ri->ctx = pkcs7_get0_ctx(p7);
0f113f3e
MC
495 return ri;
496 err:
e0e920b1 497 PKCS7_RECIP_INFO_free(ri);
0f113f3e
MC
498 return NULL;
499}
58964a49 500
6b691a5c 501int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
0f113f3e
MC
502{
503 int i;
504 STACK_OF(PKCS7_RECIP_INFO) *sk;
505
506 i = OBJ_obj2nid(p7->type);
507 switch (i) {
508 case NID_pkcs7_signedAndEnveloped:
509 sk = p7->d.signed_and_enveloped->recipientinfo;
510 break;
511 case NID_pkcs7_enveloped:
512 sk = p7->d.enveloped->recipientinfo;
513 break;
514 default:
515 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
516 PKCS7_R_WRONG_CONTENT_TYPE);
26a7d938 517 return 0;
0f113f3e
MC
518 }
519
520 if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
521 return 0;
208fb891 522 return 1;
0f113f3e 523}
58964a49 524
6b691a5c 525int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
0f113f3e
MC
526{
527 int ret;
528 EVP_PKEY *pkey = NULL;
529 if (!ASN1_INTEGER_set(p7i->version, 0))
530 return 0;
531 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
532 X509_get_issuer_name(x509)))
533 return 0;
534
f422a514 535 ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
0f113f3e 536 if (!(p7i->issuer_and_serial->serial =
1337a3a9 537 ASN1_INTEGER_dup(X509_get0_serialNumber(x509))))
0f113f3e
MC
538 return 0;
539
8382fd3a 540 pkey = X509_get0_pubkey(x509);
0f113f3e
MC
541
542 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
543 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
544 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
545 goto err;
546 }
547
548 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
549 if (ret == -2) {
550 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
551 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
552 goto err;
553 }
554 if (ret <= 0) {
555 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
556 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
557 goto err;
558 }
559
05f0fb9f 560 X509_up_ref(x509);
0f113f3e
MC
561 p7i->cert = x509;
562
563 return 1;
564
565 err:
0f113f3e
MC
566 return 0;
567}
58964a49 568
6b691a5c 569X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
0f113f3e
MC
570{
571 if (PKCS7_type_is_signed(p7))
572 return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
573 si->issuer_and_serial->issuer,
574 si->
575 issuer_and_serial->serial));
576 else
26a7d938 577 return NULL;
0f113f3e 578}
d02b48c6 579
84fa704c 580int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
0f113f3e
MC
581{
582 int i;
583 PKCS7_ENC_CONTENT *ec;
584
585 i = OBJ_obj2nid(p7->type);
586 switch (i) {
587 case NID_pkcs7_signedAndEnveloped:
588 ec = p7->d.signed_and_enveloped->enc_data;
589 break;
590 case NID_pkcs7_enveloped:
591 ec = p7->d.enveloped->enc_data;
592 break;
593 default:
594 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
26a7d938 595 return 0;
0f113f3e
MC
596 }
597
598 /* Check cipher OID exists and has data in it */
599 i = EVP_CIPHER_type(cipher);
600 if (i == NID_undef) {
601 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
602 PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
26a7d938 603 return 0;
0f113f3e
MC
604 }
605
606 ec->cipher = cipher;
90a1f2d7 607 ec->ctx = pkcs7_get0_ctx(p7);
0f113f3e
MC
608 return 1;
609}
58964a49 610
9fdcc21f 611/* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */
11d8cdc6 612int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
0f113f3e
MC
613{
614 ASN1_OCTET_STRING *os = NULL;
615
616 switch (OBJ_obj2nid(p7->type)) {
617 case NID_pkcs7_data:
618 os = p7->d.data;
619 break;
620
621 case NID_pkcs7_signedAndEnveloped:
622 os = p7->d.signed_and_enveloped->enc_data->enc_data;
623 if (os == NULL) {
f422a514 624 os = ASN1_OCTET_STRING_new();
0f113f3e
MC
625 p7->d.signed_and_enveloped->enc_data->enc_data = os;
626 }
627 break;
628
629 case NID_pkcs7_enveloped:
630 os = p7->d.enveloped->enc_data->enc_data;
631 if (os == NULL) {
f422a514 632 os = ASN1_OCTET_STRING_new();
0f113f3e
MC
633 p7->d.enveloped->enc_data->enc_data = os;
634 }
635 break;
636
637 case NID_pkcs7_signed:
638 os = p7->d.sign->contents->d.data;
639 break;
640
641 default:
642 os = NULL;
643 break;
644 }
645
646 if (os == NULL)
647 return 0;
648
649 os->flags |= ASN1_STRING_FLAG_NDEF;
650 *boundary = &os->data;
651
652 return 1;
653}