apps/cms.c: Correct -sign output and -verify input with -binary
authorDr. David von Oheimb <David.von.Oheimb@siemens.com>
Wed, 19 May 2021 17:44:22 +0000 (19:44 +0200)
committerDr. David von Oheimb <dev@ddvo.net>
Sat, 22 May 2021 12:28:51 +0000 (14:28 +0200)
Also add related warnings on irrelevant use of -nodetach and -content options.

Fixes #15347

Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15358)

apps/cms.c
doc/man1/openssl-cms.pod.in
smcont.signed_ [new file with mode: 0644]
test/recipes/80-test_cms.t
test/smcont.bin

index e9fe29ab8ed379577f39c3a9fd3cd58a8825288f..da00ece93ba5151d12ec6b6b0851cc53374232a4 100644 (file)
@@ -287,10 +287,11 @@ static void warn_binary(const char *file)
                 BIO_printf(bio_err, "Warning: input file '%s' contains %s"
                            " character; better use -binary option\n",
                            file, *cur == '\0' ? "NUL" : "8-bit");
-                break;
+                goto end;
             }
         }
     }
+ end:
     BIO_free(bio);
 }
 
@@ -320,7 +321,8 @@ int cms_main(int argc, char **argv)
     char *originatorfile = NULL, *recipfile = NULL, *ciphername = NULL;
     char *to = NULL, *from = NULL, *subject = NULL, *prog;
     cms_key_param *key_first = NULL, *key_param = NULL;
-    int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
+    int flags = CMS_DETACHED, binary_files = 0;
+    int noout = 0, print = 0, keyidx = -1, vpmtouched = 0;
     int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
     int operation = 0, ret = 1, rr_print = 0, rr_allorfirst = -1;
     int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_UNDEF;
@@ -811,14 +813,26 @@ int cms_main(int argc, char **argv)
 
     ret = 2;
 
-    if (!(operation & SMIME_SIGNERS))
+    if ((operation & SMIME_SIGNERS) == 0) {
+        if ((flags & CMS_DETACHED) == 0)
+            BIO_printf(bio_err,
+                       "Warning: -nodetach option is ignored for non-signing operation\n");
+
         flags &= ~CMS_DETACHED;
+    }
+    if ((operation & SMIME_IP) == 0 && contfile != NULL)
+        BIO_printf(bio_err,
+                   "Warning: -contfile option is ignored for the given operation\n");
 
     if ((flags & CMS_BINARY) != 0) {
         if (!(operation & SMIME_OP))
             outformat = FORMAT_BINARY;
         if (!(operation & SMIME_IP))
             informat = FORMAT_BINARY;
+        if ((operation & SMIME_SIGNERS) != 0 && (flags & CMS_DETACHED) != 0)
+            binary_files = 1;
+        if ((operation & SMIME_IP) != 0 && contfile == NULL)
+            binary_files = 1;
     }
 
     if (operation == SMIME_ENCRYPT) {
@@ -902,7 +916,7 @@ int cms_main(int argc, char **argv)
     if ((flags & CMS_BINARY) == 0)
         warn_binary(infile);
     in = bio_open_default(infile, 'r',
-                          (flags & CMS_BINARY) != 0 ? FORMAT_BINARY : informat);
+                          binary_files ? FORMAT_BINARY : informat);
     if (in == NULL)
         goto end;
 
@@ -945,7 +959,8 @@ int cms_main(int argc, char **argv)
             goto end;
     }
 
-    out = bio_open_default(outfile, 'w', outformat);
+    out = bio_open_default(outfile, 'w',
+                           binary_files ? FORMAT_BINARY : outformat);
     if (out == NULL)
         goto end;
 
index 6e0f86804ac534f01319940ca9c298ff8446ff7f..c63a7f330ba63600764c814bd8ff10d2f73c09d5 100644 (file)
@@ -507,8 +507,8 @@ will be written to this file if the verification was successful.
 
 =item B<-content> I<filename>
 
-This specifies a file containing the detached content, this is only
-useful with the B<-verify> command. This is only usable if the CMS
+This specifies a file containing the detached content for operations taking
+S/MIME input, such as the B<-verify> command. This is only usable if the CMS
 structure is using the detached signature form where the content is
 not included. This option will override any content if the input format
 is S/MIME and it uses the multipart/signed MIME content type.
diff --git a/smcont.signed_ b/smcont.signed_
new file mode 100644 (file)
index 0000000..59701f3
Binary files /dev/null and b/smcont.signed_ differ
index 7896bc9b1228b22b53cc3d1c66b823950b69cc4f..193c738a5d325a3c285a35b644cfa392cb094000 100644 (file)
@@ -818,7 +818,6 @@ subtest "CMS binary input tests\n" => sub {
     my $cert = srctop_file("test", "certs", "ee-self-signed.pem");
     my $key = srctop_file("test", "certs", "ee-key.pem");
 
-    plan skip_all => "Binary input tests currently disabled on Windows" if $^O =~ /^MSWin32$/;
     plan tests => 11;
 
     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256",
@@ -829,29 +828,31 @@ subtest "CMS binary input tests\n" => sub {
                 "-binary", "-in", $signed, "-out", $verified])),
        "verify binary input with -binary");
     is(compare($input, $verified), 0, "binary input retained with -binary");
+
     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256",
                 "-signer", $cert, "-inkey", $key,
-                "-in", $input, "-out", $signed])),
+                "-in", $input, "-out", $signed.".nobin"])),
        "sign binary input without -binary");
     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $cert,
-                "-in", $signed, "-out", $verified])),
+                "-in", $signed.".nobin", "-out", $verified.".nobin"])),
        "verify binary input without -binary");
-    is(compare($input, $verified), 1, "binary input not retained without -binary");
+    is(compare($input, $verified.".nobin"), 1, "binary input not retained without -binary");
     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $cert, "-crlfeol",
-                "-binary", "-in", $signed, "-out", $verified])),
+                "-binary", "-in", $signed, "-out", $verified.".crlfeol"])),
        "verify binary input wrong crlfeol");
 
     ok(run(app(["openssl", "cms", "-sign", "-md", "sha256", "-crlfeol",
                 "-signer", $cert, "-inkey", $key,
                 "-binary", "-in", $input, "-out", $signed.".crlf"])),
-       "sign binary input crlfeol");
+       "sign binary input with -binary -crlfeol");
     ok(run(app(["openssl", "cms", "-verify", "-CAfile", $cert, "-crlfeol",
                 "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
-       "verify binary input crlfeol");
-    is(compare($input, $verified.".crlf"), 0);
+       "verify binary input with -binary -crlfeol");
+    is(compare($input, $verified.".crlf"), 0,
+       "binary input retained with -binary -crlfeol");
     ok(!run(app(["openssl", "cms", "-verify", "-CAfile", $cert,
-                "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf"])),
-       "verify binary input missing crlfeol");
+                "-binary", "-in", $signed.".crlf", "-out", $verified.".crlf2"])),
+       "verify binary input with -binary missing -crlfeol");
 };
 
 sub check_availability {
index 2a5ce10224ce2b98b481273ef8a04cc4557a9e26..96e5c574857b8230987d0a82affbb14d7450af80 100644 (file)
Binary files a/test/smcont.bin and b/test/smcont.bin differ