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