xref: /openssl/test/recipes/15-test_genec.t (revision c0f39ded)
1#! /usr/bin/env perl
2# Copyright 2017-2020 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 OpenSSL::Test qw/:DEFAULT srctop_file/;
15use OpenSSL::Test::Utils;
16
17# 'supported' and 'unsupported' reflect the current state of things.  In
18# Test::More terms, 'supported' works exactly like ok(run(whatever)), while
19# 'unsupported' wraps that in a TODO: { } block.
20#
21# The first argument is the test name (this becomes the last argument to
22# 'ok')
23# The remaining argument are passed unchecked to 'run'.
24
25# 1:    the result of app() or similar, i.e. something you can pass to
26sub supported_pass {
27    my $str = shift;
28
29    ok(run(@_), $str);
30}
31
32sub supported_fail {
33    my $str = shift;
34
35    ok(!run(@_), $str);
36}
37
38setup("test_genec");
39
40plan skip_all => "This test is unsupported in a no-ec build"
41    if disabled("ec");
42
43my @prime_curves = qw(
44    secp112r1
45    secp112r2
46    secp128r1
47    secp128r2
48    secp160k1
49    secp160r1
50    secp160r2
51    secp192k1
52    secp224k1
53    secp224r1
54    secp256k1
55    secp384r1
56    secp521r1
57    prime192v1
58    prime192v2
59    prime192v3
60    prime239v1
61    prime239v2
62    prime239v3
63    prime256v1
64    wap-wsg-idm-ecid-wtls6
65    wap-wsg-idm-ecid-wtls7
66    wap-wsg-idm-ecid-wtls8
67    wap-wsg-idm-ecid-wtls9
68    wap-wsg-idm-ecid-wtls12
69    brainpoolP160r1
70    brainpoolP160t1
71    brainpoolP192r1
72    brainpoolP192t1
73    brainpoolP224r1
74    brainpoolP224t1
75    brainpoolP256r1
76    brainpoolP256t1
77    brainpoolP320r1
78    brainpoolP320t1
79    brainpoolP384r1
80    brainpoolP384t1
81    brainpoolP512r1
82    brainpoolP512t1
83);
84
85my @binary_curves = qw(
86    sect113r1
87    sect113r2
88    sect131r1
89    sect131r2
90    sect163k1
91    sect163r1
92    sect163r2
93    sect193r1
94    sect193r2
95    sect233k1
96    sect233r1
97    sect239k1
98    sect283k1
99    sect283r1
100    sect409k1
101    sect409r1
102    sect571k1
103    sect571r1
104    c2pnb163v1
105    c2pnb163v2
106    c2pnb163v3
107    c2pnb176v1
108    c2tnb191v1
109    c2tnb191v2
110    c2tnb191v3
111    c2pnb208w1
112    c2tnb239v1
113    c2tnb239v2
114    c2tnb239v3
115    c2pnb272w1
116    c2pnb304w1
117    c2tnb359v1
118    c2pnb368w1
119    c2tnb431r1
120    wap-wsg-idm-ecid-wtls1
121    wap-wsg-idm-ecid-wtls3
122    wap-wsg-idm-ecid-wtls4
123    wap-wsg-idm-ecid-wtls5
124    wap-wsg-idm-ecid-wtls10
125    wap-wsg-idm-ecid-wtls11
126);
127
128my @explicit_only_curves = ();
129push(@explicit_only_curves, qw(
130        Oakley-EC2N-3
131        Oakley-EC2N-4
132    )) if !disabled("ec2m");
133
134my @other_curves = ();
135push(@other_curves, 'SM2')
136    if !disabled("sm2");
137
138my @curve_aliases = qw(
139    P-192
140    P-224
141    P-256
142    P-384
143    P-521
144);
145push(@curve_aliases, qw(
146    B-163
147    B-233
148    B-283
149    B-409
150    B-571
151    K-163
152    K-233
153    K-283
154    K-409
155    K-571
156)) if !disabled("ec2m");
157
158my @curve_list = ();
159push(@curve_list, @prime_curves);
160push(@curve_list, @binary_curves)
161    if !disabled("ec2m");
162push(@curve_list, @other_curves);
163push(@curve_list, @curve_aliases);
164
165my %params_encodings =
166    (
167     'named_curve'      => \&supported_pass,
168     'explicit'         => \&supported_pass
169    );
170
171my @output_formats = ('PEM', 'DER');
172
173plan tests => scalar(@curve_list) * scalar(keys %params_encodings)
174    * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
175    * 2                             # Test generating parameters and keys
176    + 1                             # Checking that with no curve it fails
177    + 1                             # Checking that with unknown curve it fails
178    + 1                             # Subtest for explicit only curves
179    + 1                             # base serializer test
180    ;
181
182ok(!run(app([ 'openssl', 'genpkey',
183              '-algorithm', 'EC'])),
184   "genpkey EC with no params should fail");
185
186ok(!run(app([ 'openssl', 'genpkey',
187              '-algorithm', 'EC',
188              '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])),
189   "genpkey EC with unknown curve name should fail");
190
191ok(run(app([ 'openssl', 'genpkey',
192             '-provider-path', 'providers',
193             '-provider', 'base',
194             '-config', srctop_file("test", "default.cnf"),
195             '-algorithm', 'EC',
196             '-pkeyopt', 'ec_paramgen_curve:prime256v1',
197             '-text'])),
198    "generate a private key and serialize it using the base provider");
199
200foreach my $curvename (@curve_list) {
201    foreach my $paramenc (sort keys %params_encodings) {
202        my $fn = $params_encodings{$paramenc};
203
204        # --- Test generating parameters ---
205
206        $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
207              app([ 'openssl', 'genpkey', '-genparam',
208                    '-algorithm', 'EC',
209                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
210                    '-pkeyopt', 'ec_param_enc:'.$paramenc,
211                    '-text']));
212
213        foreach my $outform (@output_formats) {
214            my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
215            $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
216                  app([ 'openssl', 'genpkey', '-genparam',
217                        '-algorithm', 'EC',
218                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
219                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
220                        '-outform', $outform,
221                        '-out', $outfile]));
222        }
223
224        # --- Test generating actual keys ---
225
226        $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
227              app([ 'openssl', 'genpkey',
228                    '-algorithm', 'EC',
229                    '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
230                    '-pkeyopt', 'ec_param_enc:'.$paramenc,
231                    '-text']));
232
233        foreach my $outform (@output_formats) {
234            my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
235            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
236                  app([ 'openssl', 'genpkey',
237                        '-algorithm', 'EC',
238                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
239                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
240                        '-outform', $outform,
241                        '-out', $outfile]));
242        }
243    }
244}
245
246subtest "test curves that only support explicit parameters encoding" => sub {
247    plan skip_all => "This test is unsupported under current configuration"
248            if scalar(@explicit_only_curves) <= 0;
249
250    plan tests => scalar(@explicit_only_curves) * scalar(keys %params_encodings)
251        * (1 + scalar(@output_formats)) # Try listed @output_formats and text output
252        * 2                             # Test generating parameters and keys
253        ;
254
255    my %params_encodings =
256        (
257         'named_curve'      => \&supported_fail,
258         'explicit'         => \&supported_pass
259        );
260
261    foreach my $curvename (@explicit_only_curves) {
262        foreach my $paramenc (sort keys %params_encodings) {
263            my $fn = $params_encodings{$paramenc};
264
265            # --- Test generating parameters ---
266
267            $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)",
268                  app([ 'openssl', 'genpkey', '-genparam',
269                        '-algorithm', 'EC',
270                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
271                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
272                        '-text']));
273
274            foreach my $outform (@output_formats) {
275                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
276                $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
277                      app([ 'openssl', 'genpkey', '-genparam',
278                            '-algorithm', 'EC',
279                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
280                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
281                            '-outform', $outform,
282                            '-out', $outfile]));
283            }
284
285            # --- Test generating actual keys ---
286
287            $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)",
288                  app([ 'openssl', 'genpkey',
289                        '-algorithm', 'EC',
290                        '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
291                        '-pkeyopt', 'ec_param_enc:'.$paramenc,
292                        '-text']));
293
294            foreach my $outform (@output_formats) {
295                my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform;
296                $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})",
297                      app([ 'openssl', 'genpkey',
298                            '-algorithm', 'EC',
299                            '-pkeyopt', 'ec_paramgen_curve:'.$curvename,
300                            '-pkeyopt', 'ec_param_enc:'.$paramenc,
301                            '-outform', $outform,
302                            '-out', $outfile]));
303            }
304        }
305    }
306};
307