summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/pkcs7')
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_asn1.c1053
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_attr.c176
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c1263
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c685
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c110
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c587
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h510
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c145
8 files changed, 0 insertions, 4529 deletions
diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c
deleted file mode 100644
index 8a6ae487da..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_asn1.c
+++ /dev/null
@@ -1,1053 +0,0 @@
1/* $OpenBSD: pk7_asn1.c,v 1.18 2024/07/08 16:23:27 beck Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1t.h>
62#include <openssl/pkcs7.h>
63#include <openssl/x509.h>
64
65/* PKCS#7 ASN1 module */
66
67/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */
68
69static const ASN1_TEMPLATE p7default_tt = {
70 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
71 .tag = 0,
72 .offset = offsetof(PKCS7, d.other),
73 .field_name = "d.other",
74 .item = &ASN1_ANY_it,
75};
76
77static const ASN1_ADB_TABLE PKCS7_adbtbl[] = {
78 {
79 .value = NID_pkcs7_data,
80 .tt = {
81 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
82 .tag = 0,
83 .offset = offsetof(PKCS7, d.data),
84 .field_name = "d.data",
85 .item = &ASN1_OCTET_STRING_NDEF_it,
86 },
87
88 },
89 {
90 .value = NID_pkcs7_signed,
91 .tt = {
92 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
93 .tag = 0,
94 .offset = offsetof(PKCS7, d.sign),
95 .field_name = "d.sign",
96 .item = &PKCS7_SIGNED_it,
97 },
98
99 },
100 {
101 .value = NID_pkcs7_enveloped,
102 .tt = {
103 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
104 .tag = 0,
105 .offset = offsetof(PKCS7, d.enveloped),
106 .field_name = "d.enveloped",
107 .item = &PKCS7_ENVELOPE_it,
108 },
109
110 },
111 {
112 .value = NID_pkcs7_signedAndEnveloped,
113 .tt = {
114 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
115 .tag = 0,
116 .offset = offsetof(PKCS7, d.signed_and_enveloped),
117 .field_name = "d.signed_and_enveloped",
118 .item = &PKCS7_SIGN_ENVELOPE_it,
119 },
120
121 },
122 {
123 .value = NID_pkcs7_digest,
124 .tt = {
125 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
126 .tag = 0,
127 .offset = offsetof(PKCS7, d.digest),
128 .field_name = "d.digest",
129 .item = &PKCS7_DIGEST_it,
130 },
131
132 },
133 {
134 .value = NID_pkcs7_encrypted,
135 .tt = {
136 .flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL | ASN1_TFLG_NDEF,
137 .tag = 0,
138 .offset = offsetof(PKCS7, d.encrypted),
139 .field_name = "d.encrypted",
140 .item = &PKCS7_ENCRYPT_it,
141 },
142
143 },
144};
145
146static const ASN1_ADB PKCS7_adb = {
147 .flags = 0,
148 .offset = offsetof(PKCS7, type),
149 .tbl = PKCS7_adbtbl,
150 .tblcount = sizeof(PKCS7_adbtbl) / sizeof(ASN1_ADB_TABLE),
151 .default_tt = &p7default_tt,
152 .null_tt = NULL,
153};
154
155/* PKCS#7 streaming support */
156static int
157pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
158{
159 ASN1_STREAM_ARG *sarg = exarg;
160 PKCS7 **pp7 = (PKCS7 **)pval;
161
162 switch (operation) {
163 case ASN1_OP_STREAM_PRE:
164 if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
165 return 0;
166 /* FALLTHROUGH */
167
168 case ASN1_OP_DETACHED_PRE:
169 sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
170 if (!sarg->ndef_bio)
171 return 0;
172 break;
173
174 case ASN1_OP_STREAM_POST:
175 case ASN1_OP_DETACHED_POST:
176 if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
177 return 0;
178 break;
179 }
180 return 1;
181}
182
183static const ASN1_AUX PKCS7_aux = {
184 .app_data = NULL,
185 .flags = 0,
186 .ref_offset = 0,
187 .ref_lock = 0,
188 .asn1_cb = pk7_cb,
189 .enc_offset = 0,
190};
191static const ASN1_TEMPLATE PKCS7_seq_tt[] = {
192 {
193 .flags = 0,
194 .tag = 0,
195 .offset = offsetof(PKCS7, type),
196 .field_name = "type",
197 .item = &ASN1_OBJECT_it,
198 },
199 {
200 .flags = ASN1_TFLG_ADB_OID,
201 .tag = -1,
202 .offset = 0,
203 .field_name = "PKCS7",
204 .item = (const ASN1_ITEM *)&PKCS7_adb,
205 },
206};
207
208const ASN1_ITEM PKCS7_it = {
209 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
210 .utype = V_ASN1_SEQUENCE,
211 .templates = PKCS7_seq_tt,
212 .tcount = sizeof(PKCS7_seq_tt) / sizeof(ASN1_TEMPLATE),
213 .funcs = &PKCS7_aux,
214 .size = sizeof(PKCS7),
215 .sname = "PKCS7",
216};
217LCRYPTO_ALIAS(PKCS7_it);
218
219
220PKCS7 *
221d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len)
222{
223 return (PKCS7 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
224 &PKCS7_it);
225}
226LCRYPTO_ALIAS(d2i_PKCS7);
227
228int
229i2d_PKCS7(PKCS7 *a, unsigned char **out)
230{
231 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_it);
232}
233LCRYPTO_ALIAS(i2d_PKCS7);
234
235PKCS7 *
236PKCS7_new(void)
237{
238 return (PKCS7 *)ASN1_item_new(&PKCS7_it);
239}
240LCRYPTO_ALIAS(PKCS7_new);
241
242void
243PKCS7_free(PKCS7 *a)
244{
245 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_it);
246}
247LCRYPTO_ALIAS(PKCS7_free);
248
249PKCS7 *
250PKCS7_dup(PKCS7 *x)
251{
252 return ASN1_item_dup(&PKCS7_it, x);
253}
254LCRYPTO_ALIAS(PKCS7_dup);
255
256static const ASN1_TEMPLATE PKCS7_SIGNED_seq_tt[] = {
257 {
258 .flags = 0,
259 .tag = 0,
260 .offset = offsetof(PKCS7_SIGNED, version),
261 .field_name = "version",
262 .item = &ASN1_INTEGER_it,
263 },
264 {
265 .flags = ASN1_TFLG_SET_OF,
266 .tag = 0,
267 .offset = offsetof(PKCS7_SIGNED, md_algs),
268 .field_name = "md_algs",
269 .item = &X509_ALGOR_it,
270 },
271 {
272 .flags = 0,
273 .tag = 0,
274 .offset = offsetof(PKCS7_SIGNED, contents),
275 .field_name = "contents",
276 .item = &PKCS7_it,
277 },
278 {
279 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
280 .tag = 0,
281 .offset = offsetof(PKCS7_SIGNED, cert),
282 .field_name = "cert",
283 .item = &X509_it,
284 },
285 {
286 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
287 .tag = 1,
288 .offset = offsetof(PKCS7_SIGNED, crl),
289 .field_name = "crl",
290 .item = &X509_CRL_it,
291 },
292 {
293 .flags = ASN1_TFLG_SET_OF,
294 .tag = 0,
295 .offset = offsetof(PKCS7_SIGNED, signer_info),
296 .field_name = "signer_info",
297 .item = &PKCS7_SIGNER_INFO_it,
298 },
299};
300
301const ASN1_ITEM PKCS7_SIGNED_it = {
302 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
303 .utype = V_ASN1_SEQUENCE,
304 .templates = PKCS7_SIGNED_seq_tt,
305 .tcount = sizeof(PKCS7_SIGNED_seq_tt) / sizeof(ASN1_TEMPLATE),
306 .funcs = NULL,
307 .size = sizeof(PKCS7_SIGNED),
308 .sname = "PKCS7_SIGNED",
309};
310LCRYPTO_ALIAS(PKCS7_SIGNED_it);
311
312
313PKCS7_SIGNED *
314d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len)
315{
316 return (PKCS7_SIGNED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
317 &PKCS7_SIGNED_it);
318}
319LCRYPTO_ALIAS(d2i_PKCS7_SIGNED);
320
321int
322i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out)
323{
324 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNED_it);
325}
326LCRYPTO_ALIAS(i2d_PKCS7_SIGNED);
327
328PKCS7_SIGNED *
329PKCS7_SIGNED_new(void)
330{
331 return (PKCS7_SIGNED *)ASN1_item_new(&PKCS7_SIGNED_it);
332}
333LCRYPTO_ALIAS(PKCS7_SIGNED_new);
334
335void
336PKCS7_SIGNED_free(PKCS7_SIGNED *a)
337{
338 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNED_it);
339}
340LCRYPTO_ALIAS(PKCS7_SIGNED_free);
341
342/* Minor tweak to operation: free up EVP_PKEY */
343static int
344si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
345{
346 if (operation == ASN1_OP_FREE_POST) {
347 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
348 EVP_PKEY_free(si->pkey);
349 }
350 return 1;
351}
352
353static const ASN1_AUX PKCS7_SIGNER_INFO_aux = {
354 .app_data = NULL,
355 .flags = 0,
356 .ref_offset = 0,
357 .ref_lock = 0,
358 .asn1_cb = si_cb,
359 .enc_offset = 0,
360};
361static const ASN1_TEMPLATE PKCS7_SIGNER_INFO_seq_tt[] = {
362 {
363 .flags = 0,
364 .tag = 0,
365 .offset = offsetof(PKCS7_SIGNER_INFO, version),
366 .field_name = "version",
367 .item = &ASN1_INTEGER_it,
368 },
369 {
370 .flags = 0,
371 .tag = 0,
372 .offset = offsetof(PKCS7_SIGNER_INFO, issuer_and_serial),
373 .field_name = "issuer_and_serial",
374 .item = &PKCS7_ISSUER_AND_SERIAL_it,
375 },
376 {
377 .flags = 0,
378 .tag = 0,
379 .offset = offsetof(PKCS7_SIGNER_INFO, digest_alg),
380 .field_name = "digest_alg",
381 .item = &X509_ALGOR_it,
382 },
383 /* NB this should be a SET OF but we use a SEQUENCE OF so the
384 * original order * is retained when the structure is reencoded.
385 * Since the attributes are implicitly tagged this will not affect
386 * the encoding.
387 */
388 {
389 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
390 .tag = 0,
391 .offset = offsetof(PKCS7_SIGNER_INFO, auth_attr),
392 .field_name = "auth_attr",
393 .item = &X509_ATTRIBUTE_it,
394 },
395 {
396 .flags = 0,
397 .tag = 0,
398 .offset = offsetof(PKCS7_SIGNER_INFO, digest_enc_alg),
399 .field_name = "digest_enc_alg",
400 .item = &X509_ALGOR_it,
401 },
402 {
403 .flags = 0,
404 .tag = 0,
405 .offset = offsetof(PKCS7_SIGNER_INFO, enc_digest),
406 .field_name = "enc_digest",
407 .item = &ASN1_OCTET_STRING_it,
408 },
409 {
410 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
411 .tag = 1,
412 .offset = offsetof(PKCS7_SIGNER_INFO, unauth_attr),
413 .field_name = "unauth_attr",
414 .item = &X509_ATTRIBUTE_it,
415 },
416};
417
418const ASN1_ITEM PKCS7_SIGNER_INFO_it = {
419 .itype = ASN1_ITYPE_SEQUENCE,
420 .utype = V_ASN1_SEQUENCE,
421 .templates = PKCS7_SIGNER_INFO_seq_tt,
422 .tcount = sizeof(PKCS7_SIGNER_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
423 .funcs = &PKCS7_SIGNER_INFO_aux,
424 .size = sizeof(PKCS7_SIGNER_INFO),
425 .sname = "PKCS7_SIGNER_INFO",
426};
427LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_it);
428
429
430PKCS7_SIGNER_INFO *
431d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len)
432{
433 return (PKCS7_SIGNER_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
434 &PKCS7_SIGNER_INFO_it);
435}
436LCRYPTO_ALIAS(d2i_PKCS7_SIGNER_INFO);
437
438int
439i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out)
440{
441 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGNER_INFO_it);
442}
443LCRYPTO_ALIAS(i2d_PKCS7_SIGNER_INFO);
444
445PKCS7_SIGNER_INFO *
446PKCS7_SIGNER_INFO_new(void)
447{
448 return (PKCS7_SIGNER_INFO *)ASN1_item_new(&PKCS7_SIGNER_INFO_it);
449}
450LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_new);
451
452void
453PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a)
454{
455 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGNER_INFO_it);
456}
457LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_free);
458
459static const ASN1_TEMPLATE PKCS7_ISSUER_AND_SERIAL_seq_tt[] = {
460 {
461 .flags = 0,
462 .tag = 0,
463 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, issuer),
464 .field_name = "issuer",
465 .item = &X509_NAME_it,
466 },
467 {
468 .flags = 0,
469 .tag = 0,
470 .offset = offsetof(PKCS7_ISSUER_AND_SERIAL, serial),
471 .field_name = "serial",
472 .item = &ASN1_INTEGER_it,
473 },
474};
475
476const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it = {
477 .itype = ASN1_ITYPE_SEQUENCE,
478 .utype = V_ASN1_SEQUENCE,
479 .templates = PKCS7_ISSUER_AND_SERIAL_seq_tt,
480 .tcount = sizeof(PKCS7_ISSUER_AND_SERIAL_seq_tt) / sizeof(ASN1_TEMPLATE),
481 .funcs = NULL,
482 .size = sizeof(PKCS7_ISSUER_AND_SERIAL),
483 .sname = "PKCS7_ISSUER_AND_SERIAL",
484};
485LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_it);
486
487
488PKCS7_ISSUER_AND_SERIAL *
489d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len)
490{
491 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
492 &PKCS7_ISSUER_AND_SERIAL_it);
493}
494LCRYPTO_ALIAS(d2i_PKCS7_ISSUER_AND_SERIAL);
495
496int
497i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out)
498{
499 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ISSUER_AND_SERIAL_it);
500}
501LCRYPTO_ALIAS(i2d_PKCS7_ISSUER_AND_SERIAL);
502
503PKCS7_ISSUER_AND_SERIAL *
504PKCS7_ISSUER_AND_SERIAL_new(void)
505{
506 return (PKCS7_ISSUER_AND_SERIAL *)ASN1_item_new(&PKCS7_ISSUER_AND_SERIAL_it);
507}
508LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_new);
509
510void
511PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a)
512{
513 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ISSUER_AND_SERIAL_it);
514}
515LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_free);
516
517static const ASN1_TEMPLATE PKCS7_ENVELOPE_seq_tt[] = {
518 {
519 .flags = 0,
520 .tag = 0,
521 .offset = offsetof(PKCS7_ENVELOPE, version),
522 .field_name = "version",
523 .item = &ASN1_INTEGER_it,
524 },
525 {
526 .flags = ASN1_TFLG_SET_OF,
527 .tag = 0,
528 .offset = offsetof(PKCS7_ENVELOPE, recipientinfo),
529 .field_name = "recipientinfo",
530 .item = &PKCS7_RECIP_INFO_it,
531 },
532 {
533 .flags = 0,
534 .tag = 0,
535 .offset = offsetof(PKCS7_ENVELOPE, enc_data),
536 .field_name = "enc_data",
537 .item = &PKCS7_ENC_CONTENT_it,
538 },
539};
540
541const ASN1_ITEM PKCS7_ENVELOPE_it = {
542 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
543 .utype = V_ASN1_SEQUENCE,
544 .templates = PKCS7_ENVELOPE_seq_tt,
545 .tcount = sizeof(PKCS7_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
546 .funcs = NULL,
547 .size = sizeof(PKCS7_ENVELOPE),
548 .sname = "PKCS7_ENVELOPE",
549};
550LCRYPTO_ALIAS(PKCS7_ENVELOPE_it);
551
552
553PKCS7_ENVELOPE *
554d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len)
555{
556 return (PKCS7_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
557 &PKCS7_ENVELOPE_it);
558}
559LCRYPTO_ALIAS(d2i_PKCS7_ENVELOPE);
560
561int
562i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out)
563{
564 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENVELOPE_it);
565}
566LCRYPTO_ALIAS(i2d_PKCS7_ENVELOPE);
567
568PKCS7_ENVELOPE *
569PKCS7_ENVELOPE_new(void)
570{
571 return (PKCS7_ENVELOPE *)ASN1_item_new(&PKCS7_ENVELOPE_it);
572}
573LCRYPTO_ALIAS(PKCS7_ENVELOPE_new);
574
575void
576PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a)
577{
578 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENVELOPE_it);
579}
580LCRYPTO_ALIAS(PKCS7_ENVELOPE_free);
581
582/* Minor tweak to operation: free up X509 */
583static int
584ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
585{
586 if (operation == ASN1_OP_FREE_POST) {
587 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
588 X509_free(ri->cert);
589 }
590 return 1;
591}
592
593static const ASN1_AUX PKCS7_RECIP_INFO_aux = {
594 .app_data = NULL,
595 .flags = 0,
596 .ref_offset = 0,
597 .ref_lock = 0,
598 .asn1_cb = ri_cb,
599 .enc_offset = 0,
600};
601static const ASN1_TEMPLATE PKCS7_RECIP_INFO_seq_tt[] = {
602 {
603 .flags = 0,
604 .tag = 0,
605 .offset = offsetof(PKCS7_RECIP_INFO, version),
606 .field_name = "version",
607 .item = &ASN1_INTEGER_it,
608 },
609 {
610 .flags = 0,
611 .tag = 0,
612 .offset = offsetof(PKCS7_RECIP_INFO, issuer_and_serial),
613 .field_name = "issuer_and_serial",
614 .item = &PKCS7_ISSUER_AND_SERIAL_it,
615 },
616 {
617 .flags = 0,
618 .tag = 0,
619 .offset = offsetof(PKCS7_RECIP_INFO, key_enc_algor),
620 .field_name = "key_enc_algor",
621 .item = &X509_ALGOR_it,
622 },
623 {
624 .flags = 0,
625 .tag = 0,
626 .offset = offsetof(PKCS7_RECIP_INFO, enc_key),
627 .field_name = "enc_key",
628 .item = &ASN1_OCTET_STRING_it,
629 },
630};
631
632const ASN1_ITEM PKCS7_RECIP_INFO_it = {
633 .itype = ASN1_ITYPE_SEQUENCE,
634 .utype = V_ASN1_SEQUENCE,
635 .templates = PKCS7_RECIP_INFO_seq_tt,
636 .tcount = sizeof(PKCS7_RECIP_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
637 .funcs = &PKCS7_RECIP_INFO_aux,
638 .size = sizeof(PKCS7_RECIP_INFO),
639 .sname = "PKCS7_RECIP_INFO",
640};
641LCRYPTO_ALIAS(PKCS7_RECIP_INFO_it);
642
643
644PKCS7_RECIP_INFO *
645d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len)
646{
647 return (PKCS7_RECIP_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
648 &PKCS7_RECIP_INFO_it);
649}
650LCRYPTO_ALIAS(d2i_PKCS7_RECIP_INFO);
651
652int
653i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out)
654{
655 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_RECIP_INFO_it);
656}
657LCRYPTO_ALIAS(i2d_PKCS7_RECIP_INFO);
658
659PKCS7_RECIP_INFO *
660PKCS7_RECIP_INFO_new(void)
661{
662 return (PKCS7_RECIP_INFO *)ASN1_item_new(&PKCS7_RECIP_INFO_it);
663}
664LCRYPTO_ALIAS(PKCS7_RECIP_INFO_new);
665
666void
667PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a)
668{
669 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_RECIP_INFO_it);
670}
671LCRYPTO_ALIAS(PKCS7_RECIP_INFO_free);
672
673static const ASN1_TEMPLATE PKCS7_ENC_CONTENT_seq_tt[] = {
674 {
675 .flags = 0,
676 .tag = 0,
677 .offset = offsetof(PKCS7_ENC_CONTENT, content_type),
678 .field_name = "content_type",
679 .item = &ASN1_OBJECT_it,
680 },
681 {
682 .flags = 0,
683 .tag = 0,
684 .offset = offsetof(PKCS7_ENC_CONTENT, algorithm),
685 .field_name = "algorithm",
686 .item = &X509_ALGOR_it,
687 },
688 {
689 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_OPTIONAL,
690 .tag = 0,
691 .offset = offsetof(PKCS7_ENC_CONTENT, enc_data),
692 .field_name = "enc_data",
693 .item = &ASN1_OCTET_STRING_NDEF_it,
694 },
695};
696
697const ASN1_ITEM PKCS7_ENC_CONTENT_it = {
698 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
699 .utype = V_ASN1_SEQUENCE,
700 .templates = PKCS7_ENC_CONTENT_seq_tt,
701 .tcount = sizeof(PKCS7_ENC_CONTENT_seq_tt) / sizeof(ASN1_TEMPLATE),
702 .funcs = NULL,
703 .size = sizeof(PKCS7_ENC_CONTENT),
704 .sname = "PKCS7_ENC_CONTENT",
705};
706LCRYPTO_ALIAS(PKCS7_ENC_CONTENT_it);
707
708
709PKCS7_ENC_CONTENT *
710d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len)
711{
712 return (PKCS7_ENC_CONTENT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
713 &PKCS7_ENC_CONTENT_it);
714}
715LCRYPTO_ALIAS(d2i_PKCS7_ENC_CONTENT);
716
717int
718i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out)
719{
720 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENC_CONTENT_it);
721}
722LCRYPTO_ALIAS(i2d_PKCS7_ENC_CONTENT);
723
724PKCS7_ENC_CONTENT *
725PKCS7_ENC_CONTENT_new(void)
726{
727 return (PKCS7_ENC_CONTENT *)ASN1_item_new(&PKCS7_ENC_CONTENT_it);
728}
729LCRYPTO_ALIAS(PKCS7_ENC_CONTENT_new);
730
731void
732PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a)
733{
734 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENC_CONTENT_it);
735}
736LCRYPTO_ALIAS(PKCS7_ENC_CONTENT_free);
737
738static const ASN1_TEMPLATE PKCS7_SIGN_ENVELOPE_seq_tt[] = {
739 {
740 .flags = 0,
741 .tag = 0,
742 .offset = offsetof(PKCS7_SIGN_ENVELOPE, version),
743 .field_name = "version",
744 .item = &ASN1_INTEGER_it,
745 },
746 {
747 .flags = ASN1_TFLG_SET_OF,
748 .tag = 0,
749 .offset = offsetof(PKCS7_SIGN_ENVELOPE, recipientinfo),
750 .field_name = "recipientinfo",
751 .item = &PKCS7_RECIP_INFO_it,
752 },
753 {
754 .flags = ASN1_TFLG_SET_OF,
755 .tag = 0,
756 .offset = offsetof(PKCS7_SIGN_ENVELOPE, md_algs),
757 .field_name = "md_algs",
758 .item = &X509_ALGOR_it,
759 },
760 {
761 .flags = 0,
762 .tag = 0,
763 .offset = offsetof(PKCS7_SIGN_ENVELOPE, enc_data),
764 .field_name = "enc_data",
765 .item = &PKCS7_ENC_CONTENT_it,
766 },
767 {
768 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
769 .tag = 0,
770 .offset = offsetof(PKCS7_SIGN_ENVELOPE, cert),
771 .field_name = "cert",
772 .item = &X509_it,
773 },
774 {
775 .flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
776 .tag = 1,
777 .offset = offsetof(PKCS7_SIGN_ENVELOPE, crl),
778 .field_name = "crl",
779 .item = &X509_CRL_it,
780 },
781 {
782 .flags = ASN1_TFLG_SET_OF,
783 .tag = 0,
784 .offset = offsetof(PKCS7_SIGN_ENVELOPE, signer_info),
785 .field_name = "signer_info",
786 .item = &PKCS7_SIGNER_INFO_it,
787 },
788};
789
790const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it = {
791 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
792 .utype = V_ASN1_SEQUENCE,
793 .templates = PKCS7_SIGN_ENVELOPE_seq_tt,
794 .tcount = sizeof(PKCS7_SIGN_ENVELOPE_seq_tt) / sizeof(ASN1_TEMPLATE),
795 .funcs = NULL,
796 .size = sizeof(PKCS7_SIGN_ENVELOPE),
797 .sname = "PKCS7_SIGN_ENVELOPE",
798};
799LCRYPTO_ALIAS(PKCS7_SIGN_ENVELOPE_it);
800
801
802PKCS7_SIGN_ENVELOPE *
803d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len)
804{
805 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
806 &PKCS7_SIGN_ENVELOPE_it);
807}
808LCRYPTO_ALIAS(d2i_PKCS7_SIGN_ENVELOPE);
809
810int
811i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out)
812{
813 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_SIGN_ENVELOPE_it);
814}
815LCRYPTO_ALIAS(i2d_PKCS7_SIGN_ENVELOPE);
816
817PKCS7_SIGN_ENVELOPE *
818PKCS7_SIGN_ENVELOPE_new(void)
819{
820 return (PKCS7_SIGN_ENVELOPE *)ASN1_item_new(&PKCS7_SIGN_ENVELOPE_it);
821}
822LCRYPTO_ALIAS(PKCS7_SIGN_ENVELOPE_new);
823
824void
825PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a)
826{
827 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_SIGN_ENVELOPE_it);
828}
829LCRYPTO_ALIAS(PKCS7_SIGN_ENVELOPE_free);
830
831static const ASN1_TEMPLATE PKCS7_ENCRYPT_seq_tt[] = {
832 {
833 .flags = 0,
834 .tag = 0,
835 .offset = offsetof(PKCS7_ENCRYPT, version),
836 .field_name = "version",
837 .item = &ASN1_INTEGER_it,
838 },
839 {
840 .flags = 0,
841 .tag = 0,
842 .offset = offsetof(PKCS7_ENCRYPT, enc_data),
843 .field_name = "enc_data",
844 .item = &PKCS7_ENC_CONTENT_it,
845 },
846};
847
848const ASN1_ITEM PKCS7_ENCRYPT_it = {
849 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
850 .utype = V_ASN1_SEQUENCE,
851 .templates = PKCS7_ENCRYPT_seq_tt,
852 .tcount = sizeof(PKCS7_ENCRYPT_seq_tt) / sizeof(ASN1_TEMPLATE),
853 .funcs = NULL,
854 .size = sizeof(PKCS7_ENCRYPT),
855 .sname = "PKCS7_ENCRYPT",
856};
857LCRYPTO_ALIAS(PKCS7_ENCRYPT_it);
858
859
860PKCS7_ENCRYPT *
861d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len)
862{
863 return (PKCS7_ENCRYPT *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
864 &PKCS7_ENCRYPT_it);
865}
866LCRYPTO_ALIAS(d2i_PKCS7_ENCRYPT);
867
868int
869i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out)
870{
871 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_ENCRYPT_it);
872}
873LCRYPTO_ALIAS(i2d_PKCS7_ENCRYPT);
874
875PKCS7_ENCRYPT *
876PKCS7_ENCRYPT_new(void)
877{
878 return (PKCS7_ENCRYPT *)ASN1_item_new(&PKCS7_ENCRYPT_it);
879}
880LCRYPTO_ALIAS(PKCS7_ENCRYPT_new);
881
882void
883PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a)
884{
885 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_ENCRYPT_it);
886}
887LCRYPTO_ALIAS(PKCS7_ENCRYPT_free);
888
889static const ASN1_TEMPLATE PKCS7_DIGEST_seq_tt[] = {
890 {
891 .flags = 0,
892 .tag = 0,
893 .offset = offsetof(PKCS7_DIGEST, version),
894 .field_name = "version",
895 .item = &ASN1_INTEGER_it,
896 },
897 {
898 .flags = 0,
899 .tag = 0,
900 .offset = offsetof(PKCS7_DIGEST, md),
901 .field_name = "md",
902 .item = &X509_ALGOR_it,
903 },
904 {
905 .flags = 0,
906 .tag = 0,
907 .offset = offsetof(PKCS7_DIGEST, contents),
908 .field_name = "contents",
909 .item = &PKCS7_it,
910 },
911 {
912 .flags = 0,
913 .tag = 0,
914 .offset = offsetof(PKCS7_DIGEST, digest),
915 .field_name = "digest",
916 .item = &ASN1_OCTET_STRING_it,
917 },
918};
919
920const ASN1_ITEM PKCS7_DIGEST_it = {
921 .itype = ASN1_ITYPE_NDEF_SEQUENCE,
922 .utype = V_ASN1_SEQUENCE,
923 .templates = PKCS7_DIGEST_seq_tt,
924 .tcount = sizeof(PKCS7_DIGEST_seq_tt) / sizeof(ASN1_TEMPLATE),
925 .funcs = NULL,
926 .size = sizeof(PKCS7_DIGEST),
927 .sname = "PKCS7_DIGEST",
928};
929LCRYPTO_ALIAS(PKCS7_DIGEST_it);
930
931
932PKCS7_DIGEST *
933d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len)
934{
935 return (PKCS7_DIGEST *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
936 &PKCS7_DIGEST_it);
937}
938LCRYPTO_ALIAS(d2i_PKCS7_DIGEST);
939
940int
941i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out)
942{
943 return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS7_DIGEST_it);
944}
945LCRYPTO_ALIAS(i2d_PKCS7_DIGEST);
946
947PKCS7_DIGEST *
948PKCS7_DIGEST_new(void)
949{
950 return (PKCS7_DIGEST *)ASN1_item_new(&PKCS7_DIGEST_it);
951}
952LCRYPTO_ALIAS(PKCS7_DIGEST_new);
953
954void
955PKCS7_DIGEST_free(PKCS7_DIGEST *a)
956{
957 ASN1_item_free((ASN1_VALUE *)a, &PKCS7_DIGEST_it);
958}
959LCRYPTO_ALIAS(PKCS7_DIGEST_free);
960
961/* Specials for authenticated attributes */
962
963/* When signing attributes we want to reorder them to match the sorted
964 * encoding.
965 */
966
967static const ASN1_TEMPLATE PKCS7_ATTR_SIGN_item_tt = {
968 .flags = ASN1_TFLG_SET_ORDER,
969 .tag = 0,
970 .offset = 0,
971 .field_name = "PKCS7_ATTRIBUTES",
972 .item = &X509_ATTRIBUTE_it,
973};
974
975const ASN1_ITEM PKCS7_ATTR_SIGN_it = {
976 .itype = ASN1_ITYPE_PRIMITIVE,
977 .utype = -1,
978 .templates = &PKCS7_ATTR_SIGN_item_tt,
979 .tcount = 0,
980 .funcs = NULL,
981 .size = 0,
982 .sname = "PKCS7_ATTR_SIGN",
983};
984LCRYPTO_ALIAS(PKCS7_ATTR_SIGN_it);
985
986/* When verifying attributes we need to use the received order. So
987 * we use SEQUENCE OF and tag it to SET OF
988 */
989
990static const ASN1_TEMPLATE PKCS7_ATTR_VERIFY_item_tt = {
991 .flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
992 .tag = V_ASN1_SET,
993 .offset = 0,
994 .field_name = "PKCS7_ATTRIBUTES",
995 .item = &X509_ATTRIBUTE_it,
996};
997
998const ASN1_ITEM PKCS7_ATTR_VERIFY_it = {
999 .itype = ASN1_ITYPE_PRIMITIVE,
1000 .utype = -1,
1001 .templates = &PKCS7_ATTR_VERIFY_item_tt,
1002 .tcount = 0,
1003 .funcs = NULL,
1004 .size = 0,
1005 .sname = "PKCS7_ATTR_VERIFY",
1006};
1007LCRYPTO_ALIAS(PKCS7_ATTR_VERIFY_it);
1008
1009
1010int
1011PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx)
1012{
1013 return ASN1_item_print(out, (ASN1_VALUE *)x, indent,
1014 &PKCS7_it, pctx);
1015}
1016LCRYPTO_ALIAS(PKCS7_print_ctx);
1017
1018PKCS7 *
1019d2i_PKCS7_bio(BIO *bp, PKCS7 **p7)
1020{
1021 return ASN1_item_d2i_bio(&PKCS7_it, bp, p7);
1022}
1023LCRYPTO_ALIAS(d2i_PKCS7_bio);
1024
1025int
1026i2d_PKCS7_bio(BIO *bp, PKCS7 *p7)
1027{
1028 return ASN1_item_i2d_bio(&PKCS7_it, bp, p7);
1029}
1030LCRYPTO_ALIAS(i2d_PKCS7_bio);
1031
1032PKCS7 *
1033d2i_PKCS7_fp(FILE *fp, PKCS7 **p7)
1034{
1035 return ASN1_item_d2i_fp(&PKCS7_it, fp, p7);
1036}
1037LCRYPTO_ALIAS(d2i_PKCS7_fp);
1038
1039int
1040i2d_PKCS7_fp(FILE *fp, PKCS7 *p7)
1041{
1042 return ASN1_item_i2d_fp(&PKCS7_it, fp, p7);
1043}
1044LCRYPTO_ALIAS(i2d_PKCS7_fp);
1045
1046int
1047PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
1048 const EVP_MD *type, unsigned char *md, unsigned int *len)
1049{
1050 return(ASN1_item_digest(&PKCS7_ISSUER_AND_SERIAL_it, type,
1051 (char *)data, md, len));
1052}
1053LCRYPTO_ALIAS(PKCS7_ISSUER_AND_SERIAL_digest);
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c
deleted file mode 100644
index 52463aa3a3..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_attr.c
+++ /dev/null
@@ -1,176 +0,0 @@
1/* $OpenBSD: pk7_attr.c,v 1.15 2024/02/19 15:37:44 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2001.
4 */
5/* ====================================================================
6 * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <stdio.h>
60
61#include <openssl/asn1.h>
62#include <openssl/err.h>
63#include <openssl/objects.h>
64#include <openssl/pkcs7.h>
65#include <openssl/x509.h>
66
67int
68PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
69{
70 ASN1_STRING *seq;
71 if (!(seq = ASN1_STRING_new())) {
72 PKCS7error(ERR_R_MALLOC_FAILURE);
73 return 0;
74 }
75 seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data,
76 &X509_ALGORS_it);
77 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
78 V_ASN1_SEQUENCE, seq);
79}
80LCRYPTO_ALIAS(PKCS7_add_attrib_smimecap);
81
82STACK_OF(X509_ALGOR) *
83PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
84{
85 ASN1_TYPE *cap;
86 const unsigned char *p;
87
88 cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities);
89 if (!cap || (cap->type != V_ASN1_SEQUENCE))
90 return NULL;
91 p = cap->value.sequence->data;
92 return (STACK_OF(X509_ALGOR) *)
93 ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
94 &X509_ALGORS_it);
95}
96LCRYPTO_ALIAS(PKCS7_get_smimecap);
97
98/* Basic smime-capabilities OID and optional integer arg */
99int
100PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
101{
102 X509_ALGOR *alg;
103
104 if (!(alg = X509_ALGOR_new())) {
105 PKCS7error(ERR_R_MALLOC_FAILURE);
106 return 0;
107 }
108 ASN1_OBJECT_free(alg->algorithm);
109 alg->algorithm = OBJ_nid2obj(nid);
110 if (arg > 0) {
111 ASN1_INTEGER *nbit;
112
113 if (!(alg->parameter = ASN1_TYPE_new()))
114 goto err;
115 if (!(nbit = ASN1_INTEGER_new()))
116 goto err;
117 if (!ASN1_INTEGER_set(nbit, arg)) {
118 ASN1_INTEGER_free(nbit);
119 goto err;
120 }
121 alg->parameter->value.integer = nbit;
122 alg->parameter->type = V_ASN1_INTEGER;
123 }
124 if (sk_X509_ALGOR_push(sk, alg) == 0)
125 goto err;
126 return 1;
127
128err:
129 PKCS7error(ERR_R_MALLOC_FAILURE);
130 X509_ALGOR_free(alg);
131 return 0;
132}
133LCRYPTO_ALIAS(PKCS7_simple_smimecap);
134
135int
136PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
137{
138 if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
139 return 0;
140 if (!coid)
141 coid = OBJ_nid2obj(NID_pkcs7_data);
142 return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
143 V_ASN1_OBJECT, coid);
144}
145LCRYPTO_ALIAS(PKCS7_add_attrib_content_type);
146
147int
148PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
149{
150 if (!t && !(t = X509_gmtime_adj(NULL, 0))) {
151 PKCS7error(ERR_R_MALLOC_FAILURE);
152 return 0;
153 }
154 return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
155 V_ASN1_UTCTIME, t);
156}
157LCRYPTO_ALIAS(PKCS7_add0_attrib_signing_time);
158
159int
160PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, const unsigned char *md,
161 int mdlen)
162{
163 ASN1_OCTET_STRING *os;
164
165 os = ASN1_OCTET_STRING_new();
166 if (!os)
167 return 0;
168 if (!ASN1_STRING_set(os, md, mdlen) ||
169 !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
170 V_ASN1_OCTET_STRING, os)) {
171 ASN1_OCTET_STRING_free(os);
172 return 0;
173 }
174 return 1;
175}
176LCRYPTO_ALIAS(PKCS7_add1_attrib_digest);
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
deleted file mode 100644
index 020de71fef..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ /dev/null
@@ -1,1263 +0,0 @@
1/* $OpenBSD: pk7_doit.c,v 1.59 2025/03/18 12:53:25 tb Exp $ */
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 <stdlib.h>
61#include <string.h>
62
63#include <openssl/err.h>
64#include <openssl/objects.h>
65#include <openssl/x509.h>
66#include <openssl/x509v3.h>
67
68#include "evp_local.h"
69#include "x509_local.h"
70
71static int
72PKCS7_type_is_other(PKCS7* p7)
73{
74 int isOther = 1;
75
76 int nid = OBJ_obj2nid(p7->type);
77
78 switch (nid ) {
79 case NID_pkcs7_data:
80 case NID_pkcs7_signed:
81 case NID_pkcs7_enveloped:
82 case NID_pkcs7_signedAndEnveloped:
83 case NID_pkcs7_digest:
84 case NID_pkcs7_encrypted:
85 isOther = 0;
86 break;
87 default:
88 isOther = 1;
89 }
90
91 return isOther;
92
93}
94
95ASN1_OCTET_STRING *
96PKCS7_get_octet_string(PKCS7 *p7)
97{
98 if (PKCS7_type_is_data(p7))
99 return p7->d.data;
100 if (PKCS7_type_is_other(p7) && p7->d.other &&
101 (p7->d.other->type == V_ASN1_OCTET_STRING))
102 return p7->d.other->value.octet_string;
103 return NULL;
104}
105
106static int
107PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
108{
109 BIO *btmp;
110 const EVP_MD *md;
111
112 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
113 PKCS7error(ERR_R_BIO_LIB);
114 goto err;
115 }
116
117 md = EVP_get_digestbyobj(alg->algorithm);
118 if (md == NULL) {
119 PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE);
120 goto err;
121 }
122
123 if (BIO_set_md(btmp, md) <= 0) {
124 PKCS7error(ERR_R_BIO_LIB);
125 goto err;
126 }
127
128 if (*pbio == NULL)
129 *pbio = btmp;
130 else if (!BIO_push(*pbio, btmp)) {
131 PKCS7error(ERR_R_BIO_LIB);
132 goto err;
133 }
134 btmp = NULL;
135
136 return 1;
137
138err:
139 BIO_free(btmp);
140 return 0;
141
142}
143
144static int
145pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, unsigned char *key, int keylen)
146{
147 EVP_PKEY_CTX *pctx = NULL;
148 EVP_PKEY *pkey = NULL;
149 unsigned char *ek = NULL;
150 int ret = 0;
151 size_t eklen;
152
153 pkey = X509_get_pubkey(ri->cert);
154 if (!pkey)
155 return 0;
156
157 pctx = EVP_PKEY_CTX_new(pkey, NULL);
158 if (!pctx)
159 return 0;
160
161 if (EVP_PKEY_encrypt_init(pctx) <= 0)
162 goto err;
163
164 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
165 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
166 PKCS7error(PKCS7_R_CTRL_ERROR);
167 goto err;
168 }
169
170 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
171 goto err;
172
173 ek = malloc(eklen);
174
175 if (ek == NULL) {
176 PKCS7error(ERR_R_MALLOC_FAILURE);
177 goto err;
178 }
179
180 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
181 goto err;
182
183 ASN1_STRING_set0(ri->enc_key, ek, eklen);
184 ek = NULL;
185
186 ret = 1;
187
188err:
189 EVP_PKEY_free(pkey);
190 EVP_PKEY_CTX_free(pctx);
191 free(ek);
192 return ret;
193}
194
195
196static int
197pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, PKCS7_RECIP_INFO *ri,
198 EVP_PKEY *pkey, size_t fixlen)
199{
200 EVP_PKEY_CTX *pctx = NULL;
201 unsigned char *ek = NULL;
202 size_t eklen;
203
204 int ret = -1;
205
206 pctx = EVP_PKEY_CTX_new(pkey, NULL);
207 if (!pctx)
208 return -1;
209
210 if (EVP_PKEY_decrypt_init(pctx) <= 0)
211 goto err;
212
213 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
214 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
215 PKCS7error(PKCS7_R_CTRL_ERROR);
216 goto err;
217 }
218
219 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
220 ri->enc_key->data, ri->enc_key->length) <= 0)
221 goto err;
222
223 ek = malloc(eklen);
224 if (ek == NULL) {
225 PKCS7error(ERR_R_MALLOC_FAILURE);
226 goto err;
227 }
228
229 if (EVP_PKEY_decrypt(pctx, ek, &eklen, ri->enc_key->data,
230 ri->enc_key->length) <= 0 || eklen == 0 ||
231 (fixlen != 0 && eklen != fixlen)) {
232 ret = 0;
233 PKCS7error(ERR_R_EVP_LIB);
234 goto err;
235 }
236
237 ret = 1;
238
239 freezero(*pek, *peklen);
240
241 *pek = ek;
242 *peklen = eklen;
243
244err:
245 EVP_PKEY_CTX_free(pctx);
246 if (!ret && ek)
247 free(ek);
248
249 return ret;
250}
251
252BIO *
253PKCS7_dataInit(PKCS7 *p7, BIO *bio)
254{
255 int i;
256 BIO *out = NULL, *btmp = NULL;
257 X509_ALGOR *xa = NULL;
258 const EVP_CIPHER *evp_cipher = NULL;
259 STACK_OF(X509_ALGOR) *md_sk = NULL;
260 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
261 X509_ALGOR *xalg = NULL;
262 PKCS7_RECIP_INFO *ri = NULL;
263 ASN1_OCTET_STRING *os = NULL;
264
265 if (p7 == NULL) {
266 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
267 return NULL;
268 }
269
270 /*
271 * The content field in the PKCS7 ContentInfo is optional,
272 * but that really only applies to inner content (precisely,
273 * detached signatures).
274 *
275 * When reading content, missing outer content is therefore
276 * treated as an error.
277 *
278 * When creating content, PKCS7_content_new() must be called
279 * before calling this method, so a NULL p7->d is always
280 * an error.
281 */
282 if (p7->d.ptr == NULL) {
283 PKCS7error(PKCS7_R_NO_CONTENT);
284 return NULL;
285 }
286
287 i = OBJ_obj2nid(p7->type);
288 p7->state = PKCS7_S_HEADER;
289
290 switch (i) {
291 case NID_pkcs7_signed:
292 md_sk = p7->d.sign->md_algs;
293 os = PKCS7_get_octet_string(p7->d.sign->contents);
294 break;
295 case NID_pkcs7_signedAndEnveloped:
296 rsk = p7->d.signed_and_enveloped->recipientinfo;
297 md_sk = p7->d.signed_and_enveloped->md_algs;
298 xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
299 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
300 if (evp_cipher == NULL) {
301 PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED);
302 goto err;
303 }
304 break;
305 case NID_pkcs7_enveloped:
306 rsk = p7->d.enveloped->recipientinfo;
307 xalg = p7->d.enveloped->enc_data->algorithm;
308 evp_cipher = p7->d.enveloped->enc_data->cipher;
309 if (evp_cipher == NULL) {
310 PKCS7error(PKCS7_R_CIPHER_NOT_INITIALIZED);
311 goto err;
312 }
313 break;
314 case NID_pkcs7_digest:
315 xa = p7->d.digest->md;
316 os = PKCS7_get_octet_string(p7->d.digest->contents);
317 break;
318 case NID_pkcs7_data:
319 break;
320 default:
321 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
322 goto err;
323 }
324
325 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
326 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
327 goto err;
328
329 if (xa && !PKCS7_bio_add_digest(&out, xa))
330 goto err;
331
332 if (evp_cipher != NULL) {
333 unsigned char key[EVP_MAX_KEY_LENGTH];
334 unsigned char iv[EVP_MAX_IV_LENGTH];
335 int keylen, ivlen;
336 EVP_CIPHER_CTX *ctx;
337
338 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
339 PKCS7error(ERR_R_BIO_LIB);
340 goto err;
341 }
342 BIO_get_cipher_ctx(btmp, &ctx);
343 keylen = EVP_CIPHER_key_length(evp_cipher);
344 ivlen = EVP_CIPHER_iv_length(evp_cipher);
345 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
346 if (ivlen > 0)
347 arc4random_buf(iv, ivlen);
348 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL,
349 NULL, 1) <= 0)
350 goto err;
351 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
352 goto err;
353 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
354 goto err;
355
356 if (ivlen > 0) {
357 if (xalg->parameter == NULL) {
358 xalg->parameter = ASN1_TYPE_new();
359 if (xalg->parameter == NULL)
360 goto err;
361 }
362 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
363 goto err;
364 }
365
366 /* Lets do the pub key stuff :-) */
367 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
368 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
369 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
370 goto err;
371 }
372 explicit_bzero(key, keylen);
373
374 if (out == NULL)
375 out = btmp;
376 else
377 BIO_push(out, btmp);
378 btmp = NULL;
379 }
380
381 if (bio == NULL) {
382 if (PKCS7_is_detached(p7))
383 bio = BIO_new(BIO_s_null());
384 else if (os && os->length > 0)
385 bio = BIO_new_mem_buf(os->data, os->length);
386 if (bio == NULL) {
387 bio = BIO_new(BIO_s_mem());
388 if (bio == NULL)
389 goto err;
390 BIO_set_mem_eof_return(bio, 0);
391 }
392 }
393 if (out)
394 BIO_push(out, bio);
395 else
396 out = bio;
397 bio = NULL;
398 if (0) {
399err:
400 if (out != NULL)
401 BIO_free_all(out);
402 if (btmp != NULL)
403 BIO_free_all(btmp);
404 out = NULL;
405 }
406 return out;
407}
408LCRYPTO_ALIAS(PKCS7_dataInit);
409
410static int
411pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
412{
413 int ret;
414
415 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
416 pcert->cert_info->issuer);
417 if (ret)
418 return ret;
419 return ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
420 ri->issuer_and_serial->serial);
421}
422
423/* int */
424BIO *
425PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
426{
427 int i, j;
428 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
429 X509_ALGOR *xa;
430 ASN1_OCTET_STRING *data_body = NULL;
431 const EVP_MD *evp_md;
432 const EVP_CIPHER *evp_cipher = NULL;
433 EVP_CIPHER_CTX *evp_ctx = NULL;
434 X509_ALGOR *enc_alg = NULL;
435 STACK_OF(X509_ALGOR) *md_sk = NULL;
436 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
437 PKCS7_RECIP_INFO *ri = NULL;
438 unsigned char *ek = NULL, *tkey = NULL;
439 int eklen = 0, tkeylen = 0;
440
441 if (p7 == NULL) {
442 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
443 return NULL;
444 }
445
446 if (p7->d.ptr == NULL) {
447 PKCS7error(PKCS7_R_NO_CONTENT);
448 return NULL;
449 }
450
451 i = OBJ_obj2nid(p7->type);
452 p7->state = PKCS7_S_HEADER;
453
454 switch (i) {
455 case NID_pkcs7_signed:
456 data_body = PKCS7_get_octet_string(p7->d.sign->contents);
457 md_sk = p7->d.sign->md_algs;
458 break;
459 case NID_pkcs7_signedAndEnveloped:
460 rsk = p7->d.signed_and_enveloped->recipientinfo;
461 md_sk = p7->d.signed_and_enveloped->md_algs;
462 data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
463 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
464 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
465 if (evp_cipher == NULL) {
466 PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
467 goto err;
468 }
469 break;
470 case NID_pkcs7_enveloped:
471 rsk = p7->d.enveloped->recipientinfo;
472 enc_alg = p7->d.enveloped->enc_data->algorithm;
473 data_body = p7->d.enveloped->enc_data->enc_data;
474 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
475 if (evp_cipher == NULL) {
476 PKCS7error(PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
477 goto err;
478 }
479 break;
480 default:
481 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
482 goto err;
483 }
484
485 /* We will be checking the signature */
486 if (md_sk != NULL) {
487 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
488 xa = sk_X509_ALGOR_value(md_sk, i);
489 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
490 PKCS7error(ERR_R_BIO_LIB);
491 goto err;
492 }
493
494 j = OBJ_obj2nid(xa->algorithm);
495 evp_md = EVP_get_digestbynid(j);
496 if (evp_md == NULL) {
497 PKCS7error(PKCS7_R_UNKNOWN_DIGEST_TYPE);
498 goto err;
499 }
500
501 if (BIO_set_md(btmp, evp_md) <= 0) {
502 PKCS7error(ERR_R_BIO_LIB);
503 goto err;
504 }
505 if (out == NULL)
506 out = btmp;
507 else
508 BIO_push(out, btmp);
509 btmp = NULL;
510 }
511 }
512
513 if (evp_cipher != NULL) {
514 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
515 PKCS7error(ERR_R_BIO_LIB);
516 goto err;
517 }
518
519 /* It was encrypted, we need to decrypt the secret key
520 * with the private key */
521
522 /* Find the recipientInfo which matches the passed certificate
523 * (if any)
524 */
525 if (pcert) {
526 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
527 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
528 if (!pkcs7_cmp_ri(ri, pcert))
529 break;
530 ri = NULL;
531 }
532 if (ri == NULL) {
533 PKCS7error(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
534 goto err;
535 }
536 }
537
538 /* If we haven't got a certificate try each ri in turn */
539 if (pcert == NULL) {
540 /* Always attempt to decrypt all rinfo even
541 * after success as a defence against MMA timing
542 * attacks.
543 */
544 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
545 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
546
547 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
548 EVP_CIPHER_key_length(evp_cipher)) < 0)
549 goto err;
550 ERR_clear_error();
551 }
552 } else {
553 /* Only exit on fatal errors, not decrypt failure */
554 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
555 goto err;
556 ERR_clear_error();
557 }
558
559 evp_ctx = NULL;
560 BIO_get_cipher_ctx(etmp, &evp_ctx);
561 if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL,
562 NULL, 0) <= 0)
563 goto err;
564 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
565 goto err;
566 /* Generate random key as MMA defence */
567 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
568 tkey = malloc(tkeylen);
569 if (!tkey)
570 goto err;
571 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
572 goto err;
573 if (ek == NULL) {
574 ek = tkey;
575 eklen = tkeylen;
576 tkey = NULL;
577 }
578
579 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
580 /* Some S/MIME clients don't use the same key
581 * and effective key length. The key length is
582 * determined by the size of the decrypted RSA key.
583 */
584 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
585 /* Use random key as MMA defence */
586 freezero(ek, eklen);
587 ek = tkey;
588 eklen = tkeylen;
589 tkey = NULL;
590 }
591 }
592 /* Clear errors so we don't leak information useful in MMA */
593 ERR_clear_error();
594 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
595 goto err;
596
597 freezero(ek, eklen);
598 ek = NULL;
599 freezero(tkey, tkeylen);
600 tkey = NULL;
601
602 if (out == NULL)
603 out = etmp;
604 else
605 BIO_push(out, etmp);
606 etmp = NULL;
607 }
608
609 if (PKCS7_is_detached(p7) || (in_bio != NULL)) {
610 bio = in_bio;
611 } else {
612 if (data_body != NULL && data_body->length > 0)
613 bio = BIO_new_mem_buf(data_body->data, data_body->length);
614 else {
615 bio = BIO_new(BIO_s_mem());
616 BIO_set_mem_eof_return(bio, 0);
617 }
618 if (bio == NULL)
619 goto err;
620 }
621 BIO_push(out, bio);
622
623 if (0) {
624err:
625 freezero(ek, eklen);
626 freezero(tkey, tkeylen);
627 if (out != NULL)
628 BIO_free_all(out);
629 if (btmp != NULL)
630 BIO_free_all(btmp);
631 if (etmp != NULL)
632 BIO_free_all(etmp);
633 out = NULL;
634 }
635 return out;
636}
637LCRYPTO_ALIAS(PKCS7_dataDecode);
638
639static BIO *
640PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
641{
642 for (;;) {
643 bio = BIO_find_type(bio, BIO_TYPE_MD);
644 if (bio == NULL) {
645 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
646 return NULL;
647 }
648 BIO_get_md_ctx(bio, pmd);
649 if (*pmd == NULL) {
650 PKCS7error(ERR_R_INTERNAL_ERROR);
651 return NULL;
652 }
653 if (EVP_MD_CTX_type(*pmd) == nid)
654 return bio;
655 bio = BIO_next(bio);
656 }
657 return NULL;
658}
659
660static int
661do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
662{
663 unsigned char md_data[EVP_MAX_MD_SIZE];
664 unsigned int md_len;
665
666 /* Add signing time if not already present */
667 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
668 if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
669 PKCS7error(ERR_R_MALLOC_FAILURE);
670 return 0;
671 }
672 }
673
674 /* Add digest */
675 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
676 PKCS7error(ERR_R_EVP_LIB);
677 return 0;
678 }
679 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
680 PKCS7error(ERR_R_MALLOC_FAILURE);
681 return 0;
682 }
683
684 /* Now sign the attributes */
685 if (!PKCS7_SIGNER_INFO_sign(si))
686 return 0;
687
688 return 1;
689}
690
691
692int
693PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
694{
695 int ret = 0;
696 int i, j;
697 BIO *btmp;
698 PKCS7_SIGNER_INFO *si;
699 EVP_MD_CTX *mdc, ctx_tmp;
700 STACK_OF(X509_ATTRIBUTE) *sk;
701 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
702 ASN1_OCTET_STRING *os = NULL;
703
704 if (p7 == NULL) {
705 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
706 return 0;
707 }
708
709 if (p7->d.ptr == NULL) {
710 PKCS7error(PKCS7_R_NO_CONTENT);
711 return 0;
712 }
713
714 EVP_MD_CTX_legacy_clear(&ctx_tmp);
715 i = OBJ_obj2nid(p7->type);
716 p7->state = PKCS7_S_HEADER;
717
718 switch (i) {
719 case NID_pkcs7_data:
720 os = p7->d.data;
721 break;
722 case NID_pkcs7_signedAndEnveloped:
723 /* XXX */
724 si_sk = p7->d.signed_and_enveloped->signer_info;
725 os = p7->d.signed_and_enveloped->enc_data->enc_data;
726 if (!os) {
727 os = ASN1_OCTET_STRING_new();
728 if (!os) {
729 PKCS7error(ERR_R_MALLOC_FAILURE);
730 goto err;
731 }
732 p7->d.signed_and_enveloped->enc_data->enc_data = os;
733 }
734 break;
735 case NID_pkcs7_enveloped:
736 /* XXX */
737 os = p7->d.enveloped->enc_data->enc_data;
738 if (!os) {
739 os = ASN1_OCTET_STRING_new();
740 if (!os) {
741 PKCS7error(ERR_R_MALLOC_FAILURE);
742 goto err;
743 }
744 p7->d.enveloped->enc_data->enc_data = os;
745 }
746 break;
747 case NID_pkcs7_signed:
748 si_sk = p7->d.sign->signer_info;
749 os = PKCS7_get_octet_string(p7->d.sign->contents);
750 if (!PKCS7_is_detached(p7) && os == NULL) {
751 PKCS7error(PKCS7_R_DECODE_ERROR);
752 goto err;
753 }
754 /* If detached data then the content is excluded */
755 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
756 ASN1_OCTET_STRING_free(os);
757 os = NULL;
758 p7->d.sign->contents->d.data = NULL;
759 }
760 break;
761
762 case NID_pkcs7_digest:
763 os = PKCS7_get_octet_string(p7->d.digest->contents);
764 if (os == NULL) {
765 PKCS7error(PKCS7_R_DECODE_ERROR);
766 goto err;
767 }
768 /* If detached data then the content is excluded */
769 if (PKCS7_type_is_data(p7->d.digest->contents) &&
770 p7->detached) {
771 ASN1_OCTET_STRING_free(os);
772 os = NULL;
773 p7->d.digest->contents->d.data = NULL;
774 }
775 break;
776
777 default:
778 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
779 goto err;
780 }
781
782 if (si_sk != NULL) {
783 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
784 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
785 if (si->pkey == NULL)
786 continue;
787
788 j = OBJ_obj2nid(si->digest_alg->algorithm);
789
790 if ((btmp = PKCS7_find_digest(&mdc, bio, j)) == NULL)
791 goto err;
792
793 /* We now have the EVP_MD_CTX, lets do the
794 * signing. */
795 if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
796 goto err;
797
798 sk = si->auth_attr;
799
800 /* If there are attributes, we add the digest
801 * attribute and only sign the attributes */
802 if (sk_X509_ATTRIBUTE_num(sk) > 0) {
803 if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
804 goto err;
805 } else {
806 unsigned char *abuf = NULL;
807 unsigned int abuflen;
808 abuflen = EVP_PKEY_size(si->pkey);
809 abuf = malloc(abuflen);
810 if (!abuf)
811 goto err;
812
813 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
814 si->pkey)) {
815 PKCS7error(ERR_R_EVP_LIB);
816 free(abuf);
817 goto err;
818 }
819 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
820 }
821 }
822 } else if (i == NID_pkcs7_digest) {
823 unsigned char md_data[EVP_MAX_MD_SIZE];
824 unsigned int md_len;
825
826 if (!PKCS7_find_digest(&mdc, bio,
827 OBJ_obj2nid(p7->d.digest->md->algorithm)))
828 goto err;
829 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
830 goto err;
831 if (ASN1_STRING_set(p7->d.digest->digest, md_data,
832 md_len) == 0)
833 goto err;
834 }
835
836 if (!PKCS7_is_detached(p7)) {
837 /*
838 * NOTE: only reach os == NULL here because detached
839 * digested data support is broken?
840 */
841 if (os == NULL)
842 goto err;
843 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
844 char *cont;
845 long contlen;
846
847 btmp = BIO_find_type(bio, BIO_TYPE_MEM);
848 if (btmp == NULL) {
849 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
850 goto err;
851 }
852 contlen = BIO_get_mem_data(btmp, &cont);
853 /*
854 * Mark the BIO read only then we can use its copy
855 * of the data instead of making an extra copy.
856 */
857 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
858 BIO_set_mem_eof_return(btmp, 0);
859 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
860 }
861 }
862 ret = 1;
863err:
864 EVP_MD_CTX_cleanup(&ctx_tmp);
865 return ret;
866}
867LCRYPTO_ALIAS(PKCS7_dataFinal);
868
869int
870PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
871{
872 EVP_MD_CTX mctx;
873 EVP_PKEY_CTX *pctx;
874 unsigned char *abuf = NULL;
875 int alen;
876 size_t siglen;
877 const EVP_MD *md = NULL;
878
879 md = EVP_get_digestbyobj(si->digest_alg->algorithm);
880 if (md == NULL)
881 return 0;
882
883 EVP_MD_CTX_legacy_clear(&mctx);
884 if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
885 goto err;
886
887 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
888 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
889 PKCS7error(PKCS7_R_CTRL_ERROR);
890 goto err;
891 }
892
893 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
894 &PKCS7_ATTR_SIGN_it);
895 if (!abuf)
896 goto err;
897 if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
898 goto err;
899 free(abuf);
900 abuf = NULL;
901 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
902 goto err;
903 abuf = malloc(siglen);
904 if (!abuf)
905 goto err;
906 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
907 goto err;
908
909 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
910 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
911 PKCS7error(PKCS7_R_CTRL_ERROR);
912 goto err;
913 }
914
915 EVP_MD_CTX_cleanup(&mctx);
916
917 ASN1_STRING_set0(si->enc_digest, abuf, siglen);
918
919 return 1;
920
921err:
922 free(abuf);
923 EVP_MD_CTX_cleanup(&mctx);
924 return 0;
925}
926LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_sign);
927
928int
929PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
930 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
931{
932 PKCS7_ISSUER_AND_SERIAL *ias;
933 int ret = 0, i;
934 STACK_OF(X509) *cert;
935 X509 *x509;
936
937 if (p7 == NULL) {
938 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
939 return 0;
940 }
941
942 if (p7->d.ptr == NULL) {
943 PKCS7error(PKCS7_R_NO_CONTENT);
944 return 0;
945 }
946
947 if (PKCS7_type_is_signed(p7)) {
948 cert = p7->d.sign->cert;
949 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
950 cert = p7->d.signed_and_enveloped->cert;
951 } else {
952 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE);
953 goto err;
954 }
955 /* XXXX */
956 ias = si->issuer_and_serial;
957
958 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
959
960 /* were we able to find the cert in passed to us */
961 if (x509 == NULL) {
962 PKCS7error(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
963 goto err;
964 }
965
966 /* Lets verify */
967 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
968 PKCS7error(ERR_R_X509_LIB);
969 goto err;
970 }
971 if (X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN) == 0) {
972 X509_STORE_CTX_cleanup(ctx);
973 goto err;
974 }
975 i = X509_verify_cert(ctx);
976 if (i <= 0) {
977 PKCS7error(ERR_R_X509_LIB);
978 X509_STORE_CTX_cleanup(ctx);
979 goto err;
980 }
981 X509_STORE_CTX_cleanup(ctx);
982
983 return PKCS7_signatureVerify(bio, p7, si, x509);
984
985err:
986 return ret;
987}
988LCRYPTO_ALIAS(PKCS7_dataVerify);
989
990int
991PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509)
992{
993 ASN1_OCTET_STRING *os;
994 EVP_MD_CTX mdc_tmp, *mdc;
995 int ret = 0, i;
996 int md_type;
997 STACK_OF(X509_ATTRIBUTE) *sk;
998 BIO *btmp;
999 EVP_PKEY *pkey;
1000
1001 EVP_MD_CTX_legacy_clear(&mdc_tmp);
1002
1003 if (!PKCS7_type_is_signed(p7) &&
1004 !PKCS7_type_is_signedAndEnveloped(p7)) {
1005 PKCS7error(PKCS7_R_WRONG_PKCS7_TYPE);
1006 goto err;
1007 }
1008
1009 md_type = OBJ_obj2nid(si->digest_alg->algorithm);
1010
1011 btmp = bio;
1012 for (;;) {
1013 if ((btmp == NULL) ||
1014 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
1015 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1016 goto err;
1017 }
1018 BIO_get_md_ctx(btmp, &mdc);
1019 if (mdc == NULL) {
1020 PKCS7error(ERR_R_INTERNAL_ERROR);
1021 goto err;
1022 }
1023 if (EVP_MD_CTX_type(mdc) == md_type)
1024 break;
1025 /* Workaround for some broken clients that put the signature
1026 * OID instead of the digest OID in digest_alg->algorithm
1027 */
1028 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
1029 break;
1030 btmp = BIO_next(btmp);
1031 }
1032
1033 /* mdc is the digest ctx that we want, unless there are attributes,
1034 * in which case the digest is the signed attributes */
1035 if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc))
1036 goto err;
1037
1038 sk = si->auth_attr;
1039 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
1040 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
1041 unsigned int md_len;
1042 int alen;
1043 ASN1_OCTET_STRING *message_digest;
1044
1045 if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len))
1046 goto err;
1047 message_digest = PKCS7_digest_from_attributes(sk);
1048 if (!message_digest) {
1049 PKCS7error(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1050 goto err;
1051 }
1052 if ((message_digest->length != (int)md_len) ||
1053 (memcmp(message_digest->data, md_dat, md_len))) {
1054 PKCS7error(PKCS7_R_DIGEST_FAILURE);
1055 ret = -1;
1056 goto err;
1057 }
1058
1059 if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type),
1060 NULL))
1061 goto err;
1062
1063 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
1064 &PKCS7_ATTR_VERIFY_it);
1065 if (alen <= 0) {
1066 PKCS7error(ERR_R_ASN1_LIB);
1067 ret = -1;
1068 goto err;
1069 }
1070 if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) {
1071 free(abuf);
1072 goto err;
1073 }
1074
1075 free(abuf);
1076 }
1077
1078 os = si->enc_digest;
1079 pkey = X509_get_pubkey(x509);
1080 if (!pkey) {
1081 ret = -1;
1082 goto err;
1083 }
1084
1085 i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
1086 EVP_PKEY_free(pkey);
1087 if (i <= 0) {
1088 PKCS7error(PKCS7_R_SIGNATURE_FAILURE);
1089 ret = -1;
1090 goto err;
1091 } else
1092 ret = 1;
1093err:
1094 EVP_MD_CTX_cleanup(&mdc_tmp);
1095 return ret;
1096}
1097LCRYPTO_ALIAS(PKCS7_signatureVerify);
1098
1099PKCS7_ISSUER_AND_SERIAL *
1100PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
1101{
1102 STACK_OF(PKCS7_RECIP_INFO) *rsk;
1103 PKCS7_RECIP_INFO *ri;
1104 int i;
1105
1106 i = OBJ_obj2nid(p7->type);
1107 if (i != NID_pkcs7_signedAndEnveloped)
1108 return NULL;
1109 if (p7->d.signed_and_enveloped == NULL)
1110 return NULL;
1111 rsk = p7->d.signed_and_enveloped->recipientinfo;
1112 if (rsk == NULL)
1113 return NULL;
1114 ri = sk_PKCS7_RECIP_INFO_value(rsk, 0);
1115 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
1116 return NULL;
1117 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
1118 return ri->issuer_and_serial;
1119}
1120LCRYPTO_ALIAS(PKCS7_get_issuer_and_serial);
1121
1122static ASN1_TYPE *
1123get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
1124{
1125 int i;
1126 X509_ATTRIBUTE *xa;
1127 ASN1_OBJECT *o;
1128
1129 o = OBJ_nid2obj(nid);
1130 if (!o || !sk)
1131 return NULL;
1132 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1133 xa = sk_X509_ATTRIBUTE_value(sk, i);
1134 if (OBJ_cmp(xa->object, o) == 0)
1135 return sk_ASN1_TYPE_value(xa->set, 0);
1136 }
1137 return NULL;
1138}
1139
1140ASN1_TYPE *
1141PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
1142{
1143 return get_attribute(si->auth_attr, nid);
1144}
1145LCRYPTO_ALIAS(PKCS7_get_signed_attribute);
1146
1147ASN1_TYPE *
1148PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
1149{
1150 return get_attribute(si->unauth_attr, nid);
1151}
1152LCRYPTO_ALIAS(PKCS7_get_attribute);
1153
1154ASN1_OCTET_STRING *
1155PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
1156{
1157 ASN1_TYPE *astype;
1158
1159 if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
1160 return NULL;
1161 if (astype->type != V_ASN1_OCTET_STRING)
1162 return NULL;
1163 return astype->value.octet_string;
1164}
1165LCRYPTO_ALIAS(PKCS7_digest_from_attributes);
1166
1167int
1168PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
1169 STACK_OF(X509_ATTRIBUTE) *sk)
1170{
1171 int i;
1172
1173 if (p7si->auth_attr != NULL)
1174 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr,
1175 X509_ATTRIBUTE_free);
1176 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
1177 if (p7si->auth_attr == NULL)
1178 return 0;
1179 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1180 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
1181 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i))))
1182 == NULL)
1183 return 0;
1184 }
1185 return 1;
1186}
1187LCRYPTO_ALIAS(PKCS7_set_signed_attributes);
1188
1189int
1190PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk)
1191{
1192 int i;
1193
1194 if (p7si->unauth_attr != NULL)
1195 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr,
1196 X509_ATTRIBUTE_free);
1197 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
1198 if (p7si->unauth_attr == NULL)
1199 return 0;
1200 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1201 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
1202 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value(sk, i))))
1203 == NULL)
1204 return 0;
1205 }
1206 return 1;
1207}
1208LCRYPTO_ALIAS(PKCS7_set_attributes);
1209
1210static int
1211add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, void *value)
1212{
1213 X509_ATTRIBUTE *attr = NULL;
1214
1215 if (*sk == NULL) {
1216 *sk = sk_X509_ATTRIBUTE_new_null();
1217 if (*sk == NULL)
1218 return 0;
1219new_attrib:
1220 if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
1221 return 0;
1222 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
1223 X509_ATTRIBUTE_free(attr);
1224 return 0;
1225 }
1226 } else {
1227 int i;
1228
1229 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
1230 attr = sk_X509_ATTRIBUTE_value(*sk, i);
1231 if (OBJ_obj2nid(attr->object) == nid) {
1232 X509_ATTRIBUTE_free(attr);
1233 attr = X509_ATTRIBUTE_create(nid, atrtype,
1234 value);
1235 if (attr == NULL)
1236 return 0;
1237 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
1238 X509_ATTRIBUTE_free(attr);
1239 return 0;
1240 }
1241 goto end;
1242 }
1243 }
1244 goto new_attrib;
1245 }
1246end:
1247 return 1;
1248}
1249
1250int
1251PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1252 void *value)
1253{
1254 return add_attribute(&(p7si->auth_attr), nid, atrtype, value);
1255}
1256LCRYPTO_ALIAS(PKCS7_add_signed_attribute);
1257
1258int
1259PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, void *value)
1260{
1261 return add_attribute(&(p7si->unauth_attr), nid, atrtype, value);
1262}
1263LCRYPTO_ALIAS(PKCS7_add_attribute);
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
deleted file mode 100644
index a1c7d61cca..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ /dev/null
@@ -1,685 +0,0 @@
1/* $OpenBSD: pk7_lib.c,v 1.30 2024/12/06 07:10:20 tb Exp $ */
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
61#include <openssl/err.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
64
65#include "asn1_local.h"
66#include "evp_local.h"
67#include "x509_local.h"
68
69long
70PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
71{
72 int nid;
73 long ret = 0;
74
75 nid = OBJ_obj2nid(p7->type);
76
77 switch (cmd) {
78 case PKCS7_OP_SET_DETACHED_SIGNATURE:
79 if (nid == NID_pkcs7_signed) {
80 if (p7->d.sign == NULL) {
81 PKCS7error(PKCS7_R_NO_CONTENT);
82 break;
83 }
84 ret = p7->detached = (int)larg;
85 if (ret && PKCS7_type_is_data(p7->d.sign->contents)) {
86 ASN1_OCTET_STRING *os;
87 os = p7->d.sign->contents->d.data;
88 ASN1_OCTET_STRING_free(os);
89 p7->d.sign->contents->d.data = NULL;
90 }
91 } else {
92 PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
93 ret = 0;
94 }
95 break;
96 case PKCS7_OP_GET_DETACHED_SIGNATURE:
97 if (nid == NID_pkcs7_signed) {
98 if (p7->d.sign == NULL ||
99 p7->d.sign->contents->d.ptr == NULL)
100 ret = 1;
101 else
102 ret = 0;
103
104 p7->detached = ret;
105 } else {
106 PKCS7error(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE);
107 ret = 0;
108 }
109
110 break;
111 default:
112 PKCS7error(PKCS7_R_UNKNOWN_OPERATION);
113 ret = 0;
114 }
115 return (ret);
116}
117LCRYPTO_ALIAS(PKCS7_ctrl);
118
119int
120PKCS7_content_new(PKCS7 *p7, int type)
121{
122 PKCS7 *ret = NULL;
123
124 if ((ret = PKCS7_new()) == NULL)
125 goto err;
126 if (!PKCS7_set_type(ret, type))
127 goto err;
128 if (!PKCS7_set_content(p7, ret))
129 goto err;
130
131 return (1);
132err:
133 if (ret != NULL)
134 PKCS7_free(ret);
135 return (0);
136}
137LCRYPTO_ALIAS(PKCS7_content_new);
138
139int
140PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data)
141{
142 int i;
143
144 i = OBJ_obj2nid(p7->type);
145 switch (i) {
146 case NID_pkcs7_signed:
147 if (p7->d.sign->contents != NULL)
148 PKCS7_free(p7->d.sign->contents);
149 p7->d.sign->contents = p7_data;
150 break;
151 case NID_pkcs7_digest:
152 if (p7->d.digest->contents != NULL)
153 PKCS7_free(p7->d.digest->contents);
154 p7->d.digest->contents = p7_data;
155 break;
156 case NID_pkcs7_data:
157 case NID_pkcs7_enveloped:
158 case NID_pkcs7_signedAndEnveloped:
159 case NID_pkcs7_encrypted:
160 default:
161 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
162 goto err;
163 }
164 return (1);
165err:
166 return (0);
167}
168LCRYPTO_ALIAS(PKCS7_set_content);
169
170int
171PKCS7_set_type(PKCS7 *p7, int type)
172{
173 ASN1_OBJECT *obj;
174
175 /*PKCS7_content_free(p7);*/
176 obj=OBJ_nid2obj(type); /* will not fail */
177
178 switch (type) {
179 case NID_pkcs7_signed:
180 p7->type = obj;
181 if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL)
182 goto err;
183 if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) {
184 PKCS7_SIGNED_free(p7->d.sign);
185 p7->d.sign = NULL;
186 goto err;
187 }
188 break;
189 case NID_pkcs7_data:
190 p7->type = obj;
191 if ((p7->d.data = ASN1_OCTET_STRING_new()) == NULL)
192 goto err;
193 break;
194 case NID_pkcs7_signedAndEnveloped:
195 p7->type = obj;
196 if ((p7->d.signed_and_enveloped =
197 PKCS7_SIGN_ENVELOPE_new()) == NULL)
198 goto err;
199 if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1))
200 goto err;
201 p7->d.signed_and_enveloped->enc_data->content_type =
202 OBJ_nid2obj(NID_pkcs7_data);
203 break;
204 case NID_pkcs7_enveloped:
205 p7->type = obj;
206 if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) == NULL)
207 goto err;
208 if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0))
209 goto err;
210 p7->d.enveloped->enc_data->content_type =
211 OBJ_nid2obj(NID_pkcs7_data);
212 break;
213 case NID_pkcs7_encrypted:
214 p7->type = obj;
215 if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) == NULL)
216 goto err;
217 if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0))
218 goto err;
219 p7->d.encrypted->enc_data->content_type =
220 OBJ_nid2obj(NID_pkcs7_data);
221 break;
222
223 case NID_pkcs7_digest:
224 p7->type = obj;
225 if ((p7->d.digest = PKCS7_DIGEST_new()) == NULL)
226 goto err;
227 if (!ASN1_INTEGER_set(p7->d.digest->version, 0))
228 goto err;
229 break;
230 default:
231 PKCS7error(PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
232 goto err;
233 }
234 return (1);
235err:
236 return (0);
237}
238LCRYPTO_ALIAS(PKCS7_set_type);
239
240int
241PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other)
242{
243 p7->type = OBJ_nid2obj(type);
244 p7->d.other = other;
245 return 1;
246}
247LCRYPTO_ALIAS(PKCS7_set0_type_other);
248
249int
250PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi)
251{
252 int i, j, nid;
253 X509_ALGOR *alg;
254 STACK_OF(PKCS7_SIGNER_INFO) *signer_sk;
255 STACK_OF(X509_ALGOR) *md_sk;
256
257 i = OBJ_obj2nid(p7->type);
258 switch (i) {
259 case NID_pkcs7_signed:
260 signer_sk = p7->d.sign->signer_info;
261 md_sk = p7->d.sign->md_algs;
262 break;
263 case NID_pkcs7_signedAndEnveloped:
264 signer_sk = p7->d.signed_and_enveloped->signer_info;
265 md_sk = p7->d.signed_and_enveloped->md_algs;
266 break;
267 default:
268 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
269 return (0);
270 }
271
272 nid = OBJ_obj2nid(psi->digest_alg->algorithm);
273
274 /* If the digest is not currently listed, add it */
275 j = 0;
276 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
277 alg = sk_X509_ALGOR_value(md_sk, i);
278 if (OBJ_obj2nid(alg->algorithm) == nid) {
279 j = 1;
280 break;
281 }
282 }
283 if (!j) /* we need to add another algorithm */
284 {
285 if (!(alg = X509_ALGOR_new()) ||
286 !(alg->parameter = ASN1_TYPE_new())) {
287 X509_ALGOR_free(alg);
288 PKCS7error(ERR_R_MALLOC_FAILURE);
289 return (0);
290 }
291 alg->algorithm = OBJ_nid2obj(nid);
292 alg->parameter->type = V_ASN1_NULL;
293 if (!sk_X509_ALGOR_push(md_sk, alg)) {
294 X509_ALGOR_free(alg);
295 return 0;
296 }
297 }
298
299 if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi))
300 return 0;
301 return (1);
302}
303LCRYPTO_ALIAS(PKCS7_add_signer);
304
305int
306PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
307{
308 int i;
309 STACK_OF(X509) **sk;
310
311 i = OBJ_obj2nid(p7->type);
312 switch (i) {
313 case NID_pkcs7_signed:
314 sk = &(p7->d.sign->cert);
315 break;
316 case NID_pkcs7_signedAndEnveloped:
317 sk = &(p7->d.signed_and_enveloped->cert);
318 break;
319 default:
320 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
321 return (0);
322 }
323
324 if (*sk == NULL)
325 *sk = sk_X509_new_null();
326 if (*sk == NULL) {
327 PKCS7error(ERR_R_MALLOC_FAILURE);
328 return 0;
329 }
330 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
331 if (!sk_X509_push(*sk, x509)) {
332 X509_free(x509);
333 return 0;
334 }
335 return (1);
336}
337LCRYPTO_ALIAS(PKCS7_add_certificate);
338
339int
340PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
341{
342 int i;
343 STACK_OF(X509_CRL) **sk;
344
345 i = OBJ_obj2nid(p7->type);
346 switch (i) {
347 case NID_pkcs7_signed:
348 sk = &(p7->d.sign->crl);
349 break;
350 case NID_pkcs7_signedAndEnveloped:
351 sk = &(p7->d.signed_and_enveloped->crl);
352 break;
353 default:
354 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
355 return (0);
356 }
357
358 if (*sk == NULL)
359 *sk = sk_X509_CRL_new_null();
360 if (*sk == NULL) {
361 PKCS7error(ERR_R_MALLOC_FAILURE);
362 return 0;
363 }
364
365 CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
366 if (!sk_X509_CRL_push(*sk, crl)) {
367 X509_CRL_free(crl);
368 return 0;
369 }
370 return (1);
371}
372LCRYPTO_ALIAS(PKCS7_add_crl);
373
374int
375PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
376 const EVP_MD *dgst)
377{
378 int nid;
379 int ret;
380
381 /* We now need to add another PKCS7_SIGNER_INFO entry */
382 if (!ASN1_INTEGER_set(p7i->version, 1))
383 goto err;
384 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
385 X509_get_issuer_name(x509)))
386 goto err;
387
388 /* because ASN1_INTEGER_set is used to set a 'long' we will do
389 * things the ugly way. */
390 ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
391 if (!(p7i->issuer_and_serial->serial =
392 ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
393 goto err;
394
395 /* lets keep the pkey around for a while */
396 CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
397 p7i->pkey = pkey;
398
399 /*
400 * Do not use X509_ALGOR_set_evp_md() to match historical behavior.
401 * A mistranslation of the ASN.1 from 1988 to 1997 syntax lost the
402 * OPTIONAL field, cf. the NOTE above RFC 5754, 2.1.
403 * Using X509_ALGOR_set_evp_md() would change encoding of the SHAs.
404 */
405 nid = EVP_MD_type(dgst);
406 if (!X509_ALGOR_set0_by_nid(p7i->digest_alg, nid, V_ASN1_NULL, NULL))
407 return 0;
408
409 if (pkey->ameth && pkey->ameth->pkey_ctrl) {
410 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
411 0, p7i);
412 if (ret > 0)
413 return 1;
414 if (ret != -2) {
415 PKCS7error(PKCS7_R_SIGNING_CTRL_FAILURE);
416 return 0;
417 }
418 }
419 PKCS7error(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
420err:
421 return 0;
422}
423LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_set);
424
425PKCS7_SIGNER_INFO *
426PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst)
427{
428 PKCS7_SIGNER_INFO *si = NULL;
429
430 if (dgst == NULL) {
431 int def_nid;
432 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
433 goto err;
434 dgst = EVP_get_digestbynid(def_nid);
435 if (dgst == NULL) {
436 PKCS7error(PKCS7_R_NO_DEFAULT_DIGEST);
437 goto err;
438 }
439 }
440
441 if ((si = PKCS7_SIGNER_INFO_new()) == NULL)
442 goto err;
443 if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst))
444 goto err;
445 if (!PKCS7_add_signer(p7, si))
446 goto err;
447 return (si);
448err:
449 if (si)
450 PKCS7_SIGNER_INFO_free(si);
451 return (NULL);
452}
453LCRYPTO_ALIAS(PKCS7_add_signature);
454
455int
456PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md)
457{
458 if (PKCS7_type_is_digest(p7)) {
459 if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) {
460 PKCS7error(ERR_R_MALLOC_FAILURE);
461 return 0;
462 }
463 p7->d.digest->md->parameter->type = V_ASN1_NULL;
464 p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md));
465 return 1;
466 }
467
468 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
469 return 1;
470}
471LCRYPTO_ALIAS(PKCS7_set_digest);
472
473STACK_OF(PKCS7_SIGNER_INFO) *
474PKCS7_get_signer_info(PKCS7 *p7)
475{
476 if (p7 == NULL || p7->d.ptr == NULL)
477 return (NULL);
478 if (PKCS7_type_is_signed(p7)) {
479 return (p7->d.sign->signer_info);
480 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
481 return (p7->d.signed_and_enveloped->signer_info);
482 } else
483 return (NULL);
484}
485LCRYPTO_ALIAS(PKCS7_get_signer_info);
486
487void
488PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
489 X509_ALGOR **pdig, X509_ALGOR **psig)
490{
491 if (pk)
492 *pk = si->pkey;
493 if (pdig)
494 *pdig = si->digest_alg;
495 if (psig)
496 *psig = si->digest_enc_alg;
497}
498LCRYPTO_ALIAS(PKCS7_SIGNER_INFO_get0_algs);
499
500void
501PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
502{
503 if (penc)
504 *penc = ri->key_enc_algor;
505}
506LCRYPTO_ALIAS(PKCS7_RECIP_INFO_get0_alg);
507
508PKCS7_RECIP_INFO *
509PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
510{
511 PKCS7_RECIP_INFO *ri;
512
513 if ((ri = PKCS7_RECIP_INFO_new()) == NULL)
514 goto err;
515 if (!PKCS7_RECIP_INFO_set(ri, x509))
516 goto err;
517 if (!PKCS7_add_recipient_info(p7, ri))
518 goto err;
519 return ri;
520err:
521 if (ri)
522 PKCS7_RECIP_INFO_free(ri);
523 return NULL;
524}
525LCRYPTO_ALIAS(PKCS7_add_recipient);
526
527int
528PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
529{
530 int i;
531 STACK_OF(PKCS7_RECIP_INFO) *sk;
532
533 i = OBJ_obj2nid(p7->type);
534 switch (i) {
535 case NID_pkcs7_signedAndEnveloped:
536 sk = p7->d.signed_and_enveloped->recipientinfo;
537 break;
538 case NID_pkcs7_enveloped:
539 sk = p7->d.enveloped->recipientinfo;
540 break;
541 default:
542 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
543 return (0);
544 }
545
546 if (!sk_PKCS7_RECIP_INFO_push(sk, ri))
547 return 0;
548 return (1);
549}
550LCRYPTO_ALIAS(PKCS7_add_recipient_info);
551
552int
553PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
554{
555 int ret;
556 EVP_PKEY *pkey = NULL;
557 if (!ASN1_INTEGER_set(p7i->version, 0))
558 return 0;
559 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
560 X509_get_issuer_name(x509)))
561 return 0;
562
563 ASN1_INTEGER_free(p7i->issuer_and_serial->serial);
564 if (!(p7i->issuer_and_serial->serial =
565 ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
566 return 0;
567
568 pkey = X509_get_pubkey(x509);
569
570 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) {
571 PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
572 goto err;
573 }
574
575 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
576 0, p7i);
577 if (ret == -2) {
578 PKCS7error(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
579 goto err;
580 }
581 if (ret <= 0) {
582 PKCS7error(PKCS7_R_ENCRYPTION_CTRL_FAILURE);
583 goto err;
584 }
585
586 EVP_PKEY_free(pkey);
587
588 CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509);
589 p7i->cert = x509;
590
591 return 1;
592
593err:
594 EVP_PKEY_free(pkey);
595 return 0;
596}
597LCRYPTO_ALIAS(PKCS7_RECIP_INFO_set);
598
599X509 *
600PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
601{
602 if (PKCS7_type_is_signed(p7))
603 return(X509_find_by_issuer_and_serial(p7->d.sign->cert,
604 si->issuer_and_serial->issuer,
605 si->issuer_and_serial->serial));
606 else
607 return (NULL);
608}
609LCRYPTO_ALIAS(PKCS7_cert_from_signer_info);
610
611int
612PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
613{
614 int i;
615 PKCS7_ENC_CONTENT *ec;
616
617 i = OBJ_obj2nid(p7->type);
618 switch (i) {
619 case NID_pkcs7_signedAndEnveloped:
620 ec = p7->d.signed_and_enveloped->enc_data;
621 break;
622 case NID_pkcs7_enveloped:
623 ec = p7->d.enveloped->enc_data;
624 break;
625 default:
626 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
627 return (0);
628 }
629
630 /* Check cipher OID exists and has data in it*/
631 i = EVP_CIPHER_type(cipher);
632 if (i == NID_undef) {
633 PKCS7error(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
634 return (0);
635 }
636
637 ec->cipher = cipher;
638 return 1;
639}
640LCRYPTO_ALIAS(PKCS7_set_cipher);
641
642int
643PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
644{
645 ASN1_OCTET_STRING *os = NULL;
646
647 switch (OBJ_obj2nid(p7->type)) {
648 case NID_pkcs7_data:
649 os = p7->d.data;
650 break;
651
652 case NID_pkcs7_signedAndEnveloped:
653 os = p7->d.signed_and_enveloped->enc_data->enc_data;
654 if (os == NULL) {
655 os = ASN1_OCTET_STRING_new();
656 p7->d.signed_and_enveloped->enc_data->enc_data = os;
657 }
658 break;
659
660 case NID_pkcs7_enveloped:
661 os = p7->d.enveloped->enc_data->enc_data;
662 if (os == NULL) {
663 os = ASN1_OCTET_STRING_new();
664 p7->d.enveloped->enc_data->enc_data = os;
665 }
666 break;
667
668 case NID_pkcs7_signed:
669 os = p7->d.sign->contents->d.data;
670 break;
671
672 default:
673 os = NULL;
674 break;
675 }
676
677 if (os == NULL)
678 return 0;
679
680 os->flags |= ASN1_STRING_FLAG_NDEF;
681 *boundary = &os->data;
682
683 return 1;
684}
685LCRYPTO_ALIAS(PKCS7_stream);
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
deleted file mode 100644
index 381335589f..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ /dev/null
@@ -1,110 +0,0 @@
1/* $OpenBSD: pk7_mime.c,v 1.20 2024/01/25 13:44:08 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 */
54
55#include <ctype.h>
56#include <stdio.h>
57
58#include <openssl/asn1.h>
59#include <openssl/x509.h>
60
61#include "asn1_local.h"
62
63/* PKCS#7 wrappers round generalised stream and MIME routines */
64BIO *
65BIO_new_PKCS7(BIO *out, PKCS7 *p7)
66{
67 return BIO_new_NDEF(out, (ASN1_VALUE *)p7, &PKCS7_it);
68}
69LCRYPTO_ALIAS(BIO_new_PKCS7);
70
71int
72i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
73{
74 return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, &PKCS7_it);
75}
76LCRYPTO_ALIAS(i2d_PKCS7_bio_stream);
77
78int
79PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
80{
81 return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
82 "PKCS7", &PKCS7_it);
83}
84LCRYPTO_ALIAS(PEM_write_bio_PKCS7_stream);
85
86int
87SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
88{
89 STACK_OF(X509_ALGOR) *mdalgs = NULL;
90 int ctype_nid;
91
92 if ((ctype_nid = OBJ_obj2nid(p7->type)) == NID_pkcs7_signed) {
93 if (p7->d.sign == NULL)
94 return 0;
95 mdalgs = p7->d.sign->md_algs;
96 }
97
98 flags ^= SMIME_OLDMIME;
99
100 return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
101 ctype_nid, NID_undef, mdalgs, &PKCS7_it);
102}
103LCRYPTO_ALIAS(SMIME_write_PKCS7);
104
105PKCS7 *
106SMIME_read_PKCS7(BIO *bio, BIO **bcont)
107{
108 return (PKCS7 *)SMIME_read_ASN1(bio, bcont, &PKCS7_it);
109}
110LCRYPTO_ALIAS(SMIME_read_PKCS7);
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
deleted file mode 100644
index cff89c34e1..0000000000
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ /dev/null
@@ -1,587 +0,0 @@
1/* $OpenBSD: pk7_smime.c,v 1.27 2024/04/20 10:11:55 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59/* Simple PKCS#7 processing functions */
60
61#include <stdio.h>
62
63#include <openssl/err.h>
64#include <openssl/x509.h>
65#include <openssl/x509v3.h>
66
67#include "x509_local.h"
68
69static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
70
71PKCS7 *
72PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, BIO *data,
73 int flags)
74{
75 PKCS7 *p7;
76 int i;
77
78 if (!(p7 = PKCS7_new())) {
79 PKCS7error(ERR_R_MALLOC_FAILURE);
80 return NULL;
81 }
82
83 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
84 goto err;
85
86 if (!PKCS7_content_new(p7, NID_pkcs7_data))
87 goto err;
88
89 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) {
90 PKCS7error(PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
91 goto err;
92 }
93
94 if (!(flags & PKCS7_NOCERTS)) {
95 for (i = 0; i < sk_X509_num(certs); i++) {
96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
97 goto err;
98 }
99 }
100
101 if (flags & PKCS7_DETACHED)
102 PKCS7_set_detached(p7, 1);
103
104 if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
105 return p7;
106
107 if (PKCS7_final(p7, data, flags))
108 return p7;
109
110err:
111 PKCS7_free(p7);
112 return NULL;
113}
114LCRYPTO_ALIAS(PKCS7_sign);
115
116int
117PKCS7_final(PKCS7 *p7, BIO *data, int flags)
118{
119 BIO *p7bio;
120 int ret = 0;
121
122 if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
123 PKCS7error(ERR_R_MALLOC_FAILURE);
124 return 0;
125 }
126
127 SMIME_crlf_copy(data, p7bio, flags);
128
129 (void)BIO_flush(p7bio);
130
131 if (!PKCS7_dataFinal(p7, p7bio)) {
132 PKCS7error(PKCS7_R_PKCS7_DATASIGN);
133 goto err;
134 }
135
136 ret = 1;
137
138err:
139 BIO_free_all(p7bio);
140
141 return ret;
142}
143LCRYPTO_ALIAS(PKCS7_final);
144
145/* Check to see if a cipher exists and if so add S/MIME capabilities */
146
147static int
148add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
149{
150 if (EVP_get_cipherbynid(nid))
151 return PKCS7_simple_smimecap(sk, nid, arg);
152 return 1;
153}
154
155PKCS7_SIGNER_INFO *
156PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, EVP_PKEY *pkey,
157 const EVP_MD *md, int flags)
158{
159 PKCS7_SIGNER_INFO *si = NULL;
160 STACK_OF(X509_ALGOR) *smcap = NULL;
161
162 if (!X509_check_private_key(signcert, pkey)) {
163 PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
164 return NULL;
165 }
166
167 if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) {
168 PKCS7error(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
169 return NULL;
170 }
171
172 if (!(flags & PKCS7_NOCERTS)) {
173 if (!PKCS7_add_certificate(p7, signcert))
174 goto err;
175 }
176
177 if (!(flags & PKCS7_NOATTR)) {
178 if (!PKCS7_add_attrib_content_type(si, NULL))
179 goto err;
180 /* Add SMIMECapabilities */
181 if (!(flags & PKCS7_NOSMIMECAP)) {
182 if (!(smcap = sk_X509_ALGOR_new_null())) {
183 PKCS7error(ERR_R_MALLOC_FAILURE);
184 goto err;
185 }
186 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
187 !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
188 !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) ||
189 !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) ||
190 !add_cipher_smcap(smcap, NID_rc2_cbc, 128) ||
191 !add_cipher_smcap(smcap, NID_rc2_cbc, 64) ||
192 !add_cipher_smcap(smcap, NID_des_cbc, -1) ||
193 !add_cipher_smcap(smcap, NID_rc2_cbc, 40) ||
194 !PKCS7_add_attrib_smimecap(si, smcap))
195 goto err;
196 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
197 smcap = NULL;
198 }
199 if (flags & PKCS7_REUSE_DIGEST) {
200 if (!pkcs7_copy_existing_digest(p7, si))
201 goto err;
202 if (!(flags & PKCS7_PARTIAL) &&
203 !PKCS7_SIGNER_INFO_sign(si))
204 goto err;
205 }
206 }
207 return si;
208
209err:
210 if (smcap)
211 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
212 return NULL;
213}
214LCRYPTO_ALIAS(PKCS7_sign_add_signer);
215
216/* Search for a digest matching SignerInfo digest type and if found
217 * copy across.
218 */
219
220static int
221pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
222{
223 int i;
224 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
225 PKCS7_SIGNER_INFO *sitmp;
226 ASN1_OCTET_STRING *osdig = NULL;
227
228 sinfos = PKCS7_get_signer_info(p7);
229 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
230 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
231 if (si == sitmp)
232 break;
233 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
234 continue;
235 if (!OBJ_cmp(si->digest_alg->algorithm,
236 sitmp->digest_alg->algorithm)) {
237 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
238 break;
239 }
240
241 }
242
243 if (osdig)
244 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
245
246 PKCS7error(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
247 return 0;
248}
249
250int
251PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata,
252 BIO *out, int flags)
253{
254 STACK_OF(X509) *signers;
255 X509 *signer;
256 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
257 PKCS7_SIGNER_INFO *si;
258 X509_STORE_CTX cert_ctx;
259 char buf[4096];
260 int i, j = 0, k, ret = 0;
261 BIO *p7bio;
262 BIO *tmpin, *tmpout;
263
264 if (!p7) {
265 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
266 return 0;
267 }
268
269 if (!PKCS7_type_is_signed(p7)) {
270 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
271 return 0;
272 }
273
274 /* Check for no data and no content: no data to verify signature */
275 if (PKCS7_get_detached(p7) && !indata) {
276 PKCS7error(PKCS7_R_NO_CONTENT);
277 return 0;
278 }
279
280 /*
281 * Very old Netscape illegally included empty content with
282 * a detached signature. Very old users should upgrade.
283 */
284 /* Check for data and content: two sets of data */
285 if (!PKCS7_get_detached(p7) && indata) {
286 PKCS7error(PKCS7_R_CONTENT_AND_DATA_PRESENT);
287 return 0;
288 }
289
290 sinfos = PKCS7_get_signer_info(p7);
291
292 if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) {
293 PKCS7error(PKCS7_R_NO_SIGNATURES_ON_DATA);
294 return 0;
295 }
296
297
298 signers = PKCS7_get0_signers(p7, certs, flags);
299
300 if (!signers)
301 return 0;
302
303 /* Now verify the certificates */
304
305 if (!(flags & PKCS7_NOVERIFY))
306 for (k = 0; k < sk_X509_num(signers); k++) {
307 signer = sk_X509_value (signers, k);
308 if (!(flags & PKCS7_NOCHAIN)) {
309 if (!X509_STORE_CTX_init(&cert_ctx, store,
310 signer, p7->d.sign->cert)) {
311 PKCS7error(ERR_R_X509_LIB);
312 sk_X509_free(signers);
313 return 0;
314 }
315 if (X509_STORE_CTX_set_default(&cert_ctx,
316 "smime_sign") == 0) {
317 sk_X509_free(signers);
318 return 0;
319 }
320 } else if (!X509_STORE_CTX_init(&cert_ctx, store,
321 signer, NULL)) {
322 PKCS7error(ERR_R_X509_LIB);
323 sk_X509_free(signers);
324 return 0;
325 }
326 if (!(flags & PKCS7_NOCRL))
327 X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl);
328 i = X509_verify_cert(&cert_ctx);
329 if (i <= 0)
330 j = X509_STORE_CTX_get_error(&cert_ctx);
331 X509_STORE_CTX_cleanup(&cert_ctx);
332 if (i <= 0) {
333 PKCS7error(PKCS7_R_CERTIFICATE_VERIFY_ERROR);
334 ERR_asprintf_error_data("Verify error:%s",
335 X509_verify_cert_error_string(j));
336 sk_X509_free(signers);
337 return 0;
338 }
339 /* Check for revocation status here */
340 }
341
342 /*
343 * Performance optimization: if the content is a memory BIO then
344 * store its contents in a temporary read only memory BIO. This
345 * avoids potentially large numbers of slow copies of data which will
346 * occur when reading from a read write memory BIO when signatures
347 * are calculated.
348 */
349 if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) {
350 char *ptr;
351 long len;
352
353 len = BIO_get_mem_data(indata, &ptr);
354 tmpin = BIO_new_mem_buf(ptr, len);
355 if (tmpin == NULL) {
356 PKCS7error(ERR_R_MALLOC_FAILURE);
357 return 0;
358 }
359 } else
360 tmpin = indata;
361
362
363 if (!(p7bio = PKCS7_dataInit(p7, tmpin)))
364 goto err;
365
366 if (flags & PKCS7_TEXT) {
367 if (!(tmpout = BIO_new(BIO_s_mem()))) {
368 PKCS7error(ERR_R_MALLOC_FAILURE);
369 goto err;
370 }
371 BIO_set_mem_eof_return(tmpout, 0);
372 } else
373 tmpout = out;
374
375 /* We now have to 'read' from p7bio to calculate digests etc. */
376 for (;;) {
377 i = BIO_read(p7bio, buf, sizeof(buf));
378 if (i <= 0)
379 break;
380 if (tmpout)
381 BIO_write(tmpout, buf, i);
382 }
383
384 if (flags & PKCS7_TEXT) {
385 if (!SMIME_text(tmpout, out)) {
386 PKCS7error(PKCS7_R_SMIME_TEXT_ERROR);
387 BIO_free(tmpout);
388 goto err;
389 }
390 BIO_free(tmpout);
391 }
392
393 /* Now Verify All Signatures */
394 if (!(flags & PKCS7_NOSIGS))
395 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
396 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
397 signer = sk_X509_value (signers, i);
398 j = PKCS7_signatureVerify(p7bio, p7, si, signer);
399 if (j <= 0) {
400 PKCS7error(PKCS7_R_SIGNATURE_FAILURE);
401 goto err;
402 }
403 }
404
405 ret = 1;
406
407err:
408 if (tmpin == indata) {
409 if (indata)
410 BIO_pop(p7bio);
411 }
412 BIO_free_all(p7bio);
413 sk_X509_free(signers);
414
415 return ret;
416}
417LCRYPTO_ALIAS(PKCS7_verify);
418
419STACK_OF(X509) *
420PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
421{
422 STACK_OF(X509) *signers;
423 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
424 PKCS7_SIGNER_INFO *si;
425 PKCS7_ISSUER_AND_SERIAL *ias;
426 X509 *signer;
427 int i;
428
429 if (!p7) {
430 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
431 return NULL;
432 }
433
434 if (!PKCS7_type_is_signed(p7)) {
435 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
436 return NULL;
437 }
438
439 /* Collect all the signers together */
440 sinfos = PKCS7_get_signer_info(p7);
441 if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
442 PKCS7error(PKCS7_R_NO_SIGNERS);
443 return 0;
444 }
445
446 if (!(signers = sk_X509_new_null())) {
447 PKCS7error(ERR_R_MALLOC_FAILURE);
448 return NULL;
449 }
450
451 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) {
452 si = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
453 ias = si->issuer_and_serial;
454 signer = NULL;
455 /* If any certificates passed they take priority */
456 if (certs)
457 signer = X509_find_by_issuer_and_serial (certs,
458 ias->issuer, ias->serial);
459 if (!signer && !(flags & PKCS7_NOINTERN) && p7->d.sign->cert)
460 signer =
461 X509_find_by_issuer_and_serial(p7->d.sign->cert,
462 ias->issuer, ias->serial);
463 if (!signer) {
464 PKCS7error(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
465 sk_X509_free(signers);
466 return 0;
467 }
468
469 if (!sk_X509_push(signers, signer)) {
470 sk_X509_free(signers);
471 return NULL;
472 }
473 }
474 return signers;
475}
476LCRYPTO_ALIAS(PKCS7_get0_signers);
477
478/* Build a complete PKCS#7 enveloped data */
479
480PKCS7 *
481PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
482 int flags)
483{
484 PKCS7 *p7;
485 BIO *p7bio = NULL;
486 int i;
487 X509 *x509;
488
489 if (!(p7 = PKCS7_new())) {
490 PKCS7error(ERR_R_MALLOC_FAILURE);
491 return NULL;
492 }
493
494 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
495 goto err;
496 if (!PKCS7_set_cipher(p7, cipher)) {
497 PKCS7error(PKCS7_R_ERROR_SETTING_CIPHER);
498 goto err;
499 }
500
501 for (i = 0; i < sk_X509_num(certs); i++) {
502 x509 = sk_X509_value(certs, i);
503 if (!PKCS7_add_recipient(p7, x509)) {
504 PKCS7error(PKCS7_R_ERROR_ADDING_RECIPIENT);
505 goto err;
506 }
507 }
508
509 if (flags & PKCS7_STREAM)
510 return p7;
511
512 if (PKCS7_final(p7, in, flags))
513 return p7;
514
515err:
516 BIO_free_all(p7bio);
517 PKCS7_free(p7);
518 return NULL;
519}
520LCRYPTO_ALIAS(PKCS7_encrypt);
521
522int
523PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags)
524{
525 BIO *tmpmem;
526 int ret, i;
527 char buf[4096];
528
529 if (!p7) {
530 PKCS7error(PKCS7_R_INVALID_NULL_POINTER);
531 return 0;
532 }
533
534 if (!PKCS7_type_is_enveloped(p7)) {
535 PKCS7error(PKCS7_R_WRONG_CONTENT_TYPE);
536 return 0;
537 }
538
539 if (cert && !X509_check_private_key(cert, pkey)) {
540 PKCS7error(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
541 return 0;
542 }
543
544 if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) {
545 PKCS7error(PKCS7_R_DECRYPT_ERROR);
546 return 0;
547 }
548
549 if (flags & PKCS7_TEXT) {
550 BIO *tmpbuf;
551
552 /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */
553 if (!(tmpbuf = BIO_new(BIO_f_buffer()))) {
554 PKCS7error(ERR_R_MALLOC_FAILURE);
555 BIO_free_all(tmpmem);
556 return 0;
557 }
558 BIO_push(tmpbuf, tmpmem);
559 ret = SMIME_text(tmpbuf, data);
560 if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) {
561 if (!BIO_get_cipher_status(tmpmem))
562 ret = 0;
563 }
564 BIO_free_all(tmpbuf);
565 return ret;
566 } else {
567 for (;;) {
568 i = BIO_read(tmpmem, buf, sizeof(buf));
569 if (i <= 0) {
570 ret = 1;
571 if (BIO_method_type(tmpmem) ==
572 BIO_TYPE_CIPHER) {
573 if (!BIO_get_cipher_status(tmpmem))
574 ret = 0;
575 }
576 break;
577 }
578 if (BIO_write(data, buf, i) != i) {
579 ret = 0;
580 break;
581 }
582 }
583 BIO_free_all(tmpmem);
584 return ret;
585 }
586}
587LCRYPTO_ALIAS(PKCS7_decrypt);
diff --git a/src/lib/libcrypto/pkcs7/pkcs7.h b/src/lib/libcrypto/pkcs7/pkcs7.h
deleted file mode 100644
index 6fd5adf457..0000000000
--- a/src/lib/libcrypto/pkcs7/pkcs7.h
+++ /dev/null
@@ -1,510 +0,0 @@
1/* $OpenBSD: pkcs7.h,v 1.22 2024/10/23 01:57:19 jsg Exp $ */
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#ifndef HEADER_PKCS7_H
60#define HEADER_PKCS7_H
61
62#include <openssl/opensslconf.h>
63
64#include <openssl/asn1.h>
65#include <openssl/bio.h>
66#include <openssl/ossl_typ.h>
67
68#ifdef __cplusplus
69extern "C" {
70#endif
71
72/*
73Encryption_ID DES-CBC
74Digest_ID MD5
75Digest_Encryption_ID rsaEncryption
76Key_Encryption_ID rsaEncryption
77*/
78
79typedef struct pkcs7_issuer_and_serial_st {
80 X509_NAME *issuer;
81 ASN1_INTEGER *serial;
82} PKCS7_ISSUER_AND_SERIAL;
83
84typedef struct pkcs7_signer_info_st {
85 ASN1_INTEGER *version; /* version 1 */
86 PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
87 X509_ALGOR *digest_alg;
88 STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */
89 X509_ALGOR *digest_enc_alg;
90 ASN1_OCTET_STRING *enc_digest;
91 STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */
92
93 /* The private key to sign with */
94 EVP_PKEY *pkey;
95} PKCS7_SIGNER_INFO;
96
97DECLARE_STACK_OF(PKCS7_SIGNER_INFO)
98
99typedef struct pkcs7_recip_info_st {
100 ASN1_INTEGER *version; /* version 0 */
101 PKCS7_ISSUER_AND_SERIAL *issuer_and_serial;
102 X509_ALGOR *key_enc_algor;
103 ASN1_OCTET_STRING *enc_key;
104 X509 *cert; /* get the pub-key from this */
105} PKCS7_RECIP_INFO;
106
107DECLARE_STACK_OF(PKCS7_RECIP_INFO)
108
109typedef struct pkcs7_signed_st {
110 ASN1_INTEGER *version; /* version 1 */
111 STACK_OF(X509_ALGOR) *md_algs; /* md used */
112 STACK_OF(X509) *cert; /* [ 0 ] */
113 STACK_OF(X509_CRL) *crl; /* [ 1 ] */
114 STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
115
116 struct pkcs7_st *contents;
117} PKCS7_SIGNED;
118/* The above structure is very very similar to PKCS7_SIGN_ENVELOPE.
119 * How about merging the two */
120
121typedef struct pkcs7_enc_content_st {
122 ASN1_OBJECT *content_type;
123 X509_ALGOR *algorithm;
124 ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
125 const EVP_CIPHER *cipher;
126} PKCS7_ENC_CONTENT;
127
128typedef struct pkcs7_enveloped_st {
129 ASN1_INTEGER *version; /* version 0 */
130 STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
131 PKCS7_ENC_CONTENT *enc_data;
132} PKCS7_ENVELOPE;
133
134typedef struct pkcs7_signedandenveloped_st {
135 ASN1_INTEGER *version; /* version 1 */
136 STACK_OF(X509_ALGOR) *md_algs; /* md used */
137 STACK_OF(X509) *cert; /* [ 0 ] */
138 STACK_OF(X509_CRL) *crl; /* [ 1 ] */
139 STACK_OF(PKCS7_SIGNER_INFO) *signer_info;
140
141 PKCS7_ENC_CONTENT *enc_data;
142 STACK_OF(PKCS7_RECIP_INFO) *recipientinfo;
143} PKCS7_SIGN_ENVELOPE;
144
145typedef struct pkcs7_digest_st {
146 ASN1_INTEGER *version; /* version 0 */
147 X509_ALGOR *md; /* md used */
148 struct pkcs7_st *contents;
149 ASN1_OCTET_STRING *digest;
150} PKCS7_DIGEST;
151
152typedef struct pkcs7_encrypted_st {
153 ASN1_INTEGER *version; /* version 0 */
154 PKCS7_ENC_CONTENT *enc_data;
155} PKCS7_ENCRYPT;
156
157typedef struct pkcs7_st {
158 /* The following is non NULL if it contains ASN1 encoding of
159 * this structure */
160 unsigned char *asn1;
161 long length;
162
163#define PKCS7_S_HEADER 0
164#define PKCS7_S_BODY 1
165#define PKCS7_S_TAIL 2
166 int state; /* used during processing */
167
168 int detached;
169
170 ASN1_OBJECT *type;
171 /* content as defined by the type */
172 /* all encryption/message digests are applied to the 'contents',
173 * leaving out the 'type' field. */
174 union {
175 char *ptr;
176
177 /* NID_pkcs7_data */
178 ASN1_OCTET_STRING *data;
179
180 /* NID_pkcs7_signed */
181 PKCS7_SIGNED *sign;
182
183 /* NID_pkcs7_enveloped */
184 PKCS7_ENVELOPE *enveloped;
185
186 /* NID_pkcs7_signedAndEnveloped */
187 PKCS7_SIGN_ENVELOPE *signed_and_enveloped;
188
189 /* NID_pkcs7_digest */
190 PKCS7_DIGEST *digest;
191
192 /* NID_pkcs7_encrypted */
193 PKCS7_ENCRYPT *encrypted;
194
195 /* Anything else */
196 ASN1_TYPE *other;
197 } d;
198} PKCS7;
199
200DECLARE_STACK_OF(PKCS7)
201DECLARE_PKCS12_STACK_OF(PKCS7)
202
203#define PKCS7_OP_SET_DETACHED_SIGNATURE 1
204#define PKCS7_OP_GET_DETACHED_SIGNATURE 2
205
206#define PKCS7_get_signed_attributes(si) ((si)->auth_attr)
207#define PKCS7_get_attributes(si) ((si)->unauth_attr)
208
209#define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed)
210#define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
211#define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped)
212#define PKCS7_type_is_signedAndEnveloped(a) \
213 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
214#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
215#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
216#define PKCS7_type_is_encrypted(a) \
217 (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
218
219#define PKCS7_set_detached(p,v) \
220 PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL)
221#define PKCS7_get_detached(p) \
222 PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL)
223
224#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
225
226/* S/MIME related flags */
227
228#define PKCS7_TEXT 0x1
229#define PKCS7_NOCERTS 0x2
230#define PKCS7_NOSIGS 0x4
231#define PKCS7_NOCHAIN 0x8
232#define PKCS7_NOINTERN 0x10
233#define PKCS7_NOVERIFY 0x20
234#define PKCS7_DETACHED 0x40
235#define PKCS7_BINARY 0x80
236#define PKCS7_NOATTR 0x100
237#define PKCS7_NOSMIMECAP 0x200
238#define PKCS7_NOOLDMIMETYPE 0x400
239#define PKCS7_CRLFEOL 0x800
240#define PKCS7_STREAM 0x1000
241#define PKCS7_NOCRL 0x2000
242#define PKCS7_PARTIAL 0x4000
243#define PKCS7_REUSE_DIGEST 0x8000
244
245/* Flags: for compatibility with older code */
246
247#define SMIME_TEXT PKCS7_TEXT
248#define SMIME_NOCERTS PKCS7_NOCERTS
249#define SMIME_NOSIGS PKCS7_NOSIGS
250#define SMIME_NOCHAIN PKCS7_NOCHAIN
251#define SMIME_NOINTERN PKCS7_NOINTERN
252#define SMIME_NOVERIFY PKCS7_NOVERIFY
253#define SMIME_DETACHED PKCS7_DETACHED
254#define SMIME_BINARY PKCS7_BINARY
255#define SMIME_NOATTR PKCS7_NOATTR
256
257PKCS7_ISSUER_AND_SERIAL *PKCS7_ISSUER_AND_SERIAL_new(void);
258void PKCS7_ISSUER_AND_SERIAL_free(PKCS7_ISSUER_AND_SERIAL *a);
259PKCS7_ISSUER_AND_SERIAL *d2i_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL **a, const unsigned char **in, long len);
260int i2d_PKCS7_ISSUER_AND_SERIAL(PKCS7_ISSUER_AND_SERIAL *a, unsigned char **out);
261extern const ASN1_ITEM PKCS7_ISSUER_AND_SERIAL_it;
262
263int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,
264 const EVP_MD *type, unsigned char *md, unsigned int *len);
265PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7);
266int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7);
267PKCS7 *PKCS7_dup(PKCS7 *p7);
268PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7);
269int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7);
270int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
271int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
272
273PKCS7_SIGNER_INFO *PKCS7_SIGNER_INFO_new(void);
274void PKCS7_SIGNER_INFO_free(PKCS7_SIGNER_INFO *a);
275PKCS7_SIGNER_INFO *d2i_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO **a, const unsigned char **in, long len);
276int i2d_PKCS7_SIGNER_INFO(PKCS7_SIGNER_INFO *a, unsigned char **out);
277extern const ASN1_ITEM PKCS7_SIGNER_INFO_it;
278PKCS7_RECIP_INFO *PKCS7_RECIP_INFO_new(void);
279void PKCS7_RECIP_INFO_free(PKCS7_RECIP_INFO *a);
280PKCS7_RECIP_INFO *d2i_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO **a, const unsigned char **in, long len);
281int i2d_PKCS7_RECIP_INFO(PKCS7_RECIP_INFO *a, unsigned char **out);
282extern const ASN1_ITEM PKCS7_RECIP_INFO_it;
283PKCS7_SIGNED *PKCS7_SIGNED_new(void);
284void PKCS7_SIGNED_free(PKCS7_SIGNED *a);
285PKCS7_SIGNED *d2i_PKCS7_SIGNED(PKCS7_SIGNED **a, const unsigned char **in, long len);
286int i2d_PKCS7_SIGNED(PKCS7_SIGNED *a, unsigned char **out);
287extern const ASN1_ITEM PKCS7_SIGNED_it;
288PKCS7_ENC_CONTENT *PKCS7_ENC_CONTENT_new(void);
289void PKCS7_ENC_CONTENT_free(PKCS7_ENC_CONTENT *a);
290PKCS7_ENC_CONTENT *d2i_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT **a, const unsigned char **in, long len);
291int i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **out);
292extern const ASN1_ITEM PKCS7_ENC_CONTENT_it;
293PKCS7_ENVELOPE *PKCS7_ENVELOPE_new(void);
294void PKCS7_ENVELOPE_free(PKCS7_ENVELOPE *a);
295PKCS7_ENVELOPE *d2i_PKCS7_ENVELOPE(PKCS7_ENVELOPE **a, const unsigned char **in, long len);
296int i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **out);
297extern const ASN1_ITEM PKCS7_ENVELOPE_it;
298PKCS7_SIGN_ENVELOPE *PKCS7_SIGN_ENVELOPE_new(void);
299void PKCS7_SIGN_ENVELOPE_free(PKCS7_SIGN_ENVELOPE *a);
300PKCS7_SIGN_ENVELOPE *d2i_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE **a, const unsigned char **in, long len);
301int i2d_PKCS7_SIGN_ENVELOPE(PKCS7_SIGN_ENVELOPE *a, unsigned char **out);
302extern const ASN1_ITEM PKCS7_SIGN_ENVELOPE_it;
303PKCS7_DIGEST *PKCS7_DIGEST_new(void);
304void PKCS7_DIGEST_free(PKCS7_DIGEST *a);
305PKCS7_DIGEST *d2i_PKCS7_DIGEST(PKCS7_DIGEST **a, const unsigned char **in, long len);
306int i2d_PKCS7_DIGEST(PKCS7_DIGEST *a, unsigned char **out);
307extern const ASN1_ITEM PKCS7_DIGEST_it;
308PKCS7_ENCRYPT *PKCS7_ENCRYPT_new(void);
309void PKCS7_ENCRYPT_free(PKCS7_ENCRYPT *a);
310PKCS7_ENCRYPT *d2i_PKCS7_ENCRYPT(PKCS7_ENCRYPT **a, const unsigned char **in, long len);
311int i2d_PKCS7_ENCRYPT(PKCS7_ENCRYPT *a, unsigned char **out);
312extern const ASN1_ITEM PKCS7_ENCRYPT_it;
313PKCS7 *PKCS7_new(void);
314void PKCS7_free(PKCS7 *a);
315PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len);
316int i2d_PKCS7(PKCS7 *a, unsigned char **out);
317extern const ASN1_ITEM PKCS7_it;
318
319extern const ASN1_ITEM PKCS7_ATTR_SIGN_it;
320extern const ASN1_ITEM PKCS7_ATTR_VERIFY_it;
321
322int PKCS7_print_ctx(BIO *out, PKCS7 *x, int indent, const ASN1_PCTX *pctx);
323
324long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
325
326int PKCS7_set_type(PKCS7 *p7, int type);
327int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
328int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
329int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
330 const EVP_MD *dgst);
331int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
332int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
333int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
334int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
335int PKCS7_content_new(PKCS7 *p7, int nid);
336int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
337 BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
338int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
339 X509 *x509);
340
341BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
342int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
343BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
344
345
346PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
347 EVP_PKEY *pkey, const EVP_MD *dgst);
348X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
349int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
350STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
351
352PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
353void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
354 X509_ALGOR **pdig, X509_ALGOR **psig);
355void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
356int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
357int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
358int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
359int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
360
361PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
362ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
363int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type,
364 void *data);
365int PKCS7_add_attribute (PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
366 void *value);
367ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid);
368ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid);
369int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
370 STACK_OF(X509_ATTRIBUTE) *sk);
371int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, STACK_OF(X509_ATTRIBUTE) *sk);
372
373
374PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
375 BIO *data, int flags);
376
377PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
378 X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
379 int flags);
380
381int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
382int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
383 BIO *indata, BIO *out, int flags);
384STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
385PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
386 int flags);
387int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags);
388
389int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
390 STACK_OF(X509_ALGOR) *cap);
391STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
392int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
393
394int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
395int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
396int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
397 const unsigned char *md, int mdlen);
398
399int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
400PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
401
402BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
403
404
405void ERR_load_PKCS7_strings(void);
406
407/* Error codes for the PKCS7 functions. */
408
409/* Function codes. */
410#define PKCS7_F_B64_READ_PKCS7 120
411#define PKCS7_F_B64_WRITE_PKCS7 121
412#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136
413#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140
414#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135
415#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
416#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
417#define PKCS7_F_PKCS7_ADD_CRL 101
418#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
419#define PKCS7_F_PKCS7_ADD_SIGNATURE 131
420#define PKCS7_F_PKCS7_ADD_SIGNER 103
421#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125
422#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138
423#define PKCS7_F_PKCS7_CTRL 104
424#define PKCS7_F_PKCS7_DATADECODE 112
425#define PKCS7_F_PKCS7_DATAFINAL 128
426#define PKCS7_F_PKCS7_DATAINIT 105
427#define PKCS7_F_PKCS7_DATASIGN 106
428#define PKCS7_F_PKCS7_DATAVERIFY 107
429#define PKCS7_F_PKCS7_DECRYPT 114
430#define PKCS7_F_PKCS7_DECRYPT_RINFO 133
431#define PKCS7_F_PKCS7_ENCODE_RINFO 132
432#define PKCS7_F_PKCS7_ENCRYPT 115
433#define PKCS7_F_PKCS7_FINAL 134
434#define PKCS7_F_PKCS7_FIND_DIGEST 127
435#define PKCS7_F_PKCS7_GET0_SIGNERS 124
436#define PKCS7_F_PKCS7_RECIP_INFO_SET 130
437#define PKCS7_F_PKCS7_SET_CIPHER 108
438#define PKCS7_F_PKCS7_SET_CONTENT 109
439#define PKCS7_F_PKCS7_SET_DIGEST 126
440#define PKCS7_F_PKCS7_SET_TYPE 110
441#define PKCS7_F_PKCS7_SIGN 116
442#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
443#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
444#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139
445#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137
446#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
447#define PKCS7_F_PKCS7_VERIFY 117
448#define PKCS7_F_SMIME_READ_PKCS7 122
449#define PKCS7_F_SMIME_TEXT 123
450
451/* Reason codes. */
452#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117
453#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
454#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
455#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
456#define PKCS7_R_CTRL_ERROR 152
457#define PKCS7_R_DECODE_ERROR 130
458#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
459#define PKCS7_R_DECRYPT_ERROR 119
460#define PKCS7_R_DIGEST_FAILURE 101
461#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149
462#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
463#define PKCS7_R_ERROR_ADDING_RECIPIENT 120
464#define PKCS7_R_ERROR_SETTING_CIPHER 121
465#define PKCS7_R_INVALID_MIME_TYPE 131
466#define PKCS7_R_INVALID_NULL_POINTER 143
467#define PKCS7_R_MIME_NO_CONTENT_TYPE 132
468#define PKCS7_R_MIME_PARSE_ERROR 133
469#define PKCS7_R_MIME_SIG_PARSE_ERROR 134
470#define PKCS7_R_MISSING_CERIPEND_INFO 103
471#define PKCS7_R_NO_CONTENT 122
472#define PKCS7_R_NO_CONTENT_TYPE 135
473#define PKCS7_R_NO_DEFAULT_DIGEST 151
474#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154
475#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
476#define PKCS7_R_NO_MULTIPART_BOUNDARY 137
477#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
478#define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146
479#define PKCS7_R_NO_SIGNATURES_ON_DATA 123
480#define PKCS7_R_NO_SIGNERS 142
481#define PKCS7_R_NO_SIG_CONTENT_TYPE 138
482#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
483#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
484#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153
485#define PKCS7_R_PKCS7_DATAFINAL 126
486#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
487#define PKCS7_R_PKCS7_DATASIGN 145
488#define PKCS7_R_PKCS7_PARSE_ERROR 139
489#define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140
490#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
491#define PKCS7_R_SIGNATURE_FAILURE 105
492#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
493#define PKCS7_R_SIGNING_CTRL_FAILURE 147
494#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148
495#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
496#define PKCS7_R_SMIME_TEXT_ERROR 129
497#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
498#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107
499#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108
500#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109
501#define PKCS7_R_UNKNOWN_OPERATION 110
502#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111
503#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112
504#define PKCS7_R_WRONG_CONTENT_TYPE 113
505#define PKCS7_R_WRONG_PKCS7_TYPE 114
506
507#ifdef __cplusplus
508}
509#endif
510#endif
diff --git a/src/lib/libcrypto/pkcs7/pkcs7err.c b/src/lib/libcrypto/pkcs7/pkcs7err.c
deleted file mode 100644
index d4e6d7cf77..0000000000
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ /dev/null
@@ -1,145 +0,0 @@
1/* $OpenBSD: pkcs7err.c,v 1.16 2024/06/24 06:43:22 tb Exp $ */
2/* ====================================================================
3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@OpenSSL.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include <stdio.h>
57
58#include <openssl/opensslconf.h>
59
60#include <openssl/err.h>
61#include <openssl/pkcs7.h>
62
63#include "err_local.h"
64
65#ifndef OPENSSL_NO_ERR
66
67#define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0)
68#define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason)
69
70static const ERR_STRING_DATA PKCS7_str_functs[] = {
71 {ERR_FUNC(0xfff), "CRYPTO_internal"},
72 {0, NULL}
73};
74
75static const ERR_STRING_DATA PKCS7_str_reasons[] = {
76 {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
77 {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "cipher has no object identifier"},
78 {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"},
79 {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), "content and data present"},
80 {ERR_REASON(PKCS7_R_CTRL_ERROR) , "ctrl error"},
81 {ERR_REASON(PKCS7_R_DECODE_ERROR) , "decode error"},
82 {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), "decrypted key is wrong length"},
83 {ERR_REASON(PKCS7_R_DECRYPT_ERROR) , "decrypt error"},
84 {ERR_REASON(PKCS7_R_DIGEST_FAILURE) , "digest failure"},
85 {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"},
86 {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "encryption not supported for this key type"},
87 {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"},
88 {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"},
89 {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) , "invalid mime type"},
90 {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"},
91 {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
92 {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR) , "mime parse error"},
93 {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
94 {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"},
95 {ERR_REASON(PKCS7_R_NO_CONTENT) , "no content"},
96 {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) , "no content type"},
97 {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) , "no default digest"},
98 {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), "no matching digest type found"},
99 {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), "no multipart body failure"},
100 {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
101 {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), "no recipient matches certificate"},
102 {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), "no recipient matches key"},
103 {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"},
104 {ERR_REASON(PKCS7_R_NO_SIGNERS) , "no signers"},
105 {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) , "no sig content type"},
106 {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), "operation not supported on this type"},
107 {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"},
108 {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"},
109 {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) , "pkcs7 datafinal"},
110 {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"},
111 {ERR_REASON(PKCS7_R_PKCS7_DATASIGN) , "pkcs7 datasign"},
112 {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR) , "pkcs7 parse error"},
113 {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"},
114 {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), "private key does not match certificate"},
115 {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) , "signature failure"},
116 {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), "signer certificate not found"},
117 {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"},
118 {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), "signing not supported for this key type"},
119 {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
120 {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) , "smime text error"},
121 {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), "unable to find certificate"},
122 {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"},
123 {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), "unable to find message digest"},
124 {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE) , "unknown digest type"},
125 {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION) , "unknown operation"},
126 {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"},
127 {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"},
128 {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE) , "wrong content type"},
129 {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE) , "wrong pkcs7 type"},
130 {0, NULL}
131};
132
133#endif
134
135void
136ERR_load_PKCS7_strings(void)
137{
138#ifndef OPENSSL_NO_ERR
139 if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) {
140 ERR_load_const_strings(PKCS7_str_functs);
141 ERR_load_const_strings(PKCS7_str_reasons);
142 }
143#endif
144}
145LCRYPTO_ALIAS(ERR_load_PKCS7_strings);