Demo of use of errors in applications.
[openssl.git] / apps / cms.c
1 /* apps/cms.c */
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 #include "apps.h"
59
60 #ifndef OPENSSL_NO_CMS
61
62 #include <openssl/crypto.h>
63 #include <openssl/pem.h>
64 #include <openssl/err.h>
65 #include <openssl/x509_vfy.h>
66 #include <openssl/x509v3.h>
67 #include <openssl/cms.h>
68
69 #undef PROG
70 #define PROG cms_main
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(STACK_OF(OPENSSL_STRING) *rr_to,
75                                                 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 typedef struct cms_key_param_st cms_key_param;
103
104 struct cms_key_param_st
105         {
106         int idx;
107         STACK_OF(OPENSSL_STRING)*param;
108         cms_key_param *next;
109         };
110
111 int MAIN(int, char **);
112
113 int MAIN(int argc, char **argv)
114         {
115         ENGINE *e = NULL;
116         int operation = 0;
117         int ret = 0;
118         char **args;
119         const char *inmode = "r", *outmode = "w";
120         char *infile = NULL, *outfile = NULL, *rctfile = NULL;
121         char *signerfile = NULL, *recipfile = NULL;
122         STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
123         char *certfile = NULL, *keyfile = NULL, *contfile=NULL;
124         char *certsoutfile = NULL;
125         const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL;
126         CMS_ContentInfo *cms = NULL, *rcms = NULL;
127         X509_STORE *store = NULL;
128         X509 *cert = NULL, *recip = NULL, *signer = NULL;
129         EVP_PKEY *key = NULL;
130         STACK_OF(X509) *encerts = NULL, *other = NULL;
131         BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
132         int badarg = 0;
133         int flags = CMS_DETACHED, noout = 0, print = 0;
134         int verify_retcode = 0;
135         int rr_print = 0, rr_allorfirst = -1;
136         STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
137         CMS_ReceiptRequest *rr = NULL;
138         char *to = NULL, *from = NULL, *subject = NULL;
139         char *CAfile = NULL, *CApath = NULL;
140         char *passargin = NULL, *passin = NULL;
141         char *inrand = NULL;
142         int need_rand = 0;
143         const EVP_MD *sign_md = NULL;
144         int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
145         int rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
146 #ifndef OPENSSL_NO_ENGINE
147         char *engine=NULL;
148 #endif
149         unsigned char *secret_key = NULL, *secret_keyid = NULL;
150         unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
151         size_t secret_keylen = 0, secret_keyidlen = 0;
152
153         cms_key_param *key_first = NULL, *key_param = NULL;
154
155         ASN1_OBJECT *econtent_type = NULL;
156
157         X509_VERIFY_PARAM *vpm = NULL;
158
159         args = argv + 1;
160         ret = 1;
161
162         apps_startup();
163
164         if (bio_err == NULL)
165                 {
166                 if ((bio_err = BIO_new(BIO_s_file())) != NULL)
167                         BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
168                 }
169
170         if (!load_config(bio_err, NULL))
171                 goto end;
172
173         while (!badarg && *args && *args[0] == '-')
174                 {
175                 if (!strcmp (*args, "-encrypt"))
176                         operation = SMIME_ENCRYPT;
177                 else if (!strcmp (*args, "-decrypt"))
178                         operation = SMIME_DECRYPT;
179                 else if (!strcmp (*args, "-sign"))
180                         operation = SMIME_SIGN;
181                 else if (!strcmp (*args, "-sign_receipt"))
182                         operation = SMIME_SIGN_RECEIPT;
183                 else if (!strcmp (*args, "-resign"))
184                         operation = SMIME_RESIGN;
185                 else if (!strcmp (*args, "-verify"))
186                         operation = SMIME_VERIFY;
187                 else if (!strcmp (*args, "-verify_retcode"))
188                         verify_retcode = 1;
189                 else if (!strcmp(*args,"-verify_receipt"))
190                         {
191                         operation = SMIME_VERIFY_RECEIPT;
192                         if (!args[1])
193                                 goto argerr;
194                         args++;
195                         rctfile = *args;
196                         }
197                 else if (!strcmp (*args, "-cmsout"))
198                         operation = SMIME_CMSOUT;
199                 else if (!strcmp (*args, "-data_out"))
200                         operation = SMIME_DATAOUT;
201                 else if (!strcmp (*args, "-data_create"))
202                         operation = SMIME_DATA_CREATE;
203                 else if (!strcmp (*args, "-digest_verify"))
204                         operation = SMIME_DIGEST_VERIFY;
205                 else if (!strcmp (*args, "-digest_create"))
206                         operation = SMIME_DIGEST_CREATE;
207                 else if (!strcmp (*args, "-compress"))
208                         operation = SMIME_COMPRESS;
209                 else if (!strcmp (*args, "-uncompress"))
210                         operation = SMIME_UNCOMPRESS;
211                 else if (!strcmp (*args, "-EncryptedData_decrypt"))
212                         operation = SMIME_ENCRYPTED_DECRYPT;
213                 else if (!strcmp (*args, "-EncryptedData_encrypt"))
214                         operation = SMIME_ENCRYPTED_ENCRYPT;
215 #ifndef OPENSSL_NO_DES
216                 else if (!strcmp (*args, "-des3")) 
217                                 cipher = EVP_des_ede3_cbc();
218                 else if (!strcmp (*args, "-des")) 
219                                 cipher = EVP_des_cbc();
220                 else if (!strcmp (*args, "-des3-wrap")) 
221                                 wrap_cipher = EVP_des_ede3_wrap();
222 #endif
223 #ifndef OPENSSL_NO_SEED
224                 else if (!strcmp (*args, "-seed")) 
225                                 cipher = EVP_seed_cbc();
226 #endif
227 #ifndef OPENSSL_NO_RC2
228                 else if (!strcmp (*args, "-rc2-40")) 
229                                 cipher = EVP_rc2_40_cbc();
230                 else if (!strcmp (*args, "-rc2-128")) 
231                                 cipher = EVP_rc2_cbc();
232                 else if (!strcmp (*args, "-rc2-64")) 
233                                 cipher = EVP_rc2_64_cbc();
234 #endif
235 #ifndef OPENSSL_NO_AES
236                 else if (!strcmp(*args,"-aes128"))
237                                 cipher = EVP_aes_128_cbc();
238                 else if (!strcmp(*args,"-aes192"))
239                                 cipher = EVP_aes_192_cbc();
240                 else if (!strcmp(*args,"-aes256"))
241                                 cipher = EVP_aes_256_cbc();
242                 else if (!strcmp(*args,"-aes128-wrap"))
243                                 wrap_cipher = EVP_aes_128_wrap();
244                 else if (!strcmp(*args,"-aes192-wrap"))
245                                 wrap_cipher = EVP_aes_192_wrap();
246                 else if (!strcmp(*args,"-aes256-wrap"))
247                                 wrap_cipher = EVP_aes_256_wrap();
248 #endif
249 #ifndef OPENSSL_NO_CAMELLIA
250                 else if (!strcmp(*args,"-camellia128"))
251                                 cipher = EVP_camellia_128_cbc();
252                 else if (!strcmp(*args,"-camellia192"))
253                                 cipher = EVP_camellia_192_cbc();
254                 else if (!strcmp(*args,"-camellia256"))
255                                 cipher = EVP_camellia_256_cbc();
256 #endif
257                 else if (!strcmp (*args, "-debug_decrypt")) 
258                                 flags |= CMS_DEBUG_DECRYPT;
259                 else if (!strcmp (*args, "-text")) 
260                                 flags |= CMS_TEXT;
261                 else if (!strcmp (*args, "-nointern")) 
262                                 flags |= CMS_NOINTERN;
263                 else if (!strcmp (*args, "-noverify") 
264                         || !strcmp (*args, "-no_signer_cert_verify")) 
265                                 flags |= CMS_NO_SIGNER_CERT_VERIFY;
266                 else if (!strcmp (*args, "-nocerts")) 
267                                 flags |= CMS_NOCERTS;
268                 else if (!strcmp (*args, "-noattr")) 
269                                 flags |= CMS_NOATTR;
270                 else if (!strcmp (*args, "-nodetach")) 
271                                 flags &= ~CMS_DETACHED;
272                 else if (!strcmp (*args, "-nosmimecap"))
273                                 flags |= CMS_NOSMIMECAP;
274                 else if (!strcmp (*args, "-binary"))
275                                 flags |= CMS_BINARY;
276                 else if (!strcmp (*args, "-keyid"))
277                                 flags |= CMS_USE_KEYID;
278                 else if (!strcmp (*args, "-nosigs"))
279                                 flags |= CMS_NOSIGS;
280                 else if (!strcmp (*args, "-no_content_verify"))
281                                 flags |= CMS_NO_CONTENT_VERIFY;
282                 else if (!strcmp (*args, "-no_attr_verify"))
283                                 flags |= CMS_NO_ATTR_VERIFY;
284                 else if (!strcmp (*args, "-stream"))
285                                 flags |= CMS_STREAM;
286                 else if (!strcmp (*args, "-indef"))
287                                 flags |= CMS_STREAM;
288                 else if (!strcmp (*args, "-noindef"))
289                                 flags &= ~CMS_STREAM;
290                 else if (!strcmp (*args, "-nooldmime"))
291                                 flags |= CMS_NOOLDMIMETYPE;
292                 else if (!strcmp (*args, "-crlfeol"))
293                                 flags |= CMS_CRLFEOL;
294                 else if (!strcmp (*args, "-noout"))
295                                 noout = 1;
296                 else if (!strcmp (*args, "-receipt_request_print"))
297                                 rr_print = 1;
298                 else if (!strcmp (*args, "-receipt_request_all"))
299                                 rr_allorfirst = 0;
300                 else if (!strcmp (*args, "-receipt_request_first"))
301                                 rr_allorfirst = 1;
302                 else if (!strcmp(*args,"-receipt_request_from"))
303                         {
304                         if (!args[1])
305                                 goto argerr;
306                         args++;
307                         if (!rr_from)
308                                 rr_from = sk_OPENSSL_STRING_new_null();
309                         sk_OPENSSL_STRING_push(rr_from, *args);
310                         }
311                 else if (!strcmp(*args,"-receipt_request_to"))
312                         {
313                         if (!args[1])
314                                 goto argerr;
315                         args++;
316                         if (!rr_to)
317                                 rr_to = sk_OPENSSL_STRING_new_null();
318                         sk_OPENSSL_STRING_push(rr_to, *args);
319                         }
320                 else if (!strcmp (*args, "-print"))
321                                 {
322                                 noout = 1;
323                                 print = 1;
324                                 }
325                 else if (!strcmp(*args,"-secretkey"))
326                         {
327                         long ltmp;
328                         if (!args[1])
329                                 goto argerr;
330                         args++;
331                         secret_key = string_to_hex(*args, &ltmp);
332                         if (!secret_key)
333                                 {
334                                 BIO_printf(bio_err, "Invalid key %s\n", *args);
335                                 goto argerr;
336                                 }
337                         secret_keylen = (size_t)ltmp;
338                         }
339                 else if (!strcmp(*args,"-secretkeyid"))
340                         {
341                         long ltmp;
342                         if (!args[1])
343                                 goto argerr;
344                         args++;
345                         secret_keyid = string_to_hex(*args, &ltmp);
346                         if (!secret_keyid)
347                                 {
348                                 BIO_printf(bio_err, "Invalid id %s\n", *args);
349                                 goto argerr;
350                                 }
351                         secret_keyidlen = (size_t)ltmp;
352                         }
353                 else if (!strcmp(*args,"-pwri_password"))
354                         {
355                         if (!args[1])
356                                 goto argerr;
357                         args++;
358                         pwri_pass = (unsigned char *)*args;
359                         }
360                 else if (!strcmp(*args,"-econtent_type"))
361                         {
362                         if (!args[1])
363                                 goto argerr;
364                         args++;
365                         econtent_type = OBJ_txt2obj(*args, 0);
366                         if (!econtent_type)
367                                 {
368                                 BIO_printf(bio_err, "Invalid OID %s\n", *args);
369                                 goto argerr;
370                                 }
371                         }
372                 else if (!strcmp(*args,"-rand"))
373                         {
374                         if (!args[1])
375                                 goto argerr;
376                         args++;
377                         inrand = *args;
378                         need_rand = 1;
379                         }
380 #ifndef OPENSSL_NO_ENGINE
381                 else if (!strcmp(*args,"-engine"))
382                         {
383                         if (!args[1])
384                                 goto argerr;
385                         engine = *++args;
386                         }
387 #endif
388                 else if (!strcmp(*args,"-passin"))
389                         {
390                         if (!args[1])
391                                 goto argerr;
392                         passargin = *++args;
393                         }
394                 else if (!strcmp (*args, "-to"))
395                         {
396                         if (!args[1])
397                                 goto argerr;
398                         to = *++args;
399                         }
400                 else if (!strcmp (*args, "-from"))
401                         {
402                         if (!args[1])
403                                 goto argerr;
404                         from = *++args;
405                         }
406                 else if (!strcmp (*args, "-subject"))
407                         {
408                         if (!args[1])
409                                 goto argerr;
410                         subject = *++args;
411                         }
412                 else if (!strcmp (*args, "-signer"))
413                         {
414                         if (!args[1])
415                                 goto argerr;
416                         /* If previous -signer argument add signer to list */
417
418                         if (signerfile)
419                                 {
420                                 if (!sksigners)
421                                         sksigners = sk_OPENSSL_STRING_new_null();
422                                 sk_OPENSSL_STRING_push(sksigners, signerfile);
423                                 if (!keyfile)
424                                         keyfile = signerfile;
425                                 if (!skkeys)
426                                         skkeys = sk_OPENSSL_STRING_new_null();
427                                 sk_OPENSSL_STRING_push(skkeys, keyfile);
428                                 keyfile = NULL;
429                                 }
430                         signerfile = *++args;
431                         }
432                 else if (!strcmp (*args, "-recip"))
433                         {
434                         if (!args[1])
435                                 goto argerr;
436                         if (operation == SMIME_ENCRYPT)
437                                 {
438                                 if (!encerts)
439                                         encerts = sk_X509_new_null();
440                                 cert = load_cert(bio_err,*++args,FORMAT_PEM,
441                                                 NULL, e,
442                                                 "recipient certificate file");
443                                 if (!cert)
444                                         goto end;
445                                 sk_X509_push(encerts, cert);
446                                 cert = NULL;
447                                 }
448                         else    
449                                 recipfile = *++args;
450                         }
451                 else if (!strcmp (*args, "-certsout"))
452                         {
453                         if (!args[1])
454                                 goto argerr;
455                         certsoutfile = *++args;
456                         }
457                 else if (!strcmp (*args, "-md"))
458                         {
459                         if (!args[1])
460                                 goto argerr;
461                         sign_md = EVP_get_digestbyname(*++args);
462                         if (sign_md == NULL)
463                                 {
464                                 BIO_printf(bio_err, "Unknown digest %s\n",
465                                                         *args);
466                                 goto argerr;
467                                 }
468                         }
469                 else if (!strcmp (*args, "-inkey"))
470                         {
471                         if (!args[1])   
472                                 goto argerr;
473                         /* If previous -inkey arument add signer to list */
474                         if (keyfile)
475                                 {
476                                 if (!signerfile)
477                                         {
478                                         BIO_puts(bio_err, "Illegal -inkey without -signer\n");
479                                         goto argerr;
480                                         }
481                                 if (!sksigners)
482                                         sksigners = sk_OPENSSL_STRING_new_null();
483                                 sk_OPENSSL_STRING_push(sksigners, signerfile);
484                                 signerfile = NULL;
485                                 if (!skkeys)
486                                         skkeys = sk_OPENSSL_STRING_new_null();
487                                 sk_OPENSSL_STRING_push(skkeys, keyfile);
488                                 }
489                         keyfile = *++args;
490                         }
491                 else if (!strcmp (*args, "-keyform"))
492                         {
493                         if (!args[1])
494                                 goto argerr;
495                         keyform = str2fmt(*++args);
496                         }
497                 else if (!strcmp (*args, "-keyopt"))
498                         {
499                         int keyidx = -1;
500                         if (!args[1])
501                                 goto argerr;
502                         if (operation == SMIME_ENCRYPT)
503                                 {
504                                 if (encerts)
505                                         keyidx += sk_X509_num(encerts);
506                                 }
507                         else
508                                 {
509                                 if (keyfile || signerfile)
510                                         keyidx++;
511                                 if (skkeys)
512                                         keyidx += sk_OPENSSL_STRING_num(skkeys);
513                                 }
514                         if (keyidx < 0)
515                                 {
516                                 BIO_printf(bio_err, "No key specified\n");
517                                 goto argerr;
518                                 }
519                         if (key_param == NULL || key_param->idx != keyidx)
520                                 {
521                                 cms_key_param *nparam;
522                                 nparam = OPENSSL_malloc(sizeof(cms_key_param));
523                                 nparam->idx = keyidx;
524                                 nparam->param = sk_OPENSSL_STRING_new_null();
525                                 nparam->next = NULL;
526                                 if (key_first == NULL)
527                                         key_first = nparam;
528                                 else
529                                         key_param->next = nparam;
530                                 key_param = nparam;
531                                 }
532                         sk_OPENSSL_STRING_push(key_param->param, *++args);
533                         }
534                 else if (!strcmp (*args, "-rctform"))
535                         {
536                         if (!args[1])
537                                 goto argerr;
538                         rctformat = str2fmt(*++args);
539                         }
540                 else if (!strcmp (*args, "-certfile"))
541                         {
542                         if (!args[1])
543                                 goto argerr;
544                         certfile = *++args;
545                         }
546                 else if (!strcmp (*args, "-CAfile"))
547                         {
548                         if (!args[1])
549                                 goto argerr;
550                         CAfile = *++args;
551                         }
552                 else if (!strcmp (*args, "-CApath"))
553                         {
554                         if (!args[1])
555                                 goto argerr;
556                         CApath = *++args;
557                         }
558                 else if (!strcmp (*args, "-in"))
559                         {
560                         if (!args[1])
561                                 goto argerr;
562                         infile = *++args;
563                         }
564                 else if (!strcmp (*args, "-inform"))
565                         {
566                         if (!args[1])
567                                 goto argerr;
568                         informat = str2fmt(*++args);
569                         }
570                 else if (!strcmp (*args, "-outform"))
571                         {
572                         if (!args[1])
573                                 goto argerr;
574                         outformat = str2fmt(*++args);
575                         }
576                 else if (!strcmp (*args, "-out"))
577                         {
578                         if (!args[1])
579                                 goto argerr;
580                         outfile = *++args;
581                         }
582                 else if (!strcmp (*args, "-content"))
583                         {
584                         if (!args[1])
585                                 goto argerr;
586                         contfile = *++args;
587                         }
588                 else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
589                         continue;
590                 else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
591                         badarg = 1;
592                 args++;
593                 }
594
595         if (((rr_allorfirst != -1) || rr_from) && !rr_to)
596                 {
597                 BIO_puts(bio_err, "No Signed Receipts Recipients\n");
598                 goto argerr;
599                 }
600
601         if (!(operation & SMIME_SIGNERS)  && (rr_to || rr_from))
602                 {
603                 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
604                 goto argerr;
605                 }
606         if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
607                 {
608                 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
609                 goto argerr;
610                 }
611
612         if (operation & SMIME_SIGNERS)
613                 {
614                 if (keyfile && !signerfile)
615                         {
616                         BIO_puts(bio_err, "Illegal -inkey without -signer\n");
617                         goto argerr;
618                         }
619                 /* Check to see if any final signer needs to be appended */
620                 if (signerfile)
621                         {
622                         if (!sksigners)
623                                 sksigners = sk_OPENSSL_STRING_new_null();
624                         sk_OPENSSL_STRING_push(sksigners, signerfile);
625                         if (!skkeys)
626                                 skkeys = sk_OPENSSL_STRING_new_null();
627                         if (!keyfile)
628                                 keyfile = signerfile;
629                         sk_OPENSSL_STRING_push(skkeys, keyfile);
630                         }
631                 if (!sksigners)
632                         {
633                         BIO_printf(bio_err, "No signer certificate specified\n");
634                         badarg = 1;
635                         }
636                 signerfile = NULL;
637                 keyfile = NULL;
638                 need_rand = 1;
639                 }
640
641         else if (operation == SMIME_DECRYPT)
642                 {
643                 if (!recipfile && !keyfile && !secret_key && !pwri_pass)
644                         {
645                         BIO_printf(bio_err, "No recipient certificate or key specified\n");
646                         badarg = 1;
647                         }
648                 }
649         else if (operation == SMIME_ENCRYPT)
650                 {
651                 if (!*args && !secret_key && !pwri_pass && !encerts)
652                         {
653                         BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
654                         badarg = 1;
655                         }
656                 need_rand = 1;
657                 }
658         else if (!operation)
659                 badarg = 1;
660
661         if (badarg)
662                 {
663                 argerr:
664                 BIO_printf (bio_err, "Usage cms [options] cert.pem ...\n");
665                 BIO_printf (bio_err, "where options are\n");
666                 BIO_printf (bio_err, "-encrypt       encrypt message\n");
667                 BIO_printf (bio_err, "-decrypt       decrypt encrypted message\n");
668                 BIO_printf (bio_err, "-sign          sign message\n");
669                 BIO_printf (bio_err, "-verify        verify signed message\n");
670                 BIO_printf (bio_err, "-cmsout        output CMS structure\n");
671 #ifndef OPENSSL_NO_DES
672                 BIO_printf (bio_err, "-des3          encrypt with triple DES\n");
673                 BIO_printf (bio_err, "-des           encrypt with DES\n");
674 #endif
675 #ifndef OPENSSL_NO_SEED
676                 BIO_printf (bio_err, "-seed          encrypt with SEED\n");
677 #endif
678 #ifndef OPENSSL_NO_RC2
679                 BIO_printf (bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
680                 BIO_printf (bio_err, "-rc2-64        encrypt with RC2-64\n");
681                 BIO_printf (bio_err, "-rc2-128       encrypt with RC2-128\n");
682 #endif
683 #ifndef OPENSSL_NO_AES
684                 BIO_printf (bio_err, "-aes128, -aes192, -aes256\n");
685                 BIO_printf (bio_err, "               encrypt PEM output with cbc aes\n");
686 #endif
687 #ifndef OPENSSL_NO_CAMELLIA
688                 BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n");
689                 BIO_printf (bio_err, "               encrypt PEM output with cbc camellia\n");
690 #endif
691                 BIO_printf (bio_err, "-nointern      don't search certificates in message for signer\n");
692                 BIO_printf (bio_err, "-nosigs        don't verify message signature\n");
693                 BIO_printf (bio_err, "-noverify      don't verify signers certificate\n");
694                 BIO_printf (bio_err, "-nocerts       don't include signers certificate when signing\n");
695                 BIO_printf (bio_err, "-nodetach      use opaque signing\n");
696                 BIO_printf (bio_err, "-noattr        don't include any signed attributes\n");
697                 BIO_printf (bio_err, "-binary        don't translate message to text\n");
698                 BIO_printf (bio_err, "-certfile file other certificates file\n");
699                 BIO_printf (bio_err, "-certsout file certificate output file\n");
700                 BIO_printf (bio_err, "-signer file   signer certificate file\n");
701                 BIO_printf (bio_err, "-recip  file   recipient certificate file for decryption\n");
702                 BIO_printf (bio_err, "-keyid         use subject key identifier\n");
703                 BIO_printf (bio_err, "-in file       input file\n");
704                 BIO_printf (bio_err, "-inform arg    input format SMIME (default), PEM or DER\n");
705                 BIO_printf (bio_err, "-inkey file    input private key (if not signer or recipient)\n");
706                 BIO_printf (bio_err, "-keyform arg   input private key format (PEM or ENGINE)\n");
707                 BIO_printf (bio_err, "-keyopt nm:v   set public key parameters\n");
708                 BIO_printf (bio_err, "-out file      output file\n");
709                 BIO_printf (bio_err, "-outform arg   output format SMIME (default), PEM or DER\n");
710                 BIO_printf (bio_err, "-content file  supply or override content for detached signature\n");
711                 BIO_printf (bio_err, "-to addr       to address\n");
712                 BIO_printf (bio_err, "-from ad       from address\n");
713                 BIO_printf (bio_err, "-subject s     subject\n");
714                 BIO_printf (bio_err, "-text          include or delete text MIME headers\n");
715                 BIO_printf (bio_err, "-CApath dir    trusted certificates directory\n");
716                 BIO_printf (bio_err, "-CAfile file   trusted certificates file\n");
717                 BIO_printf (bio_err, "-crl_check     check revocation status of signer's certificate using CRLs\n");
718                 BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
719 #ifndef OPENSSL_NO_ENGINE
720                 BIO_printf (bio_err, "-engine e      use engine e, possibly a hardware device.\n");
721 #endif
722                 BIO_printf (bio_err, "-passin arg    input file pass phrase source\n");
723                 BIO_printf(bio_err,  "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
724                 BIO_printf(bio_err,  "               load the file (or the files in the directory) into\n");
725                 BIO_printf(bio_err,  "               the random number generator\n");
726                 BIO_printf (bio_err, "cert.pem       recipient certificate(s) for encryption\n");
727                 goto end;
728                 }
729
730 #ifndef OPENSSL_NO_ENGINE
731         e = setup_engine(bio_err, engine, 0);
732 #endif
733
734         if (!app_passwd(bio_err, passargin, NULL, &passin, NULL))
735                 {
736                 BIO_printf(bio_err, "Error getting password\n");
737                 goto end;
738                 }
739
740         if (need_rand)
741                 {
742                 app_RAND_load_file(NULL, bio_err, (inrand != NULL));
743                 if (inrand != NULL)
744                         BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
745                                 app_RAND_load_files(inrand));
746                 }
747
748         ret = 2;
749
750         if (!(operation & SMIME_SIGNERS))
751                 flags &= ~CMS_DETACHED;
752
753         if (operation & SMIME_OP)
754                 {
755                 if (outformat == FORMAT_ASN1)
756                         outmode = "wb";
757                 }
758         else
759                 {
760                 if (flags & CMS_BINARY)
761                         outmode = "wb";
762                 }
763
764         if (operation & SMIME_IP)
765                 {
766                 if (informat == FORMAT_ASN1)
767                         inmode = "rb";
768                 }
769         else
770                 {
771                 if (flags & CMS_BINARY)
772                         inmode = "rb";
773                 }
774
775         if (operation == SMIME_ENCRYPT)
776                 {
777                 if (!cipher)
778                         {
779 #ifndef OPENSSL_NO_DES                  
780                         cipher = EVP_des_ede3_cbc();
781 #else
782                         BIO_printf(bio_err, "No cipher selected\n");
783                         goto end;
784 #endif
785                         }
786
787                 if (secret_key && !secret_keyid)
788                         {
789                         BIO_printf(bio_err, "No secret key id\n");
790                         goto end;
791                         }
792
793                 if (*args && !encerts)
794                         encerts = sk_X509_new_null();
795                 while (*args)
796                         {
797                         if (!(cert = load_cert(bio_err,*args,FORMAT_PEM,
798                                 NULL, e, "recipient certificate file")))
799                                 goto end;
800                         sk_X509_push(encerts, cert);
801                         cert = NULL;
802                         args++;
803                         }
804                 }
805
806         if (certfile)
807                 {
808                 if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
809                         e, "certificate file")))
810                         {
811                         ERR_print_errors(bio_err);
812                         goto end;
813                         }
814                 }
815
816         if (recipfile && (operation == SMIME_DECRYPT))
817                 {
818                 if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
819                         e, "recipient certificate file")))
820                         {
821                         ERR_print_errors(bio_err);
822                         goto end;
823                         }
824                 }
825
826         if (operation == SMIME_SIGN_RECEIPT)
827                 {
828                 if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM,NULL,
829                         e, "receipt signer certificate file")))
830                         {
831                         ERR_print_errors(bio_err);
832                         goto end;
833                         }
834                 }
835
836         if (operation == SMIME_DECRYPT)
837                 {
838                 if (!keyfile)
839                         keyfile = recipfile;
840                 }
841         else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT))
842                 {
843                 if (!keyfile)
844                         keyfile = signerfile;
845                 }
846         else keyfile = NULL;
847
848         if (keyfile)
849                 {
850                 key = load_key(bio_err, keyfile, keyform, 0, passin, e,
851                                "signing key file");
852                 if (!key)
853                         goto end;
854                 }
855
856         if (infile)
857                 {
858                 if (!(in = BIO_new_file(infile, inmode)))
859                         {
860                         BIO_printf (bio_err,
861                                  "Can't open input file %s\n", infile);
862                         goto end;
863                         }
864                 }
865         else
866                 in = BIO_new_fp(stdin, BIO_NOCLOSE);
867
868         if (operation & SMIME_IP)
869                 {
870                 if (informat == FORMAT_SMIME) 
871                         cms = SMIME_read_CMS(in, &indata);
872                 else if (informat == FORMAT_PEM) 
873                         cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
874                 else if (informat == FORMAT_ASN1) 
875                         cms = d2i_CMS_bio(in, NULL);
876                 else
877                         {
878                         BIO_printf(bio_err, "Bad input format for CMS file\n");
879                         goto end;
880                         }
881
882                 if (!cms)
883                         {
884                         BIO_printf(bio_err, "Error reading S/MIME message\n");
885                         goto end;
886                         }
887                 if (contfile)
888                         {
889                         BIO_free(indata);
890                         if (!(indata = BIO_new_file(contfile, "rb")))
891                                 {
892                                 BIO_printf(bio_err, "Can't read content file %s\n", contfile);
893                                 goto end;
894                                 }
895                         }
896                 if (certsoutfile)
897                         {
898                         STACK_OF(X509) *allcerts;
899                         allcerts = CMS_get1_certs(cms);
900                         if (!save_certs(certsoutfile, allcerts))
901                                 {
902                                 BIO_printf(bio_err,
903                                                 "Error writing certs to %s\n",
904                                                                 certsoutfile);
905                                 ret = 5;
906                                 goto end;
907                                 }
908                         sk_X509_pop_free(allcerts, X509_free);
909                         }
910                 }
911
912         if (rctfile)
913                 {
914                 char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
915                 if (!(rctin = BIO_new_file(rctfile, rctmode)))
916                         {
917                         BIO_printf (bio_err,
918                                  "Can't open receipt file %s\n", rctfile);
919                         goto end;
920                         }
921                 
922                 if (rctformat == FORMAT_SMIME) 
923                         rcms = SMIME_read_CMS(rctin, NULL);
924                 else if (rctformat == FORMAT_PEM) 
925                         rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
926                 else if (rctformat == FORMAT_ASN1) 
927                         rcms = d2i_CMS_bio(rctin, NULL);
928                 else
929                         {
930                         BIO_printf(bio_err, "Bad input format for receipt\n");
931                         goto end;
932                         }
933
934                 if (!rcms)
935                         {
936                         BIO_printf(bio_err, "Error reading receipt\n");
937                         goto end;
938                         }
939                 }
940
941         if (outfile)
942                 {
943                 if (!(out = BIO_new_file(outfile, outmode)))
944                         {
945                         BIO_printf (bio_err,
946                                  "Can't open output file %s\n", outfile);
947                         goto end;
948                         }
949                 }
950         else
951                 {
952                 out = BIO_new_fp(stdout, BIO_NOCLOSE);
953 #ifdef OPENSSL_SYS_VMS
954                 {
955                     BIO *tmpbio = BIO_new(BIO_f_linebuffer());
956                     out = BIO_push(tmpbio, out);
957                 }
958 #endif
959                 }
960
961         if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT))
962                 {
963                 if (!(store = setup_verify(bio_err, CAfile, CApath)))
964                         goto end;
965                 X509_STORE_set_verify_cb(store, cms_cb);
966                 if (vpm)
967                         X509_STORE_set1_param(store, vpm);
968                 }
969
970
971         ret = 3;
972
973         if (operation == SMIME_DATA_CREATE)
974                 {
975                 cms = CMS_data_create(in, flags);
976                 }
977         else if (operation == SMIME_DIGEST_CREATE)
978                 {
979                 cms = CMS_digest_create(in, sign_md, flags);
980                 }
981         else if (operation == SMIME_COMPRESS)
982                 {
983                 cms = CMS_compress(in, -1, flags);
984                 }
985         else if (operation == SMIME_ENCRYPT)
986                 {
987                 int i;
988                 flags |= CMS_PARTIAL;
989                 cms = CMS_encrypt(NULL, in, cipher, flags);
990                 if (!cms)
991                         goto end;
992                 for (i = 0; i < sk_X509_num(encerts); i++)
993                         {
994                         CMS_RecipientInfo *ri;
995                         cms_key_param *kparam;
996                         int tflags = flags;
997                         X509 *x = sk_X509_value(encerts, i);
998                         for(kparam = key_first; kparam; kparam = kparam->next)
999                                 {
1000                                 if(kparam->idx == i)
1001                                         {
1002                                         tflags |= CMS_KEY_PARAM;
1003                                         break;
1004                                         }
1005                                 }
1006                         ri = CMS_add1_recipient_cert(cms, x, tflags);
1007                         if (!ri)
1008                                 goto end;
1009                         if (kparam)
1010                                 {
1011                                 EVP_PKEY_CTX *pctx;
1012                                 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
1013                                 if (!cms_set_pkey_param(pctx, kparam->param))
1014                                         goto end;
1015                                 }
1016                         if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE
1017                                 && wrap_cipher)
1018                                 {
1019                                 EVP_CIPHER_CTX *wctx;
1020                                 wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
1021                                 EVP_EncryptInit_ex(wctx, wrap_cipher,
1022                                                         NULL, NULL, NULL);
1023                                 }
1024                         }
1025
1026                 if (secret_key)
1027                         {
1028                         if (!CMS_add0_recipient_key(cms, NID_undef, 
1029                                                 secret_key, secret_keylen,
1030                                                 secret_keyid, secret_keyidlen,
1031                                                 NULL, NULL, NULL))
1032                                 goto end;
1033                         /* NULL these because call absorbs them */
1034                         secret_key = NULL;
1035                         secret_keyid = NULL;
1036                         }
1037                 if (pwri_pass)
1038                         {
1039                         pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass);
1040                         if (!pwri_tmp)
1041                                 goto end;
1042                         if (!CMS_add0_recipient_password(cms,
1043                                                 -1, NID_undef, NID_undef,
1044                                                  pwri_tmp, -1, NULL))
1045                                 goto end;
1046                         pwri_tmp = NULL;
1047                         }
1048                 if (!(flags & CMS_STREAM))
1049                         {
1050                         if (!CMS_final(cms, in, NULL, flags))
1051                                 goto end;
1052                         }
1053                 }
1054         else if (operation == SMIME_ENCRYPTED_ENCRYPT)
1055                 {
1056                 cms = CMS_EncryptedData_encrypt(in, cipher,
1057                                                 secret_key, secret_keylen,
1058                                                 flags);
1059
1060                 }
1061         else if (operation == SMIME_SIGN_RECEIPT)
1062                 {
1063                 CMS_ContentInfo *srcms = NULL;
1064                 STACK_OF(CMS_SignerInfo) *sis;
1065                 CMS_SignerInfo *si;
1066                 sis = CMS_get0_SignerInfos(cms);
1067                 if (!sis)
1068                         goto end;
1069                 si = sk_CMS_SignerInfo_value(sis, 0);
1070                 srcms = CMS_sign_receipt(si, signer, key, other, flags);
1071                 if (!srcms)
1072                         goto end;
1073                 CMS_ContentInfo_free(cms);
1074                 cms = srcms;
1075                 }
1076         else if (operation & SMIME_SIGNERS)
1077                 {
1078                 int i;
1079                 /* If detached data content we enable streaming if
1080                  * S/MIME output format.
1081                  */
1082                 if (operation == SMIME_SIGN)
1083                         {
1084                                 
1085                         if (flags & CMS_DETACHED)
1086                                 {
1087                                 if (outformat == FORMAT_SMIME)
1088                                         flags |= CMS_STREAM;
1089                                 }
1090                         flags |= CMS_PARTIAL;
1091                         cms = CMS_sign(NULL, NULL, other, in, flags);
1092                         if (!cms)
1093                                 goto end;
1094                         if (econtent_type)
1095                                 CMS_set1_eContentType(cms, econtent_type);
1096
1097                         if (rr_to)
1098                                 {
1099                                 rr = make_receipt_request(rr_to, rr_allorfirst,
1100                                                                 rr_from);
1101                                 if (!rr)
1102                                         {
1103                                         BIO_puts(bio_err,
1104                                 "Signed Receipt Request Creation Error\n");
1105                                         goto end;
1106                                         }
1107                                 }
1108                         }
1109                 else
1110                         flags |= CMS_REUSE_DIGEST;
1111                 for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++)
1112                         {
1113                         CMS_SignerInfo *si;
1114                         cms_key_param *kparam;
1115                         int tflags = flags;
1116                         signerfile = sk_OPENSSL_STRING_value(sksigners, i);
1117                         keyfile = sk_OPENSSL_STRING_value(skkeys, i);
1118
1119                         signer = load_cert(bio_err, signerfile,FORMAT_PEM, NULL,
1120                                         e, "signer certificate");
1121                         if (!signer)
1122                                 goto end;
1123                         key = load_key(bio_err, keyfile, keyform, 0, passin, e,
1124                                "signing key file");
1125                         if (!key)
1126                                 goto end;
1127                         for(kparam = key_first; kparam; kparam = kparam->next)
1128                                 {
1129                                 if(kparam->idx == i)
1130                                         {
1131                                         tflags |= CMS_KEY_PARAM;
1132                                         break;
1133                                         }
1134                                 }
1135                         si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
1136                         if (!si)
1137                                 goto end;
1138                         if (kparam)
1139                                 {
1140                                 EVP_PKEY_CTX *pctx;
1141                                 pctx = CMS_SignerInfo_get0_pkey_ctx(si);
1142                                 if (!cms_set_pkey_param(pctx, kparam->param))
1143                                         goto end;
1144                                 }
1145                         if (rr && !CMS_add1_ReceiptRequest(si, rr))
1146                                 goto end;
1147                         X509_free(signer);
1148                         signer = NULL;
1149                         EVP_PKEY_free(key);
1150                         key = NULL;
1151                         }
1152                 /* If not streaming or resigning finalize structure */
1153                 if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM))
1154                         {
1155                         if (!CMS_final(cms, in, NULL, flags))
1156                                 goto end;
1157                         }
1158                 }
1159
1160         if (!cms)
1161                 {
1162                 BIO_printf(bio_err, "Error creating CMS structure\n");
1163                 goto end;
1164                 }
1165
1166         ret = 4;
1167         if (operation == SMIME_DECRYPT)
1168                 {
1169                 if (flags & CMS_DEBUG_DECRYPT)
1170                         CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
1171
1172                 if (secret_key)
1173                         {
1174                         if (!CMS_decrypt_set1_key(cms,
1175                                                 secret_key, secret_keylen,
1176                                                 secret_keyid, secret_keyidlen))
1177                                 {
1178                                 BIO_puts(bio_err,
1179                                         "Error decrypting CMS using secret key\n");
1180                                 goto end;
1181                                 }
1182                         }
1183
1184                 if (key)
1185                         {
1186                         if (!CMS_decrypt_set1_pkey(cms, key, recip))
1187                                 {
1188                                 BIO_puts(bio_err,
1189                                         "Error decrypting CMS using private key\n");
1190                                 goto end;
1191                                 }
1192                         }
1193
1194                 if (pwri_pass)
1195                         {
1196                         if (!CMS_decrypt_set1_password(cms, pwri_pass, -1))
1197                                 {
1198                                 BIO_puts(bio_err,
1199                                         "Error decrypting CMS using password\n");
1200                                 goto end;
1201                                 }
1202                         }
1203
1204                 if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags))
1205                         {
1206                         BIO_printf(bio_err, "Error decrypting CMS structure\n");
1207                         goto end;
1208                         }
1209                 }
1210         else if (operation == SMIME_DATAOUT)
1211                 {
1212                 if (!CMS_data(cms, out, flags))
1213                         goto end;
1214                 }
1215         else if (operation == SMIME_UNCOMPRESS)
1216                 {
1217                 if (!CMS_uncompress(cms, indata, out, flags))
1218                         goto end;
1219                 }
1220         else if (operation == SMIME_DIGEST_VERIFY)
1221                 {
1222                 if (CMS_digest_verify(cms, indata, out, flags) > 0)
1223                         BIO_printf(bio_err, "Verification successful\n");
1224                 else
1225                         {
1226                         BIO_printf(bio_err, "Verification failure\n");
1227                         goto end;
1228                         }
1229                 }
1230         else if (operation == SMIME_ENCRYPTED_DECRYPT)
1231                 {
1232                 if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
1233                                                 indata, out, flags))
1234                         goto end;
1235                 }
1236         else if (operation == SMIME_VERIFY)
1237                 {
1238                 if (CMS_verify(cms, other, store, indata, out, flags) > 0)
1239                         BIO_printf(bio_err, "Verification successful\n");
1240                 else
1241                         {
1242                         BIO_printf(bio_err, "Verification failure\n");
1243                         if (verify_retcode)
1244                                 ret = verify_err + 32;
1245                         goto end;
1246                         }
1247                 if (signerfile)
1248                         {
1249                         STACK_OF(X509) *signers;
1250                         signers = CMS_get0_signers(cms);
1251                         if (!save_certs(signerfile, signers))
1252                                 {
1253                                 BIO_printf(bio_err,
1254                                                 "Error writing signers to %s\n",
1255                                                                 signerfile);
1256                                 ret = 5;
1257                                 goto end;
1258                                 }
1259                         sk_X509_free(signers);
1260                         }
1261                 if (rr_print)
1262                         receipt_request_print(bio_err, cms);
1263                                         
1264                 }
1265         else if (operation == SMIME_VERIFY_RECEIPT)
1266                 {
1267                 if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
1268                         BIO_printf(bio_err, "Verification successful\n");
1269                 else
1270                         {
1271                         BIO_printf(bio_err, "Verification failure\n");
1272                         goto end;
1273                         }
1274                 }
1275         else
1276                 {
1277                 if (noout)
1278                         {
1279                         if (print)
1280                                 CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
1281                         }
1282                 else if (outformat == FORMAT_SMIME)
1283                         {
1284                         if (to)
1285                                 BIO_printf(out, "To: %s\n", to);
1286                         if (from)
1287                                 BIO_printf(out, "From: %s\n", from);
1288                         if (subject)
1289                                 BIO_printf(out, "Subject: %s\n", subject);
1290                         if (operation == SMIME_RESIGN)
1291                                 ret = SMIME_write_CMS(out, cms, indata, flags);
1292                         else
1293                                 ret = SMIME_write_CMS(out, cms, in, flags);
1294                         }
1295                 else if (outformat == FORMAT_PEM) 
1296                         ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
1297                 else if (outformat == FORMAT_ASN1) 
1298                         ret = i2d_CMS_bio_stream(out,cms, in, flags);
1299                 else
1300                         {
1301                         BIO_printf(bio_err, "Bad output format for CMS file\n");
1302                         goto end;
1303                         }
1304                 if (ret <= 0)
1305                         {
1306                         ret = 6;
1307                         goto end;
1308                         }
1309                 }
1310         ret = 0;
1311 end:
1312         if (ret)
1313                 ERR_print_errors(bio_err);
1314         if (need_rand)
1315                 app_RAND_write_file(NULL, bio_err);
1316         sk_X509_pop_free(encerts, X509_free);
1317         sk_X509_pop_free(other, X509_free);
1318         if (vpm)
1319                 X509_VERIFY_PARAM_free(vpm);
1320         if (sksigners)
1321                 sk_OPENSSL_STRING_free(sksigners);
1322         if (skkeys)
1323                 sk_OPENSSL_STRING_free(skkeys);
1324         if (secret_key)
1325                 OPENSSL_free(secret_key);
1326         if (secret_keyid)
1327                 OPENSSL_free(secret_keyid);
1328         if (pwri_tmp)
1329                 OPENSSL_free(pwri_tmp);
1330         if (econtent_type)
1331                 ASN1_OBJECT_free(econtent_type);
1332         if (rr)
1333                 CMS_ReceiptRequest_free(rr);
1334         if (rr_to)
1335                 sk_OPENSSL_STRING_free(rr_to);
1336         if (rr_from)
1337                 sk_OPENSSL_STRING_free(rr_from);
1338         for(key_param = key_first; key_param;)
1339                 {
1340                 cms_key_param *tparam;
1341                 sk_OPENSSL_STRING_free(key_param->param);
1342                 tparam = key_param->next;
1343                 OPENSSL_free(key_param);
1344                 key_param = tparam;
1345                 }
1346         X509_STORE_free(store);
1347         X509_free(cert);
1348         X509_free(recip);
1349         X509_free(signer);
1350         EVP_PKEY_free(key);
1351         CMS_ContentInfo_free(cms);
1352         CMS_ContentInfo_free(rcms);
1353         BIO_free(rctin);
1354         BIO_free(in);
1355         BIO_free(indata);
1356         BIO_free_all(out);
1357         if (passin) OPENSSL_free(passin);
1358         return (ret);
1359 }
1360
1361 static int save_certs(char *signerfile, STACK_OF(X509) *signers)
1362         {
1363         int i;
1364         BIO *tmp;
1365         if (!signerfile)
1366                 return 1;
1367         tmp = BIO_new_file(signerfile, "w");
1368         if (!tmp) return 0;
1369         for(i = 0; i < sk_X509_num(signers); i++)
1370                 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1371         BIO_free(tmp);
1372         return 1;
1373         }
1374         
1375
1376 /* Minimal callback just to output policy info (if any) */
1377
1378 static int cms_cb(int ok, X509_STORE_CTX *ctx)
1379         {
1380         int error;
1381
1382         error = X509_STORE_CTX_get_error(ctx);
1383
1384         verify_err = error;
1385
1386         if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
1387                 && ((error != X509_V_OK) || (ok != 2)))
1388                 return ok;
1389
1390         policies_print(NULL, ctx);
1391
1392         return ok;
1393
1394         }
1395
1396 static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1397         {
1398         STACK_OF(GENERAL_NAME) *gens;
1399         GENERAL_NAME *gen;
1400         int i, j;
1401         for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++)
1402                 {
1403                 gens = sk_GENERAL_NAMES_value(gns, i);
1404                 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++)
1405                         {
1406                         gen = sk_GENERAL_NAME_value(gens, j);
1407                         BIO_puts(out, "    ");
1408                         GENERAL_NAME_print(out, gen);
1409                         BIO_puts(out, "\n");
1410                         }
1411                 }
1412         return;
1413         }
1414
1415 static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1416         {
1417         STACK_OF(CMS_SignerInfo) *sis;
1418         CMS_SignerInfo *si;
1419         CMS_ReceiptRequest *rr;
1420         int allorfirst;
1421         STACK_OF(GENERAL_NAMES) *rto, *rlist;
1422         ASN1_STRING *scid;
1423         int i, rv;
1424         sis = CMS_get0_SignerInfos(cms);
1425         for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++)
1426                 {
1427                 si = sk_CMS_SignerInfo_value(sis, i);
1428                 rv = CMS_get1_ReceiptRequest(si, &rr);
1429                 BIO_printf(bio_err, "Signer %d:\n", i + 1);
1430                 if (rv == 0)
1431                         BIO_puts(bio_err, "  No Receipt Request\n");
1432                 else if (rv < 0)
1433                         {
1434                         BIO_puts(bio_err, "  Receipt Request Parse Error\n");
1435                         ERR_print_errors(bio_err);
1436                         }
1437                 else
1438                         {
1439                         char *id;
1440                         int idlen;
1441                         CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1442                                                         &rlist, &rto);
1443                         BIO_puts(out, "  Signed Content ID:\n");
1444                         idlen = ASN1_STRING_length(scid);
1445                         id = (char *)ASN1_STRING_data(scid);
1446                         BIO_dump_indent(out, id, idlen, 4);
1447                         BIO_puts(out, "  Receipts From");
1448                         if (rlist)
1449                                 {
1450                                 BIO_puts(out, " List:\n");
1451                                 gnames_stack_print(out, rlist);
1452                                 }
1453                         else if (allorfirst == 1)
1454                                 BIO_puts(out, ": First Tier\n");
1455                         else if (allorfirst == 0)
1456                                 BIO_puts(out, ": All\n");
1457                         else
1458                                 BIO_printf(out, " Unknown (%d)\n", allorfirst);
1459                         BIO_puts(out, "  Receipts To:\n");
1460                         gnames_stack_print(out, rto);
1461                         }
1462                 if (rr)
1463                         CMS_ReceiptRequest_free(rr);
1464                 }
1465         }
1466
1467 static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1468         {
1469         int i;
1470         STACK_OF(GENERAL_NAMES) *ret;
1471         GENERAL_NAMES *gens = NULL;
1472         GENERAL_NAME *gen = NULL;
1473         ret = sk_GENERAL_NAMES_new_null();
1474         if (!ret)
1475                 goto err;
1476         for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++)
1477                 {
1478                 char *str = sk_OPENSSL_STRING_value(ns, i);
1479                 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1480                 if (!gen)
1481                         goto err;
1482                 gens = GENERAL_NAMES_new();
1483                 if (!gens)
1484                         goto err;
1485                 if (!sk_GENERAL_NAME_push(gens, gen))
1486                         goto err;
1487                 gen = NULL;
1488                 if (!sk_GENERAL_NAMES_push(ret, gens))
1489                         goto err;
1490                 gens = NULL;
1491                 }
1492
1493         return ret;
1494
1495         err:
1496         if (ret)
1497                 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1498         if (gens)
1499                 GENERAL_NAMES_free(gens);
1500         if (gen)
1501                 GENERAL_NAME_free(gen);
1502         return NULL;
1503         }
1504
1505
1506 static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to,
1507                                                 int rr_allorfirst,
1508                                                 STACK_OF(OPENSSL_STRING) *rr_from)
1509         {
1510         STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
1511         CMS_ReceiptRequest *rr;
1512         rct_to = make_names_stack(rr_to);
1513         if (!rct_to)
1514                 goto err;
1515         if (rr_from)
1516                 {
1517                 rct_from = make_names_stack(rr_from);
1518                 if (!rct_from)
1519                         goto err;
1520                 }
1521         else
1522                 rct_from = NULL;
1523         rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1524                                                 rct_to);
1525         return rr;
1526         err:
1527         return NULL;
1528         }
1529
1530 static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
1531                         STACK_OF(OPENSSL_STRING) *param)
1532         {
1533         char *keyopt;
1534         int i;
1535         if (sk_OPENSSL_STRING_num(param) <= 0)
1536                 return 1;
1537         for (i = 0; i < sk_OPENSSL_STRING_num(param); i++)
1538                 {
1539                 keyopt = sk_OPENSSL_STRING_value(param, i);
1540                 if (pkey_ctrl_string(pctx, keyopt) <= 0)
1541                         {
1542                         BIO_printf(bio_err, "parameter error \"%s\"\n",
1543                                                 keyopt);
1544                         ERR_print_errors(bio_err);
1545                         return 0;
1546                         }
1547                 }
1548         return 1;
1549         }
1550
1551 #endif