]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
apps: cover pkeyutl oneshot buffer path with empty file input
authorJakub Zelenka <jakub.zelenka@openssl.foundation>
Mon, 22 Jun 2026 17:47:23 +0000 (19:47 +0200)
committerTomas Mraz <tomas@openssl.foundation>
Thu, 25 Jun 2026 17:00:28 +0000 (19:00 +0200)
The non-mmap buffer fallback in do_raw_keyop() for oneshot (only_nomd)
keys was never exercised on Unix, since any file with non-zero size
takes the mmap path and returns before reaching it. Signing and
verifying an empty file gives filesize 0, which skips the mmap block
(guarded by filesize > 0) and falls through to the buffer switch,
covering both the SIGN and VERIFY arms.

Assisted-by: Claude:claude-opus-4-8
Reviewed-by: Daniel Kubec <kubec@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jun 25 17:00:36 2026
(Merged from https://github.com/openssl/openssl/pull/31644)

test/recipes/20-test_pkeyutl.t

index 4458887f5cfbaf7e7f0512f1a5e76428fa20b976..e7552a8021ac64092401d54032a8faabbbc5cbae 100644 (file)
@@ -17,7 +17,7 @@ use File::Compare qw/compare_text compare/;
 
 setup("test_pkeyutl");
 
-plan tests => 31;
+plan tests => 32;
 
 # For the tests below we use the cert itself as the TBS file
 
@@ -214,7 +214,7 @@ SKIP: {
 }
 
 SKIP: {
-    skip "EdDSA is not supported by this OpenSSL build", 6
+    skip "EdDSA is not supported by this OpenSSL build", 7
         if disabled("ecx");
 
     subtest "pkeyutl -rawin oneshot with file input (mmap or buffer path)" => sub {
@@ -273,6 +273,41 @@ SKIP: {
         unlink($stderr_file) if -f $stderr_file;
     };
 
+    subtest "pkeyutl -rawin oneshot with empty file (buffer path, filesize 0)" => sub {
+        my $ed25519_key = srctop_file("test", "tested25519.pem");
+        my $ed25519_pub = srctop_file("test", "tested25519pub.pem");
+        my $empty = "pkeyutl_empty.bin";
+        my $sigfile = "rawin_empty_ed25519.sig";
+        # Ed25519 is deterministic, so signing the empty message with
+        # tested25519.pem always yields this exact signature.
+        my $expected_sig =
+            "42a443bd375c962f571dbf7402654219655b30c395dee06e" .
+            "d2a4a41342686da620889e374807266a3aab535345985c96" .
+            "cbb7475c8b0df47968d29fbf3d352e0c";
+
+        plan tests => 3;
+
+        # create a zero-length input file
+        open(my $fh, '>', $empty) or die "cannot create $empty: $!";
+        close($fh);
+
+        ok(run(app(['openssl', 'pkeyutl', '-sign', '-rawin', '-inkey', $ed25519_key,
+                    '-in', $empty, '-out', $sigfile])),
+           "Ed25519 -rawin sign from empty file (filesize 0 buffer path)");
+        ok(run(app(['openssl', 'pkeyutl', '-verify', '-rawin', '-pubin', '-inkey', $ed25519_pub,
+                    '-sigfile', $sigfile, '-in', $empty])),
+           "Ed25519 -rawin verify from empty file");
+
+        # check the produced signature matches the known reference value
+        open(my $sfh, '<:raw', $sigfile) or die "cannot open $sigfile: $!";
+        read($sfh, my $sig, -s $sigfile);
+        close($sfh);
+        is(unpack("H*", $sig), $expected_sig,
+           "Ed25519 -rawin empty file signature matches the reference value");
+
+        unlink($empty);
+    };
+
     subtest "Ed2559 CLI signature generation and verification" => sub {
         tsignverify("Ed25519",
                     srctop_file("test","tested25519.pem"),