vendor/LIBRESSL: Import LibreSSL 3.6.1
[dragonfly.git] / crypto / libressl / apps / openssl / cms.c
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 *
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
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
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
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
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
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
313 cms_opt_print(void)
314 {
315         cms_config.noout = 1;
316         cms_config.print = 1;
317         return (0);
318 }
319
320 static int
321 cms_opt_pwri_pass(char *arg)
322 {
323         cms_config.pwri_pass = (unsigned char *)arg;
324         return (0);
325 }
326
327 static int
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
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
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
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, &ltmp)) == 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
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, &ltmp)) == 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
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
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
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
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
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
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
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
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
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
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 *
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
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