1 /*
2 * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 /* CMS utility function */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include "apps.h"
15 #include "progs.h"
16
17 #include <openssl/crypto.h>
18 #include <openssl/pem.h>
19 #include <openssl/err.h>
20 #include <openssl/x509_vfy.h>
21 #include <openssl/x509v3.h>
22 #include <openssl/cms.h>
23
24 static int save_certs(char *signerfile, STACK_OF(X509) *signers);
25 static int cms_cb(int ok, X509_STORE_CTX *ctx);
26 static void receipt_request_print(CMS_ContentInfo *cms);
27 static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
28 STACK_OF(OPENSSL_STRING) *rr_from);
29 static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
30 STACK_OF(OPENSSL_STRING) *param);
31
32 #define SMIME_OP 0x100
33 #define SMIME_IP 0x200
34 #define SMIME_SIGNERS 0x400
35 #define SMIME_ENCRYPT (1 | SMIME_OP)
36 #define SMIME_DECRYPT (2 | SMIME_IP)
37 #define SMIME_SIGN (3 | SMIME_OP | SMIME_SIGNERS)
38 #define SMIME_VERIFY (4 | SMIME_IP)
39 #define SMIME_RESIGN (5 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
40 #define SMIME_SIGN_RECEIPT (6 | SMIME_IP | SMIME_OP)
41 #define SMIME_VERIFY_RECEIPT (7 | SMIME_IP)
42 #define SMIME_DIGEST_CREATE (8 | SMIME_OP)
43 #define SMIME_DIGEST_VERIFY (9 | SMIME_IP)
44 #define SMIME_COMPRESS (10 | SMIME_OP)
45 #define SMIME_UNCOMPRESS (11 | SMIME_IP)
46 #define SMIME_ENCRYPTED_ENCRYPT (12 | SMIME_OP)
47 #define SMIME_ENCRYPTED_DECRYPT (13 | SMIME_IP)
48 #define SMIME_DATA_CREATE (14 | SMIME_OP)
49 #define SMIME_DATA_OUT (15 | SMIME_IP)
50 #define SMIME_CMSOUT (16 | SMIME_IP | SMIME_OP)
51
52 static int verify_err = 0;
53
54 typedef struct cms_key_param_st cms_key_param;
55
56 struct cms_key_param_st {
57 int idx;
58 STACK_OF(OPENSSL_STRING) *param;
59 cms_key_param *next;
60 };
61
62 typedef enum OPTION_choice {
63 OPT_COMMON,
64 OPT_INFORM,
65 OPT_OUTFORM,
66 OPT_IN,
67 OPT_OUT,
68 OPT_ENCRYPT,
69 OPT_DECRYPT,
70 OPT_SIGN,
71 OPT_CADES,
72 OPT_SIGN_RECEIPT,
73 OPT_RESIGN,
74 OPT_VERIFY,
75 OPT_VERIFY_RETCODE,
76 OPT_VERIFY_RECEIPT,
77 OPT_CMSOUT,
78 OPT_DATA_OUT,
79 OPT_DATA_CREATE,
80 OPT_DIGEST_VERIFY,
81 OPT_DIGEST,
82 OPT_DIGEST_CREATE,
83 OPT_COMPRESS,
84 OPT_UNCOMPRESS,
85 OPT_ED_DECRYPT,
86 OPT_ED_ENCRYPT,
87 OPT_DEBUG_DECRYPT,
88 OPT_TEXT,
89 OPT_ASCIICRLF,
90 OPT_NOINTERN,
91 OPT_NOVERIFY,
92 OPT_NOCERTS,
93 OPT_NOATTR,
94 OPT_NODETACH,
95 OPT_NOSMIMECAP,
96 OPT_NO_SIGNING_TIME,
97 OPT_BINARY,
98 OPT_KEYID,
99 OPT_NOSIGS,
100 OPT_NO_CONTENT_VERIFY,
101 OPT_NO_ATTR_VERIFY,
102 OPT_INDEF,
103 OPT_NOINDEF,
104 OPT_CRLFEOL,
105 OPT_NOOUT,
106 OPT_RR_PRINT,
107 OPT_RR_ALL,
108 OPT_RR_FIRST,
109 OPT_RCTFORM,
110 OPT_CERTFILE,
111 OPT_CAFILE,
112 OPT_CAPATH,
113 OPT_CASTORE,
114 OPT_NOCAPATH,
115 OPT_NOCAFILE,
116 OPT_NOCASTORE,
117 OPT_CONTENT,
118 OPT_PRINT,
119 OPT_NAMEOPT,
120 OPT_SECRETKEY,
121 OPT_SECRETKEYID,
122 OPT_PWRI_PASSWORD,
123 OPT_ECONTENT_TYPE,
124 OPT_PASSIN,
125 OPT_TO,
126 OPT_FROM,
127 OPT_SUBJECT,
128 OPT_SIGNER,
129 OPT_RECIP,
130 OPT_CERTSOUT,
131 OPT_MD,
132 OPT_INKEY,
133 OPT_KEYFORM,
134 OPT_KEYOPT,
135 OPT_RR_FROM,
136 OPT_RR_TO,
137 OPT_AES128_WRAP,
138 OPT_AES192_WRAP,
139 OPT_AES256_WRAP,
140 OPT_3DES_WRAP,
141 OPT_WRAP,
142 OPT_ENGINE,
143 OPT_R_ENUM,
144 OPT_PROV_ENUM,
145 OPT_CONFIG,
146 OPT_V_ENUM,
147 OPT_CIPHER,
148 OPT_ORIGINATOR
149 } OPTION_CHOICE;
150
151 const OPTIONS cms_options[] = {
152 { OPT_HELP_STR, 1, '-', "Usage: %s [options] [cert...]\n" },
153 { "help", OPT_HELP, '-', "Display this summary" },
154
155 OPT_SECTION("General"),
156 { "in", OPT_IN, '<', "Input file" },
157 { "out", OPT_OUT, '>', "Output file" },
158 OPT_CONFIG_OPTION,
159
160 OPT_SECTION("Operation"),
161 { "encrypt", OPT_ENCRYPT, '-', "Encrypt message" },
162 { "decrypt", OPT_DECRYPT, '-', "Decrypt encrypted message" },
163 { "sign", OPT_SIGN, '-', "Sign message" },
164 { "verify", OPT_VERIFY, '-', "Verify signed message" },
165 { "resign", OPT_RESIGN, '-', "Resign a signed message" },
166 { "sign_receipt", OPT_SIGN_RECEIPT, '-',
167 "Generate a signed receipt for a message" },
168 { "verify_receipt", OPT_VERIFY_RECEIPT, '<',
169 "Verify receipts; exit if receipt signatures do not verify" },
170 { "digest", OPT_DIGEST, 's', "Sign a pre-computed digest in hex notation" },
171 { "digest_create", OPT_DIGEST_CREATE, '-',
172 "Create a CMS \"DigestedData\" object" },
173 { "digest_verify", OPT_DIGEST_VERIFY, '-',
174 "Verify a CMS \"DigestedData\" object and output it" },
175 { "compress", OPT_COMPRESS, '-', "Create a CMS \"CompressedData\" object" },
176 { "uncompress", OPT_UNCOMPRESS, '-',
177 "Uncompress a CMS \"CompressedData\" object" },
178 { "EncryptedData_encrypt", OPT_ED_ENCRYPT, '-',
179 "Create CMS \"EncryptedData\" object using symmetric key" },
180 { "EncryptedData_decrypt", OPT_ED_DECRYPT, '-',
181 "Decrypt CMS \"EncryptedData\" object using symmetric key" },
182 { "data_create", OPT_DATA_CREATE, '-', "Create a CMS \"Data\" object" },
183 { "data_out", OPT_DATA_OUT, '-', "Copy CMS \"Data\" object to output" },
184 { "cmsout", OPT_CMSOUT, '-', "Output CMS structure" },
185
186 OPT_SECTION("File format"),
187 { "inform", OPT_INFORM, 'c', "Input format SMIME (default), PEM or DER" },
188 { "outform", OPT_OUTFORM, 'c',
189 "Output format SMIME (default), PEM or DER" },
190 { "rctform", OPT_RCTFORM, 'F', "Receipt file format" },
191 { "stream", OPT_INDEF, '-', "Enable CMS streaming" },
192 { "indef", OPT_INDEF, '-', "Same as -stream" },
193 { "noindef", OPT_NOINDEF, '-', "Disable CMS streaming" },
194 { "binary", OPT_BINARY, '-',
195 "Treat input as binary: do not translate to canonical form" },
196 { "crlfeol", OPT_CRLFEOL, '-',
197 "Use CRLF as EOL termination instead of LF only" },
198 { "asciicrlf", OPT_ASCIICRLF, '-',
199 "Perform CRLF canonicalisation when signing" },
200
201 OPT_SECTION("Keys and passwords"),
202 { "pwri_password", OPT_PWRI_PASSWORD, 's',
203 "Specific password for recipient" },
204 { "secretkey", OPT_SECRETKEY, 's',
205 "Use specified hex-encoded key to decrypt/encrypt recipients or content" },
206 { "secretkeyid", OPT_SECRETKEYID, 's',
207 "Identity of the -secretkey for CMS \"KEKRecipientInfo\" object" },
208 { "inkey", OPT_INKEY, 's',
209 "Input private key (if not signer or recipient)" },
210 { "passin", OPT_PASSIN, 's', "Input file pass phrase source" },
211 { "keyopt", OPT_KEYOPT, 's', "Set public key parameters as n:v pairs" },
212 { "keyform", OPT_KEYFORM, 'f',
213 "Input private key format (ENGINE, other values ignored)" },
214 #ifndef OPENSSL_NO_ENGINE
215 { "engine", OPT_ENGINE, 's', "Use engine e, possibly a hardware device" },
216 #endif
217 OPT_PROV_OPTIONS,
218 OPT_R_OPTIONS,
219
220 OPT_SECTION("Encryption and decryption"),
221 { "originator", OPT_ORIGINATOR, 's', "Originator certificate file" },
222 { "recip", OPT_RECIP, '<', "Recipient cert file" },
223 { "cert...", OPT_PARAM, '.',
224 "Recipient certs (optional; used only when encrypting)" },
225 { "", OPT_CIPHER, '-',
226 "The encryption algorithm to use (any supported cipher)" },
227 { "wrap", OPT_WRAP, 's',
228 "Key wrap algorithm to use when encrypting with key agreement" },
229 { "aes128-wrap", OPT_AES128_WRAP, '-', "Use AES128 to wrap key" },
230 { "aes192-wrap", OPT_AES192_WRAP, '-', "Use AES192 to wrap key" },
231 { "aes256-wrap", OPT_AES256_WRAP, '-', "Use AES256 to wrap key" },
232 { "des3-wrap", OPT_3DES_WRAP, '-', "Use 3DES-EDE to wrap key" },
233 { "debug_decrypt", OPT_DEBUG_DECRYPT, '-',
234 "Disable MMA protection, return error if no recipient found (see doc)" },
235
236 OPT_SECTION("Signing"),
237 { "md", OPT_MD, 's', "Digest algorithm to use" },
238 { "signer", OPT_SIGNER, 's', "Signer certificate input file" },
239 { "certfile", OPT_CERTFILE, '<',
240 "Extra signer and intermediate CA certificates to include when signing" },
241 { OPT_MORE_STR, 0, 0,
242 "or to use as preferred signer certs and for chain building when verifying" },
243 { "cades", OPT_CADES, '-',
244 "Include signingCertificate attribute (CAdES-BES)" },
245 { "nodetach", OPT_NODETACH, '-', "Use opaque signing" },
246 { "nocerts", OPT_NOCERTS, '-',
247 "Don't include signer's certificate when signing" },
248 { "noattr", OPT_NOATTR, '-', "Don't include any signed attributes" },
249 { "nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute" },
250 { "no_signing_time", OPT_NO_SIGNING_TIME, '-',
251 "Omit the signing time attribute" },
252 { "receipt_request_all", OPT_RR_ALL, '-',
253 "When signing, create a receipt request for all recipients" },
254 { "receipt_request_first", OPT_RR_FIRST, '-',
255 "When signing, create a receipt request for first recipient" },
256 { "receipt_request_from", OPT_RR_FROM, 's',
257 "Create signed receipt request with specified email address" },
258 { "receipt_request_to", OPT_RR_TO, 's',
259 "Create signed receipt targeted to specified address" },
260
261 OPT_SECTION("Verification"),
262 { "signer", OPT_DUP, 's', "Signer certificate(s) output file" },
263 { "content", OPT_CONTENT, '<',
264 "Supply or override content for detached signature" },
265 { "no_content_verify", OPT_NO_CONTENT_VERIFY, '-',
266 "Do not verify signed content signatures" },
267 { "no_attr_verify", OPT_NO_ATTR_VERIFY, '-',
268 "Do not verify signed attribute signatures" },
269 { "nosigs", OPT_NOSIGS, '-', "Don't verify message signature" },
270 { "noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate" },
271 { "nointern", OPT_NOINTERN, '-',
272 "Don't search certificates in message for signer" },
273 { "cades", OPT_DUP, '-', "Check signingCertificate (CAdES-BES)" },
274 { "verify_retcode", OPT_VERIFY_RETCODE, '-',
275 "Exit non-zero on verification failure" },
276 { "CAfile", OPT_CAFILE, '<', "Trusted certificates file" },
277 { "CApath", OPT_CAPATH, '/', "Trusted certificates directory" },
278 { "CAstore", OPT_CASTORE, ':', "Trusted certificates store URI" },
279 { "no-CAfile", OPT_NOCAFILE, '-',
280 "Do not load the default certificates file" },
281 { "no-CApath", OPT_NOCAPATH, '-',
282 "Do not load certificates from the default certificates directory" },
283 { "no-CAstore", OPT_NOCASTORE, '-',
284 "Do not load certificates from the default certificates store" },
285
286 OPT_SECTION("Output"),
287 { "keyid", OPT_KEYID, '-', "Use subject key identifier" },
288 { "econtent_type", OPT_ECONTENT_TYPE, 's', "OID for external content" },
289 { "text", OPT_TEXT, '-', "Include or delete text MIME headers" },
290 { "certsout", OPT_CERTSOUT, '>', "Certificate output file" },
291 { "to", OPT_TO, 's', "To address" },
292 { "from", OPT_FROM, 's', "From address" },
293 { "subject", OPT_SUBJECT, 's', "Subject" },
294
295 OPT_SECTION("Printing"),
296 { "noout", OPT_NOOUT, '-',
297 "For the -cmsout operation do not output the parsed CMS structure" },
298 { "print", OPT_PRINT, '-',
299 "For the -cmsout operation print out all fields of the CMS structure" },
300 { "nameopt", OPT_NAMEOPT, 's',
301 "For the -print option specifies various strings printing options" },
302 { "receipt_request_print", OPT_RR_PRINT, '-', "Print CMS Receipt Request" },
303
304 OPT_V_OPTIONS,
305 { NULL }
306 };
307
load_content_info(int informat,BIO * in,int flags,BIO ** indata,const char * name)308 static CMS_ContentInfo *load_content_info(int informat, BIO *in, int flags,
309 BIO **indata, const char *name)
310 {
311 CMS_ContentInfo *ret, *ci;
312
313 ret = CMS_ContentInfo_new_ex(app_get0_libctx(), app_get0_propq());
314 if (ret == NULL) {
315 BIO_printf(bio_err, "Error allocating CMS_contentinfo\n");
316 return NULL;
317 }
318 switch (informat) {
319 case FORMAT_SMIME:
320 ci = SMIME_read_CMS_ex(in, flags, indata, &ret);
321 break;
322 case FORMAT_PEM:
323 ci = PEM_read_bio_CMS(in, &ret, NULL, NULL);
324 break;
325 case FORMAT_ASN1:
326 ci = d2i_CMS_bio(in, &ret);
327 break;
328 default:
329 BIO_printf(bio_err, "Bad input format for %s\n", name);
330 goto err;
331 }
332 if (ci == NULL) {
333 BIO_printf(bio_err, "Error reading %s Content Info\n", name);
334 goto err;
335 }
336 return ret;
337 err:
338 CMS_ContentInfo_free(ret);
339 return NULL;
340 }
341
cms_main(int argc,char ** argv)342 int cms_main(int argc, char **argv)
343 {
344 CONF *conf = NULL;
345 ASN1_OBJECT *econtent_type = NULL;
346 BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
347 CMS_ContentInfo *cms = NULL, *rcms = NULL;
348 CMS_ReceiptRequest *rr = NULL;
349 ENGINE *e = NULL;
350 EVP_PKEY *key = NULL;
351 EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL;
352 EVP_MD *sign_md = NULL;
353 STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
354 STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
355 STACK_OF(X509) *encerts = sk_X509_new_null(), *other = NULL;
356 X509 *cert = NULL, *recip = NULL, *signer = NULL, *originator = NULL;
357 X509_STORE *store = NULL;
358 X509_VERIFY_PARAM *vpm = X509_VERIFY_PARAM_new();
359 char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
360 const char *CAfile = NULL, *CApath = NULL, *CAstore = NULL;
361 char *certsoutfile = NULL, *digestname = NULL, *wrapname = NULL;
362 int noCAfile = 0, noCApath = 0, noCAstore = 0;
363 char *digesthex = NULL;
364 unsigned char *digestbin = NULL;
365 long digestlen = 0;
366 char *infile = NULL, *outfile = NULL, *rctfile = NULL;
367 char *passinarg = NULL, *passin = NULL, *signerfile = NULL;
368 char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL;
369 char *to = NULL, *from = NULL, *subject = NULL, *prog;
370 cms_key_param *key_first = NULL, *key_param = NULL;
371 int flags = CMS_DETACHED, binary_files = 0;
372 int noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
373 int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
374 int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1;
375 int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_UNDEF;
376 size_t secret_keylen = 0, secret_keyidlen = 0;
377 unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
378 unsigned char *secret_key = NULL, *secret_keyid = NULL;
379 long ltmp;
380 const char *mime_eol = "\n";
381 OPTION_CHOICE o;
382 OSSL_LIB_CTX *libctx = app_get0_libctx();
383
384 if (encerts == NULL || vpm == NULL)
385 goto end;
386
387 opt_set_unknown_name("cipher");
388 prog = opt_init(argc, argv, cms_options);
389 while ((o = opt_next()) != OPT_EOF) {
390 switch (o) {
391 case OPT_EOF:
392 case OPT_ERR:
393 opthelp:
394 BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
395 goto end;
396 case OPT_HELP:
397 opt_help(cms_options);
398 ret = 0;
399 goto end;
400 case OPT_INFORM:
401 if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat))
402 goto opthelp;
403 break;
404 case OPT_OUTFORM:
405 if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat))
406 goto opthelp;
407 break;
408 case OPT_OUT:
409 outfile = opt_arg();
410 break;
411
412 case OPT_ENCRYPT:
413 operation = SMIME_ENCRYPT;
414 break;
415 case OPT_DECRYPT:
416 operation = SMIME_DECRYPT;
417 break;
418 case OPT_SIGN:
419 operation = SMIME_SIGN;
420 break;
421 case OPT_VERIFY:
422 operation = SMIME_VERIFY;
423 break;
424 case OPT_RESIGN:
425 operation = SMIME_RESIGN;
426 break;
427 case OPT_SIGN_RECEIPT:
428 operation = SMIME_SIGN_RECEIPT;
429 break;
430 case OPT_VERIFY_RECEIPT:
431 operation = SMIME_VERIFY_RECEIPT;
432 rctfile = opt_arg();
433 break;
434 case OPT_VERIFY_RETCODE:
435 verify_retcode = 1;
436 break;
437 case OPT_DIGEST_CREATE:
438 operation = SMIME_DIGEST_CREATE;
439 break;
440 case OPT_DIGEST:
441 digesthex = opt_arg();
442 break;
443 case OPT_DIGEST_VERIFY:
444 operation = SMIME_DIGEST_VERIFY;
445 break;
446 case OPT_COMPRESS:
447 operation = SMIME_COMPRESS;
448 break;
449 case OPT_UNCOMPRESS:
450 operation = SMIME_UNCOMPRESS;
451 break;
452 case OPT_ED_ENCRYPT:
453 operation = SMIME_ENCRYPTED_ENCRYPT;
454 break;
455 case OPT_ED_DECRYPT:
456 operation = SMIME_ENCRYPTED_DECRYPT;
457 break;
458 case OPT_DATA_CREATE:
459 operation = SMIME_DATA_CREATE;
460 break;
461 case OPT_DATA_OUT:
462 operation = SMIME_DATA_OUT;
463 break;
464 case OPT_CMSOUT:
465 operation = SMIME_CMSOUT;
466 break;
467
468 case OPT_DEBUG_DECRYPT:
469 flags |= CMS_DEBUG_DECRYPT;
470 break;
471 case OPT_TEXT:
472 flags |= CMS_TEXT;
473 break;
474 case OPT_ASCIICRLF:
475 flags |= CMS_ASCIICRLF;
476 break;
477 case OPT_NOINTERN:
478 flags |= CMS_NOINTERN;
479 break;
480 case OPT_NOVERIFY:
481 flags |= CMS_NO_SIGNER_CERT_VERIFY;
482 break;
483 case OPT_NOCERTS:
484 flags |= CMS_NOCERTS;
485 break;
486 case OPT_NOATTR:
487 flags |= CMS_NOATTR;
488 break;
489 case OPT_NODETACH:
490 flags &= ~CMS_DETACHED;
491 break;
492 case OPT_NOSMIMECAP:
493 flags |= CMS_NOSMIMECAP;
494 break;
495 case OPT_NO_SIGNING_TIME:
496 flags |= CMS_NO_SIGNING_TIME;
497 break;
498 case OPT_BINARY:
499 flags |= CMS_BINARY;
500 break;
501 case OPT_CADES:
502 flags |= CMS_CADES;
503 break;
504 case OPT_KEYID:
505 flags |= CMS_USE_KEYID;
506 break;
507 case OPT_NOSIGS:
508 flags |= CMS_NOSIGS;
509 break;
510 case OPT_NO_CONTENT_VERIFY:
511 flags |= CMS_NO_CONTENT_VERIFY;
512 break;
513 case OPT_NO_ATTR_VERIFY:
514 flags |= CMS_NO_ATTR_VERIFY;
515 break;
516 case OPT_INDEF:
517 flags |= CMS_STREAM;
518 break;
519 case OPT_NOINDEF:
520 flags &= ~CMS_STREAM;
521 break;
522 case OPT_CRLFEOL:
523 mime_eol = "\r\n";
524 flags |= CMS_CRLFEOL;
525 break;
526 case OPT_NOOUT:
527 noout = 1;
528 break;
529 case OPT_RR_PRINT:
530 rr_print = 1;
531 break;
532 case OPT_RR_ALL:
533 rr_allorfirst = 0;
534 break;
535 case OPT_RR_FIRST:
536 rr_allorfirst = 1;
537 break;
538 case OPT_RCTFORM:
539 if (!opt_format(opt_arg(),
540 OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
541 goto opthelp;
542 break;
543 case OPT_CERTFILE:
544 certfile = opt_arg();
545 break;
546 case OPT_CAFILE:
547 CAfile = opt_arg();
548 break;
549 case OPT_CAPATH:
550 CApath = opt_arg();
551 break;
552 case OPT_CASTORE:
553 CAstore = opt_arg();
554 break;
555 case OPT_NOCAFILE:
556 noCAfile = 1;
557 break;
558 case OPT_NOCAPATH:
559 noCApath = 1;
560 break;
561 case OPT_NOCASTORE:
562 noCAstore = 1;
563 break;
564 case OPT_IN:
565 infile = opt_arg();
566 break;
567 case OPT_CONTENT:
568 contfile = opt_arg();
569 break;
570 case OPT_RR_FROM:
571 if (rr_from == NULL
572 && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL)
573 goto end;
574 if (sk_OPENSSL_STRING_push(rr_from, opt_arg()) <= 0)
575 goto end;
576 break;
577 case OPT_RR_TO:
578 if (rr_to == NULL
579 && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL)
580 goto end;
581 if (sk_OPENSSL_STRING_push(rr_to, opt_arg()) <= 0)
582 goto end;
583 break;
584 case OPT_PRINT:
585 noout = print = 1;
586 break;
587 case OPT_NAMEOPT:
588 if (!set_nameopt(opt_arg()))
589 goto opthelp;
590 break;
591 case OPT_SECRETKEY:
592 if (secret_key != NULL) {
593 BIO_printf(bio_err, "Invalid key (supplied twice) %s\n",
594 opt_arg());
595 goto opthelp;
596 }
597 secret_key = OPENSSL_hexstr2buf(opt_arg(), <mp);
598 if (secret_key == NULL) {
599 BIO_printf(bio_err, "Invalid key %s\n", opt_arg());
600 goto end;
601 }
602 secret_keylen = (size_t)ltmp;
603 break;
604 case OPT_SECRETKEYID:
605 if (secret_keyid != NULL) {
606 BIO_printf(bio_err, "Invalid id (supplied twice) %s\n",
607 opt_arg());
608 goto opthelp;
609 }
610 secret_keyid = OPENSSL_hexstr2buf(opt_arg(), <mp);
611 if (secret_keyid == NULL) {
612 BIO_printf(bio_err, "Invalid id %s\n", opt_arg());
613 goto opthelp;
614 }
615 secret_keyidlen = (size_t)ltmp;
616 break;
617 case OPT_PWRI_PASSWORD:
618 pwri_pass = (unsigned char *)opt_arg();
619 break;
620 case OPT_ECONTENT_TYPE:
621 if (econtent_type != NULL) {
622 BIO_printf(bio_err, "Invalid OID (supplied twice) %s\n",
623 opt_arg());
624 goto opthelp;
625 }
626 econtent_type = OBJ_txt2obj(opt_arg(), 0);
627 if (econtent_type == NULL) {
628 BIO_printf(bio_err, "Invalid OID %s\n", opt_arg());
629 goto opthelp;
630 }
631 break;
632 case OPT_ENGINE:
633 e = setup_engine(opt_arg(), 0);
634 break;
635 case OPT_PASSIN:
636 passinarg = opt_arg();
637 break;
638 case OPT_TO:
639 to = opt_arg();
640 break;
641 case OPT_FROM:
642 from = opt_arg();
643 break;
644 case OPT_SUBJECT:
645 subject = opt_arg();
646 break;
647 case OPT_CERTSOUT:
648 certsoutfile = opt_arg();
649 break;
650 case OPT_MD:
651 digestname = opt_arg();
652 break;
653 case OPT_SIGNER:
654 /* If previous -signer argument add signer to list */
655 if (signerfile != NULL) {
656 if (sksigners == NULL
657 && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
658 goto end;
659 if (sk_OPENSSL_STRING_push(sksigners, signerfile) <= 0)
660 goto end;
661 if (keyfile == NULL)
662 keyfile = signerfile;
663 if (skkeys == NULL
664 && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
665 goto end;
666 if (sk_OPENSSL_STRING_push(skkeys, keyfile) <= 0)
667 goto end;
668 keyfile = NULL;
669 }
670 signerfile = opt_arg();
671 break;
672 case OPT_ORIGINATOR:
673 originatorfile = opt_arg();
674 break;
675 case OPT_INKEY:
676 /* If previous -inkey argument add signer to list */
677 if (keyfile != NULL) {
678 if (signerfile == NULL) {
679 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
680 goto end;
681 }
682 if (sksigners == NULL
683 && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
684 goto end;
685 if (sk_OPENSSL_STRING_push(sksigners, signerfile) <= 0)
686 goto end;
687 signerfile = NULL;
688 if (skkeys == NULL
689 && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
690 goto end;
691 if (sk_OPENSSL_STRING_push(skkeys, keyfile) <= 0)
692 goto end;
693 }
694 keyfile = opt_arg();
695 break;
696 case OPT_KEYFORM:
697 if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
698 goto opthelp;
699 break;
700 case OPT_RECIP:
701 if (operation == SMIME_ENCRYPT) {
702 cert = load_cert(opt_arg(), FORMAT_UNDEF,
703 "recipient certificate file");
704 if (cert == NULL)
705 goto end;
706 if (!sk_X509_push(encerts, cert))
707 goto end;
708 cert = NULL;
709 } else {
710 recipfile = opt_arg();
711 }
712 break;
713 case OPT_CIPHER:
714 ciphername = opt_unknown();
715 break;
716 case OPT_KEYOPT:
717 keyidx = -1;
718 if (operation == SMIME_ENCRYPT) {
719 if (sk_X509_num(encerts) > 0)
720 keyidx += sk_X509_num(encerts);
721 } else {
722 if (keyfile != NULL || signerfile != NULL)
723 keyidx++;
724 if (skkeys != NULL)
725 keyidx += sk_OPENSSL_STRING_num(skkeys);
726 }
727 if (keyidx < 0) {
728 BIO_printf(bio_err, "No key specified\n");
729 goto opthelp;
730 }
731 if (key_param == NULL || key_param->idx != keyidx) {
732 cms_key_param *nparam;
733 nparam = app_malloc(sizeof(*nparam), "key param buffer");
734 if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL) {
735 OPENSSL_free(nparam);
736 goto end;
737 }
738 nparam->idx = keyidx;
739 nparam->next = NULL;
740 if (key_first == NULL)
741 key_first = nparam;
742 else
743 key_param->next = nparam;
744 key_param = nparam;
745 }
746 if (sk_OPENSSL_STRING_push(key_param->param, opt_arg()) <= 0)
747 goto end;
748 break;
749 case OPT_V_CASES:
750 if (!opt_verify(o, vpm))
751 goto end;
752 vpmtouched++;
753 break;
754 case OPT_R_CASES:
755 if (!opt_rand(o))
756 goto end;
757 break;
758 case OPT_PROV_CASES:
759 if (!opt_provider(o))
760 goto end;
761 break;
762 case OPT_CONFIG:
763 conf = app_load_config_modules(opt_arg());
764 if (conf == NULL)
765 goto end;
766 break;
767 case OPT_WRAP:
768 wrapname = opt_arg();
769 break;
770 case OPT_AES128_WRAP:
771 case OPT_AES192_WRAP:
772 case OPT_AES256_WRAP:
773 case OPT_3DES_WRAP:
774 wrapname = opt_flag() + 1;
775 break;
776 }
777 }
778 if (!app_RAND_load())
779 goto end;
780
781 if (digestname != NULL) {
782 if (!opt_md(digestname, &sign_md))
783 goto end;
784 }
785 if (!opt_cipher_any(ciphername, &cipher))
786 goto end;
787 if (wrapname != NULL) {
788 if (!opt_cipher_any(wrapname, &wrap_cipher))
789 goto end;
790 }
791
792 /* Remaining args are files to process. */
793 argv = opt_rest();
794
795 if ((rr_allorfirst != -1 || rr_from != NULL) && rr_to == NULL) {
796 BIO_puts(bio_err, "No Signed Receipts Recipients\n");
797 goto opthelp;
798 }
799
800 if (!(operation & SMIME_SIGNERS) && (rr_to != NULL || rr_from != NULL)) {
801 BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
802 goto opthelp;
803 }
804 if (!(operation & SMIME_SIGNERS) && (skkeys != NULL || sksigners != NULL)) {
805 BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
806 goto opthelp;
807 }
808
809 if ((flags & CMS_CADES) != 0) {
810 if ((flags & CMS_NOATTR) != 0) {
811 BIO_puts(bio_err, "Incompatible options: "
812 "CAdES requires signed attributes\n");
813 goto opthelp;
814 }
815 if (operation == SMIME_VERIFY
816 && (flags & (CMS_NO_SIGNER_CERT_VERIFY | CMS_NO_ATTR_VERIFY)) != 0) {
817 BIO_puts(bio_err, "Incompatible options: CAdES validation requires"
818 " certs and signed attributes validations\n");
819 goto opthelp;
820 }
821 }
822
823 if (operation & SMIME_SIGNERS) {
824 if (keyfile != NULL && signerfile == NULL) {
825 BIO_puts(bio_err, "Illegal -inkey without -signer\n");
826 goto opthelp;
827 }
828 /* Check to see if any final signer needs to be appended */
829 if (signerfile != NULL) {
830 if (sksigners == NULL
831 && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
832 goto end;
833 if (sk_OPENSSL_STRING_push(sksigners, signerfile) <= 0)
834 goto end;
835 if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
836 goto end;
837 if (keyfile == NULL)
838 keyfile = signerfile;
839 if (sk_OPENSSL_STRING_push(skkeys, keyfile) <= 0)
840 goto end;
841 }
842 if (sksigners == NULL) {
843 BIO_printf(bio_err, "No signer certificate specified\n");
844 goto opthelp;
845 }
846 signerfile = NULL;
847 keyfile = NULL;
848 } else if (operation == SMIME_DECRYPT) {
849 if (recipfile == NULL && keyfile == NULL
850 && secret_key == NULL && pwri_pass == NULL) {
851 BIO_printf(bio_err,
852 "No recipient certificate or key specified\n");
853 goto opthelp;
854 }
855 } else if (operation == SMIME_ENCRYPT) {
856 if (*argv == NULL && secret_key == NULL
857 && pwri_pass == NULL && sk_X509_num(encerts) <= 0) {
858 BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
859 goto opthelp;
860 }
861 } else if (!operation) {
862 BIO_printf(bio_err, "No operation option (-encrypt|-decrypt|-sign|-verify|...) specified.\n");
863 goto opthelp;
864 }
865
866 if (!app_passwd(passinarg, NULL, &passin, NULL)) {
867 BIO_printf(bio_err, "Error getting password\n");
868 goto end;
869 }
870
871 ret = 2;
872
873 if ((operation & SMIME_SIGNERS) == 0) {
874 if ((flags & CMS_DETACHED) == 0)
875 BIO_printf(bio_err,
876 "Warning: -nodetach option is ignored for non-signing operation\n");
877
878 flags &= ~CMS_DETACHED;
879 }
880 if ((operation & SMIME_IP) == 0 && contfile != NULL)
881 BIO_printf(bio_err,
882 "Warning: -contfile option is ignored for the given operation\n");
883 if (operation != SMIME_ENCRYPT && *argv != NULL)
884 BIO_printf(bio_err,
885 "Warning: recipient certificate file parameters ignored for operation other than -encrypt\n");
886
887 if ((flags & CMS_BINARY) != 0) {
888 if (!(operation & SMIME_OP))
889 outformat = FORMAT_BINARY;
890 if (!(operation & SMIME_IP))
891 informat = FORMAT_BINARY;
892 if ((operation & SMIME_SIGNERS) != 0 && (flags & CMS_DETACHED) != 0)
893 binary_files = 1;
894 if ((operation & SMIME_IP) != 0 && contfile == NULL)
895 binary_files = 1;
896 }
897
898 if (operation == SMIME_ENCRYPT) {
899 if (!cipher)
900 cipher = (EVP_CIPHER *)EVP_aes_256_cbc();
901 if (secret_key && !secret_keyid) {
902 BIO_printf(bio_err, "No secret key id\n");
903 goto end;
904 }
905
906 for (; *argv != NULL; argv++) {
907 cert = load_cert(*argv, FORMAT_UNDEF,
908 "recipient certificate file");
909 if (cert == NULL)
910 goto end;
911 if (!sk_X509_push(encerts, cert))
912 goto end;
913 cert = NULL;
914 }
915 }
916
917 if (certfile != NULL) {
918 if (!load_certs(certfile, 0, &other, NULL, "certificate file")) {
919 ERR_print_errors(bio_err);
920 goto end;
921 }
922 }
923
924 if (recipfile != NULL && (operation == SMIME_DECRYPT)) {
925 if ((recip = load_cert(recipfile, FORMAT_UNDEF,
926 "recipient certificate file"))
927 == NULL) {
928 ERR_print_errors(bio_err);
929 goto end;
930 }
931 }
932
933 if (originatorfile != NULL) {
934 if ((originator = load_cert(originatorfile, FORMAT_UNDEF,
935 "originator certificate file"))
936 == NULL) {
937 ERR_print_errors(bio_err);
938 goto end;
939 }
940 }
941
942 if (operation == SMIME_SIGN_RECEIPT) {
943 if ((signer = load_cert(signerfile, FORMAT_UNDEF,
944 "receipt signer certificate file"))
945 == NULL) {
946 ERR_print_errors(bio_err);
947 goto end;
948 }
949 }
950
951 if ((operation == SMIME_DECRYPT) || (operation == SMIME_ENCRYPT)) {
952 if (keyfile == NULL)
953 keyfile = recipfile;
954 } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) {
955 if (keyfile == NULL)
956 keyfile = signerfile;
957 } else {
958 keyfile = NULL;
959 }
960
961 if (keyfile != NULL) {
962 key = load_key(keyfile, keyform, 0, passin, e, "signing key");
963 if (key == NULL)
964 goto end;
965 }
966
967 if (digesthex != NULL) {
968 if (operation != SMIME_SIGN) {
969 BIO_printf(bio_err,
970 "Cannot use -digest for non-signing operation\n");
971 goto end;
972 }
973 if (infile != NULL
974 || (flags & CMS_DETACHED) == 0
975 || (flags & CMS_STREAM) != 0) {
976 BIO_printf(bio_err,
977 "Cannot use -digest when -in, -nodetach or streaming is used\n");
978 goto end;
979 }
980 digestbin = OPENSSL_hexstr2buf(digesthex, &digestlen);
981 if (digestbin == NULL) {
982 BIO_printf(bio_err,
983 "Invalid hex value after -digest\n");
984 goto end;
985 }
986 } else {
987 in = bio_open_default(infile, 'r',
988 binary_files ? FORMAT_BINARY : informat);
989 if (in == NULL)
990 goto end;
991 }
992
993 if (operation & SMIME_IP) {
994 cms = load_content_info(informat, in, flags, &indata, "SMIME");
995 if (cms == NULL)
996 goto end;
997 if (contfile != NULL) {
998 BIO_free(indata);
999 if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
1000 BIO_printf(bio_err, "Can't read content file %s\n", contfile);
1001 goto end;
1002 }
1003 }
1004 if (certsoutfile != NULL) {
1005 STACK_OF(X509) *allcerts;
1006 allcerts = CMS_get1_certs(cms);
1007 if (!save_certs(certsoutfile, allcerts)) {
1008 BIO_printf(bio_err,
1009 "Error writing certs to %s\n", certsoutfile);
1010 ret = 5;
1011 goto end;
1012 }
1013 OSSL_STACK_OF_X509_free(allcerts);
1014 }
1015 }
1016
1017 if (rctfile != NULL) {
1018 char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
1019
1020 if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
1021 BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
1022 goto end;
1023 }
1024
1025 rcms = load_content_info(rctformat, rctin, 0, NULL, "receipt");
1026 if (rcms == NULL)
1027 goto end;
1028 }
1029
1030 out = bio_open_default(outfile, 'w',
1031 binary_files ? FORMAT_BINARY : outformat);
1032 if (out == NULL)
1033 goto end;
1034
1035 if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) {
1036 if ((store = setup_verify(CAfile, noCAfile, CApath, noCApath,
1037 CAstore, noCAstore))
1038 == NULL)
1039 goto end;
1040 X509_STORE_set_verify_cb(store, cms_cb);
1041 if (vpmtouched)
1042 X509_STORE_set1_param(store, vpm);
1043 }
1044
1045 ret = 3;
1046
1047 if (operation == SMIME_DATA_CREATE) {
1048 cms = CMS_data_create_ex(in, flags, libctx, app_get0_propq());
1049 } else if (operation == SMIME_DIGEST_CREATE) {
1050 cms = CMS_digest_create_ex(in, sign_md, flags, libctx, app_get0_propq());
1051 } else if (operation == SMIME_COMPRESS) {
1052 cms = CMS_compress(in, -1, flags);
1053 } else if (operation == SMIME_ENCRYPT) {
1054 int i;
1055 flags |= CMS_PARTIAL;
1056 cms = CMS_encrypt_ex(NULL, in, cipher, flags, libctx, app_get0_propq());
1057 if (cms == NULL)
1058 goto end;
1059 for (i = 0; i < sk_X509_num(encerts); i++) {
1060 CMS_RecipientInfo *ri;
1061 cms_key_param *kparam;
1062 int tflags = flags | CMS_KEY_PARAM;
1063 /* This flag enforces allocating the EVP_PKEY_CTX for the recipient here */
1064 EVP_PKEY_CTX *pctx;
1065 X509 *x = sk_X509_value(encerts, i);
1066 int res;
1067
1068 for (kparam = key_first; kparam; kparam = kparam->next) {
1069 if (kparam->idx == i) {
1070 break;
1071 }
1072 }
1073 ri = CMS_add1_recipient(cms, x, key, originator, tflags);
1074 if (ri == NULL)
1075 goto end;
1076
1077 pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
1078 if (pctx != NULL && kparam != NULL) {
1079 if (!cms_set_pkey_param(pctx, kparam->param))
1080 goto end;
1081 }
1082
1083 res = EVP_PKEY_CTX_ctrl(pctx, -1, -1,
1084 EVP_PKEY_CTRL_CIPHER,
1085 EVP_CIPHER_get_nid(cipher), NULL);
1086 if (res <= 0 && res != -2)
1087 goto end;
1088
1089 if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE
1090 && wrap_cipher != NULL) {
1091 EVP_CIPHER_CTX *wctx;
1092 wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
1093 if (EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL) != 1)
1094 goto end;
1095 }
1096 }
1097
1098 if (secret_key != NULL) {
1099 if (!CMS_add0_recipient_key(cms, NID_undef,
1100 secret_key, secret_keylen,
1101 secret_keyid, secret_keyidlen,
1102 NULL, NULL, NULL))
1103 goto end;
1104 /* NULL these because call absorbs them */
1105 secret_key = NULL;
1106 secret_keyid = NULL;
1107 }
1108 if (pwri_pass != NULL) {
1109 pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass);
1110 if (pwri_tmp == NULL)
1111 goto end;
1112 if (CMS_add0_recipient_password(cms,
1113 -1, NID_undef, NID_undef,
1114 pwri_tmp, -1, NULL)
1115 == NULL)
1116 goto end;
1117 pwri_tmp = NULL;
1118 }
1119 if (!(flags & CMS_STREAM)) {
1120 if (!CMS_final(cms, in, NULL, flags)) {
1121 if (originator != NULL
1122 && ERR_GET_REASON(ERR_peek_error())
1123 == CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT) {
1124 BIO_printf(bio_err, "Cannot use originator for encryption\n");
1125 goto end;
1126 }
1127 goto end;
1128 }
1129 }
1130 } else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
1131 cms = CMS_EncryptedData_encrypt_ex(in, cipher, secret_key,
1132 secret_keylen, flags, libctx, app_get0_propq());
1133
1134 } else if (operation == SMIME_SIGN_RECEIPT) {
1135 CMS_ContentInfo *srcms = NULL;
1136 STACK_OF(CMS_SignerInfo) *sis;
1137 CMS_SignerInfo *si;
1138 sis = CMS_get0_SignerInfos(cms);
1139 if (sis == NULL)
1140 goto end;
1141 si = sk_CMS_SignerInfo_value(sis, 0);
1142 srcms = CMS_sign_receipt(si, signer, key, other, flags);
1143 if (srcms == NULL)
1144 goto end;
1145 CMS_ContentInfo_free(cms);
1146 cms = srcms;
1147 } else if (operation & SMIME_SIGNERS) {
1148 int i;
1149 /*
1150 * If detached data content and not signing pre-computed digest, we
1151 * enable streaming if S/MIME output format.
1152 */
1153 if (operation == SMIME_SIGN) {
1154
1155 if ((flags & CMS_DETACHED) != 0 && digestbin == NULL) {
1156 if (outformat == FORMAT_SMIME)
1157 flags |= CMS_STREAM;
1158 }
1159 flags |= CMS_PARTIAL;
1160 cms = CMS_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq());
1161 if (cms == NULL)
1162 goto end;
1163 if (econtent_type != NULL)
1164 CMS_set1_eContentType(cms, econtent_type);
1165
1166 if (rr_to != NULL
1167 && ((rr = make_receipt_request(rr_to, rr_allorfirst, rr_from))
1168 == NULL)) {
1169 BIO_puts(bio_err, "Signed Receipt Request Creation Error\n");
1170 goto end;
1171 }
1172 } else {
1173 flags |= CMS_REUSE_DIGEST;
1174 }
1175 for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
1176 CMS_SignerInfo *si;
1177 cms_key_param *kparam;
1178 int tflags = flags;
1179 signerfile = sk_OPENSSL_STRING_value(sksigners, i);
1180 keyfile = sk_OPENSSL_STRING_value(skkeys, i);
1181
1182 signer = load_cert(signerfile, FORMAT_UNDEF, "signer certificate");
1183 if (signer == NULL) {
1184 ret = 2;
1185 goto end;
1186 }
1187 key = load_key(keyfile, keyform, 0, passin, e, "signing key");
1188 if (key == NULL) {
1189 ret = 2;
1190 goto end;
1191 }
1192
1193 for (kparam = key_first; kparam; kparam = kparam->next) {
1194 if (kparam->idx == i) {
1195 tflags |= CMS_KEY_PARAM;
1196 break;
1197 }
1198 }
1199 si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
1200 if (si == NULL)
1201 goto end;
1202 if (kparam != NULL) {
1203 EVP_PKEY_CTX *pctx;
1204 pctx = CMS_SignerInfo_get0_pkey_ctx(si);
1205 if (!cms_set_pkey_param(pctx, kparam->param))
1206 goto end;
1207 }
1208 if (rr != NULL && !CMS_add1_ReceiptRequest(si, rr))
1209 goto end;
1210 X509_free(signer);
1211 signer = NULL;
1212 EVP_PKEY_free(key);
1213 key = NULL;
1214 }
1215 /* If not streaming or resigning finalize structure */
1216 if (operation == SMIME_SIGN && digestbin != NULL
1217 && (flags & CMS_STREAM) == 0) {
1218 /* Use pre-computed digest instead of content */
1219 if (!CMS_final_digest(cms, digestbin, digestlen, NULL, flags))
1220 goto end;
1221 } else if (operation == SMIME_SIGN && (flags & CMS_STREAM) == 0) {
1222 if (!CMS_final(cms, in, NULL, flags))
1223 goto end;
1224 }
1225 }
1226
1227 if (cms == NULL) {
1228 BIO_printf(bio_err, "Error creating CMS structure\n");
1229 goto end;
1230 }
1231
1232 ret = 4;
1233 if (operation == SMIME_DECRYPT) {
1234 if (flags & CMS_DEBUG_DECRYPT)
1235 CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);
1236
1237 if (secret_key != NULL) {
1238 if (!CMS_decrypt_set1_key(cms,
1239 secret_key, secret_keylen,
1240 secret_keyid, secret_keyidlen)) {
1241 BIO_puts(bio_err, "Error decrypting CMS using secret key\n");
1242 goto end;
1243 }
1244 }
1245
1246 if (key != NULL) {
1247 if (!CMS_decrypt_set1_pkey_and_peer(cms, key, recip, originator)) {
1248 BIO_puts(bio_err, "Error decrypting CMS using private key\n");
1249 goto end;
1250 }
1251 }
1252
1253 if (pwri_pass != NULL) {
1254 if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
1255 BIO_puts(bio_err, "Error decrypting CMS using password\n");
1256 goto end;
1257 }
1258 }
1259
1260 if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) {
1261 BIO_printf(bio_err, "Error decrypting CMS structure\n");
1262 goto end;
1263 }
1264 } else if (operation == SMIME_DATA_OUT) {
1265 if (!CMS_data(cms, out, flags))
1266 goto end;
1267 } else if (operation == SMIME_UNCOMPRESS) {
1268 if (!CMS_uncompress(cms, indata, out, flags))
1269 goto end;
1270 } else if (operation == SMIME_DIGEST_VERIFY) {
1271 if (CMS_digest_verify(cms, indata, out, flags) > 0) {
1272 BIO_printf(bio_err, "Verification successful\n");
1273 } else {
1274 BIO_printf(bio_err, "Verification failure\n");
1275 goto end;
1276 }
1277 } else if (operation == SMIME_ENCRYPTED_DECRYPT) {
1278 if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
1279 indata, out, flags))
1280 goto end;
1281 } else if (operation == SMIME_VERIFY) {
1282 if (CMS_verify(cms, other, store, indata, out, flags) > 0) {
1283 BIO_printf(bio_err, "%s Verification successful\n",
1284 (flags & CMS_CADES) != 0 ? "CAdES" : "CMS");
1285 } else {
1286 BIO_printf(bio_err, "%s Verification failure\n",
1287 (flags & CMS_CADES) != 0 ? "CAdES" : "CMS");
1288 if (verify_retcode)
1289 ret = verify_err + 32;
1290 goto end;
1291 }
1292 if (signerfile != NULL) {
1293 STACK_OF(X509) *signers = CMS_get0_signers(cms);
1294
1295 if (!save_certs(signerfile, signers)) {
1296 BIO_printf(bio_err,
1297 "Error writing signers to %s\n", signerfile);
1298 ret = 5;
1299 goto end;
1300 }
1301 sk_X509_free(signers);
1302 }
1303 if (rr_print)
1304 receipt_request_print(cms);
1305
1306 } else if (operation == SMIME_VERIFY_RECEIPT) {
1307 if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0) {
1308 BIO_printf(bio_err, "Verification successful\n");
1309 } else {
1310 BIO_printf(bio_err, "Verification failure\n");
1311 goto end;
1312 }
1313 } else {
1314 if (noout) {
1315 if (print) {
1316 ASN1_PCTX *pctx = NULL;
1317 if (get_nameopt() != XN_FLAG_ONELINE) {
1318 pctx = ASN1_PCTX_new();
1319 if (pctx != NULL) { /* Print anyway if malloc failed */
1320 ASN1_PCTX_set_flags(pctx, ASN1_PCTX_FLAGS_SHOW_ABSENT);
1321 ASN1_PCTX_set_str_flags(pctx, get_nameopt());
1322 ASN1_PCTX_set_nm_flags(pctx, get_nameopt());
1323 }
1324 }
1325 CMS_ContentInfo_print_ctx(out, cms, 0, pctx);
1326 ASN1_PCTX_free(pctx);
1327 }
1328 } else if (outformat == FORMAT_SMIME) {
1329 if (to)
1330 BIO_printf(out, "To: %s%s", to, mime_eol);
1331 if (from)
1332 BIO_printf(out, "From: %s%s", from, mime_eol);
1333 if (subject)
1334 BIO_printf(out, "Subject: %s%s", subject, mime_eol);
1335 if (operation == SMIME_RESIGN)
1336 ret = SMIME_write_CMS(out, cms, indata, flags);
1337 else
1338 ret = SMIME_write_CMS(out, cms, in, flags);
1339 } else if (outformat == FORMAT_PEM) {
1340 ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
1341 } else if (outformat == FORMAT_ASN1) {
1342 ret = i2d_CMS_bio_stream(out, cms, in, flags);
1343 } else {
1344 BIO_printf(bio_err, "Bad output format for CMS file\n");
1345 goto end;
1346 }
1347 if (ret <= 0) {
1348 BIO_printf(bio_err, "Error writing CMS output\n");
1349 ret = 6;
1350 goto end;
1351 }
1352 }
1353 ret = 0;
1354 end:
1355 if (ret)
1356 ERR_print_errors(bio_err);
1357 OSSL_STACK_OF_X509_free(encerts);
1358 OSSL_STACK_OF_X509_free(other);
1359 X509_VERIFY_PARAM_free(vpm);
1360 sk_OPENSSL_STRING_free(sksigners);
1361 sk_OPENSSL_STRING_free(skkeys);
1362 OPENSSL_free(secret_key);
1363 OPENSSL_free(secret_keyid);
1364 OPENSSL_free(pwri_tmp);
1365 ASN1_OBJECT_free(econtent_type);
1366 CMS_ReceiptRequest_free(rr);
1367 sk_OPENSSL_STRING_free(rr_to);
1368 sk_OPENSSL_STRING_free(rr_from);
1369 for (key_param = key_first; key_param;) {
1370 cms_key_param *tparam;
1371 sk_OPENSSL_STRING_free(key_param->param);
1372 tparam = key_param->next;
1373 OPENSSL_free(key_param);
1374 key_param = tparam;
1375 }
1376 X509_STORE_free(store);
1377 X509_free(cert);
1378 X509_free(recip);
1379 X509_free(signer);
1380 X509_free(originator);
1381 EVP_PKEY_free(key);
1382 EVP_CIPHER_free(cipher);
1383 EVP_CIPHER_free(wrap_cipher);
1384 EVP_MD_free(sign_md);
1385 CMS_ContentInfo_free(cms);
1386 CMS_ContentInfo_free(rcms);
1387 release_engine(e);
1388 BIO_free(rctin);
1389 BIO_free(in);
1390 BIO_free(indata);
1391 BIO_free_all(out);
1392 OPENSSL_free(digestbin);
1393 OPENSSL_free(passin);
1394 NCONF_free(conf);
1395 return ret;
1396 }
1397
save_certs(char * signerfile,STACK_OF (X509)* signers)1398 static int save_certs(char *signerfile, STACK_OF(X509) *signers)
1399 {
1400 int i;
1401 BIO *tmp;
1402 if (signerfile == NULL)
1403 return 1;
1404 tmp = BIO_new_file(signerfile, "w");
1405 if (tmp == NULL)
1406 return 0;
1407 for (i = 0; i < sk_X509_num(signers); i++)
1408 PEM_write_bio_X509(tmp, sk_X509_value(signers, i));
1409 BIO_free(tmp);
1410 return 1;
1411 }
1412
1413 /* Minimal callback just to output policy info (if any) */
1414
cms_cb(int ok,X509_STORE_CTX * ctx)1415 static int cms_cb(int ok, X509_STORE_CTX *ctx)
1416 {
1417 int error;
1418
1419 error = X509_STORE_CTX_get_error(ctx);
1420
1421 verify_err = error;
1422
1423 if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
1424 && ((error != X509_V_OK) || (ok != 2)))
1425 return ok;
1426
1427 policies_print(ctx);
1428
1429 return ok;
1430 }
1431
gnames_stack_print(STACK_OF (GENERAL_NAMES)* gns)1432 static void gnames_stack_print(STACK_OF(GENERAL_NAMES) *gns)
1433 {
1434 STACK_OF(GENERAL_NAME) *gens;
1435 GENERAL_NAME *gen;
1436 int i, j;
1437
1438 for (i = 0; i < sk_GENERAL_NAMES_num(gns); i++) {
1439 gens = sk_GENERAL_NAMES_value(gns, i);
1440 for (j = 0; j < sk_GENERAL_NAME_num(gens); j++) {
1441 gen = sk_GENERAL_NAME_value(gens, j);
1442 BIO_puts(bio_err, " ");
1443 GENERAL_NAME_print(bio_err, gen);
1444 BIO_puts(bio_err, "\n");
1445 }
1446 }
1447 return;
1448 }
1449
receipt_request_print(CMS_ContentInfo * cms)1450 static void receipt_request_print(CMS_ContentInfo *cms)
1451 {
1452 STACK_OF(CMS_SignerInfo) *sis;
1453 CMS_SignerInfo *si;
1454 CMS_ReceiptRequest *rr;
1455 int allorfirst;
1456 STACK_OF(GENERAL_NAMES) *rto, *rlist;
1457 ASN1_STRING *scid;
1458 int i, rv;
1459 sis = CMS_get0_SignerInfos(cms);
1460 for (i = 0; i < sk_CMS_SignerInfo_num(sis); i++) {
1461 si = sk_CMS_SignerInfo_value(sis, i);
1462 rv = CMS_get1_ReceiptRequest(si, &rr);
1463 BIO_printf(bio_err, "Signer %d:\n", i + 1);
1464 if (rv == 0) {
1465 BIO_puts(bio_err, " No Receipt Request\n");
1466 } else if (rv < 0) {
1467 BIO_puts(bio_err, " Receipt Request Parse Error\n");
1468 ERR_print_errors(bio_err);
1469 } else {
1470 const char *id;
1471 int idlen;
1472 CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
1473 &rlist, &rto);
1474 BIO_puts(bio_err, " Signed Content ID:\n");
1475 idlen = ASN1_STRING_length(scid);
1476 id = (const char *)ASN1_STRING_get0_data(scid);
1477 BIO_dump_indent(bio_err, id, idlen, 4);
1478 BIO_puts(bio_err, " Receipts From");
1479 if (rlist != NULL) {
1480 BIO_puts(bio_err, " List:\n");
1481 gnames_stack_print(rlist);
1482 } else if (allorfirst == 1) {
1483 BIO_puts(bio_err, ": First Tier\n");
1484 } else if (allorfirst == 0) {
1485 BIO_puts(bio_err, ": All\n");
1486 } else {
1487 BIO_printf(bio_err, " Unknown (%d)\n", allorfirst);
1488 }
1489 BIO_puts(bio_err, " Receipts To:\n");
1490 gnames_stack_print(rto);
1491 }
1492 CMS_ReceiptRequest_free(rr);
1493 }
1494 }
1495
STACK_OF(GENERAL_NAMES)1496 static STACK_OF(GENERAL_NAMES) *make_names_stack(STACK_OF(OPENSSL_STRING) *ns)
1497 {
1498 int i;
1499 STACK_OF(GENERAL_NAMES) *ret;
1500 GENERAL_NAMES *gens = NULL;
1501 GENERAL_NAME *gen = NULL;
1502 ret = sk_GENERAL_NAMES_new_null();
1503 if (ret == NULL)
1504 goto err;
1505 for (i = 0; i < sk_OPENSSL_STRING_num(ns); i++) {
1506 char *str = sk_OPENSSL_STRING_value(ns, i);
1507 gen = a2i_GENERAL_NAME(NULL, NULL, NULL, GEN_EMAIL, str, 0);
1508 if (gen == NULL)
1509 goto err;
1510 gens = GENERAL_NAMES_new();
1511 if (gens == NULL)
1512 goto err;
1513 if (!sk_GENERAL_NAME_push(gens, gen))
1514 goto err;
1515 gen = NULL;
1516 if (!sk_GENERAL_NAMES_push(ret, gens))
1517 goto err;
1518 gens = NULL;
1519 }
1520
1521 return ret;
1522
1523 err:
1524 sk_GENERAL_NAMES_pop_free(ret, GENERAL_NAMES_free);
1525 GENERAL_NAMES_free(gens);
1526 GENERAL_NAME_free(gen);
1527 return NULL;
1528 }
1529
make_receipt_request(STACK_OF (OPENSSL_STRING)* rr_to,int rr_allorfirst,STACK_OF (OPENSSL_STRING)* rr_from)1530 static CMS_ReceiptRequest *make_receipt_request(STACK_OF(OPENSSL_STRING) *rr_to, int rr_allorfirst,
1531 STACK_OF(OPENSSL_STRING) *rr_from)
1532 {
1533 STACK_OF(GENERAL_NAMES) *rct_to = NULL, *rct_from = NULL;
1534 CMS_ReceiptRequest *rr;
1535
1536 rct_to = make_names_stack(rr_to);
1537 if (rct_to == NULL)
1538 goto err;
1539 if (rr_from != NULL) {
1540 rct_from = make_names_stack(rr_from);
1541 if (rct_from == NULL)
1542 goto err;
1543 } else {
1544 rct_from = NULL;
1545 }
1546 rr = CMS_ReceiptRequest_create0_ex(NULL, -1, rr_allorfirst, rct_from,
1547 rct_to, app_get0_libctx());
1548 if (rr == NULL)
1549 goto err;
1550 return rr;
1551 err:
1552 sk_GENERAL_NAMES_pop_free(rct_to, GENERAL_NAMES_free);
1553 sk_GENERAL_NAMES_pop_free(rct_from, GENERAL_NAMES_free);
1554 return NULL;
1555 }
1556
cms_set_pkey_param(EVP_PKEY_CTX * pctx,STACK_OF (OPENSSL_STRING)* param)1557 static int cms_set_pkey_param(EVP_PKEY_CTX *pctx,
1558 STACK_OF(OPENSSL_STRING) *param)
1559 {
1560 char *keyopt;
1561 int i;
1562 if (sk_OPENSSL_STRING_num(param) <= 0)
1563 return 1;
1564 for (i = 0; i < sk_OPENSSL_STRING_num(param); i++) {
1565 keyopt = sk_OPENSSL_STRING_value(param, i);
1566 if (pkey_ctrl_string(pctx, keyopt) <= 0) {
1567 BIO_printf(bio_err, "parameter error \"%s\"\n", keyopt);
1568 ERR_print_errors(bio_err);
1569 return 0;
1570 }
1571 }
1572 return 1;
1573 }
1574