1#! /usr/bin/env perl
2# Copyright 2017-2021 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
10use strict;
11use warnings;
12
13use File::Spec;
14use File::Basename;
15use OpenSSL::Test qw/:DEFAULT with srctop_file/;
16use OpenSSL::Test::Utils;
17
18setup("test_dgst");
19
20plan tests => 9;
21
22sub tsignverify {
23    my $testtext = shift;
24    my $privkey = shift;
25    my $pubkey = shift;
26
27    my $data_to_sign = srctop_file('test', 'data.bin');
28    my $other_data = srctop_file('test', 'data2.bin');
29
30    my $sigfile = basename($privkey, '.pem') . '.sig';
31    plan tests => 4;
32
33    ok(run(app(['openssl', 'dgst', '-sign', $privkey,
34                '-out', $sigfile,
35                $data_to_sign])),
36       $testtext.": Generating signature");
37
38    ok(run(app(['openssl', 'dgst', '-prverify', $privkey,
39                '-signature', $sigfile,
40                $data_to_sign])),
41       $testtext.": Verify signature with private key");
42
43    ok(run(app(['openssl', 'dgst', '-verify', $pubkey,
44                '-signature', $sigfile,
45                $data_to_sign])),
46       $testtext.": Verify signature with public key");
47
48    ok(!run(app(['openssl', 'dgst', '-verify', $pubkey,
49                 '-signature', $sigfile,
50                 $other_data])),
51       $testtext.": Expect failure verifying mismatching data");
52}
53
54SKIP: {
55    skip "RSA is not supported by this OpenSSL build", 1
56        if disabled("rsa");
57
58    subtest "RSA signature generation and verification with `dgst` CLI" => sub {
59        tsignverify("RSA",
60                    srctop_file("test","testrsa.pem"),
61                    srctop_file("test","testrsapub.pem"));
62    };
63}
64
65SKIP: {
66    skip "DSA is not supported by this OpenSSL build", 1
67        if disabled("dsa");
68
69    subtest "DSA signature generation and verification with `dgst` CLI" => sub {
70        tsignverify("DSA",
71                    srctop_file("test","testdsa.pem"),
72                    srctop_file("test","testdsapub.pem"));
73    };
74}
75
76SKIP: {
77    skip "ECDSA is not supported by this OpenSSL build", 1
78        if disabled("ec");
79
80    subtest "ECDSA signature generation and verification with `dgst` CLI" => sub {
81        tsignverify("ECDSA",
82                    srctop_file("test","testec-p256.pem"),
83                    srctop_file("test","testecpub-p256.pem"));
84    };
85}
86
87SKIP: {
88    skip "EdDSA is not supported by this OpenSSL build", 2
89        if disabled("ec");
90
91    skip "EdDSA is not supported with `dgst` CLI", 2;
92
93    subtest "Ed25519 signature generation and verification with `dgst` CLI" => sub {
94        tsignverify("Ed25519",
95                    srctop_file("test","tested25519.pem"),
96                    srctop_file("test","tested25519pub.pem"));
97    };
98
99    subtest "Ed448 signature generation and verification with `dgst` CLI" => sub {
100        tsignverify("Ed448",
101                    srctop_file("test","tested448.pem"),
102                    srctop_file("test","tested448pub.pem"));
103    };
104}
105
106subtest "HMAC generation with `dgst` CLI" => sub {
107    plan tests => 2;
108
109    my $testdata = srctop_file('test', 'data.bin');
110    #HMAC the data twice to check consistency
111    my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac', '123456',
112                            $testdata, $testdata]), capture => 1);
113    chomp(@hmacdata);
114    my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
115    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
116    ok($hmacdata[1] =~ $expected,
117       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
118};
119
120subtest "HMAC generation with `dgst` CLI, default digest" => sub {
121    plan tests => 2;
122
123    my $testdata = srctop_file('test', 'data.bin');
124    #HMAC the data twice to check consistency
125    my @hmacdata = run(app(['openssl', 'dgst', '-hmac', '123456',
126                            $testdata, $testdata]), capture => 1);
127    chomp(@hmacdata);
128    my $expected = qr/HMAC-SHA256\(\Q$testdata\E\)= 6f12484129c4a761747f13d8234a1ff0e074adb34e9e9bf3a155c391b97b9a7c/;
129    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
130    ok($hmacdata[1] =~ $expected,
131       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
132};
133
134subtest "HMAC generation with `dgst` CLI, key via option" => sub {
135    plan tests => 2;
136
137    my $testdata = srctop_file('test', 'data.bin');
138    #HMAC the data twice to check consistency
139    my @hmacdata = run(app(['openssl', 'dgst', '-sha256', '-hmac',
140                            '-macopt', 'hexkey:FFFF',
141                            $testdata, $testdata]), capture => 1);
142    chomp(@hmacdata);
143    my $expected = qr/HMAC-SHA2-256\(\Q$testdata\E\)= b6727b7bb251dfa65846e0a8223bdd57d244aa6d7e312cb906d8e21f2dee3a57/;
144    ok($hmacdata[0] =~ $expected, "HMAC: Check HMAC value is as expected ($hmacdata[0]) vs ($expected)");
145    ok($hmacdata[1] =~ $expected,
146       "HMAC: Check second HMAC value is consistent with the first ($hmacdata[1]) vs ($expected)");
147};
148
149subtest "Custom length XOF digest generation with `dgst` CLI" => sub {
150    plan tests => 2;
151
152    my $testdata = srctop_file('test', 'data.bin');
153    #Digest the data twice to check consistency
154    my @xofdata = run(app(['openssl', 'dgst', '-shake128', '-xoflen', '64',
155                           $testdata, $testdata]), capture => 1);
156    chomp(@xofdata);
157    my $expected = qr/SHAKE-128\(\Q$testdata\E\)= bb565dac72640109e1c926ef441d3fa64ffd0b3e2bf8cd73d5182dfba19b6a8a2eab96d2df854b647b3795ef090582abe41ba4e0717dc4df40bc4e17d88e4677/;
158    ok($xofdata[0] =~ $expected, "XOF: Check digest value is as expected ($xofdata[0]) vs ($expected)");
159    ok($xofdata[1] =~ $expected,
160       "XOF: Check second digest value is consistent with the first ($xofdata[1]) vs ($expected)");
161};
162