1/* apps/cms.c */
2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project.
5 */
6/* ====================================================================
7 * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 *
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in
18 *    the documentation and/or other materials provided with the
19 *    distribution.
20 *
21 * 3. All advertising materials mentioning features or use of this
22 *    software must display the following acknowledgment:
23 *    "This product includes software developed by the OpenSSL Project
24 *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 *
26 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27 *    endorse or promote products derived from this software without
28 *    prior written permission. For written permission, please contact
29 *    licensing@OpenSSL.org.
30 *
31 * 5. Products derived from this software may not be called "OpenSSL"
32 *    nor may "OpenSSL" appear in their names without prior written
33 *    permission of the OpenSSL Project.
34 *
35 * 6. Redistributions of any form whatsoever must retain the following
36 *    acknowledgment:
37 *    "This product includes software developed by the OpenSSL Project
38 *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 *
40 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51 * OF THE POSSIBILITY OF SUCH DAMAGE.
52 * ====================================================================
53 */
54
55/* CMS utility function */
56
57#include <stdio.h>
58#include <string.h>
59#include "apps.h"
60
61#ifndef OPENSSL_NO_CMS
62
63# include <openssl/crypto.h>
64# include <openssl/pem.h>
65# include <openssl/err.h>
66# include <openssl/x509_vfy.h>
67# include <openssl/x509v3.h>
68# include <openssl/cms.h>
69
70# undef PROG
71# define PROG cms_main
72static int save_certs(char *signerfile, STACK_OF(X509) *signers);
73static int cms_cb(int ok, X509_STORE_CTX *ctx);
74static void receipt_request_print(BIO *out, CMS_ContentInfo *cms);
75static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
76                                                *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
77                                                *rr_from);
78static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
79                              STACK_OF(OPENSSL_STRING) *param);
80
81# define SMIME_OP        0x10
82# define SMIME_IP        0x20
83# define SMIME_SIGNERS   0x40
84# define SMIME_ENCRYPT           (1 | SMIME_OP)
85# define SMIME_DECRYPT           (2 | SMIME_IP)
86# define SMIME_SIGN              (3 | SMIME_OP | SMIME_SIGNERS)
87# define SMIME_VERIFY            (4 | SMIME_IP)
88# define SMIME_CMSOUT            (5 | SMIME_IP | SMIME_OP)
89# define SMIME_RESIGN            (6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
90# define SMIME_DATAOUT           (7 | SMIME_IP)
91# define SMIME_DATA_CREATE       (8 | SMIME_OP)
92# define SMIME_DIGEST_VERIFY     (9 | SMIME_IP)
93# define SMIME_DIGEST_CREATE     (10 | SMIME_OP)
94# define SMIME_UNCOMPRESS        (11 | SMIME_IP)
95# define SMIME_COMPRESS          (12 | SMIME_OP)
96# define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
97# define SMIME_ENCRYPTED_ENCRYPT (14 | SMIME_OP)
98# define SMIME_SIGN_RECEIPT      (15 | SMIME_IP | SMIME_OP)
99# define SMIME_VERIFY_RECEIPT    (16 | SMIME_IP)
100
101int verify_err = 0;
102
103typedef struct cms_key_param_st cms_key_param;
104
105struct cms_key_param_st {
106    int idx;
107    STACK_OF(OPENSSL_STRING) *param;
108    cms_key_param *next;
109};
110
111int MAIN(int, char **);
112
113int 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        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
166            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
167    }
168
169    if (!load_config(bio_err, NULL))
170        goto end;
171
172    while (!badarg && *args && *args[0] == '-') {
173        if (!strcmp(*args, "-encrypt"))
174            operation = SMIME_ENCRYPT;
175        else if (!strcmp(*args, "-decrypt"))
176            operation = SMIME_DECRYPT;
177        else if (!strcmp(*args, "-sign"))
178            operation = SMIME_SIGN;
179        else if (!strcmp(*args, "-sign_receipt"))
180            operation = SMIME_SIGN_RECEIPT;
181        else if (!strcmp(*args, "-resign"))
182            operation = SMIME_RESIGN;
183        else if (!strcmp(*args, "-verify"))
184            operation = SMIME_VERIFY;
185        else if (!strcmp(*args, "-verify_retcode"))
186            verify_retcode = 1;
187        else if (!strcmp(*args, "-verify_receipt")) {
188            operation = SMIME_VERIFY_RECEIPT;
189            if (!args[1])
190                goto argerr;
191            args++;
192            rctfile = *args;
193        } else if (!strcmp(*args, "-cmsout"))
194            operation = SMIME_CMSOUT;
195        else if (!strcmp(*args, "-data_out"))
196            operation = SMIME_DATAOUT;
197        else if (!strcmp(*args, "-data_create"))
198            operation = SMIME_DATA_CREATE;
199        else if (!strcmp(*args, "-digest_verify"))
200            operation = SMIME_DIGEST_VERIFY;
201        else if (!strcmp(*args, "-digest_create"))
202            operation = SMIME_DIGEST_CREATE;
203        else if (!strcmp(*args, "-compress"))
204            operation = SMIME_COMPRESS;
205        else if (!strcmp(*args, "-uncompress"))
206            operation = SMIME_UNCOMPRESS;
207        else if (!strcmp(*args, "-EncryptedData_decrypt"))
208            operation = SMIME_ENCRYPTED_DECRYPT;
209        else if (!strcmp(*args, "-EncryptedData_encrypt"))
210            operation = SMIME_ENCRYPTED_ENCRYPT;
211# ifndef OPENSSL_NO_DES
212        else if (!strcmp(*args, "-des3"))
213            cipher = EVP_des_ede3_cbc();
214        else if (!strcmp(*args, "-des"))
215            cipher = EVP_des_cbc();
216        else if (!strcmp(*args, "-des3-wrap"))
217            wrap_cipher = EVP_des_ede3_wrap();
218# endif
219# ifndef OPENSSL_NO_SEED
220        else if (!strcmp(*args, "-seed"))
221            cipher = EVP_seed_cbc();
222# endif
223# ifndef OPENSSL_NO_RC2
224        else if (!strcmp(*args, "-rc2-40"))
225            cipher = EVP_rc2_40_cbc();
226        else if (!strcmp(*args, "-rc2-128"))
227            cipher = EVP_rc2_cbc();
228        else if (!strcmp(*args, "-rc2-64"))
229            cipher = EVP_rc2_64_cbc();
230# endif
231# ifndef OPENSSL_NO_AES
232        else if (!strcmp(*args, "-aes128"))
233            cipher = EVP_aes_128_cbc();
234        else if (!strcmp(*args, "-aes192"))
235            cipher = EVP_aes_192_cbc();
236        else if (!strcmp(*args, "-aes256"))
237            cipher = EVP_aes_256_cbc();
238        else if (!strcmp(*args, "-aes128-wrap"))
239            wrap_cipher = EVP_aes_128_wrap();
240        else if (!strcmp(*args, "-aes192-wrap"))
241            wrap_cipher = EVP_aes_192_wrap();
242        else if (!strcmp(*args, "-aes256-wrap"))
243            wrap_cipher = EVP_aes_256_wrap();
244# endif
245# ifndef OPENSSL_NO_CAMELLIA
246        else if (!strcmp(*args, "-camellia128"))
247            cipher = EVP_camellia_128_cbc();
248        else if (!strcmp(*args, "-camellia192"))
249            cipher = EVP_camellia_192_cbc();
250        else if (!strcmp(*args, "-camellia256"))
251            cipher = EVP_camellia_256_cbc();
252# endif
253        else if (!strcmp(*args, "-debug_decrypt"))
254            flags |= CMS_DEBUG_DECRYPT;
255        else if (!strcmp(*args, "-text"))
256            flags |= CMS_TEXT;
257        else if (!strcmp(*args, "-nointern"))
258            flags |= CMS_NOINTERN;
259        else if (!strcmp(*args, "-noverify")
260                 || !strcmp(*args, "-no_signer_cert_verify"))
261            flags |= CMS_NO_SIGNER_CERT_VERIFY;
262        else if (!strcmp(*args, "-nocerts"))
263            flags |= CMS_NOCERTS;
264        else if (!strcmp(*args, "-noattr"))
265            flags |= CMS_NOATTR;
266        else if (!strcmp(*args, "-nodetach"))
267            flags &= ~CMS_DETACHED;
268        else if (!strcmp(*args, "-nosmimecap"))
269            flags |= CMS_NOSMIMECAP;
270        else if (!strcmp(*args, "-binary"))
271            flags |= CMS_BINARY;
272        else if (!strcmp(*args, "-keyid"))
273            flags |= CMS_USE_KEYID;
274        else if (!strcmp(*args, "-nosigs"))
275            flags |= CMS_NOSIGS;
276        else if (!strcmp(*args, "-no_content_verify"))
277            flags |= CMS_NO_CONTENT_VERIFY;
278        else if (!strcmp(*args, "-no_attr_verify"))
279            flags |= CMS_NO_ATTR_VERIFY;
280        else if (!strcmp(*args, "-stream"))
281            flags |= CMS_STREAM;
282        else if (!strcmp(*args, "-indef"))
283            flags |= CMS_STREAM;
284        else if (!strcmp(*args, "-noindef"))
285            flags &= ~CMS_STREAM;
286        else if (!strcmp(*args, "-nooldmime"))
287            flags |= CMS_NOOLDMIMETYPE;
288        else if (!strcmp(*args, "-crlfeol"))
289            flags |= CMS_CRLFEOL;
290        else if (!strcmp(*args, "-noout"))
291            noout = 1;
292        else if (!strcmp(*args, "-receipt_request_print"))
293            rr_print = 1;
294        else if (!strcmp(*args, "-receipt_request_all"))
295            rr_allorfirst = 0;
296        else if (!strcmp(*args, "-receipt_request_first"))
297            rr_allorfirst = 1;
298        else if (!strcmp(*args, "-receipt_request_from")) {
299            if (!args[1])
300                goto argerr;
301            args++;
302            if (!rr_from)
303                rr_from = sk_OPENSSL_STRING_new_null();
304            sk_OPENSSL_STRING_push(rr_from, *args);
305        } else if (!strcmp(*args, "-receipt_request_to")) {
306            if (!args[1])
307                goto argerr;
308            args++;
309            if (!rr_to)
310                rr_to = sk_OPENSSL_STRING_new_null();
311            sk_OPENSSL_STRING_push(rr_to, *args);
312        } else if (!strcmp(*args, "-print")) {
313            noout = 1;
314            print = 1;
315        } else if (!strcmp(*args, "-secretkey")) {
316            long ltmp;
317            if (!args[1])
318                goto argerr;
319            args++;
320            secret_key = string_to_hex(*args, &ltmp);
321            if (!secret_key) {
322                BIO_printf(bio_err, "Invalid key %s\n", *args);
323                goto argerr;
324            }
325            secret_keylen = (size_t)ltmp;
326        } else if (!strcmp(*args, "-secretkeyid")) {
327            long ltmp;
328            if (!args[1])
329                goto argerr;
330            args++;
331            secret_keyid = string_to_hex(*args, &ltmp);
332            if (!secret_keyid) {
333                BIO_printf(bio_err, "Invalid id %s\n", *args);
334                goto argerr;
335            }
336            secret_keyidlen = (size_t)ltmp;
337        } else if (!strcmp(*args, "-pwri_password")) {
338            if (!args[1])
339                goto argerr;
340            args++;
341            pwri_pass = (unsigned char *)*args;
342        } else if (!strcmp(*args, "-econtent_type")) {
343            if (!args[1])
344                goto argerr;
345            args++;
346            econtent_type = OBJ_txt2obj(*args, 0);
347            if (!econtent_type) {
348                BIO_printf(bio_err, "Invalid OID %s\n", *args);
349                goto argerr;
350            }
351        } else if (!strcmp(*args, "-rand")) {
352            if (!args[1])
353                goto argerr;
354            args++;
355            inrand = *args;
356            need_rand = 1;
357        }
358# ifndef OPENSSL_NO_ENGINE
359        else if (!strcmp(*args, "-engine")) {
360            if (!args[1])
361                goto argerr;
362            engine = *++args;
363        }
364# endif
365        else if (!strcmp(*args, "-passin")) {
366            if (!args[1])
367                goto argerr;
368            passargin = *++args;
369        } else if (!strcmp(*args, "-to")) {
370            if (!args[1])
371                goto argerr;
372            to = *++args;
373        } else if (!strcmp(*args, "-from")) {
374            if (!args[1])
375                goto argerr;
376            from = *++args;
377        } else if (!strcmp(*args, "-subject")) {
378            if (!args[1])
379                goto argerr;
380            subject = *++args;
381        } else if (!strcmp(*args, "-signer")) {
382            if (!args[1])
383                goto argerr;
384            /* If previous -signer argument add signer to list */
385
386            if (signerfile) {
387                if (!sksigners)
388                    sksigners = sk_OPENSSL_STRING_new_null();
389                sk_OPENSSL_STRING_push(sksigners, signerfile);
390                if (!keyfile)
391                    keyfile = signerfile;
392                if (!skkeys)
393                    skkeys = sk_OPENSSL_STRING_new_null();
394                sk_OPENSSL_STRING_push(skkeys, keyfile);
395                keyfile = NULL;
396            }
397            signerfile = *++args;
398        } else if (!strcmp(*args, "-recip")) {
399            if (!args[1])
400                goto argerr;
401            if (operation == SMIME_ENCRYPT) {
402                if (!encerts)
403                    encerts = sk_X509_new_null();
404                cert = load_cert(bio_err, *++args, FORMAT_PEM,
405                                 NULL, e, "recipient certificate file");
406                if (!cert)
407                    goto end;
408                sk_X509_push(encerts, cert);
409                cert = NULL;
410            } else
411                recipfile = *++args;
412        } else if (!strcmp(*args, "-certsout")) {
413            if (!args[1])
414                goto argerr;
415            certsoutfile = *++args;
416        } else if (!strcmp(*args, "-md")) {
417            if (!args[1])
418                goto argerr;
419            sign_md = EVP_get_digestbyname(*++args);
420            if (sign_md == NULL) {
421                BIO_printf(bio_err, "Unknown digest %s\n", *args);
422                goto argerr;
423            }
424        } else if (!strcmp(*args, "-inkey")) {
425            if (!args[1])
426                goto argerr;
427            /* If previous -inkey arument add signer to list */
428            if (keyfile) {
429                if (!signerfile) {
430                    BIO_puts(bio_err, "Illegal -inkey without -signer\n");
431                    goto argerr;
432                }
433                if (!sksigners)
434                    sksigners = sk_OPENSSL_STRING_new_null();
435                sk_OPENSSL_STRING_push(sksigners, signerfile);
436                signerfile = NULL;
437                if (!skkeys)
438                    skkeys = sk_OPENSSL_STRING_new_null();
439                sk_OPENSSL_STRING_push(skkeys, keyfile);
440            }
441            keyfile = *++args;
442        } else if (!strcmp(*args, "-keyform")) {
443            if (!args[1])
444                goto argerr;
445            keyform = str2fmt(*++args);
446        } else if (!strcmp(*args, "-keyopt")) {
447            int keyidx = -1;
448            if (!args[1])
449                goto argerr;
450            if (operation == SMIME_ENCRYPT) {
451                if (encerts)
452                    keyidx += sk_X509_num(encerts);
453            } else {
454                if (keyfile || signerfile)
455                    keyidx++;
456                if (skkeys)
457                    keyidx += sk_OPENSSL_STRING_num(skkeys);
458            }
459            if (keyidx < 0) {
460                BIO_printf(bio_err, "No key specified\n");
461                goto argerr;
462            }
463            if (key_param == NULL || key_param->idx != keyidx) {
464                cms_key_param *nparam;
465                nparam = OPENSSL_malloc(sizeof(cms_key_param));
466                if (!nparam) {
467                    BIO_printf(bio_err, "Out of memory\n");
468                    goto argerr;
469                }
470                nparam->idx = keyidx;
471                nparam->param = sk_OPENSSL_STRING_new_null();
472                nparam->next = NULL;
473                if (key_first == NULL)
474                    key_first = nparam;
475                else
476                    key_param->next = nparam;
477                key_param = nparam;
478            }
479            sk_OPENSSL_STRING_push(key_param->param, *++args);
480        } else if (!strcmp(*args, "-rctform")) {
481            if (!args[1])
482                goto argerr;
483            rctformat = str2fmt(*++args);
484        } else if (!strcmp(*args, "-certfile")) {
485            if (!args[1])
486                goto argerr;
487            certfile = *++args;
488        } else if (!strcmp(*args, "-CAfile")) {
489            if (!args[1])
490                goto argerr;
491            CAfile = *++args;
492        } else if (!strcmp(*args, "-CApath")) {
493            if (!args[1])
494                goto argerr;
495            CApath = *++args;
496        } else if (!strcmp(*args, "-in")) {
497            if (!args[1])
498                goto argerr;
499            infile = *++args;
500        } else if (!strcmp(*args, "-inform")) {
501            if (!args[1])
502                goto argerr;
503            informat = str2fmt(*++args);
504        } else if (!strcmp(*args, "-outform")) {
505            if (!args[1])
506                goto argerr;
507            outformat = str2fmt(*++args);
508        } else if (!strcmp(*args, "-out")) {
509            if (!args[1])
510                goto argerr;
511            outfile = *++args;
512        } else if (!strcmp(*args, "-content")) {
513            if (!args[1])
514                goto argerr;
515            contfile = *++args;
516        } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm))
517            continue;
518        else if ((cipher = EVP_get_cipherbyname(*args + 1)) == NULL)
519            badarg = 1;
520        args++;
521    }
522
523    if (((rr_allorfirst != -1) || rr_from) && !rr_to) {
524        BIO_puts(bio_err, "No Signed Receipts Recipients\n");
525        goto argerr;
526    }
527
528    if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) {
529        BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
530        goto argerr;
531    }
532    if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
533        BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
534        goto argerr;
535    }
536
537    if (operation & SMIME_SIGNERS) {
538        if (keyfile && !signerfile) {
539            BIO_puts(bio_err, "Illegal -inkey without -signer\n");
540            goto argerr;
541        }
542        /* Check to see if any final signer needs to be appended */
543        if (signerfile) {
544            if (!sksigners)
545                sksigners = sk_OPENSSL_STRING_new_null();
546            sk_OPENSSL_STRING_push(sksigners, signerfile);
547            if (!skkeys)
548                skkeys = sk_OPENSSL_STRING_new_null();
549            if (!keyfile)
550                keyfile = signerfile;
551            sk_OPENSSL_STRING_push(skkeys, keyfile);
552        }
553        if (!sksigners) {
554            BIO_printf(bio_err, "No signer certificate specified\n");
555            badarg = 1;
556        }
557        signerfile = NULL;
558        keyfile = NULL;
559        need_rand = 1;
560    }
561
562    else if (operation == SMIME_DECRYPT) {
563        if (!recipfile && !keyfile && !secret_key && !pwri_pass) {
564            BIO_printf(bio_err,
565                       "No recipient certificate or key specified\n");
566            badarg = 1;
567        }
568    } else if (operation == SMIME_ENCRYPT) {
569        if (!*args && !secret_key && !pwri_pass && !encerts) {
570            BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
571            badarg = 1;
572        }
573        need_rand = 1;
574    } else if (!operation)
575        badarg = 1;
576
577    if (badarg) {
578 argerr:
579        BIO_printf(bio_err, "Usage cms [options] cert.pem ...\n");
580        BIO_printf(bio_err, "where options are\n");
581        BIO_printf(bio_err, "-encrypt       encrypt message\n");
582        BIO_printf(bio_err, "-decrypt       decrypt encrypted message\n");
583        BIO_printf(bio_err, "-sign          sign message\n");
584        BIO_printf(bio_err, "-verify        verify signed message\n");
585        BIO_printf(bio_err, "-cmsout        output CMS structure\n");
586# ifndef OPENSSL_NO_DES
587        BIO_printf(bio_err, "-des3          encrypt with triple DES\n");
588        BIO_printf(bio_err, "-des           encrypt with DES\n");
589# endif
590# ifndef OPENSSL_NO_SEED
591        BIO_printf(bio_err, "-seed          encrypt with SEED\n");
592# endif
593# ifndef OPENSSL_NO_RC2
594        BIO_printf(bio_err, "-rc2-40        encrypt with RC2-40 (default)\n");
595        BIO_printf(bio_err, "-rc2-64        encrypt with RC2-64\n");
596        BIO_printf(bio_err, "-rc2-128       encrypt with RC2-128\n");
597# endif
598# ifndef OPENSSL_NO_AES
599        BIO_printf(bio_err, "-aes128, -aes192, -aes256\n");
600        BIO_printf(bio_err,
601                   "               encrypt PEM output with cbc aes\n");
602# endif
603# ifndef OPENSSL_NO_CAMELLIA
604        BIO_printf(bio_err, "-camellia128, -camellia192, -camellia256\n");
605        BIO_printf(bio_err,
606                   "               encrypt PEM output with cbc camellia\n");
607# endif
608        BIO_printf(bio_err,
609                   "-nointern      don't search certificates in message for signer\n");
610        BIO_printf(bio_err,
611                   "-nosigs        don't verify message signature\n");
612        BIO_printf(bio_err,
613                   "-noverify      don't verify signers certificate\n");
614        BIO_printf(bio_err,
615                   "-nocerts       don't include signers certificate when signing\n");
616        BIO_printf(bio_err, "-nodetach      use opaque signing\n");
617        BIO_printf(bio_err,
618                   "-noattr        don't include any signed attributes\n");
619        BIO_printf(bio_err,
620                   "-binary        don't translate message to text\n");
621        BIO_printf(bio_err, "-certfile file other certificates file\n");
622        BIO_printf(bio_err, "-certsout file certificate output file\n");
623        BIO_printf(bio_err, "-signer file   signer certificate file\n");
624        BIO_printf(bio_err,
625                   "-recip  file   recipient certificate file for decryption\n");
626        BIO_printf(bio_err, "-keyid         use subject key identifier\n");
627        BIO_printf(bio_err, "-in file       input file\n");
628        BIO_printf(bio_err,
629                   "-inform arg    input format SMIME (default), PEM or DER\n");
630        BIO_printf(bio_err,
631                   "-inkey file    input private key (if not signer or recipient)\n");
632        BIO_printf(bio_err,
633                   "-keyform arg   input private key format (PEM or ENGINE)\n");
634        BIO_printf(bio_err, "-keyopt nm:v   set public key parameters\n");
635        BIO_printf(bio_err, "-out file      output file\n");
636        BIO_printf(bio_err,
637                   "-outform arg   output format SMIME (default), PEM or DER\n");
638        BIO_printf(bio_err,
639                   "-content file  supply or override content for detached signature\n");
640        BIO_printf(bio_err, "-to addr       to address\n");
641        BIO_printf(bio_err, "-from ad       from address\n");
642        BIO_printf(bio_err, "-subject s     subject\n");
643        BIO_printf(bio_err,
644                   "-text          include or delete text MIME headers\n");
645        BIO_printf(bio_err,
646                   "-CApath dir    trusted certificates directory\n");
647        BIO_printf(bio_err, "-CAfile file   trusted certificates file\n");
648        BIO_printf(bio_err,
649                   "-no_alt_chains only ever use the first certificate chain found\n");
650        BIO_printf(bio_err,
651                   "-crl_check     check revocation status of signer's certificate using CRLs\n");
652        BIO_printf(bio_err,
653                   "-crl_check_all check revocation status of signer's certificate chain using CRLs\n");
654# ifndef OPENSSL_NO_ENGINE
655        BIO_printf(bio_err,
656                   "-engine e      use engine e, possibly a hardware device.\n");
657# endif
658        BIO_printf(bio_err, "-passin arg    input file pass phrase source\n");
659        BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
660                   LIST_SEPARATOR_CHAR);
661        BIO_printf(bio_err,
662                   "               load the file (or the files in the directory) into\n");
663        BIO_printf(bio_err, "               the random number generator\n");
664        BIO_printf(bio_err,
665                   "cert.pem       recipient certificate(s) for encryption\n");
666        goto end;
667    }
668# ifndef OPENSSL_NO_ENGINE
669    e = setup_engine(bio_err, engine, 0);
670# endif
671
672    if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
673        BIO_printf(bio_err, "Error getting password\n");
674        goto end;
675    }
676
677    if (need_rand) {
678        app_RAND_load_file(NULL, bio_err, (inrand != NULL));
679        if (inrand != NULL)
680            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
681                       app_RAND_load_files(inrand));
682    }
683
684    ret = 2;
685
686    if (!(operation & SMIME_SIGNERS))
687        flags &= ~CMS_DETACHED;
688
689    if (operation & SMIME_OP) {
690        if (outformat == FORMAT_ASN1)
691            outmode = "wb";
692    } else {
693        if (flags & CMS_BINARY)
694            outmode = "wb";
695    }
696
697    if (operation & SMIME_IP) {
698        if (informat == FORMAT_ASN1)
699            inmode = "rb";
700    } else {
701        if (flags & CMS_BINARY)
702            inmode = "rb";
703    }
704
705    if (operation == SMIME_ENCRYPT) {
706        if (!cipher) {
707# ifndef OPENSSL_NO_DES
708            cipher = EVP_des_ede3_cbc();
709# else
710            BIO_printf(bio_err, "No cipher selected\n");
711            goto end;
712# endif
713        }
714
715        if (secret_key && !secret_keyid) {
716            BIO_printf(bio_err, "No secret key id\n");
717            goto end;
718        }
719
720        if (*args && !encerts)
721            encerts = sk_X509_new_null();
722        while (*args) {
723            if (!(cert = load_cert(bio_err, *args, FORMAT_PEM,
724                                   NULL, e, "recipient certificate file")))
725                goto end;
726            sk_X509_push(encerts, cert);
727            cert = NULL;
728            args++;
729        }
730    }
731
732    if (certfile) {
733        if (!(other = load_certs(bio_err, certfile, FORMAT_PEM, NULL,
734                                 e, "certificate file"))) {
735            ERR_print_errors(bio_err);
736            goto end;
737        }
738    }
739
740    if (recipfile && (operation == SMIME_DECRYPT)) {
741        if (!(recip = load_cert(bio_err, recipfile, FORMAT_PEM, NULL,
742                                e, "recipient certificate file"))) {
743            ERR_print_errors(bio_err);
744            goto end;
745        }
746    }
747
748    if (operation == SMIME_SIGN_RECEIPT) {
749        if (!(signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,
750                                 e, "receipt signer certificate file"))) {
751            ERR_print_errors(bio_err);
752            goto end;
753        }
754    }
755
756    if (operation == SMIME_DECRYPT) {
757        if (!keyfile)
758            keyfile = recipfile;
759    } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) {
760        if (!keyfile)
761            keyfile = signerfile;
762    } else
763        keyfile = NULL;
764
765    if (keyfile) {
766        key = load_key(bio_err, keyfile, keyform, 0, passin, e,
767                       "signing key file");
768        if (!key)
769            goto end;
770    }
771
772    if (infile) {
773        if (!(in = BIO_new_file(infile, inmode))) {
774            BIO_printf(bio_err, "Can't open input file %s\n", infile);
775            goto end;
776        }
777    } else
778        in = BIO_new_fp(stdin, BIO_NOCLOSE);
779
780    if (operation & SMIME_IP) {
781        if (informat == FORMAT_SMIME)
782            cms = SMIME_read_CMS(in, &indata);
783        else if (informat == FORMAT_PEM)
784            cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
785        else if (informat == FORMAT_ASN1)
786            cms = d2i_CMS_bio(in, NULL);
787        else {
788            BIO_printf(bio_err, "Bad input format for CMS file\n");
789            goto end;
790        }
791
792        if (!cms) {
793            BIO_printf(bio_err, "Error reading S/MIME message\n");
794            goto end;
795        }
796        if (contfile) {
797            BIO_free(indata);
798            if (!(indata = BIO_new_file(contfile, "rb"))) {
799                BIO_printf(bio_err, "Can't read content file %s\n", contfile);
800                goto end;
801            }
802        }
803        if (certsoutfile) {
804            STACK_OF(X509) *allcerts;
805            allcerts = CMS_get1_certs(cms);
806            if (!save_certs(certsoutfile, allcerts)) {
807                BIO_printf(bio_err,
808                           "Error writing certs to %s\n", certsoutfile);
809                ret = 5;
810                goto end;
811            }
812            sk_X509_pop_free(allcerts, X509_free);
813        }
814    }
815
816    if (rctfile) {
817        char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
818        if (!(rctin = BIO_new_file(rctfile, rctmode))) {
819            BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
820            goto end;
821        }
822
823        if (rctformat == FORMAT_SMIME)
824            rcms = SMIME_read_CMS(rctin, NULL);
825        else if (rctformat == FORMAT_PEM)
826            rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
827        else if (rctformat == FORMAT_ASN1)
828            rcms = d2i_CMS_bio(rctin, NULL);
829        else {
830            BIO_printf(bio_err, "Bad input format for receipt\n");
831            goto end;
832        }
833
834        if (!rcms) {
835            BIO_printf(bio_err, "Error reading receipt\n");
836            goto end;
837        }
838    }
839
840    if (outfile) {
841        if (!(out = BIO_new_file(outfile, outmode))) {
842            BIO_printf(bio_err, "Can't open output file %s\n", outfile);
843            goto end;
844        }
845    } else {
846        out = BIO_new_fp(stdout, BIO_NOCLOSE);
847# ifdef OPENSSL_SYS_VMS
848        {
849            BIO *tmpbio = BIO_new(BIO_f_linebuffer());
850            out = BIO_push(tmpbio, out);
851        }
852# endif
853    }
854
855    if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) {
856        if (!(store = setup_verify(bio_err, CAfile, CApath)))
857            goto end;
858        X509_STORE_set_verify_cb(store, cms_cb);
859        if (vpm)
860            X509_STORE_set1_param(store, vpm);
861    }
862
863    ret = 3;
864
865    if (operation == SMIME_DATA_CREATE) {
866        cms = CMS_data_create(in, flags);
867    } else if (operation == SMIME_DIGEST_CREATE) {
868        cms = CMS_digest_create(in, sign_md, flags);
869    } else if (operation == SMIME_COMPRESS) {
870        cms = CMS_compress(in, -1, flags);
871    } else if (operation == SMIME_ENCRYPT) {
872        int i;
873        flags |= CMS_PARTIAL;
874        cms = CMS_encrypt(NULL, in, cipher, flags);
875        if (!cms)
876            goto end;
877        for (i = 0; i < sk_X509_num(encerts); i++) {
878            CMS_RecipientInfo *ri;
879            cms_key_param *kparam;
880            int tflags = flags;
881            X509 *x = sk_X509_value(encerts, i);
882            for (kparam = key_first; kparam; kparam = kparam->next) {
883                if (kparam->idx == i) {
884                    tflags |= CMS_KEY_PARAM;
885                    break;
886                }
887            }
888            ri = CMS_add1_recipient_cert(cms, x, tflags);
889            if (!ri)
890                goto end;
891            if (kparam) {
892                EVP_PKEY_CTX *pctx;
893                pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
894                if (!cms_set_pkey_param(pctx, kparam->param))
895                    goto end;
896            }
897            if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE
898                && wrap_cipher) {
899                EVP_CIPHER_CTX *wctx;
900                wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
901                EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL);
902            }
903        }
904
905        if (secret_key) {
906            if (!CMS_add0_recipient_key(cms, NID_undef,
907                                        secret_key, secret_keylen,
908                                        secret_keyid, secret_keyidlen,
909                                        NULL, NULL, NULL))
910                goto end;
911            /* NULL these because call absorbs them */
912            secret_key = NULL;
913            secret_keyid = NULL;
914        }
915        if (pwri_pass) {
916            pwri_tmp = (unsigned char *)BUF_strdup((char *)pwri_pass);
917            if (!pwri_tmp)
918                goto end;
919            if (!CMS_add0_recipient_password(cms,
920                                             -1, NID_undef, NID_undef,
921                                             pwri_tmp, -1, NULL))
922                goto end;
923            pwri_tmp = NULL;
924        }
925        if (!(flags & CMS_STREAM)) {
926            if (!CMS_final(cms, in, NULL, flags))
927                goto end;
928        }
929    } else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
930        cms = CMS_EncryptedData_encrypt(in, cipher,
931                                        secret_key, secret_keylen, flags);
932
933    } else if (operation == SMIME_SIGN_RECEIPT) {
934        CMS_ContentInfo *srcms = NULL;
935        STACK_OF(CMS_SignerInfo) *sis;
936        CMS_SignerInfo *si;
937        sis = CMS_get0_SignerInfos(cms);
938        if (!sis)
939            goto end;
940        si = sk_CMS_SignerInfo_value(sis, 0);
941        srcms = CMS_sign_receipt(si, signer, key, other, flags);
942        if (!srcms)
943            goto end;
944        CMS_ContentInfo_free(cms);
945        cms = srcms;
946    } else if (operation & SMIME_SIGNERS) {
947        int i;
948        /*
949         * If detached data content we enable streaming if S/MIME output
950         * format.
951         */
952        if (operation == SMIME_SIGN) {
953
954            if (flags & CMS_DETACHED) {
955                if (outformat == FORMAT_SMIME)
956                    flags |= CMS_STREAM;
957            }
958            flags |= CMS_PARTIAL;
959            cms = CMS_sign(NULL, NULL, other, in, flags);
960            if (!cms)
961                goto end;
962            if (econtent_type)
963                CMS_set1_eContentType(cms, econtent_type);
964
965            if (rr_to) {
966                rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
967                if (!rr) {
968                    BIO_puts(bio_err,
969                             "Signed Receipt Request Creation Error\n");
970                    goto end;
971                }
972            }
973        } else
974            flags |= CMS_REUSE_DIGEST;
975        for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
976            CMS_SignerInfo *si;
977            cms_key_param *kparam;
978            int tflags = flags;
979            signerfile = sk_OPENSSL_STRING_value(sksigners, i);
980            keyfile = sk_OPENSSL_STRING_value(skkeys, i);
981
982            signer = load_cert(bio_err, signerfile, FORMAT_PEM, NULL,
983                               e, "signer certificate");
984            if (!signer)
985                goto end;
986            key = load_key(bio_err, keyfile, keyform, 0, passin, e,
987                           "signing key file");
988            if (!key)
989                goto end;
990            for (kparam = key_first; kparam; kparam = kparam->next) {
991                if (kparam->idx == i) {
992                    tflags |= CMS_KEY_PARAM;
993                    break;
994                }
995            }
996            si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
997            if (!si)
998                goto end;
999            if (kparam) {
1000                EVP_PKEY_CTX *pctx;
1001                pctx = CMS_SignerInfo_get0_pkey_ctx(si);
1002                if (!cms_set_pkey_param(pctx, kparam->param))
1003                    goto end;
1004            }
1005            if (rr && !CMS_add1_ReceiptRequest(si, rr))
1006                goto end;
1007            X509_free(signer);
1008            signer = NULL;
1009            EVP_PKEY_free(key);
1010            key = NULL;
1011        }
1012        /* If not streaming or resigning finalize structure */
1013        if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
1014            if (!CMS_final(cms, in, NULL, flags))
1015                goto end;
1016        }
1017    }
1018
1019    if (!cms) {
1020        BIO_printf(bio_err, "Error creating CMS structure\n");
1021        goto end;
1022    }
1023
1024    ret = 4;
1025    if (operation == SMIME_DECRYPT) {
1026        if (flags & CMS_DEBUG_DECRYPT)
1027            CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
1028
1029        if (secret_key) {
1030            if (!CMS_decrypt_set1_key(cms,
1031                                      secret_key, secret_keylen,
1032                                      secret_keyid, secret_keyidlen)) {
1033                BIO_puts(bio_err, "Error decrypting CMS using secret key\n");
1034                goto end;
1035            }
1036        }
1037
1038        if (key) {
1039            if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
1040                BIO_puts(bio_err, "Error decrypting CMS using private key\n");
1041                goto end;
1042            }
1043        }
1044
1045        if (pwri_pass) {
1046            if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
1047                BIO_puts(bio_err, "Error decrypting CMS using password\n");
1048                goto end;
1049            }
1050        }
1051
1052        if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) {
1053            BIO_printf(bio_err, "Error decrypting CMS structure\n");
1054            goto end;
1055        }
1056    } else if (operation == SMIME_DATAOUT) {
1057        if (!CMS_data(cms, out, flags))
1058            goto end;
1059    } else if (operation == SMIME_UNCOMPRESS) {
1060        if (!CMS_uncompress(cms, indata, out, flags))
1061            goto end;
1062    } else if (operation == SMIME_DIGEST_VERIFY) {
1063        if (CMS_digest_verify(cms, indata, out, flags) > 0)
1064            BIO_printf(bio_err, "Verification successful\n");
1065        else {
1066            BIO_printf(bio_err, "Verification failure\n");
1067            goto end;
1068        }
1069    } else if (operation == SMIME_ENCRYPTED_DECRYPT) {
1070        if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
1071                                       indata, out, flags))
1072            goto end;
1073    } else if (operation == SMIME_VERIFY) {
1074        if (CMS_verify(cms, other, store, indata, out, flags) > 0)
1075            BIO_printf(bio_err, "Verification successful\n");
1076        else {
1077            BIO_printf(bio_err, "Verification failure\n");
1078            if (verify_retcode)
1079                ret = verify_err + 32;
1080            goto end;
1081        }
1082        if (signerfile) {
1083            STACK_OF(X509) *signers;
1084            signers = CMS_get0_signers(cms);
1085            if (!save_certs(signerfile, signers)) {
1086                BIO_printf(bio_err,
1087                           "Error writing signers to %s\n", signerfile);
1088                ret = 5;
1089                goto end;
1090            }
1091            sk_X509_free(signers);
1092        }
1093        if (rr_print)
1094            receipt_request_print(bio_err, cms);
1095
1096    } else if (operation == SMIME_VERIFY_RECEIPT) {
1097        if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
1098            BIO_printf(bio_err, "Verification successful\n");
1099        else {
1100            BIO_printf(bio_err, "Verification failure\n");
1101            goto end;
1102        }
1103    } else {
1104        if (noout) {
1105            if (print)
1106                CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
1107        } else if (outformat == FORMAT_SMIME) {
1108            if (to)
1109                BIO_printf(out, "To: %s\n", to);
1110            if (from)
1111                BIO_printf(out, "From: %s\n", from);
1112            if (subject)
1113                BIO_printf(out, "Subject: %s\n", subject);
1114            if (operation == SMIME_RESIGN)
1115                ret = SMIME_write_CMS(out, cms, indata, flags);
1116            else
1117                ret = SMIME_write_CMS(out, cms, in, flags);
1118        } else if (outformat == FORMAT_PEM)
1119            ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
1120        else if (outformat == FORMAT_ASN1)
1121            ret = i2d_CMS_bio_stream(out, cms, in, flags);
1122        else {
1123            BIO_printf(bio_err, "Bad output format for CMS file\n");
1124            goto end;
1125        }
1126        if (ret <= 0) {
1127            ret = 6;
1128            goto end;
1129        }
1130    }
1131    ret = 0;
1132 end:
1133    if (ret)
1134        ERR_print_errors(bio_err);
1135    if (need_rand)
1136        app_RAND_write_file(NULL, bio_err);
1137    sk_X509_pop_free(encerts, X509_free);
1138    sk_X509_pop_free(other, X509_free);
1139    if (vpm)
1140        X509_VERIFY_PARAM_free(vpm);
1141    if (sksigners)
1142        sk_OPENSSL_STRING_free(sksigners);
1143    if (skkeys)
1144        sk_OPENSSL_STRING_free(skkeys);
1145    if (secret_key)
1146        OPENSSL_free(secret_key);
1147    if (secret_keyid)
1148        OPENSSL_free(secret_keyid);
1149    if (pwri_tmp)
1150        OPENSSL_free(pwri_tmp);
1151    if (econtent_type)
1152        ASN1_OBJECT_free(econtent_type);
1153    if (rr)
1154        CMS_ReceiptRequest_free(rr);
1155    if (rr_to)
1156        sk_OPENSSL_STRING_free(rr_to);
1157    if (rr_from)
1158        sk_OPENSSL_STRING_free(rr_from);
1159    for (key_param = key_first; key_param;) {
1160        cms_key_param *tparam;
1161        sk_OPENSSL_STRING_free(key_param->param);
1162        tparam = key_param->next;
1163        OPENSSL_free(key_param);
1164        key_param = tparam;
1165    }
1166    X509_STORE_free(store);
1167    X509_free(cert);
1168    X509_free(recip);
1169    X509_free(signer);
1170    EVP_PKEY_free(key);
1171    CMS_ContentInfo_free(cms);
1172    CMS_ContentInfo_free(rcms);
1173    BIO_free(rctin);
1174    BIO_free(in);
1175    BIO_free(indata);
1176    BIO_free_all(out);
1177    if (passin)
1178        OPENSSL_free(passin);
1179    return (ret);
1180}
1181
1182static int save_certs(char *signerfile, STACK_OF(X509) *signers)
1183{
1184    int i;
1185    BIO *tmp;
1186    if (!signerfile)
1187        return 1;
1188    tmp = BIO_new_file(signerfile, "w");
1189    if (!tmp)
1190        return 0;
1191    for (i = 0; i < sk_X509_num(signers); i++)
1192        PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1193    BIO_free(tmp);
1194    return 1;
1195}
1196
1197/* Minimal callback just to output policy info (if any) */
1198
1199static int cms_cb(int ok, X509_STORE_CTX *ctx)
1200{
1201    int error;
1202
1203    error = X509_STORE_CTX_get_error(ctx);
1204
1205    verify_err = error;
1206
1207    if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
1208        && ((error != X509_V_OK) || (ok != 2)))
1209        return ok;
1210
1211    policies_print(NULL, ctx);
1212
1213    return ok;
1214
1215}
1216
1217static void gnames_stack_print(BIO *out, STACK_OF(GENERAL_NAMES) *gns)
1218{
1219    STACK_OF(GENERAL_NAME) *gens;
1220    GENERAL_NAME *gen;
1221    int i, j;
1222    for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1223        gens = sk_GENERAL_NAMES_value(gns, i);
1224        for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1225            gen = sk_GENERAL_NAME_value(gens, j);
1226            BIO_puts(out, "    ");
1227            GENERAL_NAME_print(out, gen);
1228            BIO_puts(out, "\n");
1229        }
1230    }
1231    return;
1232}
1233
1234static void receipt_request_print(BIO *out, CMS_ContentInfo *cms)
1235{
1236    STACK_OF(CMS_SignerInfo) *sis;
1237    CMS_SignerInfo *si;
1238    CMS_ReceiptRequest *rr;
1239    int allorfirst;
1240    STACK_OF(GENERAL_NAMES) *rto, *rlist;
1241    ASN1_STRING *scid;
1242    int i, rv;
1243    sis = CMS_get0_SignerInfos(cms);
1244    for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1245        si = sk_CMS_SignerInfo_value(sis, i);
1246        rv = CMS_get1_ReceiptRequest(si, &rr);
1247        BIO_printf(bio_err, "Signer %d:\n", i + 1);
1248        if (rv == 0)
1249            BIO_puts(bio_err, "  No Receipt Request\n");
1250        else if (rv < 0) {
1251            BIO_puts(bio_err, "  Receipt Request Parse Error\n");
1252            ERR_print_errors(bio_err);
1253        } else {
1254            char *id;
1255            int idlen;
1256            CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1257                                           &rlist, &rto);
1258            BIO_puts(out, "  Signed Content ID:\n");
1259            idlen = ASN1_STRING_length(scid);
1260            id = (char *)ASN1_STRING_data(scid);
1261            BIO_dump_indent(out, id, idlen, 4);
1262            BIO_puts(out, "  Receipts From");
1263            if (rlist) {
1264                BIO_puts(out, " List:\n");
1265                gnames_stack_print(out, rlist);
1266            } else if (allorfirst == 1)
1267                BIO_puts(out, ": First Tier\n");
1268            else if (allorfirst == 0)
1269                BIO_puts(out, ": All\n");
1270            else
1271                BIO_printf(out, " Unknown (%d)\n", allorfirst);
1272            BIO_puts(out, "  Receipts To:\n");
1273            gnames_stack_print(out, rto);
1274        }
1275        if (rr)
1276            CMS_ReceiptRequest_free(rr);
1277    }
1278}
1279
1280static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1281{
1282    int i;
1283    STACK_OF(GENERAL_NAMES) *ret;
1284    GENERAL_NAMES *gens = NULL;
1285    GENERAL_NAME *gen = NULL;
1286    ret = sk_GENERAL_NAMES_new_null();
1287    if (!ret)
1288        goto err;
1289    for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1290        char *str = sk_OPENSSL_STRING_value(ns, i);
1291        gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1292        if (!gen)
1293            goto err;
1294        gens = GENERAL_NAMES_new();
1295        if (!gens)
1296            goto err;
1297        if (!sk_GENERAL_NAME_push(gens, gen))
1298            goto err;
1299        gen = NULL;
1300        if (!sk_GENERAL_NAMES_push(ret, gens))
1301            goto err;
1302        gens = NULL;
1303    }
1304
1305    return ret;
1306
1307 err:
1308    if (ret)
1309        sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1310    if (gens)
1311        GENERAL_NAMES_free(gens);
1312    if (gen)
1313        GENERAL_NAME_free(gen);
1314    return NULL;
1315}
1316
1317static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING)
1318                                                *rr_to, int rr_allorfirst, STACK_OF(OPENSSL_STRING)
1319                                                *rr_from)
1320{
1321    STACK_OF(GENERAL_NAMES) *rct_to, *rct_from;
1322    CMS_ReceiptRequest *rr;
1323    rct_to = make_names_stack(rr_to);
1324    if (!rct_to)
1325        goto err;
1326    if (rr_from) {
1327        rct_from = make_names_stack(rr_from);
1328        if (!rct_from)
1329            goto err;
1330    } else
1331        rct_from = NULL;
1332    rr = CMS_ReceiptRequest_create0(NULL, -1, rr_allorfirst, rct_from,
1333                                    rct_to);
1334    return rr;
1335 err:
1336    return NULL;
1337}
1338
1339static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
1340                              STACK_OF(OPENSSL_STRING) *param)
1341{
1342    char *keyopt;
1343    int i;
1344    if (sk_OPENSSL_STRING_num(param) <= 0)
1345        return 1;
1346    for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
1347        keyopt = sk_OPENSSL_STRING_value(param, i);
1348        if (pkey_ctrl_string(pctx, keyopt) <= 0) {
1349            BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
1350            ERR_print_errors(bio_err);
1351            return 0;
1352        }
1353    }
1354    return 1;
1355}
1356
1357#endif
1358