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