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