xref: /openssl/test/recipes/20-test_pkeyutl.t (revision abad748d)
1#! /usr/bin/env perl
2# Copyright 2018-2024 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
9use strict;
10use warnings;
11
12use File::Spec;
13use File::Basename;
14use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips/;
15use OpenSSL::Test::Utils;
16use File::Compare qw/compare_text compare/;
17
18setup("test_pkeyutl");
19
20plan tests => 25;
21
22# For the tests below we use the cert itself as the TBS file
23
24SKIP: {
25    skip "Skipping tests that require EC, SM2 or SM3", 4
26        if disabled("ec") || disabled("sm2") || disabled("sm3");
27
28    # SM2
29    ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-sign',
30                      '-in', srctop_file('test', 'certs', 'sm2.pem'),
31                      '-inkey', srctop_file('test', 'certs', 'sm2.key'),
32                      '-out', 'sm2.sig', '-rawin',
33                      '-digest', 'sm3', '-pkeyopt', 'distid:someid']))),
34                      "Sign a piece of data using SM2");
35    ok_nofips(run(app(([ 'openssl', 'pkeyutl',
36                      '-verify', '-certin',
37                      '-in', srctop_file('test', 'certs', 'sm2.pem'),
38                      '-inkey', srctop_file('test', 'certs', 'sm2.pem'),
39                      '-sigfile', 'sm2.sig', '-rawin',
40                      '-digest', 'sm3', '-pkeyopt', 'distid:someid']))),
41                      "Verify an SM2 signature against a piece of data");
42    ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-encrypt',
43                      '-in', srctop_file('test', 'data2.bin'),
44                      '-inkey', srctop_file('test', 'certs', 'sm2-pub.key'),
45                      '-pubin', '-out', 'sm2.enc']))),
46                      "Encrypt a piece of data using SM2");
47    ok_nofips(run(app(([ 'openssl', 'pkeyutl', '-decrypt',
48                      '-in', 'sm2.enc',
49                      '-inkey', srctop_file('test', 'certs', 'sm2.key'),
50                      '-out', 'sm2.dat'])))
51                      && compare_text('sm2.dat',
52                                      srctop_file('test', 'data2.bin')) == 0,
53                      "Decrypt a piece of data using SM2");
54}
55
56SKIP: {
57    skip "Skipping tests that require ECX", 7
58        if disabled("ecx");
59
60    # Ed25519
61    ok(run(app(([ 'openssl', 'pkeyutl', '-sign', '-in',
62                  srctop_file('test', 'certs', 'server-ed25519-cert.pem'),
63                  '-inkey', srctop_file('test', 'certs', 'server-ed25519-key.pem'),
64                  '-out', 'Ed25519.sig']))),
65                  "Sign a piece of data using Ed25519");
66    ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', '-in',
67                  srctop_file('test', 'certs', 'server-ed25519-cert.pem'),
68                  '-inkey', srctop_file('test', 'certs', 'server-ed25519-cert.pem'),
69                  '-sigfile', 'Ed25519.sig']))),
70                  "Verify an Ed25519 signature against a piece of data");
71    ok(!run(app(([ 'openssl', 'pkeyutl', '-verifyrecover', '-in', 'Ed25519.sig',
72                   '-inkey', srctop_file('test', 'certs', 'server-ed25519-key.pem')]))),
73       "Cannot use -verifyrecover with EdDSA");
74
75    # Ed448
76    ok(run(app(([ 'openssl', 'pkeyutl', '-sign', '-in',
77                  srctop_file('test', 'certs', 'server-ed448-cert.pem'),
78                  '-inkey', srctop_file('test', 'certs', 'server-ed448-key.pem'),
79                  '-out', 'Ed448.sig', '-rawin']))),
80                  "Sign a piece of data using Ed448");
81    ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', '-in',
82                  srctop_file('test', 'certs', 'server-ed448-cert.pem'),
83                  '-inkey', srctop_file('test', 'certs', 'server-ed448-cert.pem'),
84                  '-sigfile', 'Ed448.sig', '-rawin']))),
85                  "Verify an Ed448 signature against a piece of data");
86    ok(run(app(([ 'openssl', 'pkeyutl', '-sign', '-in',
87                  srctop_file('test', 'certs', 'server-ed448-cert.pem'),
88                  '-inkey', srctop_file('test', 'certs', 'server-ed448-key.pem'),
89                  '-out', 'Ed448.sig']))),
90                  "Sign a piece of data using Ed448 -rawin no more needed");
91    ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin', '-in',
92                  srctop_file('test', 'certs', 'server-ed448-cert.pem'),
93                  '-inkey', srctop_file('test', 'certs', 'server-ed448-cert.pem'),
94                  '-sigfile', 'Ed448.sig']))),
95                  "Verify an Ed448 signature against a piece of data, no -rawin");
96}
97
98my $sigfile;
99sub tsignverify {
100    my $testtext = shift;
101    my $privkey = shift;
102    my $pubkey = shift;
103    my @extraopts = @_;
104
105    my $data_to_sign = srctop_file('test', 'data.bin');
106    my $other_data = srctop_file('test', 'data2.bin');
107    $sigfile = basename($privkey, '.pem') . '.sig';
108
109    my @args = ();
110    plan tests => 5;
111
112    @args = ('openssl', 'pkeyutl', '-sign',
113             '-inkey', $privkey,
114             '-out', $sigfile,
115             '-in', $data_to_sign);
116    push(@args, @extraopts);
117    ok(run(app([@args])),
118       $testtext.": Generating signature");
119
120    @args = ('openssl', 'pkeyutl', '-sign',
121             '-inkey', $privkey,
122             '-keyform', 'DER',
123             '-out', $sigfile,
124             '-in', $data_to_sign);
125    push(@args, @extraopts);
126    ok(!run(app([@args])),
127       $testtext.": Checking that mismatching keyform fails");
128
129    @args = ('openssl', 'pkeyutl', '-verify',
130             '-inkey', $privkey,
131             '-sigfile', $sigfile,
132             '-in', $data_to_sign);
133    push(@args, @extraopts);
134    ok(run(app([@args])),
135       $testtext.": Verify signature with private key");
136
137    @args = ('openssl', 'pkeyutl', '-verify',
138             '-keyform', 'PEM',
139             '-inkey', $pubkey, '-pubin',
140             '-sigfile', $sigfile,
141             '-in', $data_to_sign);
142    push(@args, @extraopts);
143    ok(run(app([@args])),
144       $testtext.": Verify signature with public key");
145
146    @args = ('openssl', 'pkeyutl', '-verify',
147             '-inkey', $pubkey, '-pubin',
148             '-sigfile', $sigfile,
149             '-in', $other_data);
150    push(@args, @extraopts);
151    ok(!run(app([@args])),
152       $testtext.": Expect failure verifying mismatching data");
153}
154
155SKIP: {
156    skip "RSA is not supported by this OpenSSL build", 3
157        if disabled("rsa");
158
159    subtest "RSA CLI signature generation and verification" => sub {
160        tsignverify("RSA",
161                    srctop_file("test","testrsa.pem"),
162                    srctop_file("test","testrsapub.pem"),
163                    "-rawin", "-digest", "sha256");
164    };
165
166    ok(run(app((['openssl', 'pkeyutl', '-verifyrecover', '-in', $sigfile,
167                 '-pubin', '-inkey', srctop_file('test', 'testrsapub.pem')]))),
168       "RSA: Verify signature with -verifyrecover");
169
170    subtest "RSA CLI signature and verification with pkeyopt" => sub {
171        tsignverify("RSA",
172                    srctop_file("test","testrsa.pem"),
173                    srctop_file("test","testrsapub.pem"),
174                    "-rawin", "-digest", "sha256",
175                    "-pkeyopt", "rsa_padding_mode:pss");
176    };
177
178}
179
180SKIP: {
181    skip "DSA is not supported by this OpenSSL build", 1
182        if disabled("dsa");
183
184    subtest "DSA CLI signature generation and verification" => sub {
185        tsignverify("DSA",
186                    srctop_file("test","testdsa.pem"),
187                    srctop_file("test","testdsapub.pem"),
188                    "-rawin", "-digest", "sha256");
189    };
190}
191
192SKIP: {
193    skip "ECDSA is not supported by this OpenSSL build", 1
194        if disabled("ec");
195
196    subtest "ECDSA CLI signature generation and verification" => sub {
197        tsignverify("ECDSA",
198                    srctop_file("test","testec-p256.pem"),
199                    srctop_file("test","testecpub-p256.pem"),
200                    "-rawin", "-digest", "sha256");
201    };
202}
203
204SKIP: {
205    skip "EdDSA is not supported by this OpenSSL build", 4
206        if disabled("ecx");
207
208    subtest "Ed2559 CLI signature generation and verification" => sub {
209        tsignverify("Ed25519",
210                    srctop_file("test","tested25519.pem"),
211                    srctop_file("test","tested25519pub.pem"),
212                    "-rawin");
213    };
214
215    subtest "Ed448 CLI signature generation and verification" => sub {
216        tsignverify("Ed448",
217                    srctop_file("test","tested448.pem"),
218                    srctop_file("test","tested448pub.pem"),
219                    "-rawin");
220    };
221
222    subtest "Ed2559 CLI signature generation and verification, no -rawin" => sub {
223        tsignverify("Ed25519",
224                    srctop_file("test","tested25519.pem"),
225                    srctop_file("test","tested25519pub.pem"));
226    };
227
228    subtest "Ed448 CLI signature generation and verification, no -rawin" => sub {
229        tsignverify("Ed448",
230                    srctop_file("test","tested448.pem"),
231                    srctop_file("test","tested448pub.pem"));
232    };
233}
234
235#Encap/decap tests
236# openssl pkeyutl -encap -pubin -inkey rsa_pub.pem -secret secret.bin -out encap_out.bin
237# openssl pkeyutl -decap -inkey rsa_priv.pem -in encap_out.bin -out decap_out.bin
238# decap_out is equal to secret
239SKIP: {
240    skip "RSA is not supported by this OpenSSL build", 5
241        if disabled("rsa");
242
243    # Self-compat
244    ok(run(app(([ 'openssl', 'pkeyutl', '-encap', '-pubin', '-kemop', 'RSASVE',
245                  '-inkey', srctop_file('test', 'testrsa2048pub.pem'),
246                  '-out', 'encap_out.bin', '-secret', 'secret.bin']))),
247                  "RSA pubkey encapsulation");
248    ok(run(app(([ 'openssl', 'pkeyutl', '-decap', '-kemop', 'RSASVE',
249                  '-inkey', srctop_file('test', 'testrsa2048.pem'),
250                  '-in', 'encap_out.bin', '-out', 'decap_out.bin']))),
251                  "RSA pubkey decapsulation");
252    is(compare("secret.bin", "decap_out.bin"), 0, "Secret is correctly decapsulated");
253
254    # Pregenerated
255    ok(run(app(([ 'openssl', 'pkeyutl', '-decap', '-kemop', 'RSASVE',
256                  '-inkey', srctop_file('test', 'testrsa2048.pem'),
257                  '-in', srctop_file('test', 'encap_out.bin'), '-out', 'decap_out_etl.bin']))),
258                  "RSA pubkey decapsulation - pregenerated");
259
260    is(compare(srctop_file('test', 'encap_secret.bin'), "decap_out_etl.bin"), 0,
261               "Secret is correctly decapsulated - pregenerated");
262}
263
264