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