VirtualBox

source: vbox/trunk/src/libs/openssl-3.4.1/apps/cms.c@ 109302

Last change on this file since 109302 was 109052, checked in by vboxsync, 4 weeks ago

openssl-3.4.1: Applied our changes, regenerated files, added missing files and functions. This time with a three way merge. ​bugref:10890

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette