1 1.1 christos #! /usr/bin/env perl 2 1.1.1.3 christos # Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos # 4 1.1 christos # Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos # this file except in compliance with the License. You can obtain a copy 6 1.1 christos # in the file LICENSE in the source distribution or at 7 1.1 christos # https://www.openssl.org/source/license.html 8 1.1 christos 9 1.1 christos 10 1.1 christos use strict; 11 1.1 christos use warnings; 12 1.1 christos 13 1.1 christos use File::Spec; 14 1.1.1.4 christos use File::Basename; 15 1.1.1.3 christos use OpenSSL::Test qw/:DEFAULT with srctop_file bldtop_dir/; 16 1.1 christos use OpenSSL::Test::Utils; 17 1.1 christos 18 1.1 christos setup("test_dgst"); 19 1.1 christos 20 1.1.1.4 christos plan tests => 13; 21 1.1 christos 22 1.1 christos sub tsignverify { 23 1.1 christos my $testtext = shift; 24 1.1 christos my $privkey = shift; 25 1.1 christos my $pubkey = shift; 26 1.1 christos 27 1.1.1.4 christos my $data_to_sign = srctop_file('test', 'data.bin'); 28 1.1.1.4 christos my $other_data = srctop_file('test', 'data2.bin'); 29 1.1 christos 30 1.1.1.4 christos my $sigfile = basename($privkey, '.pem') . '.sig'; 31 1.1 christos plan tests => 4; 32 1.1 christos 33 1.1 christos ok(run(app(['openssl', 'dgst', '-sign', $privkey, 34 1.1.1.4 christos '-out', $sigfile, 35 1.1 christos $data_to_sign])), 36 1.1 christos $testtext.": Generating signature"); 37 1.1 christos 38 1.1 christos ok(run(app(['openssl', 'dgst', '-prverify', $privkey, 39 1.1.1.4 christos '-signature', $sigfile, 40 1.1 christos $data_to_sign])), 41 1.1 christos $testtext.": Verify signature with private key"); 42 1.1 christos 43 1.1 christos ok(run(app(['openssl', 'dgst', '-verify', $pubkey, 44 1.1.1.4 christos '-signature', $sigfile, 45 1.1 christos $data_to_sign])), 46 1.1 christos $testtext.": Verify signature with public key"); 47 1.1 christos 48 1.1 christos ok(!run(app(['openssl', 'dgst', '-verify', $pubkey, 49 1.1.1.4 christos '-signature', $sigfile, 50 1.1 christos $other_data])), 51 1.1 christos $testtext.": Expect failure verifying mismatching data"); 52 1.1.1.4 christos } 53 1.1.1.4 christos 54 1.1.1.4 christos sub tsignverify_sha512 { 55 1.1.1.4 christos my $testtext = shift; 56 1.1.1.4 christos my $privkey = shift; 57 1.1.1.4 christos my $pubkey = shift; 58 1.1.1.4 christos 59 1.1.1.4 christos my $data_to_sign = srctop_file('test', 'data.bin'); 60 1.1.1.4 christos my $other_data = srctop_file('test', 'data2.bin'); 61 1.1.1.4 christos 62 1.1.1.4 christos my $sigfile = basename($privkey, '.pem') . '.sig'; 63 1.1.1.4 christos plan tests => 5; 64 1.1.1.4 christos 65 1.1.1.4 christos ok(run(app(['openssl', 'sha512', '-sign', $privkey, 66 1.1.1.4 christos '-out', $sigfile, 67 1.1.1.4 christos $data_to_sign])), 68 1.1.1.4 christos $testtext.": Generating signature using sha512 command"); 69 1.1.1.4 christos 70 1.1.1.4 christos ok(run(app(['openssl', 'sha512', '-verify', $pubkey, 71 1.1.1.4 christos '-signature', $sigfile, 72 1.1.1.4 christos $data_to_sign])), 73 1.1.1.4 christos $testtext.": Verify signature with public key using sha512 command"); 74 1.1.1.4 christos 75 1.1.1.4 christos ok(run(app(['openssl', 'dgst', '-sha512', '-prverify', $privkey, 76 1.1.1.4 christos '-signature', $sigfile, 77 1.1.1.4 christos $data_to_sign])), 78 1.1.1.4 christos $testtext.": Verify signature with private key"); 79 1.1.1.4 christos 80 1.1.1.4 christos ok(run(app(['openssl', 'dgst', '-sha512', '-verify', $pubkey, 81 1.1.1.4 christos '-signature', $sigfile, 82 1.1.1.4 christos $data_to_sign])), 83 1.1.1.4 christos $testtext.": Verify signature with public key"); 84 1.1 christos 85 1.1.1.4 christos ok(!run(app(['openssl', 'dgst', '-sha512', '-verify', $pubkey, 86 1.1.1.4 christos '-signature', $sigfile, 87 1.1.1.4 christos $other_data])), 88 1.1.1.4 christos $testtext.": Expect failure verifying mismatching data"); 89 1.1 christos } 90 1.1 christos 91 1.1 christos SKIP: { 92 1.1 christos skip "RSA is not supported by this OpenSSL build", 1 93 1.1 christos if disabled("rsa"); 94 1.1 christos 95 1.1 christos subtest "RSA signature generation and verification with `dgst` CLI" => sub { 96 1.1 christos tsignverify("RSA", 97 1.1 christos srctop_file("test","testrsa.pem"), 98 1.1 christos srctop_file("test","testrsapub.pem")); 99 1.1 christos }; 100 1.1.1.4 christos 101 1.1.1.4 christos subtest "RSA signature generation and verification with `sha512` CLI" => sub { 102 1.1.1.4 christos tsignverify_sha512("RSA", 103 1.1.1.4 christos srctop_file("test","testrsa2048.pem"), 104 1.1.1.4 christos srctop_file("test","testrsa2048pub.pem")); 105 1.1.1.4 christos }; 106 1.1 christos } 107 1.1 christos 108 1.1 christos SKIP: { 109 1.1 christos skip "DSA is not supported by this OpenSSL build", 1 110 1.1 christos if disabled("dsa"); 111 1.1 christos 112 1.1 christos subtest "DSA signature generation and verification with `dgst` CLI" => sub { 113 1.1 christos tsignverify("DSA", 114 1.1 christos srctop_file("test","testdsa.pem"), 115 1.1 christos srctop_file("test","testdsapub.pem")); 116 1.1 christos }; 117 1.1 christos } 118 1.1 christos 119 1.1 christos SKIP: { 120 1.1 christos skip "ECDSA is not supported by this OpenSSL build", 1 121 1.1 christos if disabled("ec"); 122 1.1 christos 123 1.1 christos subtest "ECDSA signature generation and verification with `dgst` CLI" => sub { 124 1.1 christos tsignverify("ECDSA", 125 1.1 christos srctop_file("test","testec-p256.pem"), 126 1.1 christos srctop_file("test","testecpub-p256.pem")); 127 1.1 christos }; 128 1.1 christos } 129 1.1 christos 130 1.1 christos SKIP: { 131 1.1 christos skip "EdDSA is not supported by this OpenSSL build", 2 132 1.1 christos if disabled("ec"); 133 1.1 christos 134 1.1 christos skip "EdDSA is not supported with `dgst` CLI", 2; 135 1.1 christos 136 1.1 christos subtest "Ed25519 signature generation and verification with `dgst` CLI" => sub { 137 1.1 christos tsignverify("Ed25519", 138 1.1 christos srctop_file("test","tested25519.pem"), 139 1.1 christos srctop_file("test","tested25519pub.pem")); 140 1.1 christos }; 141 1.1 christos 142 1.1 christos subtest "Ed448 signature generation and verification with `dgst` CLI" => sub { 143 1.1 christos tsignverify("Ed448", 144 1.1 christos srctop_file("test","tested448.pem"), 145 1.1 christos srctop_file("test","tested448pub.pem")); 146 1.1 christos }; 147 1.1 christos } 148 1.1.1.2 christos 149 1.1.1.2 christos SKIP: { 150 1.1.1.2 christos skip "dgst with engine is not supported by this OpenSSL build", 1 151 1.1.1.2 christos if disabled("engine") || disabled("dynamic-engine"); 152 1.1.1.2 christos 153 1.1.1.2 christos subtest "SHA1 generation by engine with `dgst` CLI" => sub { 154 1.1.1.2 christos plan tests => 1; 155 1.1.1.2 christos 156 1.1.1.2 christos my $testdata = srctop_file('test', 'data.bin'); 157 1.1.1.2 christos # intentionally using -engine twice, please do not remove the duplicate line 158 1.1.1.2 christos my @macdata = run(app(['openssl', 'dgst', '-sha1', 159 1.1.1.3 christos '-engine', "ossltest", 160 1.1.1.3 christos '-engine', "ossltest", 161 1.1.1.2 christos $testdata]), capture => 1); 162 1.1.1.2 christos chomp(@macdata); 163 1.1.1.2 christos my $expected = qr/SHA1\(\Q$testdata\E\)= 000102030405060708090a0b0c0d0e0f10111213/; 164 1.1.1.2 christos ok($macdata[0] =~ $expected, "SHA1: Check HASH value is as expected ($macdata[0]) vs ($expected)"); 165 1.1.1.2 christos } 166 1.1.1.2 christos } 167 1.1.1.4 christos 168 1.1.1.4 christos subtest "HMAC generation with `dgst` CLI" => sub { 169 1.1.1.4 christos plan tests => 2; 170 1.1.1.4 christos 171 1.1.1.4 christos my $testdata = srctop_file('test', 'data.bin'); 172 1.1.1.4 christos #HMAC the data twice to check consistency 173 1.1.1.4 christos my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', '123456', 174 1.1.1.4 christos $testdata, $testdata]), capture => 1); 175 1.1.1.4 christos chomp(@hmacdata); 176 1.1.1.4 christos my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/; 177 1.1.1.4 christos ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)"); 178 1.1.1.4 christos ok($hmacdata[1] =~ $expected, 179 1.1.1.4 christos "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)"); 180 1.1.1.4 christos }; 181 1.1.1.4 christos 182 1.1.1.4 christos subtest "HMAC generation with `dgst` CLI, default digest" => sub { 183 1.1.1.4 christos plan tests => 2; 184 1.1.1.4 christos 185 1.1.1.4 christos my $testdata = srctop_file('test', 'data.bin'); 186 1.1.1.4 christos #HMAC the data twice to check consistency 187 1.1.1.4 christos my @hmacdata = run(app(['openssl', 'dgst', '-hmac', '123456', 188 1.1.1.4 christos $testdata, $testdata]), capture => 1); 189 1.1.1.4 christos chomp(@hmacdata); 190 1.1.1.4 christos my $expected = qr/HMAC-SHA256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/; 191 1.1.1.4 christos ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)"); 192 1.1.1.4 christos ok($hmacdata[1] =~ $expected, 193 1.1.1.4 christos "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)"); 194 1.1.1.4 christos }; 195 1.1.1.4 christos 196 1.1.1.4 christos subtest "HMAC generation with `dgst` CLI, key via option" => sub { 197 1.1.1.4 christos plan tests => 2; 198 1.1.1.4 christos 199 1.1.1.4 christos my $testdata = srctop_file('test', 'data.bin'); 200 1.1.1.4 christos #HMAC the data twice to check consistency 201 1.1.1.4 christos my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', 202 1.1.1.4 christos '-macopt', 'hexkey:FFFF', 203 1.1.1.4 christos $testdata, $testdata]), capture => 1); 204 1.1.1.4 christos chomp(@hmacdata); 205 1.1.1.4 christos my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= b6727b7bb251dfa65846e0a8223bdd57d244aa6d7e312cb906d8e21f2dee3a57/; 206 1.1.1.4 christos ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)"); 207 1.1.1.4 christos ok($hmacdata[1] =~ $expected, 208 1.1.1.4 christos "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)"); 209 1.1.1.4 christos }; 210 1.1.1.4 christos 211 1.1.1.4 christos subtest "Custom length XOF digest generation with `dgst` CLI" => sub { 212 1.1.1.4 christos plan tests => 2; 213 1.1.1.4 christos 214 1.1.1.4 christos my $testdata = srctop_file('test', 'data.bin'); 215 1.1.1.4 christos #Digest the data twice to check consistency 216 1.1.1.4 christos my @xofdata = run(app(['openssl', 'dgst', '-shake128', '-xoflen', '64', 217 1.1.1.4 christos $testdata, $testdata]), capture => 1); 218 1.1.1.4 christos chomp(@xofdata); 219 1.1.1.4 christos my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa64ffd0b3e2bf8cd73d5182dfba19b6a8a2eab96d2df854b647b3795ef090582abe41ba4e0717dc4df40bc4e17d88e4677/; 220 1.1.1.4 christos ok($xofdata[0] =~ $expected, "XOF: Check digest value is as expected ($xofdata[0]) vs ($expected)"); 221 1.1.1.4 christos ok($xofdata[1] =~ $expected, 222 1.1.1.4 christos "XOF: Check second digest value is consistent with the first ($xofdata[1]) vs ($expected)"); 223 1.1.1.4 christos }; 224 1.1.1.4 christos 225 1.1.1.4 christos subtest "SHAKE digest generation with no xoflen set `dgst` CLI" => sub { 226 1.1.1.4 christos plan tests => 1; 227 1.1.1.4 christos 228 1.1.1.4 christos my $testdata = srctop_file('test', 'data.bin'); 229 1.1.1.4 christos my @xofdata = run(app(['openssl', 'dgst', '-shake128', $testdata], stderr => "outerr.txt"), capture => 1); 230 1.1.1.4 christos chomp(@xofdata); 231 1.1.1.4 christos my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa6/; 232 1.1.1.4 christos ok($xofdata[0] =~ $expected, "Check short digest is output"); 233 1.1.1.4 christos }; 234 1.1.1.4 christos 235 1.1.1.4 christos SKIP: { 236 1.1.1.4 christos skip "ECDSA is not supported by this OpenSSL build", 1 237 1.1.1.4 christos if disabled("ec"); 238 1.1.1.4 christos 239 1.1.1.4 christos subtest "signing with xoflen is not supported `dgst` CLI" => sub { 240 1.1.1.4 christos plan tests => 1; 241 1.1.1.4 christos my $data_to_sign = srctop_file('test', 'data.bin'); 242 1.1.1.4 christos 243 1.1.1.4 christos ok(!run(app(['openssl', 'dgst', '-shake256', '-xoflen', '64', 244 1.1.1.4 christos '-sign', srctop_file("test","testec-p256.pem"), 245 1.1.1.4 christos '-out', 'test.sig', 246 1.1.1.4 christos srctop_file('test', 'data.bin')])), 247 1.1.1.4 christos "Generating signature with xoflen should fail"); 248 1.1.1.4 christos } 249 1.1.1.4 christos } 250