Line data Source code
1 : /* crypto/pkcs7/pk7_lib.c */
2 : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : * All rights reserved.
4 : *
5 : * This package is an SSL implementation written
6 : * by Eric Young (eay@cryptsoft.com).
7 : * The implementation was written so as to conform with Netscapes SSL.
8 : *
9 : * This library is free for commercial and non-commercial use as long as
10 : * the following conditions are aheared to. The following conditions
11 : * apply to all code found in this distribution, be it the RC4, RSA,
12 : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : * included with this distribution is covered by the same copyright terms
14 : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : *
16 : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : * the code are not to be removed.
18 : * If this package is used in a product, Eric Young should be given attribution
19 : * as the author of the parts of the library used.
20 : * This can be in the form of a textual message at program startup or
21 : * in documentation (online or textual) provided with the package.
22 : *
23 : * Redistribution and use in source and binary forms, with or without
24 : * modification, are permitted provided that the following conditions
25 : * are met:
26 : * 1. Redistributions of source code must retain the copyright
27 : * notice, this list of conditions and the following disclaimer.
28 : * 2. Redistributions in binary form must reproduce the above copyright
29 : * notice, this list of conditions and the following disclaimer in the
30 : * documentation and/or other materials provided with the distribution.
31 : * 3. All advertising materials mentioning features or use of this software
32 : * must display the following acknowledgement:
33 : * "This product includes cryptographic software written by
34 : * Eric Young (eay@cryptsoft.com)"
35 : * The word 'cryptographic' can be left out if the rouines from the library
36 : * being used are not cryptographic related :-).
37 : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : * the apps directory (application code) you must include an acknowledgement:
39 : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : *
41 : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : * SUCH DAMAGE.
52 : *
53 : * The licence and distribution terms for any publically available version or
54 : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : * copied and put under another distribution licence
56 : * [including the GNU Public Licence.]
57 : */
58 :
59 : #include <stdio.h>
60 : #include "cryptlib.h"
61 : #include <openssl/objects.h>
62 : #include <openssl/x509.h>
63 : #include "asn1_locl.h"
64 :
65 0 : long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
66 : {
67 : int nid;
68 : long ret;
69 :
70 0 : nid = OBJ_obj2nid(p7->type);
71 :
72 0 : switch (cmd) {
73 : /* NOTE(emilia): does not support detached digested data. */
74 : case PKCS7_OP_SET_DETACHED_SIGNATURE:
75 0 : if (nid == NID_pkcs7_signed) {
76 0 : ret = p7->detached = (int)larg;
77 0 : if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
78 : ASN1_OCTET_STRING *os;
79 0 : os = p7->d.sign->contents->d.data;
80 0 : ASN1_OCTET_STRING_free(os);
81 0 : p7->d.sign->contents->d.data = NULL;
82 : }
83 : } else {
84 0 : PKCS7err(PKCS7_F_PKCS7_CTRL,
85 : PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
86 : ret = 0;
87 : }
88 : break;
89 : case PKCS7_OP_GET_DETACHED_SIGNATURE:
90 0 : if (nid == NID_pkcs7_signed) {
91 0 : if (!p7->d.sign || !p7->d.sign->contents->d.ptr)
92 : ret = 1;
93 : else
94 : ret = 0;
95 :
96 0 : p7->detached = ret;
97 : } else {
98 0 : PKCS7err(PKCS7_F_PKCS7_CTRL,
99 : PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
100 : ret = 0;
101 : }
102 :
103 : break;
104 : default:
105 0 : PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION);
106 : ret = 0;
107 : }
108 0 : return (ret);
109 : }
110 :
111 0 : int PKCS7_content_new(PKCS7 *p7, int type)
112 : {
113 : PKCS7 *ret = NULL;
114 :
115 0 : if ((ret = PKCS7_new()) == NULL)
116 : goto err;
117 0 : if (!PKCS7_set_type(ret, type))
118 : goto err;
119 0 : if (!PKCS7_set_content(p7, ret))
120 : goto err;
121 :
122 : return (1);
123 : err:
124 0 : if (ret != NULL)
125 0 : PKCS7_free(ret);
126 : return (0);
127 : }
128 :
129 0 : int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
130 : {
131 : int i;
132 :
133 0 : i = OBJ_obj2nid(p7->type);
134 0 : switch (i) {
135 : case NID_pkcs7_signed:
136 0 : if (p7->d.sign->contents != NULL)
137 0 : PKCS7_free(p7->d.sign->contents);
138 0 : p7->d.sign->contents = p7_data;
139 0 : break;
140 : case NID_pkcs7_digest:
141 0 : if (p7->d.digest->contents != NULL)
142 0 : PKCS7_free(p7->d.digest->contents);
143 0 : p7->d.digest->contents = p7_data;
144 0 : break;
145 : case NID_pkcs7_data:
146 : case NID_pkcs7_enveloped:
147 : case NID_pkcs7_signedAndEnveloped:
148 : case NID_pkcs7_encrypted:
149 : default:
150 0 : PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
151 : goto err;
152 : }
153 : return (1);
154 : err:
155 0 : return (0);
156 : }
157 :
158 0 : int PKCS7_set_type(PKCS7 *p7, int type)
159 : {
160 : ASN1_OBJECT *obj;
161 :
162 : /*
163 : * PKCS7_content_free(p7);
164 : */
165 0 : obj = OBJ_nid2obj(type); /* will not fail */
166 :
167 0 : switch (type) {
168 : case NID_pkcs7_signed:
169 0 : p7->type = obj;
170 0 : if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
171 : goto err;
172 0 : if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
173 0 : PKCS7_SIGNED_free(p7->d.sign);
174 0 : p7->d.sign = NULL;
175 0 : goto err;
176 : }
177 : break;
178 : case NID_pkcs7_data:
179 0 : p7->type = obj;
180 0 : if ((p7->d.data = M_ASN1_OCTET_STRING_new()) == NULL)
181 : goto err;
182 : break;
183 : case NID_pkcs7_signedAndEnveloped:
184 0 : p7->type = obj;
185 0 : if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new())
186 : == NULL)
187 : goto err;
188 0 : ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1);
189 0 : if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
190 : goto err;
191 0 : p7->d.signed_and_enveloped->enc_data->content_type
192 0 : = OBJ_nid2obj(NID_pkcs7_data);
193 0 : break;
194 : case NID_pkcs7_enveloped:
195 0 : p7->type = obj;
196 0 : if ((p7->d.enveloped = PKCS7_ENVELOPE_new())
197 : == NULL)
198 : goto err;
199 0 : if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
200 : goto err;
201 0 : p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
202 0 : break;
203 : case NID_pkcs7_encrypted:
204 0 : p7->type = obj;
205 0 : if ((p7->d.encrypted = PKCS7_ENCRYPT_new())
206 : == NULL)
207 : goto err;
208 0 : if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
209 : goto err;
210 0 : p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data);
211 0 : break;
212 :
213 : case NID_pkcs7_digest:
214 0 : p7->type = obj;
215 0 : if ((p7->d.digest = PKCS7_DIGEST_new())
216 : == NULL)
217 : goto err;
218 0 : if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
219 : goto err;
220 : break;
221 : default:
222 0 : PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
223 0 : goto err;
224 : }
225 : return (1);
226 : err:
227 : return (0);
228 : }
229 :
230 0 : int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
231 : {
232 0 : p7->type = OBJ_nid2obj(type);
233 0 : p7->d.other = other;
234 0 : return 1;
235 : }
236 :
237 0 : int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
238 : {
239 : int i, j, nid;
240 : X509_ALGOR *alg;
241 : STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
242 : STACK_OF(X509_ALGOR) *md_sk;
243 :
244 0 : i = OBJ_obj2nid(p7->type);
245 0 : switch (i) {
246 : case NID_pkcs7_signed:
247 0 : signer_sk = p7->d.sign->signer_info;
248 0 : md_sk = p7->d.sign->md_algs;
249 0 : break;
250 : case NID_pkcs7_signedAndEnveloped:
251 0 : signer_sk = p7->d.signed_and_enveloped->signer_info;
252 0 : md_sk = p7->d.signed_and_enveloped->md_algs;
253 0 : break;
254 : default:
255 0 : PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE);
256 0 : return (0);
257 : }
258 :
259 0 : nid = OBJ_obj2nid(psi->digest_alg->algorithm);
260 :
261 : /* If the digest is not currently listed, add it */
262 : j = 0;
263 0 : for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
264 0 : alg = sk_X509_ALGOR_value(md_sk, i);
265 0 : if (OBJ_obj2nid(alg->algorithm) == nid) {
266 : j = 1;
267 : break;
268 : }
269 : }
270 0 : if (!j) { /* we need to add another algorithm */
271 0 : if (!(alg = X509_ALGOR_new())
272 0 : || !(alg->parameter = ASN1_TYPE_new())) {
273 0 : X509_ALGOR_free(alg);
274 0 : PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE);
275 0 : return (0);
276 : }
277 0 : alg->algorithm = OBJ_nid2obj(nid);
278 0 : alg->parameter->type = V_ASN1_NULL;
279 0 : if (!sk_X509_ALGOR_push(md_sk, alg)) {
280 0 : X509_ALGOR_free(alg);
281 0 : return 0;
282 : }
283 : }
284 :
285 0 : if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
286 : return 0;
287 0 : return (1);
288 : }
289 :
290 0 : int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
291 : {
292 : int i;
293 : STACK_OF(X509) **sk;
294 :
295 0 : i = OBJ_obj2nid(p7->type);
296 0 : switch (i) {
297 : case NID_pkcs7_signed:
298 0 : sk = &(p7->d.sign->cert);
299 0 : break;
300 : case NID_pkcs7_signedAndEnveloped:
301 0 : sk = &(p7->d.signed_and_enveloped->cert);
302 0 : break;
303 : default:
304 0 : PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE);
305 0 : return (0);
306 : }
307 :
308 0 : if (*sk == NULL)
309 0 : *sk = sk_X509_new_null();
310 0 : if (*sk == NULL) {
311 0 : PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
312 0 : return 0;
313 : }
314 0 : CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
315 0 : if (!sk_X509_push(*sk, x509)) {
316 0 : X509_free(x509);
317 0 : return 0;
318 : }
319 : return (1);
320 : }
321 :
322 0 : int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
323 : {
324 : int i;
325 : STACK_OF(X509_CRL) **sk;
326 :
327 0 : i = OBJ_obj2nid(p7->type);
328 0 : switch (i) {
329 : case NID_pkcs7_signed:
330 0 : sk = &(p7->d.sign->crl);
331 0 : break;
332 : case NID_pkcs7_signedAndEnveloped:
333 0 : sk = &(p7->d.signed_and_enveloped->crl);
334 0 : break;
335 : default:
336 0 : PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE);
337 0 : return (0);
338 : }
339 :
340 0 : if (*sk == NULL)
341 0 : *sk = sk_X509_CRL_new_null();
342 0 : if (*sk == NULL) {
343 0 : PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE);
344 0 : return 0;
345 : }
346 :
347 0 : CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
348 0 : if (!sk_X509_CRL_push(*sk, crl)) {
349 0 : X509_CRL_free(crl);
350 0 : return 0;
351 : }
352 : return (1);
353 : }
354 :
355 0 : int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
356 : const EVP_MD *dgst)
357 : {
358 : int ret;
359 :
360 : /* We now need to add another PKCS7_SIGNER_INFO entry */
361 0 : if (!ASN1_INTEGER_set(p7i->version, 1))
362 : goto err;
363 0 : if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
364 : X509_get_issuer_name(x509)))
365 : goto err;
366 :
367 : /*
368 : * because ASN1_INTEGER_set is used to set a 'long' we will do things the
369 : * ugly way.
370 : */
371 0 : M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
372 0 : if (!(p7i->issuer_and_serial->serial =
373 0 : M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
374 : goto err;
375 :
376 : /* lets keep the pkey around for a while */
377 0 : CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
378 0 : p7i->pkey = pkey;
379 :
380 : /* Set the algorithms */
381 :
382 0 : X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
383 : V_ASN1_NULL, NULL);
384 :
385 0 : if (pkey->ameth && pkey->ameth->pkey_ctrl) {
386 0 : ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i);
387 0 : if (ret > 0)
388 : return 1;
389 0 : if (ret != -2) {
390 0 : PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
391 : PKCS7_R_SIGNING_CTRL_FAILURE);
392 0 : return 0;
393 : }
394 : }
395 0 : PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
396 : PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
397 : err:
398 : return 0;
399 : }
400 :
401 0 : PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
402 : const EVP_MD *dgst)
403 : {
404 : PKCS7_SIGNER_INFO *si = NULL;
405 :
406 0 : if (dgst == NULL) {
407 : int def_nid;
408 0 : if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
409 : goto err;
410 0 : dgst = EVP_get_digestbynid(def_nid);
411 0 : if (dgst == NULL) {
412 0 : PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST);
413 0 : goto err;
414 : }
415 : }
416 :
417 0 : if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
418 : goto err;
419 0 : if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
420 : goto err;
421 0 : if (!PKCS7_add_signer(p7, si))
422 : goto err;
423 : return (si);
424 : err:
425 0 : if (si)
426 0 : PKCS7_SIGNER_INFO_free(si);
427 : return (NULL);
428 : }
429 :
430 0 : int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
431 : {
432 0 : if (PKCS7_type_is_digest(p7)) {
433 0 : if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) {
434 0 : PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE);
435 0 : return 0;
436 : }
437 0 : p7->d.digest->md->parameter->type = V_ASN1_NULL;
438 0 : p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
439 0 : return 1;
440 : }
441 :
442 0 : PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE);
443 0 : return 1;
444 : }
445 :
446 0 : STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
447 : {
448 0 : if (p7 == NULL || p7->d.ptr == NULL)
449 : return NULL;
450 0 : if (PKCS7_type_is_signed(p7)) {
451 0 : return (p7->d.sign->signer_info);
452 0 : } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
453 0 : return (p7->d.signed_and_enveloped->signer_info);
454 : } else
455 : return (NULL);
456 : }
457 :
458 0 : void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
459 : X509_ALGOR **pdig, X509_ALGOR **psig)
460 : {
461 0 : if (pk)
462 0 : *pk = si->pkey;
463 0 : if (pdig)
464 0 : *pdig = si->digest_alg;
465 0 : if (psig)
466 0 : *psig = si->digest_enc_alg;
467 0 : }
468 :
469 0 : void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
470 : {
471 0 : if (penc)
472 0 : *penc = ri->key_enc_algor;
473 0 : }
474 :
475 0 : PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
476 : {
477 : PKCS7_RECIP_INFO *ri;
478 :
479 0 : if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
480 : goto err;
481 0 : if (!PKCS7_RECIP_INFO_set(ri, x509))
482 : goto err;
483 0 : if (!PKCS7_add_recipient_info(p7, ri))
484 : goto err;
485 : return ri;
486 : err:
487 0 : if (ri)
488 0 : PKCS7_RECIP_INFO_free(ri);
489 : return NULL;
490 : }
491 :
492 0 : int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
493 : {
494 : int i;
495 : STACK_OF(PKCS7_RECIP_INFO) *sk;
496 :
497 0 : i = OBJ_obj2nid(p7->type);
498 0 : switch (i) {
499 : case NID_pkcs7_signedAndEnveloped:
500 0 : sk = p7->d.signed_and_enveloped->recipientinfo;
501 0 : break;
502 : case NID_pkcs7_enveloped:
503 0 : sk = p7->d.enveloped->recipientinfo;
504 0 : break;
505 : default:
506 0 : PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,
507 : PKCS7_R_WRONG_CONTENT_TYPE);
508 0 : return (0);
509 : }
510 :
511 0 : if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
512 : return 0;
513 0 : return (1);
514 : }
515 :
516 0 : int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
517 : {
518 : int ret;
519 : EVP_PKEY *pkey = NULL;
520 0 : if (!ASN1_INTEGER_set(p7i->version, 0))
521 : return 0;
522 0 : if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
523 : X509_get_issuer_name(x509)))
524 : return 0;
525 :
526 0 : M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
527 0 : if (!(p7i->issuer_and_serial->serial =
528 0 : M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
529 : return 0;
530 :
531 0 : pkey = X509_get_pubkey(x509);
532 :
533 0 : if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
534 0 : PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
535 : PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
536 0 : goto err;
537 : }
538 :
539 0 : ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i);
540 0 : if (ret == -2) {
541 0 : PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
542 : PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
543 0 : goto err;
544 : }
545 0 : if (ret <= 0) {
546 0 : PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
547 : PKCS7_R_ENCRYPTION_CTRL_FAILURE);
548 0 : goto err;
549 : }
550 :
551 0 : EVP_PKEY_free(pkey);
552 :
553 0 : CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
554 0 : p7i->cert = x509;
555 :
556 0 : return 1;
557 :
558 : err:
559 0 : if (pkey)
560 0 : EVP_PKEY_free(pkey);
561 : return 0;
562 : }
563 :
564 0 : X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
565 : {
566 0 : if (PKCS7_type_is_signed(p7))
567 0 : return (X509_find_by_issuer_and_serial(p7->d.sign->cert,
568 : si->issuer_and_serial->issuer,
569 0 : si->
570 : issuer_and_serial->serial));
571 : else
572 : return (NULL);
573 : }
574 :
575 0 : int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
576 : {
577 : int i;
578 : PKCS7_ENC_CONTENT *ec;
579 :
580 0 : i = OBJ_obj2nid(p7->type);
581 0 : switch (i) {
582 : case NID_pkcs7_signedAndEnveloped:
583 0 : ec = p7->d.signed_and_enveloped->enc_data;
584 0 : break;
585 : case NID_pkcs7_enveloped:
586 0 : ec = p7->d.enveloped->enc_data;
587 0 : break;
588 : default:
589 0 : PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE);
590 0 : return (0);
591 : }
592 :
593 : /* Check cipher OID exists and has data in it */
594 0 : i = EVP_CIPHER_type(cipher);
595 0 : if (i == NID_undef) {
596 0 : PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,
597 : PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
598 0 : return (0);
599 : }
600 :
601 0 : ec->cipher = cipher;
602 0 : return 1;
603 : }
604 :
605 0 : int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
606 : {
607 : ASN1_OCTET_STRING *os = NULL;
608 :
609 0 : switch (OBJ_obj2nid(p7->type)) {
610 : case NID_pkcs7_data:
611 0 : os = p7->d.data;
612 0 : break;
613 :
614 : case NID_pkcs7_signedAndEnveloped:
615 0 : os = p7->d.signed_and_enveloped->enc_data->enc_data;
616 0 : if (os == NULL) {
617 0 : os = M_ASN1_OCTET_STRING_new();
618 0 : p7->d.signed_and_enveloped->enc_data->enc_data = os;
619 : }
620 : break;
621 :
622 : case NID_pkcs7_enveloped:
623 0 : os = p7->d.enveloped->enc_data->enc_data;
624 0 : if (os == NULL) {
625 0 : os = M_ASN1_OCTET_STRING_new();
626 0 : p7->d.enveloped->enc_data->enc_data = os;
627 : }
628 : break;
629 :
630 : case NID_pkcs7_signed:
631 0 : os = p7->d.sign->contents->d.data;
632 0 : break;
633 :
634 : default:
635 : os = NULL;
636 : break;
637 : }
638 :
639 0 : if (os == NULL)
640 : return 0;
641 :
642 0 : os->flags |= ASN1_STRING_FLAG_NDEF;
643 0 : *boundary = &os->data;
644 :
645 0 : return 1;
646 : }
|