1 /* $OpenBSD: cms.c,v 1.30 2022/03/23 15:16:59 tb Exp $ */
2 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5 /* ====================================================================
6 * Copyright (c) 2008 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 /* CMS utility function */
55
56 #include <stdio.h>
57 #include <string.h>
58
59 #include "apps.h"
60
61 #ifndef OPENSSL_NO_CMS
62
63 #include <openssl/crypto.h>
64 #include <openssl/err.h>
65 #include <openssl/pem.h>
66 #include <openssl/x509_vfy.h>
67 #include <openssl/x509v3.h>
68
69 #include <openssl/cms.h>
70
71 static int save_certs(char *signerfile, STACK_OF(X509) *signers);
72 static int cms_cb(int ok, X509_STORE_CTX *ctx);
73 static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
74 static CMS_ReceiptRequest *make_receipt_request(
75 STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
76 STACK_OF(OPENSSL_STRING) *rr_from);
77 static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
78 STACK_OF(OPENSSL_STRING) *param);
79
80 #define SMIME_OP 0x10
81 #define SMIME_IP 0x20
82 #define SMIME_SIGNERS 0x40
83 #define SMIME_ENCRYPT (1 | SMIME_OP)
84 #define SMIME_DECRYPT (2 | SMIME_IP)
85 #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
86 #define SMIME_VERIFY (4 | SMIME_IP)
87 #define SMIME_CMSOUT (5 | SMIME_IP | SMIME_OP)
88 #define SMIME_RESIGN (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
89 #define SMIME_DATAOUT (7 | SMIME_IP)
90 #define SMIME_DATA_CREATE (8 | SMIME_OP)
91 #define SMIME_DIGEST_VERIFY (9 | SMIME_IP)
92 #define SMIME_DIGEST_CREATE (10 | SMIME_OP)
93 #define SMIME_UNCOMPRESS (11 | SMIME_IP)
94 #define SMIME_COMPRESS (12 | SMIME_OP)
95 #define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
96 #define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
97 #define SMIME_SIGN_RECEIPT (15 | SMIME_IP | SMIME_OP)
98 #define SMIME_VERIFY_RECEIPT (16 | SMIME_IP)
99
100 int verify_err = 0;
101
102 struct cms_key_param {
103 int idx;
104 STACK_OF(OPENSSL_STRING) *param;
105 struct cms_key_param *next;
106 };
107
108 static struct {
109 char *CAfile;
110 char *CApath;
111 X509 *cert;
112 char *certfile;
113 char *certsoutfile;
114 const EVP_CIPHER *cipher;
115 char *contfile;
116 ASN1_OBJECT *econtent_type;
117 STACK_OF(X509) *encerts;
118 int flags;
119 char *from;
120 char *infile;
121 int informat;
122 struct cms_key_param *key_first;
123 struct cms_key_param *key_param;
124 char *keyfile;
125 int keyform;
126 int noout;
127 int operation;
128 char *outfile;
129 int outformat;
130 char *passargin;
131 int print;
132 unsigned char *pwri_pass;
133 int rr_allorfirst;
134 STACK_OF(OPENSSL_STRING) *rr_from;
135 int rr_print;
136 STACK_OF(OPENSSL_STRING) *rr_to;
137 char *rctfile;
138 int rctformat;
139 char *recipfile;
140 unsigned char *secret_key;
141 unsigned char *secret_keyid;
142 size_t secret_keyidlen;
143 size_t secret_keylen;
144 const EVP_MD *sign_md;
145 char *signerfile;
146 STACK_OF(OPENSSL_STRING) *skkeys;
147 STACK_OF(OPENSSL_STRING) *sksigners;
148 char *subject;
149 char *to;
150 int verify_retcode;
151 X509_VERIFY_PARAM *vpm;
152 } cms_config;
153
154 static const EVP_CIPHER *
get_cipher_by_name(char * name)155 get_cipher_by_name(char *name)
156 {
157 if (name == NULL || strcmp(name, "") == 0)
158 return (NULL);
159 #ifndef OPENSSL_NO_AES
160 else if (strcmp(name, "aes128") == 0)
161 return EVP_aes_128_cbc();
162 else if (strcmp(name, "aes192") == 0)
163 return EVP_aes_192_cbc();
164 else if (strcmp(name, "aes256") == 0)
165 return EVP_aes_256_cbc();
166 #endif
167 #ifndef OPENSSL_NO_CAMELLIA
168 else if (strcmp(name, "camellia128") == 0)
169 return EVP_camellia_128_cbc();
170 else if (strcmp(name, "camellia192") == 0)
171 return EVP_camellia_192_cbc();
172 else if (strcmp(name, "camellia256") == 0)
173 return EVP_camellia_256_cbc();
174 #endif
175 #ifndef OPENSSL_NO_DES
176 else if (strcmp(name, "des") == 0)
177 return EVP_des_cbc();
178 else if (strcmp(name, "des3") == 0)
179 return EVP_des_ede3_cbc();
180 #endif
181 #ifndef OPENSSL_NO_RC2
182 else if (!strcmp(name, "rc2-40"))
183 return EVP_rc2_40_cbc();
184 else if (!strcmp(name, "rc2-64"))
185 return EVP_rc2_64_cbc();
186 else if (!strcmp(name, "rc2-128"))
187 return EVP_rc2_cbc();
188 #endif
189 else
190 return (NULL);
191 }
192
193 static int
cms_opt_cipher(int argc,char ** argv,int * argsused)194 cms_opt_cipher(int argc, char **argv, int *argsused)
195 {
196 char *name = argv[0];
197
198 if (*name++ != '-')
199 return (1);
200
201 if ((cms_config.cipher = get_cipher_by_name(name)) == NULL)
202 if ((cms_config.cipher = EVP_get_cipherbyname(name)) == NULL)
203 return (1);
204
205 *argsused = 1;
206 return (0);
207 }
208
209 static int
cms_opt_econtent_type(char * arg)210 cms_opt_econtent_type(char *arg)
211 {
212 ASN1_OBJECT_free(cms_config.econtent_type);
213
214 if ((cms_config.econtent_type = OBJ_txt2obj(arg, 0)) == NULL) {
215 BIO_printf(bio_err, "Invalid OID %s\n", arg);
216 return (1);
217 }
218 return (0);
219 }
220
221 static int
cms_opt_inkey(char * arg)222 cms_opt_inkey(char *arg)
223 {
224 if (cms_config.keyfile == NULL) {
225 cms_config.keyfile = arg;
226 return (0);
227 }
228
229 if (cms_config.signerfile == NULL) {
230 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
231 return (1);
232 }
233
234 if (cms_config.sksigners == NULL)
235 cms_config.sksigners = sk_OPENSSL_STRING_new_null();
236 if (cms_config.sksigners == NULL)
237 return (1);
238 if (!sk_OPENSSL_STRING_push(cms_config.sksigners, cms_config.signerfile))
239 return (1);
240
241 cms_config.signerfile = NULL;
242
243 if (cms_config.skkeys == NULL)
244 cms_config.skkeys = sk_OPENSSL_STRING_new_null();
245 if (cms_config.skkeys == NULL)
246 return (1);
247 if (!sk_OPENSSL_STRING_push(cms_config.skkeys, cms_config.keyfile))
248 return (1);
249
250 cms_config.keyfile = arg;
251 return (0);
252 }
253
254 static int
cms_opt_keyopt(char * arg)255 cms_opt_keyopt(char *arg)
256 {
257 int keyidx = -1;
258
259 if (cms_config.operation == SMIME_ENCRYPT) {
260 if (cms_config.encerts != NULL)
261 keyidx += sk_X509_num(cms_config.encerts);
262 } else {
263 if (cms_config.keyfile != NULL || cms_config.signerfile != NULL)
264 keyidx++;
265 if (cms_config.skkeys != NULL)
266 keyidx += sk_OPENSSL_STRING_num(cms_config.skkeys);
267 }
268
269 if (keyidx < 0) {
270 BIO_printf(bio_err, "No key specified\n");
271 return (1);
272 }
273
274 if (cms_config.key_param == NULL ||
275 cms_config.key_param->idx != keyidx) {
276 struct cms_key_param *nparam;
277
278 if ((nparam = calloc(1, sizeof(struct cms_key_param))) == NULL)
279 return (1);
280
281 nparam->idx = keyidx;
282 if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) {
283 free(nparam);
284 return (1);
285 }
286
287 nparam->next = NULL;
288 if (cms_config.key_first == NULL)
289 cms_config.key_first = nparam;
290 else
291 cms_config.key_param->next = nparam;
292
293 cms_config.key_param = nparam;
294 }
295
296 if (!sk_OPENSSL_STRING_push(cms_config.key_param->param, arg))
297 return (1);
298
299 return (0);
300 }
301
302 static int
cms_opt_md(char * arg)303 cms_opt_md(char *arg)
304 {
305 if ((cms_config.sign_md = EVP_get_digestbyname(arg)) == NULL) {
306 BIO_printf(bio_err, "Unknown digest %s\n", arg);
307 return (1);
308 }
309 return (0);
310 }
311
312 static int
cms_opt_print(void)313 cms_opt_print(void)
314 {
315 cms_config.noout = 1;
316 cms_config.print = 1;
317 return (0);
318 }
319
320 static int
cms_opt_pwri_pass(char * arg)321 cms_opt_pwri_pass(char *arg)
322 {
323 cms_config.pwri_pass = (unsigned char *)arg;
324 return (0);
325 }
326
327 static int
cms_opt_recip(char * arg)328 cms_opt_recip(char *arg)
329 {
330 if (cms_config.operation == SMIME_ENCRYPT) {
331 if (cms_config.encerts == NULL) {
332 if ((cms_config.encerts = sk_X509_new_null()) == NULL)
333 return (1);
334 }
335
336 cms_config.cert = load_cert(bio_err, arg, FORMAT_PEM,
337 NULL, "recipient certificate file");
338 if (cms_config.cert == NULL)
339 return (1);
340
341 if (!sk_X509_push(cms_config.encerts, cms_config.cert))
342 return (1);
343
344 cms_config.cert = NULL;
345 } else {
346 cms_config.recipfile = arg;
347 }
348 return (0);
349 }
350
351 static int
cms_opt_receipt_request_from(char * arg)352 cms_opt_receipt_request_from(char *arg)
353 {
354 if (cms_config.rr_from == NULL)
355 cms_config.rr_from = sk_OPENSSL_STRING_new_null();
356 if (cms_config.rr_from == NULL)
357 return (1);
358 if (!sk_OPENSSL_STRING_push(cms_config.rr_from, arg))
359 return (1);
360
361 return (0);
362 }
363
364 static int
cms_opt_receipt_request_to(char * arg)365 cms_opt_receipt_request_to(char *arg)
366 {
367 if (cms_config.rr_to == NULL)
368 cms_config.rr_to = sk_OPENSSL_STRING_new_null();
369 if (cms_config.rr_to == NULL)
370 return (1);
371 if (!sk_OPENSSL_STRING_push(cms_config.rr_to, arg))
372 return (1);
373
374 return (0);
375 }
376
377 static int
cms_opt_secretkey(char * arg)378 cms_opt_secretkey(char *arg)
379 {
380 long ltmp;
381
382 free(cms_config.secret_key);
383
384 if ((cms_config.secret_key = string_to_hex(arg, <mp)) == NULL) {
385 BIO_printf(bio_err, "Invalid key %s\n", arg);
386 return (1);
387 }
388 cms_config.secret_keylen = (size_t)ltmp;
389 return (0);
390 }
391
392 static int
cms_opt_secretkeyid(char * arg)393 cms_opt_secretkeyid(char *arg)
394 {
395 long ltmp;
396
397 free(cms_config.secret_keyid);
398
399 if ((cms_config.secret_keyid = string_to_hex(arg, <mp)) == NULL) {
400 BIO_printf(bio_err, "Invalid id %s\n", arg);
401 return (1);
402 }
403 cms_config.secret_keyidlen = (size_t)ltmp;
404 return (0);
405 }
406
407 static int
cms_opt_signer(char * arg)408 cms_opt_signer(char *arg)
409 {
410 if (cms_config.signerfile == NULL) {
411 cms_config.signerfile = arg;
412 return (0);
413 }
414
415 if (cms_config.sksigners == NULL)
416 cms_config.sksigners = sk_OPENSSL_STRING_new_null();
417 if (cms_config.sksigners == NULL)
418 return (1);
419 if (!sk_OPENSSL_STRING_push(cms_config.sksigners, cms_config.signerfile))
420 return (1);
421
422 if (cms_config.keyfile == NULL)
423 cms_config.keyfile = cms_config.signerfile;
424
425 if (cms_config.skkeys == NULL)
426 cms_config.skkeys = sk_OPENSSL_STRING_new_null();
427 if (cms_config.skkeys == NULL)
428 return (1);
429 if (!sk_OPENSSL_STRING_push(cms_config.skkeys, cms_config.keyfile))
430 return (1);
431
432 cms_config.keyfile = NULL;
433
434 cms_config.signerfile = arg;
435 return (0);
436 }
437
438 static int
cms_opt_verify_param(int argc,char ** argv,int * argsused)439 cms_opt_verify_param(int argc, char **argv, int *argsused)
440 {
441 int oargc = argc;
442 int badarg = 0;
443
444 if (!args_verify(&argv, &argc, &badarg, bio_err, &cms_config.vpm))
445 return (1);
446 if (badarg)
447 return (1);
448
449 *argsused = oargc - argc;
450
451 return (0);
452 }
453
454 static int
cms_opt_verify_receipt(char * arg)455 cms_opt_verify_receipt(char *arg)
456 {
457 cms_config.operation = SMIME_VERIFY_RECEIPT;
458 cms_config.rctfile = arg;
459 return (0);
460 }
461
462 static const struct option cms_options[] = {
463 #ifndef OPENSSL_NO_AES
464 {
465 .name = "aes128",
466 .desc = "Encrypt PEM output with CBC AES",
467 .type = OPTION_ARGV_FUNC,
468 .opt.argvfunc = cms_opt_cipher,
469 },
470 {
471 .name = "aes192",
472 .desc = "Encrypt PEM output with CBC AES",
473 .type = OPTION_ARGV_FUNC,
474 .opt.argvfunc = cms_opt_cipher,
475 },
476 {
477 .name = "aes256",
478 .desc = "Encrypt PEM output with CBC AES",
479 .type = OPTION_ARGV_FUNC,
480 .opt.argvfunc = cms_opt_cipher,
481 },
482 #endif
483 #ifndef OPENSSL_NO_CAMELLIA
484 {
485 .name = "camellia128",
486 .desc = "Encrypt PEM output with CBC Camellia",
487 .type = OPTION_ARGV_FUNC,
488 .opt.argvfunc = cms_opt_cipher,
489 },
490 {
491 .name = "camellia192",
492 .desc = "Encrypt PEM output with CBC Camellia",
493 .type = OPTION_ARGV_FUNC,
494 .opt.argvfunc = cms_opt_cipher,
495 },
496 {
497 .name = "camellia256",
498 .desc = "Encrypt PEM output with CBC Camellia",
499 .type = OPTION_ARGV_FUNC,
500 .opt.argvfunc = cms_opt_cipher,
501 },
502 #endif
503 #ifndef OPENSSL_NO_DES
504 {
505 .name = "des",
506 .desc = "Encrypt with DES",
507 .type = OPTION_ARGV_FUNC,
508 .opt.argvfunc = cms_opt_cipher,
509 },
510 {
511 .name = "des3",
512 .desc = "Encrypt with triple DES (default)",
513 .type = OPTION_ARGV_FUNC,
514 .opt.argvfunc = cms_opt_cipher,
515 },
516 #endif
517 #ifndef OPENSSL_NO_RC2
518 {
519 .name = "rc2-40",
520 .desc = "Encrypt with RC2-40",
521 .type = OPTION_ARGV_FUNC,
522 .opt.argvfunc = cms_opt_cipher,
523 },
524 {
525 .name = "rc2-64",
526 .desc = "Encrypt with RC2-64",
527 .type = OPTION_ARGV_FUNC,
528 .opt.argvfunc = cms_opt_cipher,
529 },
530 {
531 .name = "rc2-128",
532 .desc = "Encrypt with RC2-128",
533 .type = OPTION_ARGV_FUNC,
534 .opt.argvfunc = cms_opt_cipher,
535 },
536 #endif
537 {
538 .name = "CAfile",
539 .argname = "file",
540 .desc = "Certificate Authority file",
541 .type = OPTION_ARG,
542 .opt.arg = &cms_config.CAfile,
543 },
544 {
545 .name = "CApath",
546 .argname = "path",
547 .desc = "Certificate Authority path",
548 .type = OPTION_ARG,
549 .opt.arg = &cms_config.CApath,
550 },
551 {
552 .name = "binary",
553 .desc = "Do not translate message to text",
554 .type = OPTION_VALUE_OR,
555 .opt.value = &cms_config.flags,
556 .value = CMS_BINARY,
557 },
558 {
559 .name = "certfile",
560 .argname = "file",
561 .desc = "Other certificates file",
562 .type = OPTION_ARG,
563 .opt.arg = &cms_config.certfile,
564 },
565 {
566 .name = "certsout",
567 .argname = "file",
568 .desc = "Certificate output file",
569 .type = OPTION_ARG,
570 .opt.arg = &cms_config.certsoutfile,
571 },
572 {
573 .name = "cmsout",
574 .desc = "Output CMS structure",
575 .type = OPTION_VALUE,
576 .opt.value = &cms_config.operation,
577 .value = SMIME_CMSOUT,
578 },
579 {
580 .name = "compress",
581 .desc = "Create CMS CompressedData type",
582 .type = OPTION_VALUE,
583 .opt.value = &cms_config.operation,
584 .value = SMIME_COMPRESS,
585 },
586 {
587 .name = "content",
588 .argname = "file",
589 .desc = "Supply or override content for detached signature",
590 .type = OPTION_ARG,
591 .opt.arg = &cms_config.contfile,
592 },
593 {
594 .name = "crlfeol",
595 .desc = "Use CRLF as EOL termination instead of CR only",
596 .type = OPTION_VALUE_OR,
597 .opt.value = &cms_config.flags,
598 .value = CMS_CRLFEOL,
599 },
600 {
601 .name = "data_create",
602 .desc = "Create CMS Data type",
603 .type = OPTION_VALUE,
604 .opt.value = &cms_config.operation,
605 .value = SMIME_DATA_CREATE,
606 },
607 {
608 .name = "data_out",
609 .desc = "Output content from the input CMS Data type",
610 .type = OPTION_VALUE,
611 .opt.value = &cms_config.operation,
612 .value = SMIME_DATAOUT,
613 },
614 {
615 .name = "debug_decrypt",
616 .desc = "Set the CMS_DEBUG_DECRYPT flag when decrypting",
617 .type = OPTION_VALUE_OR,
618 .opt.value = &cms_config.flags,
619 .value = CMS_DEBUG_DECRYPT,
620 },
621 {
622 .name = "decrypt",
623 .desc = "Decrypt encrypted message",
624 .type = OPTION_VALUE,
625 .opt.value = &cms_config.operation,
626 .value = SMIME_DECRYPT,
627 },
628 {
629 .name = "digest_create",
630 .desc = "Create CMS DigestedData type",
631 .type = OPTION_VALUE,
632 .opt.value = &cms_config.operation,
633 .value = SMIME_DIGEST_CREATE,
634 },
635 {
636 .name = "digest_verify",
637 .desc = "Verify CMS DigestedData type and output the content",
638 .type = OPTION_VALUE,
639 .opt.value = &cms_config.operation,
640 .value = SMIME_DIGEST_VERIFY,
641 },
642 {
643 .name = "econtent_type",
644 .argname = "type",
645 .desc = "Set the encapsulated content type",
646 .type = OPTION_ARG_FUNC,
647 .opt.argfunc = cms_opt_econtent_type,
648 },
649 {
650 .name = "encrypt",
651 .desc = "Encrypt message",
652 .type = OPTION_VALUE,
653 .opt.value = &cms_config.operation,
654 .value = SMIME_ENCRYPT,
655 },
656 {
657 .name = "EncryptedData_decrypt",
658 .desc = "Decrypt CMS EncryptedData",
659 .type = OPTION_VALUE,
660 .opt.value = &cms_config.operation,
661 .value = SMIME_ENCRYPTED_DECRYPT,
662 },
663 {
664 .name = "EncryptedData_encrypt",
665 .desc = "Encrypt content using supplied symmetric key and algorithm",
666 .type = OPTION_VALUE,
667 .opt.value = &cms_config.operation,
668 .value = SMIME_ENCRYPTED_ENCRYPT,
669 },
670 {
671 .name = "from",
672 .argname = "addr",
673 .desc = "From address",
674 .type = OPTION_ARG,
675 .opt.arg = &cms_config.from,
676 },
677 {
678 .name = "in",
679 .argname = "file",
680 .desc = "Input file",
681 .type = OPTION_ARG,
682 .opt.arg = &cms_config.infile,
683 },
684 {
685 .name = "indef",
686 .desc = "Same as -stream",
687 .type = OPTION_VALUE_OR,
688 .opt.value = &cms_config.flags,
689 .value = CMS_STREAM,
690 },
691 {
692 .name = "inform",
693 .argname = "fmt",
694 .desc = "Input format (DER, PEM or SMIME (default))",
695 .type = OPTION_ARG_FORMAT,
696 .opt.value = &cms_config.informat,
697 },
698 {
699 .name = "inkey",
700 .argname = "file",
701 .desc = "Input key file",
702 .type = OPTION_ARG_FUNC,
703 .opt.argfunc = cms_opt_inkey,
704 },
705 {
706 .name = "keyform",
707 .argname = "fmt",
708 .desc = "Input key format (DER or PEM (default))",
709 .type = OPTION_ARG_FORMAT,
710 .opt.value = &cms_config.keyform,
711 },
712 {
713 .name = "keyid",
714 .desc = "Use subject key identifier",
715 .type = OPTION_VALUE_OR,
716 .opt.value = &cms_config.flags,
717 .value = CMS_USE_KEYID,
718 },
719 {
720 .name = "keyopt",
721 .argname = "nm:v",
722 .desc = "Set public key parameters",
723 .type = OPTION_ARG_FUNC,
724 .opt.argfunc = cms_opt_keyopt,
725 },
726 {
727 .name = "md",
728 .argname = "digest",
729 .desc = "Digest to use when signing or resigning",
730 .type = OPTION_ARG_FUNC,
731 .opt.argfunc = cms_opt_md,
732 },
733 {
734 .name = "no_attr_verify",
735 .desc = "Do not verify the signer's attribute of a signature",
736 .type = OPTION_VALUE_OR,
737 .opt.value = &cms_config.flags,
738 .value = CMS_NO_ATTR_VERIFY,
739 },
740 {
741 .name = "no_content_verify",
742 .desc = "Do not verify the content of a signed message",
743 .type = OPTION_VALUE_OR,
744 .opt.value = &cms_config.flags,
745 .value = CMS_NO_CONTENT_VERIFY,
746 },
747 {
748 .name = "no_signer_cert_verify",
749 .desc = "Do not verify the signer's certificate",
750 .type = OPTION_VALUE_OR,
751 .opt.value = &cms_config.flags,
752 .value = CMS_NO_SIGNER_CERT_VERIFY,
753 },
754 {
755 .name = "noattr",
756 .desc = "Do not include any signed attributes",
757 .type = OPTION_VALUE_OR,
758 .opt.value = &cms_config.flags,
759 .value = CMS_NOATTR,
760 },
761 {
762 .name = "nocerts",
763 .desc = "Do not include signer's certificate when signing",
764 .type = OPTION_VALUE_OR,
765 .opt.value = &cms_config.flags,
766 .value = CMS_NOCERTS,
767 },
768 {
769 .name = "nodetach",
770 .desc = "Use opaque signing",
771 .type = OPTION_VALUE_AND,
772 .opt.value = &cms_config.flags,
773 .value = ~CMS_DETACHED,
774 },
775 {
776 .name = "noindef",
777 .desc = "Disable CMS streaming",
778 .type = OPTION_VALUE_AND,
779 .opt.value = &cms_config.flags,
780 .value = ~CMS_STREAM,
781 },
782 {
783 .name = "nointern",
784 .desc = "Do not search certificates in message for signer",
785 .type = OPTION_VALUE_OR,
786 .opt.value = &cms_config.flags,
787 .value = CMS_NOINTERN,
788 },
789 {
790 .name = "nooldmime",
791 .desc = "Output old S/MIME content type",
792 .type = OPTION_VALUE_OR,
793 .opt.value = &cms_config.flags,
794 .value = CMS_NOOLDMIMETYPE,
795 },
796 {
797 .name = "noout",
798 .desc = "Do not output the parsed CMS structure",
799 .type = OPTION_FLAG,
800 .opt.flag = &cms_config.noout,
801 },
802 {
803 .name = "nosigs",
804 .desc = "Do not verify message signature",
805 .type = OPTION_VALUE_OR,
806 .opt.value = &cms_config.flags,
807 .value = CMS_NOSIGS,
808 },
809 {
810 .name = "nosmimecap",
811 .desc = "Omit the SMIMECapabilities attribute",
812 .type = OPTION_VALUE_OR,
813 .opt.value = &cms_config.flags,
814 .value = CMS_NOSMIMECAP,
815 },
816 {
817 .name = "noverify",
818 .desc = "Do not verify signer's certificate",
819 .type = OPTION_VALUE_OR,
820 .opt.value = &cms_config.flags,
821 .value = CMS_NO_SIGNER_CERT_VERIFY,
822 },
823 {
824 .name = "out",
825 .argname = "file",
826 .desc = "Output file",
827 .type = OPTION_ARG,
828 .opt.arg = &cms_config.outfile,
829 },
830 {
831 .name = "outform",
832 .argname = "fmt",
833 .desc = "Output format (DER, PEM or SMIME (default))",
834 .type = OPTION_ARG_FORMAT,
835 .opt.value = &cms_config.outformat,
836 },
837 {
838 .name = "passin",
839 .argname = "src",
840 .desc = "Private key password source",
841 .type = OPTION_ARG,
842 .opt.arg = &cms_config.passargin,
843 },
844 {
845 .name = "print",
846 .desc = "Print out all fields of the CMS structure for the -cmsout",
847 .type = OPTION_FUNC,
848 .opt.func = cms_opt_print,
849 },
850 {
851 .name = "pwri_password",
852 .argname = "arg",
853 .desc = "Specify PasswordRecipientInfo (PWRI) password to use",
854 .type = OPTION_ARG_FUNC,
855 .opt.argfunc = cms_opt_pwri_pass,
856 },
857 {
858 .name = "rctform",
859 .argname = "fmt",
860 .desc = "Receipt file format (DER, PEM or SMIME (default))",
861 .type = OPTION_ARG_FORMAT,
862 .opt.value = &cms_config.rctformat,
863 },
864 {
865 .name = "receipt_request_all",
866 .desc = "Indicate requests should be provided by all recipients",
867 .type = OPTION_VALUE,
868 .opt.value = &cms_config.rr_allorfirst,
869 .value = 0,
870 },
871 {
872 .name = "receipt_request_first",
873 .desc = "Indicate requests should be provided by first tier recipient",
874 .type = OPTION_VALUE,
875 .opt.value = &cms_config.rr_allorfirst,
876 .value = 1,
877 },
878 {
879 .name = "receipt_request_from",
880 .argname = "addr",
881 .desc = "Add explicit email address where receipts should be supplied",
882 .type = OPTION_ARG_FUNC,
883 .opt.argfunc = cms_opt_receipt_request_from,
884 },
885 {
886 .name = "receipt_request_print",
887 .desc = "Print out the contents of any signed receipt requests",
888 .type = OPTION_FLAG,
889 .opt.flag = &cms_config.rr_print,
890 },
891 {
892 .name = "receipt_request_to",
893 .argname = "addr",
894 .desc = "Add explicit email address where receipts should be sent to",
895 .type = OPTION_ARG_FUNC,
896 .opt.argfunc = cms_opt_receipt_request_to,
897 },
898 {
899 .name = "recip",
900 .argname = "file",
901 .desc = "Recipient certificate file for decryption",
902 .type = OPTION_ARG_FUNC,
903 .opt.argfunc = cms_opt_recip,
904 },
905 {
906 .name = "resign",
907 .desc = "Resign a signed message",
908 .type = OPTION_VALUE,
909 .opt.value = &cms_config.operation,
910 .value = SMIME_RESIGN,
911 },
912 {
913 .name = "secretkey",
914 .argname = "key",
915 .desc = "Specify symmetric key to use",
916 .type = OPTION_ARG_FUNC,
917 .opt.argfunc = cms_opt_secretkey,
918 },
919 {
920 .name = "secretkeyid",
921 .argname = "id",
922 .desc = "The key identifier for the supplied symmetric key",
923 .type = OPTION_ARG_FUNC,
924 .opt.argfunc = cms_opt_secretkeyid,
925 },
926 {
927 .name = "sign",
928 .desc = "Sign message",
929 .type = OPTION_VALUE,
930 .opt.value = &cms_config.operation,
931 .value = SMIME_SIGN,
932 },
933 {
934 .name = "sign_receipt",
935 .desc = "Generate a signed receipt for the message",
936 .type = OPTION_VALUE,
937 .opt.value = &cms_config.operation,
938 .value = SMIME_SIGN_RECEIPT,
939 },
940 {
941 .name = "signer",
942 .argname = "file",
943 .desc = "Signer certificate file",
944 .type = OPTION_ARG_FUNC,
945 .opt.argfunc = cms_opt_signer,
946 },
947 {
948 .name = "stream",
949 .desc = "Enable CMS streaming",
950 .type = OPTION_VALUE_OR,
951 .opt.value = &cms_config.flags,
952 .value = CMS_STREAM,
953 },
954 {
955 .name = "subject",
956 .argname = "s",
957 .desc = "Subject",
958 .type = OPTION_ARG,
959 .opt.arg = &cms_config.subject,
960 },
961 {
962 .name = "text",
963 .desc = "Include or delete text MIME headers",
964 .type = OPTION_VALUE_OR,
965 .opt.value = &cms_config.flags,
966 .value = CMS_TEXT,
967 },
968 {
969 .name = "to",
970 .argname = "addr",
971 .desc = "To address",
972 .type = OPTION_ARG,
973 .opt.arg = &cms_config.to,
974 },
975 {
976 .name = "uncompress",
977 .desc = "Uncompress CMS CompressedData type",
978 .type = OPTION_VALUE,
979 .opt.value = &cms_config.operation,
980 .value = SMIME_UNCOMPRESS,
981 },
982 {
983 .name = "verify",
984 .desc = "Verify signed message",
985 .type = OPTION_VALUE,
986 .opt.value = &cms_config.operation,
987 .value = SMIME_VERIFY,
988 },
989 {
990 .name = "verify_receipt",
991 .argname = "file",
992 .desc = "Verify a signed receipt in file",
993 .type = OPTION_ARG_FUNC,
994 .opt.argfunc = cms_opt_verify_receipt,
995 },
996 {
997 .name = "verify_retcode",
998 .desc = "Set verification error code to exit code",
999 .type = OPTION_FLAG,
1000 .opt.flag = &cms_config.verify_retcode,
1001 },
1002 {
1003 .name = "check_ss_sig",
1004 .type = OPTION_ARGV_FUNC,
1005 .opt.argvfunc = cms_opt_verify_param,
1006 },
1007 {
1008 .name = "crl_check",
1009 .type = OPTION_ARGV_FUNC,
1010 .opt.argvfunc = cms_opt_verify_param,
1011 },
1012 {
1013 .name = "crl_check_all",
1014 .type = OPTION_ARGV_FUNC,
1015 .opt.argvfunc = cms_opt_verify_param,
1016 },
1017 {
1018 .name = "extended_crl",
1019 .type = OPTION_ARGV_FUNC,
1020 .opt.argvfunc = cms_opt_verify_param,
1021 },
1022 {
1023 .name = "ignore_critical",
1024 .type = OPTION_ARGV_FUNC,
1025 .opt.argvfunc = cms_opt_verify_param,
1026 },
1027 {
1028 .name = "issuer_checks",
1029 .type = OPTION_ARGV_FUNC,
1030 .opt.argvfunc = cms_opt_verify_param,
1031 },
1032 {
1033 .name = "policy",
1034 .type = OPTION_ARGV_FUNC,
1035 .opt.argvfunc = cms_opt_verify_param,
1036 },
1037 {
1038 .name = "policy_check",
1039 .type = OPTION_ARGV_FUNC,
1040 .opt.argvfunc = cms_opt_verify_param,
1041 },
1042 {
1043 .name = "purpose",
1044 .type = OPTION_ARGV_FUNC,
1045 .opt.argvfunc = cms_opt_verify_param,
1046 },
1047 {
1048 .name = "x509_strict",
1049 .type = OPTION_ARGV_FUNC,
1050 .opt.argvfunc = cms_opt_verify_param,
1051 },
1052 {
1053 .name = NULL,
1054 .type = OPTION_ARGV_FUNC,
1055 .opt.argvfunc = cms_opt_cipher,
1056 },
1057 { NULL },
1058 };
1059
1060 static const struct option verify_shared_options[] = {
1061 {
1062 .name = "check_ss_sig",
1063 .desc = "Check the root CA self-signed certificate signature",
1064 },
1065 {
1066 .name = "crl_check",
1067 .desc = "Enable CRL checking for the leaf certificate",
1068 },
1069 {
1070 .name = "crl_check_all",
1071 .desc = "Enable CRL checking for the entire certificate chain",
1072 },
1073 {
1074 .name = "extended_crl",
1075 .desc = "Enable extended CRL support",
1076 },
1077 {
1078 .name = "ignore_critical",
1079 .desc = "Disable critical extension checking",
1080 },
1081 {
1082 .name = "issuer_checks",
1083 .desc = "Enable debugging of certificate issuer checks",
1084 },
1085 {
1086 .name = "policy",
1087 .argname = "name",
1088 .desc = "Add given policy to the acceptable set",
1089 },
1090 {
1091 .name = "policy_check",
1092 .desc = "Enable certificate policy checking",
1093 },
1094 {
1095 .name = "purpose",
1096 .argname = "name",
1097 .desc = "Verify for the given purpose",
1098 },
1099 {
1100 .name = "x509_strict",
1101 .desc = "Use strict X.509 rules (disables workarounds)",
1102 },
1103 { NULL },
1104 };
1105
1106 static void
cms_usage(void)1107 cms_usage(void)
1108 {
1109 int i;
1110
1111 fprintf(stderr, "usage: cms "
1112 "[-aes128 | -aes192 | -aes256 | -camellia128 |\n"
1113 " -camellia192 | -camellia256 | -des | -des3 |\n"
1114 " -rc2-40 | -rc2-64 | -rc2-128] [-CAfile file]\n"
1115 " [-CApath directory] [-binary] [-certfile file]\n"
1116 " [-certsout file] [-cmsout] [-compress] [-content file]\n"
1117 " [-crlfeol] [-data_create] [-data_out] [-debug_decrypt]\n"
1118 " [-decrypt] [-digest_create] [-digest_verify]\n"
1119 " [-econtent_type type] [-encrypt] [-EncryptedData_decrypt]\n"
1120 " [-EncryptedData_encrypt] [-from addr] [-in file]\n"
1121 " [-inform der | pem | smime] [-inkey file]\n"
1122 " [-keyform der | pem] [-keyid] [-keyopt nm:v] [-md digest]\n"
1123 " [-no_attr_verify] [-no_content_verify]\n"
1124 " [-no_signer_cert_verify] [-noattr] [-nocerts] [-nodetach]\n"
1125 " [-nointern] [-nooldmime] [-noout] [-nosigs] [-nosmimecap]\n"
1126 " [-noverify] [-out file] [-outform der | pem | smime]\n"
1127 " [-passin src] [-print] [-pwri_password arg]\n"
1128 " [-rctform der | pem | smime]\n"
1129 " [-receipt_request_all | -receipt_request_first]\n"
1130 " [-receipt_request_from addr] [-receipt_request_print]\n"
1131 " [-receipt_request_to addr] [-recip file] [-resign]\n"
1132 " [-secretkey key] [-secretkeyid id] [-sign] [-sign_receipt]\n"
1133 " [-signer file] [-stream | -indef | -noindef] [-subject s]\n"
1134 " [-text] [-to addr] [-uncompress] [-verify]\n"
1135 " [-verify_receipt file] [-verify_retcode] [cert.pem ...]\n\n");
1136
1137 options_usage(cms_options);
1138
1139 fprintf(stderr, "\nVerification options:\n\n");
1140 options_usage(verify_shared_options);
1141
1142 fprintf(stderr, "\nValid purposes:\n\n");
1143 for (i = 0; i < X509_PURPOSE_get_count(); i++) {
1144 X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
1145 fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
1146 X509_PURPOSE_get0_name(ptmp));
1147 }
1148 }
1149
1150 int
cms_main(int argc,char ** argv)1151 cms_main(int argc, char **argv)
1152 {
1153 int ret = 0;
1154 char **args;
1155 int argsused = 0;
1156 const char *inmode = "r", *outmode = "w";
1157 CMS_ContentInfo *cms = NULL, *rcms = NULL;
1158 X509_STORE *store = NULL;
1159 X509 *recip = NULL, *signer = NULL;
1160 EVP_PKEY *key = NULL;
1161 STACK_OF(X509) *other = NULL;
1162 BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
1163 int badarg = 0;
1164 CMS_ReceiptRequest *rr = NULL;
1165 char *passin = NULL;
1166 unsigned char *pwri_tmp = NULL;
1167
1168 if (single_execution) {
1169 if (pledge("stdio rpath wpath cpath tty", NULL) == -1) {
1170 perror("pledge");
1171 exit(1);
1172 }
1173 }
1174
1175 memset(&cms_config, 0, sizeof(cms_config));
1176 cms_config.flags = CMS_DETACHED;
1177 cms_config.rr_allorfirst = -1;
1178 cms_config.informat = FORMAT_SMIME;
1179 cms_config.outformat = FORMAT_SMIME;
1180 cms_config.rctformat = FORMAT_SMIME;
1181 cms_config.keyform = FORMAT_PEM;
1182 if (options_parse(argc, argv, cms_options, NULL, &argsused) != 0) {
1183 goto argerr;
1184 }
1185 args = argv + argsused;
1186 ret = 1;
1187
1188 if (((cms_config.rr_allorfirst != -1) || cms_config.rr_from != NULL) &&
1189 cms_config.rr_to == NULL) {
1190 BIO_puts(bio_err, "No Signed Receipts Recipients\n");
1191 goto argerr;
1192 }
1193 if (!(cms_config.operation & SMIME_SIGNERS) &&
1194 (cms_config.rr_to != NULL || cms_config.rr_from != NULL)) {
1195 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
1196 goto argerr;
1197 }
1198 if (!(cms_config.operation & SMIME_SIGNERS) &&
1199 (cms_config.skkeys != NULL || cms_config.sksigners != NULL)) {
1200 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
1201 goto argerr;
1202 }
1203 if (cms_config.operation & SMIME_SIGNERS) {
1204 if (cms_config.keyfile != NULL &&
1205 cms_config.signerfile == NULL) {
1206 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
1207 goto argerr;
1208 }
1209 /* Check to see if any final signer needs to be appended */
1210 if (cms_config.signerfile != NULL) {
1211 if (cms_config.sksigners == NULL &&
1212 (cms_config.sksigners =
1213 sk_OPENSSL_STRING_new_null()) == NULL)
1214 goto end;
1215 if (!sk_OPENSSL_STRING_push(cms_config.sksigners,
1216 cms_config.signerfile))
1217 goto end;
1218 if (cms_config.skkeys == NULL &&
1219 (cms_config.skkeys =
1220 sk_OPENSSL_STRING_new_null()) == NULL)
1221 goto end;
1222 if (cms_config.keyfile == NULL)
1223 cms_config.keyfile = cms_config.signerfile;
1224 if (!sk_OPENSSL_STRING_push(cms_config.skkeys,
1225 cms_config.keyfile))
1226 goto end;
1227 }
1228 if (cms_config.sksigners == NULL) {
1229 BIO_printf(bio_err,
1230 "No signer certificate specified\n");
1231 badarg = 1;
1232 }
1233 cms_config.signerfile = NULL;
1234 cms_config.keyfile = NULL;
1235 } else if (cms_config.operation == SMIME_DECRYPT) {
1236 if (cms_config.recipfile == NULL &&
1237 cms_config.keyfile == NULL &&
1238 cms_config.secret_key == NULL &&
1239 cms_config.pwri_pass == NULL) {
1240 BIO_printf(bio_err,
1241 "No recipient certificate or key specified\n");
1242 badarg = 1;
1243 }
1244 } else if (cms_config.operation == SMIME_ENCRYPT) {
1245 if (*args == NULL && cms_config.secret_key == NULL &&
1246 cms_config.pwri_pass == NULL &&
1247 cms_config.encerts == NULL) {
1248 BIO_printf(bio_err,
1249 "No recipient(s) certificate(s) specified\n");
1250 badarg = 1;
1251 }
1252 } else if (!cms_config.operation) {
1253 badarg = 1;
1254 }
1255
1256 if (badarg) {
1257 argerr:
1258 cms_usage();
1259 goto end;
1260 }
1261
1262 if (!app_passwd(bio_err, cms_config.passargin, NULL, &passin, NULL)) {
1263 BIO_printf(bio_err, "Error getting password\n");
1264 goto end;
1265 }
1266 ret = 2;
1267
1268 if (!(cms_config.operation & SMIME_SIGNERS))
1269 cms_config.flags &= ~CMS_DETACHED;
1270
1271 if (cms_config.operation & SMIME_OP) {
1272 if (cms_config.outformat == FORMAT_ASN1)
1273 outmode = "wb";
1274 } else {
1275 if (cms_config.flags & CMS_BINARY)
1276 outmode = "wb";
1277 }
1278
1279 if (cms_config.operation & SMIME_IP) {
1280 if (cms_config.informat == FORMAT_ASN1)
1281 inmode = "rb";
1282 } else {
1283 if (cms_config.flags & CMS_BINARY)
1284 inmode = "rb";
1285 }
1286
1287 if (cms_config.operation == SMIME_ENCRYPT) {
1288 if (cms_config.cipher == NULL) {
1289 #ifndef OPENSSL_NO_DES
1290 cms_config.cipher = EVP_des_ede3_cbc();
1291 #else
1292 BIO_printf(bio_err, "No cipher selected\n");
1293 goto end;
1294 #endif
1295 }
1296 if (cms_config.secret_key != NULL &&
1297 cms_config.secret_keyid == NULL) {
1298 BIO_printf(bio_err, "No secret key id\n");
1299 goto end;
1300 }
1301 if (*args != NULL && cms_config.encerts == NULL)
1302 if ((cms_config.encerts = sk_X509_new_null()) == NULL)
1303 goto end;
1304 while (*args) {
1305 if ((cms_config.cert = load_cert(bio_err, *args,
1306 FORMAT_PEM, NULL,
1307 "recipient certificate file")) == NULL)
1308 goto end;
1309 if (!sk_X509_push(cms_config.encerts, cms_config.cert))
1310 goto end;
1311 cms_config.cert = NULL;
1312 args++;
1313 }
1314 }
1315 if (cms_config.certfile != NULL) {
1316 if ((other = load_certs(bio_err, cms_config.certfile,
1317 FORMAT_PEM, NULL, "certificate file")) == NULL) {
1318 ERR_print_errors(bio_err);
1319 goto end;
1320 }
1321 }
1322 if (cms_config.recipfile != NULL &&
1323 (cms_config.operation == SMIME_DECRYPT)) {
1324 if ((recip = load_cert(bio_err, cms_config.recipfile,
1325 FORMAT_PEM, NULL, "recipient certificate file")) == NULL) {
1326 ERR_print_errors(bio_err);
1327 goto end;
1328 }
1329 }
1330 if (cms_config.operation == SMIME_SIGN_RECEIPT) {
1331 if ((signer = load_cert(bio_err, cms_config.signerfile,
1332 FORMAT_PEM, NULL,
1333 "receipt signer certificate file")) == NULL) {
1334 ERR_print_errors(bio_err);
1335 goto end;
1336 }
1337 }
1338 if (cms_config.operation == SMIME_DECRYPT) {
1339 if (cms_config.keyfile == NULL)
1340 cms_config.keyfile = cms_config.recipfile;
1341 } else if ((cms_config.operation == SMIME_SIGN) ||
1342 (cms_config.operation == SMIME_SIGN_RECEIPT)) {
1343 if (cms_config.keyfile == NULL)
1344 cms_config.keyfile = cms_config.signerfile;
1345 } else {
1346 cms_config.keyfile = NULL;
1347 }
1348
1349 if (cms_config.keyfile != NULL) {
1350 key = load_key(bio_err, cms_config.keyfile, cms_config.keyform,
1351 0, passin, "signing key file");
1352 if (key == NULL)
1353 goto end;
1354 }
1355 if (cms_config.infile != NULL) {
1356 if ((in = BIO_new_file(cms_config.infile, inmode)) == NULL) {
1357 BIO_printf(bio_err,
1358 "Can't open input file %s\n", cms_config.infile);
1359 goto end;
1360 }
1361 } else {
1362 if ((in = BIO_new_fp(stdin, BIO_NOCLOSE)) == NULL)
1363 goto end;
1364 }
1365
1366 if (cms_config.operation & SMIME_IP) {
1367 if (cms_config.informat == FORMAT_SMIME)
1368 cms = SMIME_read_CMS(in, &indata);
1369 else if (cms_config.informat == FORMAT_PEM)
1370 cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
1371 else if (cms_config.informat == FORMAT_ASN1)
1372 cms = d2i_CMS_bio(in, NULL);
1373 else {
1374 BIO_printf(bio_err, "Bad input format for CMS file\n");
1375 goto end;
1376 }
1377
1378 if (cms == NULL) {
1379 BIO_printf(bio_err, "Error reading S/MIME message\n");
1380 goto end;
1381 }
1382 if (cms_config.contfile != NULL) {
1383 BIO_free(indata);
1384 if ((indata = BIO_new_file(cms_config.contfile,
1385 "rb")) == NULL) {
1386 BIO_printf(bio_err,
1387 "Can't read content file %s\n",
1388 cms_config.contfile);
1389 goto end;
1390 }
1391 }
1392 if (cms_config.certsoutfile != NULL) {
1393 STACK_OF(X509) *allcerts;
1394 if ((allcerts = CMS_get1_certs(cms)) == NULL)
1395 goto end;
1396 if (!save_certs(cms_config.certsoutfile, allcerts)) {
1397 BIO_printf(bio_err,
1398 "Error writing certs to %s\n",
1399 cms_config.certsoutfile);
1400 sk_X509_pop_free(allcerts, X509_free);
1401 ret = 5;
1402 goto end;
1403 }
1404 sk_X509_pop_free(allcerts, X509_free);
1405 }
1406 }
1407 if (cms_config.rctfile != NULL) {
1408 char *rctmode = (cms_config.rctformat == FORMAT_ASN1) ?
1409 "rb" : "r";
1410 if ((rctin = BIO_new_file(cms_config.rctfile, rctmode)) == NULL) {
1411 BIO_printf(bio_err,
1412 "Can't open receipt file %s\n", cms_config.rctfile);
1413 goto end;
1414 }
1415 if (cms_config.rctformat == FORMAT_SMIME)
1416 rcms = SMIME_read_CMS(rctin, NULL);
1417 else if (cms_config.rctformat == FORMAT_PEM)
1418 rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
1419 else if (cms_config.rctformat == FORMAT_ASN1)
1420 rcms = d2i_CMS_bio(rctin, NULL);
1421 else {
1422 BIO_printf(bio_err, "Bad input format for receipt\n");
1423 goto end;
1424 }
1425
1426 if (rcms == NULL) {
1427 BIO_printf(bio_err, "Error reading receipt\n");
1428 goto end;
1429 }
1430 }
1431 if (cms_config.outfile != NULL) {
1432 if ((out = BIO_new_file(cms_config.outfile, outmode)) == NULL) {
1433 BIO_printf(bio_err,
1434 "Can't open output file %s\n", cms_config.outfile);
1435 goto end;
1436 }
1437 } else {
1438 if ((out = BIO_new_fp(stdout, BIO_NOCLOSE)) == NULL)
1439 goto end;
1440 }
1441
1442 if ((cms_config.operation == SMIME_VERIFY) ||
1443 (cms_config.operation == SMIME_VERIFY_RECEIPT)) {
1444 if ((store = setup_verify(bio_err, cms_config.CAfile,
1445 cms_config.CApath)) == NULL)
1446 goto end;
1447 X509_STORE_set_verify_cb(store, cms_cb);
1448 if (cms_config.vpm != NULL) {
1449 if (!X509_STORE_set1_param(store, cms_config.vpm))
1450 goto end;
1451 }
1452 }
1453 ret = 3;
1454
1455 if (cms_config.operation == SMIME_DATA_CREATE) {
1456 cms = CMS_data_create(in, cms_config.flags);
1457 } else if (cms_config.operation == SMIME_DIGEST_CREATE) {
1458 cms = CMS_digest_create(in, cms_config.sign_md,
1459 cms_config.flags);
1460 } else if (cms_config.operation == SMIME_COMPRESS) {
1461 cms = CMS_compress(in, -1, cms_config.flags);
1462 } else if (cms_config.operation == SMIME_ENCRYPT) {
1463 int i;
1464 cms_config.flags |= CMS_PARTIAL;
1465 cms = CMS_encrypt(NULL, in, cms_config.cipher,
1466 cms_config.flags);
1467 if (cms == NULL)
1468 goto end;
1469 for (i = 0; i < sk_X509_num(cms_config.encerts); i++) {
1470 CMS_RecipientInfo *ri;
1471 struct cms_key_param *kparam;
1472 int tflags = cms_config.flags;
1473 X509 *x;
1474
1475 if ((x = sk_X509_value(cms_config.encerts, i)) == NULL)
1476 goto end;
1477 for (kparam = cms_config.key_first; kparam != NULL;
1478 kparam = kparam->next) {
1479 if (kparam->idx == i) {
1480 tflags |= CMS_KEY_PARAM;
1481 break;
1482 }
1483 }
1484 ri = CMS_add1_recipient_cert(cms, x, tflags);
1485 if (ri == NULL)
1486 goto end;
1487 if (kparam != NULL) {
1488 EVP_PKEY_CTX *pctx;
1489 if ((pctx = CMS_RecipientInfo_get0_pkey_ctx(
1490 ri)) == NULL)
1491 goto end;
1492 if (!cms_set_pkey_param(pctx, kparam->param))
1493 goto end;
1494 }
1495 }
1496
1497 if (cms_config.secret_key != NULL) {
1498 if (CMS_add0_recipient_key(cms, NID_undef,
1499 cms_config.secret_key, cms_config.secret_keylen,
1500 cms_config.secret_keyid, cms_config.secret_keyidlen,
1501 NULL, NULL, NULL) == NULL)
1502 goto end;
1503 /* NULL these because call absorbs them */
1504 cms_config.secret_key = NULL;
1505 cms_config.secret_keyid = NULL;
1506 }
1507 if (cms_config.pwri_pass != NULL) {
1508 pwri_tmp = strdup(cms_config.pwri_pass);
1509 if (pwri_tmp == NULL)
1510 goto end;
1511 if (CMS_add0_recipient_password(cms, -1, NID_undef,
1512 NID_undef, pwri_tmp, -1, NULL) == NULL)
1513 goto end;
1514 pwri_tmp = NULL;
1515 }
1516 if (!(cms_config.flags & CMS_STREAM)) {
1517 if (!CMS_final(cms, in, NULL, cms_config.flags))
1518 goto end;
1519 }
1520 } else if (cms_config.operation == SMIME_ENCRYPTED_ENCRYPT) {
1521 cms = CMS_EncryptedData_encrypt(in, cms_config.cipher,
1522 cms_config.secret_key, cms_config.secret_keylen,
1523 cms_config.flags);
1524
1525 } else if (cms_config.operation == SMIME_SIGN_RECEIPT) {
1526 CMS_ContentInfo *srcms = NULL;
1527 STACK_OF(CMS_SignerInfo) *sis;
1528 CMS_SignerInfo *si;
1529 sis = CMS_get0_SignerInfos(cms);
1530 if (sis == NULL)
1531 goto end;
1532 si = sk_CMS_SignerInfo_value(sis, 0);
1533 if (si == NULL)
1534 goto end;
1535 srcms = CMS_sign_receipt(si, signer, key, other,
1536 cms_config.flags);
1537 if (srcms == NULL)
1538 goto end;
1539 CMS_ContentInfo_free(cms);
1540 cms = srcms;
1541 } else if (cms_config.operation & SMIME_SIGNERS) {
1542 int i;
1543 /*
1544 * If detached data content we enable streaming if S/MIME
1545 * output format.
1546 */
1547 if (cms_config.operation == SMIME_SIGN) {
1548
1549 if (cms_config.flags & CMS_DETACHED) {
1550 if (cms_config.outformat == FORMAT_SMIME)
1551 cms_config.flags |= CMS_STREAM;
1552 }
1553 cms_config.flags |= CMS_PARTIAL;
1554 cms = CMS_sign(NULL, NULL, other, in, cms_config.flags);
1555 if (cms == NULL)
1556 goto end;
1557 if (cms_config.econtent_type != NULL)
1558 if (!CMS_set1_eContentType(cms,
1559 cms_config.econtent_type))
1560 goto end;
1561
1562 if (cms_config.rr_to != NULL) {
1563 rr = make_receipt_request(cms_config.rr_to,
1564 cms_config.rr_allorfirst,
1565 cms_config.rr_from);
1566 if (rr == NULL) {
1567 BIO_puts(bio_err,
1568 "Signed Receipt Request Creation Error\n");
1569 goto end;
1570 }
1571 }
1572 } else {
1573 cms_config.flags |= CMS_REUSE_DIGEST;
1574 }
1575
1576 for (i = 0; i < sk_OPENSSL_STRING_num(cms_config.sksigners); i++) {
1577 CMS_SignerInfo *si;
1578 struct cms_key_param *kparam;
1579 int tflags = cms_config.flags;
1580
1581 cms_config.signerfile = sk_OPENSSL_STRING_value(
1582 cms_config.sksigners, i);
1583 cms_config.keyfile = sk_OPENSSL_STRING_value(
1584 cms_config.skkeys, i);
1585
1586 signer = load_cert(bio_err, cms_config.signerfile,
1587 FORMAT_PEM, NULL, "signer certificate");
1588 if (signer == NULL)
1589 goto end;
1590 key = load_key(bio_err, cms_config.keyfile,
1591 cms_config.keyform, 0, passin, "signing key file");
1592 if (key == NULL)
1593 goto end;
1594 for (kparam = cms_config.key_first; kparam != NULL;
1595 kparam = kparam->next) {
1596 if (kparam->idx == i) {
1597 tflags |= CMS_KEY_PARAM;
1598 break;
1599 }
1600 }
1601 si = CMS_add1_signer(cms, signer, key,
1602 cms_config.sign_md, tflags);
1603 if (si == NULL)
1604 goto end;
1605 if (kparam != NULL) {
1606 EVP_PKEY_CTX *pctx;
1607 if ((pctx = CMS_SignerInfo_get0_pkey_ctx(
1608 si)) == NULL)
1609 goto end;
1610 if (!cms_set_pkey_param(pctx, kparam->param))
1611 goto end;
1612 }
1613 if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr))
1614 goto end;
1615 X509_free(signer);
1616 signer = NULL;
1617 EVP_PKEY_free(key);
1618 key = NULL;
1619 }
1620 /* If not streaming or resigning finalize structure */
1621 if ((cms_config.operation == SMIME_SIGN) &&
1622 !(cms_config.flags & CMS_STREAM)) {
1623 if (!CMS_final(cms, in, NULL, cms_config.flags))
1624 goto end;
1625 }
1626 }
1627 if (cms == NULL) {
1628 BIO_printf(bio_err, "Error creating CMS structure\n");
1629 goto end;
1630 }
1631 ret = 4;
1632 if (cms_config.operation == SMIME_DECRYPT) {
1633 if (cms_config.flags & CMS_DEBUG_DECRYPT)
1634 CMS_decrypt(cms, NULL, NULL, NULL, NULL,
1635 cms_config.flags);
1636
1637 if (cms_config.secret_key != NULL) {
1638 if (!CMS_decrypt_set1_key(cms, cms_config.secret_key,
1639 cms_config.secret_keylen, cms_config.secret_keyid,
1640 cms_config.secret_keyidlen)) {
1641 BIO_puts(bio_err,
1642 "Error decrypting CMS using secret key\n");
1643 goto end;
1644 }
1645 }
1646 if (key != NULL) {
1647 if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
1648 BIO_puts(bio_err,
1649 "Error decrypting CMS using private key\n");
1650 goto end;
1651 }
1652 }
1653 if (cms_config.pwri_pass != NULL) {
1654 if (!CMS_decrypt_set1_password(cms,
1655 cms_config.pwri_pass, -1)) {
1656 BIO_puts(bio_err,
1657 "Error decrypting CMS using password\n");
1658 goto end;
1659 }
1660 }
1661 if (!CMS_decrypt(cms, NULL, NULL, indata, out,
1662 cms_config.flags)) {
1663 BIO_printf(bio_err, "Error decrypting CMS structure\n");
1664 goto end;
1665 }
1666 } else if (cms_config.operation == SMIME_DATAOUT) {
1667 if (!CMS_data(cms, out, cms_config.flags))
1668 goto end;
1669 } else if (cms_config.operation == SMIME_UNCOMPRESS) {
1670 if (!CMS_uncompress(cms, indata, out, cms_config.flags))
1671 goto end;
1672 } else if (cms_config.operation == SMIME_DIGEST_VERIFY) {
1673 if (CMS_digest_verify(cms, indata, out, cms_config.flags) > 0)
1674 BIO_printf(bio_err, "Verification successful\n");
1675 else {
1676 BIO_printf(bio_err, "Verification failure\n");
1677 goto end;
1678 }
1679 } else if (cms_config.operation == SMIME_ENCRYPTED_DECRYPT) {
1680 if (!CMS_EncryptedData_decrypt(cms, cms_config.secret_key,
1681 cms_config.secret_keylen, indata, out, cms_config.flags))
1682 goto end;
1683 } else if (cms_config.operation == SMIME_VERIFY) {
1684 if (CMS_verify(cms, other, store, indata, out,
1685 cms_config.flags) > 0) {
1686 BIO_printf(bio_err, "Verification successful\n");
1687 } else {
1688 BIO_printf(bio_err, "Verification failure\n");
1689 if (cms_config.verify_retcode)
1690 ret = verify_err + 32;
1691 goto end;
1692 }
1693 if (cms_config.signerfile != NULL) {
1694 STACK_OF(X509) *signers;
1695 if ((signers = CMS_get0_signers(cms)) == NULL)
1696 goto end;
1697 if (!save_certs(cms_config.signerfile, signers)) {
1698 BIO_printf(bio_err,
1699 "Error writing signers to %s\n",
1700 cms_config.signerfile);
1701 sk_X509_free(signers);
1702 ret = 5;
1703 goto end;
1704 }
1705 sk_X509_free(signers);
1706 }
1707 if (cms_config.rr_print)
1708 receipt_request_print(bio_err, cms);
1709
1710 } else if (cms_config.operation == SMIME_VERIFY_RECEIPT) {
1711 if (CMS_verify_receipt(rcms, cms, other, store,
1712 cms_config.flags) > 0) {
1713 BIO_printf(bio_err, "Verification successful\n");
1714 } else {
1715 BIO_printf(bio_err, "Verification failure\n");
1716 goto end;
1717 }
1718 } else {
1719 if (cms_config.noout) {
1720 if (cms_config.print &&
1721 !CMS_ContentInfo_print_ctx(out, cms, 0, NULL))
1722 goto end;
1723 } else if (cms_config.outformat == FORMAT_SMIME) {
1724 if (cms_config.to != NULL)
1725 BIO_printf(out, "To: %s\n", cms_config.to);
1726 if (cms_config.from != NULL)
1727 BIO_printf(out, "From: %s\n", cms_config.from);
1728 if (cms_config.subject != NULL)
1729 BIO_printf(out, "Subject: %s\n",
1730 cms_config.subject);
1731 if (cms_config.operation == SMIME_RESIGN)
1732 ret = SMIME_write_CMS(out, cms, indata,
1733 cms_config.flags);
1734 else
1735 ret = SMIME_write_CMS(out, cms, in,
1736 cms_config.flags);
1737 } else if (cms_config.outformat == FORMAT_PEM) {
1738 ret = PEM_write_bio_CMS_stream(out, cms, in,
1739 cms_config.flags);
1740 } else if (cms_config.outformat == FORMAT_ASN1) {
1741 ret = i2d_CMS_bio_stream(out, cms, in, cms_config.flags);
1742 } else {
1743 BIO_printf(bio_err, "Bad output format for CMS file\n");
1744 goto end;
1745 }
1746 if (ret <= 0) {
1747 ret = 6;
1748 goto end;
1749 }
1750 }
1751 ret = 0;
1752
1753 end:
1754 if (ret)
1755 ERR_print_errors(bio_err);
1756
1757 sk_X509_pop_free(cms_config.encerts, X509_free);
1758 sk_X509_pop_free(other, X509_free);
1759 X509_VERIFY_PARAM_free(cms_config.vpm);
1760 sk_OPENSSL_STRING_free(cms_config.sksigners);
1761 sk_OPENSSL_STRING_free(cms_config.skkeys);
1762 free(cms_config.secret_key);
1763 free(cms_config.secret_keyid);
1764 free(pwri_tmp);
1765 ASN1_OBJECT_free(cms_config.econtent_type);
1766 CMS_ReceiptRequest_free(rr);
1767 sk_OPENSSL_STRING_free(cms_config.rr_to);
1768 sk_OPENSSL_STRING_free(cms_config.rr_from);
1769 for (cms_config.key_param = cms_config.key_first; cms_config.key_param;) {
1770 struct cms_key_param *tparam;
1771 sk_OPENSSL_STRING_free(cms_config.key_param->param);
1772 tparam = cms_config.key_param->next;
1773 free(cms_config.key_param);
1774 cms_config.key_param = tparam;
1775 }
1776 X509_STORE_free(store);
1777 X509_free(cms_config.cert);
1778 X509_free(recip);
1779 X509_free(signer);
1780 EVP_PKEY_free(key);
1781 CMS_ContentInfo_free(cms);
1782 CMS_ContentInfo_free(rcms);
1783 BIO_free(rctin);
1784 BIO_free(in);
1785 BIO_free(indata);
1786 BIO_free_all(out);
1787 free(passin);
1788
1789 return (ret);
1790 }
1791
1792 static int
save_certs(char * signerfile,STACK_OF (X509)* signers)1793 save_certs(char *signerfile, STACK_OF(X509) *signers)
1794 {
1795 int i;
1796 BIO *tmp;
1797
1798 if (signerfile == NULL)
1799 return 1;
1800 tmp = BIO_new_file(signerfile, "w");
1801 if (tmp == NULL)
1802 return 0;
1803 for (i = 0; i < sk_X509_num(signers); i++)
1804 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1805 BIO_free(tmp);
1806 return 1;
1807 }
1808
1809 /* Minimal callback just to output policy info (if any) */
1810
1811 static int
cms_cb(int ok,X509_STORE_CTX * ctx)1812 cms_cb(int ok, X509_STORE_CTX *ctx)
1813 {
1814 int error;
1815
1816 error = X509_STORE_CTX_get_error(ctx);
1817
1818 verify_err = error;
1819
1820 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY) &&
1821 ((error != X509_V_OK) || (ok != 2)))
1822 return ok;
1823
1824 policies_print(NULL, ctx);
1825
1826 return ok;
1827 }
1828
1829 static void
gnames_stack_print(BIO * out,STACK_OF (GENERAL_NAMES)* gns)1830 gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1831 {
1832 STACK_OF(GENERAL_NAME) *gens;
1833 GENERAL_NAME *gen;
1834 int i, j;
1835
1836 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1837 gens = sk_GENERAL_NAMES_value(gns, i);
1838 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1839 gen = sk_GENERAL_NAME_value(gens, j);
1840 BIO_puts(out, " ");
1841 GENERAL_NAME_print(out, gen);
1842 BIO_puts(out, "\n");
1843 }
1844 }
1845 return;
1846 }
1847
1848 static void
receipt_request_print(BIO * out,CMS_ContentInfo * cms)1849 receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1850 {
1851 STACK_OF(CMS_SignerInfo) *sis;
1852 CMS_SignerInfo *si;
1853 CMS_ReceiptRequest *rr;
1854 int allorfirst;
1855 STACK_OF(GENERAL_NAMES) *rto, *rlist;
1856 ASN1_STRING *scid;
1857 int i, rv;
1858
1859 if ((sis = CMS_get0_SignerInfos(cms)) == NULL)
1860 return;
1861 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1862 if ((si = sk_CMS_SignerInfo_value(sis, i)) == NULL)
1863 return;
1864 rv = CMS_get1_ReceiptRequest(si, &rr);
1865 BIO_printf(bio_err, "Signer %d:\n", i + 1);
1866 if (rv == 0) {
1867 BIO_puts(bio_err, " No Receipt Request\n");
1868 } else if (rv < 0) {
1869 BIO_puts(bio_err, " Receipt Request Parse Error\n");
1870 ERR_print_errors(bio_err);
1871 } else {
1872 char *id;
1873 int idlen;
1874
1875 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1876 &rlist, &rto);
1877 BIO_puts(out, " Signed Content ID:\n");
1878 idlen = ASN1_STRING_length(scid);
1879 id = (char *) ASN1_STRING_data(scid);
1880 BIO_dump_indent(out, id, idlen, 4);
1881 BIO_puts(out, " Receipts From");
1882 if (rlist != NULL) {
1883 BIO_puts(out, " List:\n");
1884 gnames_stack_print(out, rlist);
1885 } else if (allorfirst == 1) {
1886 BIO_puts(out, ": First Tier\n");
1887 } else if (allorfirst == 0) {
1888 BIO_puts(out, ": All\n");
1889 } else {
1890 BIO_printf(out, " Unknown (%d)\n", allorfirst);
1891 }
1892 BIO_puts(out, " Receipts To:\n");
1893 gnames_stack_print(out, rto);
1894 }
1895 CMS_ReceiptRequest_free(rr);
1896 }
1897 }
1898
STACK_OF(GENERAL_NAMES)1899 static STACK_OF(GENERAL_NAMES) *
1900 make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1901 {
1902 int i;
1903 STACK_OF(GENERAL_NAMES) *ret;
1904 GENERAL_NAMES *gens = NULL;
1905 GENERAL_NAME *gen = NULL;
1906
1907 if ((ret = sk_GENERAL_NAMES_new_null()) == NULL)
1908 goto err;
1909 for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1910 char *str = sk_OPENSSL_STRING_value(ns, i);
1911 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1912 if (gen == NULL)
1913 goto err;
1914 gens = GENERAL_NAMES_new();
1915 if (gens == NULL)
1916 goto err;
1917 if (!sk_GENERAL_NAME_push(gens, gen))
1918 goto err;
1919 gen = NULL;
1920 if (!sk_GENERAL_NAMES_push(ret, gens))
1921 goto err;
1922 gens = NULL;
1923 }
1924
1925 return ret;
1926
1927 err:
1928 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1929 GENERAL_NAMES_free(gens);
1930 GENERAL_NAME_free(gen);
1931
1932 return NULL;
1933 }
1934
1935
1936 static CMS_ReceiptRequest *
make_receipt_request(STACK_OF (OPENSSL_STRING)* rr_to,int rr_allorfirst,STACK_OF (OPENSSL_STRING)* rr_from)1937 make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
1938 STACK_OF(OPENSSL_STRING) *rr_from)
1939 {
1940 STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
1941 CMS_ReceiptRequest *rr;
1942
1943 rct_to = make_names_stack(rr_to);
1944 if (rct_to == NULL)
1945 goto err;
1946 if (rr_from != NULL) {
1947 rct_from = make_names_stack(rr_from);
1948 if (rct_from == NULL)
1949 goto err;
1950 } else {
1951 rct_from = NULL;
1952 }
1953
1954 if ((rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1955 rct_to)) == NULL)
1956 goto err;
1957
1958 return rr;
1959
1960 err:
1961 sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
1962 sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free);
1963 return NULL;
1964 }
1965
1966 static int
cms_set_pkey_param(EVP_PKEY_CTX * pctx,STACK_OF (OPENSSL_STRING)* param)1967 cms_set_pkey_param(EVP_PKEY_CTX *pctx, STACK_OF(OPENSSL_STRING) *param)
1968 {
1969 char *keyopt;
1970 int i;
1971
1972 if (sk_OPENSSL_STRING_num(param) <= 0)
1973 return 1;
1974 for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
1975 keyopt = sk_OPENSSL_STRING_value(param, i);
1976 if (pkey_ctrl_string(pctx, keyopt) <= 0) {
1977 BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
1978 ERR_print_errors(bio_err);
1979 return 0;
1980 }
1981 }
1982 return 1;
1983 }
1984
1985 #endif
1986