|
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 |
|
64 EXPORT_C long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) |
|
65 { |
|
66 int nid; |
|
67 long ret; |
|
68 |
|
69 nid=OBJ_obj2nid(p7->type); |
|
70 |
|
71 switch (cmd) |
|
72 { |
|
73 case PKCS7_OP_SET_DETACHED_SIGNATURE: |
|
74 if (nid == NID_pkcs7_signed) |
|
75 { |
|
76 ret=p7->detached=(int)larg; |
|
77 if (ret && PKCS7_type_is_data(p7->d.sign->contents)) |
|
78 { |
|
79 ASN1_OCTET_STRING *os; |
|
80 os=p7->d.sign->contents->d.data; |
|
81 ASN1_OCTET_STRING_free(os); |
|
82 p7->d.sign->contents->d.data = NULL; |
|
83 } |
|
84 } |
|
85 else |
|
86 { |
|
87 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); |
|
88 ret=0; |
|
89 } |
|
90 break; |
|
91 case PKCS7_OP_GET_DETACHED_SIGNATURE: |
|
92 if (nid == NID_pkcs7_signed) |
|
93 { |
|
94 if(!p7->d.sign || !p7->d.sign->contents->d.ptr) |
|
95 ret = 1; |
|
96 else ret = 0; |
|
97 |
|
98 p7->detached = ret; |
|
99 } |
|
100 else |
|
101 { |
|
102 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); |
|
103 ret=0; |
|
104 } |
|
105 |
|
106 break; |
|
107 default: |
|
108 PKCS7err(PKCS7_F_PKCS7_CTRL,PKCS7_R_UNKNOWN_OPERATION); |
|
109 ret=0; |
|
110 } |
|
111 return(ret); |
|
112 } |
|
113 |
|
114 EXPORT_C int PKCS7_content_new(PKCS7 *p7, int type) |
|
115 { |
|
116 PKCS7 *ret=NULL; |
|
117 |
|
118 if ((ret=PKCS7_new()) == NULL) goto err; |
|
119 if (!PKCS7_set_type(ret,type)) goto err; |
|
120 if (!PKCS7_set_content(p7,ret)) goto err; |
|
121 |
|
122 return(1); |
|
123 err: |
|
124 if (ret != NULL) PKCS7_free(ret); |
|
125 return(0); |
|
126 } |
|
127 |
|
128 EXPORT_C int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) |
|
129 { |
|
130 int i; |
|
131 |
|
132 i=OBJ_obj2nid(p7->type); |
|
133 switch (i) |
|
134 { |
|
135 case NID_pkcs7_signed: |
|
136 if (p7->d.sign->contents != NULL) |
|
137 PKCS7_free(p7->d.sign->contents); |
|
138 p7->d.sign->contents=p7_data; |
|
139 break; |
|
140 case NID_pkcs7_digest: |
|
141 if (p7->d.digest->contents != NULL) |
|
142 PKCS7_free(p7->d.digest->contents); |
|
143 p7->d.digest->contents=p7_data; |
|
144 break; |
|
145 case NID_pkcs7_data: |
|
146 case NID_pkcs7_enveloped: |
|
147 case NID_pkcs7_signedAndEnveloped: |
|
148 case NID_pkcs7_encrypted: |
|
149 default: |
|
150 PKCS7err(PKCS7_F_PKCS7_SET_CONTENT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
|
151 goto err; |
|
152 } |
|
153 return(1); |
|
154 err: |
|
155 return(0); |
|
156 } |
|
157 |
|
158 EXPORT_C int PKCS7_set_type(PKCS7 *p7, int type) |
|
159 { |
|
160 ASN1_OBJECT *obj; |
|
161 |
|
162 /*PKCS7_content_free(p7);*/ |
|
163 obj=OBJ_nid2obj(type); /* will not fail */ |
|
164 |
|
165 switch (type) |
|
166 { |
|
167 case NID_pkcs7_signed: |
|
168 p7->type=obj; |
|
169 if ((p7->d.sign=PKCS7_SIGNED_new()) == NULL) |
|
170 goto err; |
|
171 if (!ASN1_INTEGER_set(p7->d.sign->version,1)) |
|
172 { |
|
173 PKCS7_SIGNED_free(p7->d.sign); |
|
174 p7->d.sign=NULL; |
|
175 goto err; |
|
176 } |
|
177 break; |
|
178 case NID_pkcs7_data: |
|
179 p7->type=obj; |
|
180 if ((p7->d.data=M_ASN1_OCTET_STRING_new()) == NULL) |
|
181 goto err; |
|
182 break; |
|
183 case NID_pkcs7_signedAndEnveloped: |
|
184 p7->type=obj; |
|
185 if ((p7->d.signed_and_enveloped=PKCS7_SIGN_ENVELOPE_new()) |
|
186 == NULL) goto err; |
|
187 ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1); |
|
188 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version,1)) |
|
189 goto err; |
|
190 p7->d.signed_and_enveloped->enc_data->content_type |
|
191 = OBJ_nid2obj(NID_pkcs7_data); |
|
192 break; |
|
193 case NID_pkcs7_enveloped: |
|
194 p7->type=obj; |
|
195 if ((p7->d.enveloped=PKCS7_ENVELOPE_new()) |
|
196 == NULL) goto err; |
|
197 if (!ASN1_INTEGER_set(p7->d.enveloped->version,0)) |
|
198 goto err; |
|
199 p7->d.enveloped->enc_data->content_type |
|
200 = OBJ_nid2obj(NID_pkcs7_data); |
|
201 break; |
|
202 case NID_pkcs7_encrypted: |
|
203 p7->type=obj; |
|
204 if ((p7->d.encrypted=PKCS7_ENCRYPT_new()) |
|
205 == NULL) goto err; |
|
206 if (!ASN1_INTEGER_set(p7->d.encrypted->version,0)) |
|
207 goto err; |
|
208 p7->d.encrypted->enc_data->content_type |
|
209 = OBJ_nid2obj(NID_pkcs7_data); |
|
210 break; |
|
211 |
|
212 case NID_pkcs7_digest: |
|
213 p7->type=obj; |
|
214 if ((p7->d.digest=PKCS7_DIGEST_new()) |
|
215 == NULL) goto err; |
|
216 if (!ASN1_INTEGER_set(p7->d.digest->version,0)) |
|
217 goto err; |
|
218 break; |
|
219 default: |
|
220 PKCS7err(PKCS7_F_PKCS7_SET_TYPE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); |
|
221 goto err; |
|
222 } |
|
223 return(1); |
|
224 err: |
|
225 return(0); |
|
226 } |
|
227 |
|
228 EXPORT_C int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) |
|
229 { |
|
230 p7->type = OBJ_nid2obj(type); |
|
231 p7->d.other = other; |
|
232 return 1; |
|
233 } |
|
234 |
|
235 EXPORT_C int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) |
|
236 { |
|
237 int i,j,nid; |
|
238 X509_ALGOR *alg; |
|
239 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; |
|
240 STACK_OF(X509_ALGOR) *md_sk; |
|
241 |
|
242 i=OBJ_obj2nid(p7->type); |
|
243 switch (i) |
|
244 { |
|
245 case NID_pkcs7_signed: |
|
246 signer_sk= p7->d.sign->signer_info; |
|
247 md_sk= p7->d.sign->md_algs; |
|
248 break; |
|
249 case NID_pkcs7_signedAndEnveloped: |
|
250 signer_sk= p7->d.signed_and_enveloped->signer_info; |
|
251 md_sk= p7->d.signed_and_enveloped->md_algs; |
|
252 break; |
|
253 default: |
|
254 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,PKCS7_R_WRONG_CONTENT_TYPE); |
|
255 return(0); |
|
256 } |
|
257 |
|
258 nid=OBJ_obj2nid(psi->digest_alg->algorithm); |
|
259 |
|
260 /* If the digest is not currently listed, add it */ |
|
261 j=0; |
|
262 for (i=0; i<sk_X509_ALGOR_num(md_sk); i++) |
|
263 { |
|
264 alg=sk_X509_ALGOR_value(md_sk,i); |
|
265 if (OBJ_obj2nid(alg->algorithm) == nid) |
|
266 { |
|
267 j=1; |
|
268 break; |
|
269 } |
|
270 } |
|
271 if (!j) /* we need to add another algorithm */ |
|
272 { |
|
273 if(!(alg=X509_ALGOR_new()) |
|
274 || !(alg->parameter = ASN1_TYPE_new())) |
|
275 { |
|
276 X509_ALGOR_free(alg); |
|
277 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER,ERR_R_MALLOC_FAILURE); |
|
278 return(0); |
|
279 } |
|
280 alg->algorithm=OBJ_nid2obj(nid); |
|
281 alg->parameter->type = V_ASN1_NULL; |
|
282 if (!sk_X509_ALGOR_push(md_sk,alg)) |
|
283 { |
|
284 X509_ALGOR_free(alg); |
|
285 return 0; |
|
286 } |
|
287 } |
|
288 |
|
289 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk,psi)) |
|
290 return 0; |
|
291 return(1); |
|
292 } |
|
293 |
|
294 EXPORT_C int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) |
|
295 { |
|
296 int i; |
|
297 STACK_OF(X509) **sk; |
|
298 |
|
299 i=OBJ_obj2nid(p7->type); |
|
300 switch (i) |
|
301 { |
|
302 case NID_pkcs7_signed: |
|
303 sk= &(p7->d.sign->cert); |
|
304 break; |
|
305 case NID_pkcs7_signedAndEnveloped: |
|
306 sk= &(p7->d.signed_and_enveloped->cert); |
|
307 break; |
|
308 default: |
|
309 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,PKCS7_R_WRONG_CONTENT_TYPE); |
|
310 return(0); |
|
311 } |
|
312 |
|
313 if (*sk == NULL) |
|
314 *sk=sk_X509_new_null(); |
|
315 if (*sk == NULL) |
|
316 { |
|
317 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE); |
|
318 return 0; |
|
319 } |
|
320 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); |
|
321 if (!sk_X509_push(*sk,x509)) |
|
322 { |
|
323 X509_free(x509); |
|
324 return 0; |
|
325 } |
|
326 return(1); |
|
327 } |
|
328 |
|
329 EXPORT_C int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) |
|
330 { |
|
331 int i; |
|
332 STACK_OF(X509_CRL) **sk; |
|
333 |
|
334 i=OBJ_obj2nid(p7->type); |
|
335 switch (i) |
|
336 { |
|
337 case NID_pkcs7_signed: |
|
338 sk= &(p7->d.sign->crl); |
|
339 break; |
|
340 case NID_pkcs7_signedAndEnveloped: |
|
341 sk= &(p7->d.signed_and_enveloped->crl); |
|
342 break; |
|
343 default: |
|
344 PKCS7err(PKCS7_F_PKCS7_ADD_CRL,PKCS7_R_WRONG_CONTENT_TYPE); |
|
345 return(0); |
|
346 } |
|
347 |
|
348 if (*sk == NULL) |
|
349 *sk=sk_X509_CRL_new_null(); |
|
350 if (*sk == NULL) |
|
351 { |
|
352 PKCS7err(PKCS7_F_PKCS7_ADD_CRL,ERR_R_MALLOC_FAILURE); |
|
353 return 0; |
|
354 } |
|
355 |
|
356 CRYPTO_add(&crl->references,1,CRYPTO_LOCK_X509_CRL); |
|
357 if (!sk_X509_CRL_push(*sk,crl)) |
|
358 { |
|
359 X509_CRL_free(crl); |
|
360 return 0; |
|
361 } |
|
362 return(1); |
|
363 } |
|
364 |
|
365 EXPORT_C int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, |
|
366 const EVP_MD *dgst) |
|
367 { |
|
368 int nid; |
|
369 char is_dsa; |
|
370 |
|
371 if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC) |
|
372 is_dsa = 1; |
|
373 else |
|
374 is_dsa = 0; |
|
375 /* We now need to add another PKCS7_SIGNER_INFO entry */ |
|
376 if (!ASN1_INTEGER_set(p7i->version,1)) |
|
377 goto err; |
|
378 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, |
|
379 X509_get_issuer_name(x509))) |
|
380 goto err; |
|
381 |
|
382 /* because ASN1_INTEGER_set is used to set a 'long' we will do |
|
383 * things the ugly way. */ |
|
384 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); |
|
385 if (!(p7i->issuer_and_serial->serial= |
|
386 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) |
|
387 goto err; |
|
388 |
|
389 /* lets keep the pkey around for a while */ |
|
390 CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); |
|
391 p7i->pkey=pkey; |
|
392 |
|
393 /* Set the algorithms */ |
|
394 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1); |
|
395 else |
|
396 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst)); |
|
397 |
|
398 if (p7i->digest_alg->parameter != NULL) |
|
399 ASN1_TYPE_free(p7i->digest_alg->parameter); |
|
400 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL) |
|
401 goto err; |
|
402 p7i->digest_alg->parameter->type=V_ASN1_NULL; |
|
403 |
|
404 if (p7i->digest_enc_alg->parameter != NULL) |
|
405 ASN1_TYPE_free(p7i->digest_enc_alg->parameter); |
|
406 nid = EVP_PKEY_type(pkey->type); |
|
407 if (nid == EVP_PKEY_RSA) |
|
408 { |
|
409 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); |
|
410 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) |
|
411 goto err; |
|
412 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; |
|
413 } |
|
414 else if (nid == EVP_PKEY_DSA) |
|
415 { |
|
416 #if 1 |
|
417 /* use 'dsaEncryption' OID for compatibility with other software |
|
418 * (PKCS #7 v1.5 does specify how to handle DSA) ... */ |
|
419 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa); |
|
420 #else |
|
421 /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS) |
|
422 * would make more sense. */ |
|
423 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1); |
|
424 #endif |
|
425 p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */ |
|
426 } |
|
427 else if (nid == EVP_PKEY_EC) |
|
428 { |
|
429 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1); |
|
430 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) |
|
431 goto err; |
|
432 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; |
|
433 } |
|
434 else |
|
435 return(0); |
|
436 |
|
437 return(1); |
|
438 err: |
|
439 return(0); |
|
440 } |
|
441 |
|
442 EXPORT_C PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, |
|
443 const EVP_MD *dgst) |
|
444 { |
|
445 PKCS7_SIGNER_INFO *si; |
|
446 |
|
447 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; |
|
448 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; |
|
449 if (!PKCS7_add_signer(p7,si)) goto err; |
|
450 return(si); |
|
451 err: |
|
452 PKCS7_SIGNER_INFO_free(si); |
|
453 return(NULL); |
|
454 } |
|
455 |
|
456 EXPORT_C int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) |
|
457 { |
|
458 if (PKCS7_type_is_digest(p7)) |
|
459 { |
|
460 if(!(p7->d.digest->md->parameter = ASN1_TYPE_new())) |
|
461 { |
|
462 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,ERR_R_MALLOC_FAILURE); |
|
463 return 0; |
|
464 } |
|
465 p7->d.digest->md->parameter->type = V_ASN1_NULL; |
|
466 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); |
|
467 return 1; |
|
468 } |
|
469 |
|
470 PKCS7err(PKCS7_F_PKCS7_SET_DIGEST,PKCS7_R_WRONG_CONTENT_TYPE); |
|
471 return 1; |
|
472 } |
|
473 |
|
474 EXPORT_C STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) |
|
475 { |
|
476 if (PKCS7_type_is_signed(p7)) |
|
477 { |
|
478 return(p7->d.sign->signer_info); |
|
479 } |
|
480 else if (PKCS7_type_is_signedAndEnveloped(p7)) |
|
481 { |
|
482 return(p7->d.signed_and_enveloped->signer_info); |
|
483 } |
|
484 else |
|
485 return(NULL); |
|
486 } |
|
487 |
|
488 EXPORT_C PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) |
|
489 { |
|
490 PKCS7_RECIP_INFO *ri; |
|
491 |
|
492 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; |
|
493 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; |
|
494 if (!PKCS7_add_recipient_info(p7,ri)) goto err; |
|
495 return(ri); |
|
496 err: |
|
497 PKCS7_RECIP_INFO_free(ri); |
|
498 return(NULL); |
|
499 } |
|
500 |
|
501 EXPORT_C int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) |
|
502 { |
|
503 int i; |
|
504 STACK_OF(PKCS7_RECIP_INFO) *sk; |
|
505 |
|
506 i=OBJ_obj2nid(p7->type); |
|
507 switch (i) |
|
508 { |
|
509 case NID_pkcs7_signedAndEnveloped: |
|
510 sk= p7->d.signed_and_enveloped->recipientinfo; |
|
511 break; |
|
512 case NID_pkcs7_enveloped: |
|
513 sk= p7->d.enveloped->recipientinfo; |
|
514 break; |
|
515 default: |
|
516 PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,PKCS7_R_WRONG_CONTENT_TYPE); |
|
517 return(0); |
|
518 } |
|
519 |
|
520 if (!sk_PKCS7_RECIP_INFO_push(sk,ri)) |
|
521 return 0; |
|
522 return(1); |
|
523 } |
|
524 |
|
525 EXPORT_C int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) |
|
526 { |
|
527 if (!ASN1_INTEGER_set(p7i->version,0)) |
|
528 return 0; |
|
529 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, |
|
530 X509_get_issuer_name(x509))) |
|
531 return 0; |
|
532 |
|
533 M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); |
|
534 if (!(p7i->issuer_and_serial->serial= |
|
535 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) |
|
536 return 0; |
|
537 |
|
538 X509_ALGOR_free(p7i->key_enc_algor); |
|
539 if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor))) |
|
540 return 0; |
|
541 |
|
542 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); |
|
543 p7i->cert=x509; |
|
544 |
|
545 return(1); |
|
546 } |
|
547 |
|
548 EXPORT_C X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) |
|
549 { |
|
550 if (PKCS7_type_is_signed(p7)) |
|
551 return(X509_find_by_issuer_and_serial(p7->d.sign->cert, |
|
552 si->issuer_and_serial->issuer, |
|
553 si->issuer_and_serial->serial)); |
|
554 else |
|
555 return(NULL); |
|
556 } |
|
557 |
|
558 EXPORT_C int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) |
|
559 { |
|
560 int i; |
|
561 ASN1_OBJECT *objtmp; |
|
562 PKCS7_ENC_CONTENT *ec; |
|
563 |
|
564 i=OBJ_obj2nid(p7->type); |
|
565 switch (i) |
|
566 { |
|
567 case NID_pkcs7_signedAndEnveloped: |
|
568 ec=p7->d.signed_and_enveloped->enc_data; |
|
569 break; |
|
570 case NID_pkcs7_enveloped: |
|
571 ec=p7->d.enveloped->enc_data; |
|
572 break; |
|
573 default: |
|
574 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_WRONG_CONTENT_TYPE); |
|
575 return(0); |
|
576 } |
|
577 |
|
578 /* Check cipher OID exists and has data in it*/ |
|
579 i = EVP_CIPHER_type(cipher); |
|
580 if(i == NID_undef) { |
|
581 PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); |
|
582 return(0); |
|
583 } |
|
584 objtmp = OBJ_nid2obj(i); |
|
585 |
|
586 ec->cipher = cipher; |
|
587 return 1; |
|
588 } |
|
589 |