1 1.1 christos #! /usr/bin/env perl 2 1.1 christos # Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos # 4 1.1 christos # Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos # this file except in compliance with the License. You can obtain a copy 6 1.1 christos # in the file LICENSE in the source distribution or at 7 1.1 christos # https://www.openssl.org/source/license.html 8 1.1 christos 9 1.1 christos use File::Spec::Functions; 10 1.1 christos use File::Copy; 11 1.1 christos use MIME::Base64; 12 1.1 christos use OpenSSL::Test qw(:DEFAULT srctop_file srctop_dir bldtop_file bldtop_dir 13 1.1 christos data_file); 14 1.1 christos use OpenSSL::Test::Utils; 15 1.1 christos 16 1.1 christos my $test_name = "test_store"; 17 1.1 christos setup($test_name); 18 1.1 christos 19 1.1 christos require(srctop_file("test", "recipes", "tconversion.pl")); # for test_file_contains() 20 1.1 christos 21 1.1 christos my $use_md5 = !disabled("md5"); 22 1.1 christos my $use_des = !(disabled("des") || disabled("legacy")); # also affects 3des and pkcs12 app 23 1.1 christos my $use_dsa = !disabled("dsa"); 24 1.1 christos my $use_ecc = !disabled("ec"); 25 1.1 christos 26 1.1 christos my @noexist_files = 27 1.1 christos ( "test/blahdiblah.pem", 28 1.1 christos "test/blahdibleh.der" ); 29 1.1 christos my @src_files = 30 1.1 christos ( "test/testx509.pem", 31 1.1 christos "test/testrsa.pem", 32 1.1 christos "test/testrsapub.pem", 33 1.1 christos "test/testcrl.pem", 34 1.1 christos "apps/server.pem" ); 35 1.1 christos my @data_files = 36 1.1 christos ( "testrsa.msb" ); 37 1.1 christos push(@data_files, 38 1.1 christos ( "testrsa.pvk" )) 39 1.1 christos unless disabled("legacy") || disabled("rc4"); 40 1.1 christos my @src_rsa_files = 41 1.1 christos ( "test/testrsa.pem", 42 1.1 christos "test/testrsapub.pem" ); 43 1.1 christos my @generated_files = 44 1.1 christos ( 45 1.1 christos ### generated from the source files 46 1.1 christos 47 1.1 christos "testx509.der", 48 1.1 christos "testrsa.der", 49 1.1 christos "testrsapub.der", 50 1.1 christos "testcrl.der", 51 1.1 christos 52 1.1 christos ### generated locally 53 1.1 christos 54 1.1 christos "rsa-key-pkcs1.pem", "rsa-key-pkcs1.der", 55 1.1 christos "rsa-key-pkcs1-aes128.pem", 56 1.1 christos "rsa-key-pkcs8.pem", "rsa-key-pkcs8.der", 57 1.1 christos "rsa-key-pkcs8-pbes2-sha1.pem", "rsa-key-pkcs8-pbes2-sha1.der", 58 1.1 christos "rsa-key-pkcs8-pbes2-sha256.pem", "rsa-key-pkcs8-pbes2-sha256.der", 59 1.1 christos ); 60 1.1 christos push(@generated_files, ( 61 1.1 christos "rsa-key-pkcs8-pbes1-sha1-3des.pem", "rsa-key-pkcs8-pbes1-sha1-3des.der", 62 1.1 christos )) if $use_des; 63 1.1 christos push(@generated_files, ( 64 1.1 christos "rsa-key-sha1-3des-sha1.p12", "rsa-key-sha1-3des-sha256.p12", 65 1.1 christos "rsa-key-aes256-cbc-sha256.p12", 66 1.1 christos "rsa-key-md5-des-sha1.p12", 67 1.1 christos "rsa-key-aes256-cbc-md5-des-sha256.p12" 68 1.1 christos )) if $use_des; 69 1.1 christos push(@generated_files, ( 70 1.1 christos "rsa-key-pkcs8-pbes1-md5-des.pem", "rsa-key-pkcs8-pbes1-md5-des.der" 71 1.1 christos )) if $use_md5 && $use_des; 72 1.1 christos push(@generated_files, ( 73 1.1 christos "dsa-key-pkcs1.pem", "dsa-key-pkcs1.der", 74 1.1 christos "dsa-key-pkcs1-aes128.pem", 75 1.1 christos "dsa-key-pkcs8.pem", "dsa-key-pkcs8.der", 76 1.1 christos "dsa-key-pkcs8-pbes2-sha1.pem", "dsa-key-pkcs8-pbes2-sha1.der", 77 1.1 christos )) if $use_dsa; 78 1.1 christos push(@generated_files, "dsa-key-aes256-cbc-sha256.p12") if $use_dsa && $use_des; 79 1.1 christos push(@generated_files, ( 80 1.1 christos "ec-key-pkcs1.pem", "ec-key-pkcs1.der", 81 1.1 christos "ec-key-pkcs1-aes128.pem", 82 1.1 christos "ec-key-pkcs8.pem", "ec-key-pkcs8.der", 83 1.1 christos "ec-key-pkcs8-pbes2-sha1.pem", "ec-key-pkcs8-pbes2-sha1.der", 84 1.1 christos )) if $use_ecc; 85 1.1 christos push(@generated_files, "ec-key-aes256-cbc-sha256.p12") if $use_ecc && $use_des; 86 1.1 christos my %generated_file_files = 87 1.1 christos $^O eq 'linux' 88 1.1 christos ? ( "test/testx509.pem" => "file:testx509.pem", 89 1.1 christos "test/testrsa.pem" => "file:testrsa.pem", 90 1.1 christos "test/testrsapub.pem" => "file:testrsapub.pem", 91 1.1 christos "test/testcrl.pem" => "file:testcrl.pem", 92 1.1 christos "apps/server.pem" => "file:server.pem" ) 93 1.1 christos : (); 94 1.1 christos my @noexist_file_files = 95 1.1 christos ( "file:blahdiblah.pem", 96 1.1 christos "file:test/blahdibleh.der" ); 97 1.1 christos 98 1.1 christos # There is more than one method to get a 'file:' loader. 99 1.1 christos # The default is a built-in provider implementation. 100 1.1 christos # However, there is also an engine, specially for testing purposes. 101 1.1 christos # 102 1.1 christos # @methods is a collection of extra 'openssl storeutl' arguments used to 103 1.1 christos # try the different methods. 104 1.1 christos my @methods; 105 1.1 christos my @prov_method = qw(-provider default); 106 1.1 christos push @prov_method, qw(-provider legacy) unless disabled('legacy'); 107 1.1 christos push @methods, [ @prov_method ]; 108 1.1 christos push @methods, [qw(-engine loader_attic)] 109 1.1 christos unless disabled('loadereng'); 110 1.1 christos 111 1.1 christos my $n = 4 + scalar @methods 112 1.1 christos * ( (3 * scalar @noexist_files) 113 1.1 christos + (6 * scalar @src_files) 114 1.1 christos + (2 * scalar @data_files) 115 1.1 christos + (4 * scalar @generated_files) 116 1.1 christos + (scalar keys %generated_file_files) 117 1.1 christos + (scalar @noexist_file_files) 118 1.1 christos + 3 119 1.1 christos + 11 ); 120 1.1 christos 121 1.1 christos # Test doesn't work under msys because the file name munging doesn't work 122 1.1 christos # correctly with the "ot:" prefix 123 1.1 christos my $do_test_ossltest_store = 124 1.1 christos !(disabled("engine") || disabled("dynamic-engine") || $^O =~ /^msys$/); 125 1.1 christos 126 1.1 christos if ($do_test_ossltest_store) { 127 1.1 christos # test loading with apps 'org.openssl.engine:' loader, using the 128 1.1 christos # ossltest engine. 129 1.1 christos $n += 4 * scalar @src_rsa_files; 130 1.1 christos } 131 1.1 christos 132 1.1 christos plan skip_all => "No plan" if $n == 0; 133 1.1 christos 134 1.1 christos plan tests => $n; 135 1.1 christos 136 1.1 christos my $test_x509 = srctop_file('test', 'testx509.pem'); 137 1.1 christos 138 1.1 christos ok(run(app(["openssl", "storeutl", "-crls", $test_x509])), 139 1.1 christos "storeutil with -crls option"); 140 1.1 christos 141 1.1 christos ok(!run(app(["openssl", "storeutl", $test_x509, "-crls"])), 142 1.1 christos "storeutil with extra parameter (at end) should fail"); 143 1.1 christos 144 1.1 christos indir "store_$$" => sub { 145 1.1 christos if ($do_test_ossltest_store) { 146 1.1 christos # ossltest loads PEM files, with names prefixed with 'ot:'. 147 1.1 christos # This prefix ensures that the files are, in fact, loaded through 148 1.1 christos # that engine and not mistakenly going through the 'file:' loader. 149 1.1 christos 150 1.1 christos my $engine_scheme = 'org.openssl.engine:'; 151 1.1 christos $ENV{OPENSSL_ENGINES} = bldtop_dir("engines"); 152 1.1 christos 153 1.1 christos foreach (@src_rsa_files) { 154 1.1 christos my $file = srctop_file($_); 155 1.1 christos my $file_abs = to_abs_file($file); 156 1.1 christos my @pubin = $_ =~ m|pub\.pem$| ? ("-pubin") : (); 157 1.1 christos 158 1.1 christos ok(run(app(["openssl", "rsa", "-text", "-noout", @pubin, 159 1.1 christos "-engine", "ossltest", "-inform", "engine", 160 1.1 christos "-in", "ot:$file"]))); 161 1.1 christos ok(run(app(["openssl", "rsa", "-text", "-noout", @pubin, 162 1.1 christos "-engine", "ossltest", "-inform", "engine", 163 1.1 christos "-in", "ot:$file_abs"]))); 164 1.1 christos ok(run(app(["openssl", "rsa", "-text", "-noout", @pubin, 165 1.1 christos "-in", "${engine_scheme}ossltest:ot:$file"]))); 166 1.1 christos ok(run(app(["openssl", "rsa", "-text", "-noout", @pubin, 167 1.1 christos "-in", "${engine_scheme}ossltest:ot:$file_abs"]))); 168 1.1 christos } 169 1.1 christos } 170 1.1 christos 171 1.1 christos SKIP: 172 1.1 christos { 173 1.1 christos init() or die "init failed"; 174 1.1 christos 175 1.1 christos my $rehash = init_rehash(); 176 1.1 christos 177 1.1 christos ok(run(app(["openssl", "storeutl", "-out", "cacert.pem", "cacert.pem"])), 178 1.1 christos "identical infile and outfile"); 179 1.1 christos test_file_contains("storeutl output on same input", 180 1.1 christos "cacert.pem", "Total found: 1"); 181 1.1 christos 182 1.1 christos foreach my $method (@methods) { 183 1.1 christos my @storeutl = ( qw(openssl storeutl), @$method ); 184 1.1 christos 185 1.1 christos foreach (@noexist_files) { 186 1.1 christos my $file = srctop_file($_); 187 1.1 christos 188 1.1 christos ok(!run(app([@storeutl, "-noout", $file]))); 189 1.1 christos ok(!run(app([@storeutl, "-noout", to_abs_file($file)]))); 190 1.1 christos { 191 1.1 christos local $ENV{MSYS2_ARG_CONV_EXCL} = "file:"; 192 1.1 christos 193 1.1 christos ok(!run(app([@storeutl, "-noout", 194 1.1 christos to_abs_file_uri($file)]))); 195 1.1 christos } 196 1.1 christos } 197 1.1 christos foreach (@src_files) { 198 1.1 christos my $file = srctop_file($_); 199 1.1 christos 200 1.1 christos ok(run(app([@storeutl, "-noout", $file]))); 201 1.1 christos ok(run(app([@storeutl, "-noout", to_abs_file($file)]))); 202 1.1 christos SKIP: 203 1.1 christos { 204 1.1 christos skip "file: tests disabled on MingW", 4 if $^O =~ /^msys$/; 205 1.1 christos 206 1.1 christos ok(run(app([@storeutl, "-noout", 207 1.1 christos to_abs_file_uri($file)]))); 208 1.1 christos ok(run(app([@storeutl, "-noout", 209 1.1 christos to_abs_file_uri($file, 0, "")]))); 210 1.1 christos ok(run(app([@storeutl, "-noout", 211 1.1 christos to_abs_file_uri($file, 0, "localhost")]))); 212 1.1 christos ok(!run(app([@storeutl, "-noout", 213 1.1 christos to_abs_file_uri($file, 0, "dummy")]))); 214 1.1 christos } 215 1.1 christos } 216 1.1 christos foreach (@data_files) { 217 1.1 christos my $file = data_file($_); 218 1.1 christos 219 1.1 christos ok(run(app([@storeutl, "-noout", "-passin", "pass:password", 220 1.1 christos $file]))); 221 1.1 christos ok(run(app([@storeutl, "-noout", "-passin", "pass:password", 222 1.1 christos to_abs_file($file)]))); 223 1.1 christos } 224 1.1 christos foreach (@generated_files) { 225 1.1 christos ok(run(app([@storeutl, "-noout", "-passin", "pass:password", 226 1.1 christos $_]))); 227 1.1 christos ok(run(app([@storeutl, "-noout", "-passin", "pass:password", 228 1.1 christos to_abs_file($_)]))); 229 1.1 christos 230 1.1 christos SKIP: 231 1.1 christos { 232 1.1 christos skip "file: tests disabled on MingW", 2 if $^O =~ /^msys$/; 233 1.1 christos 234 1.1 christos ok(run(app([@storeutl, "-noout", "-passin", 235 1.1 christos "pass:password", to_abs_file_uri($_)]))); 236 1.1 christos ok(!run(app([@storeutl, "-noout", "-passin", 237 1.1 christos "pass:password", to_file_uri($_)]))); 238 1.1 christos } 239 1.1 christos } 240 1.1 christos foreach (values %generated_file_files) { 241 1.1 christos SKIP: 242 1.1 christos { 243 1.1 christos skip "file: tests disabled on MingW", 1 if $^O =~ /^msys$/; 244 1.1 christos 245 1.1 christos ok(run(app([@storeutl, "-noout", $_]))); 246 1.1 christos } 247 1.1 christos } 248 1.1 christos foreach (@noexist_file_files) { 249 1.1 christos SKIP: 250 1.1 christos { 251 1.1 christos skip "file: tests disabled on MingW", 1 if $^O =~ /^msys$/; 252 1.1 christos 253 1.1 christos ok(!run(app([@storeutl, "-noout", $_]))); 254 1.1 christos } 255 1.1 christos } 256 1.1 christos { 257 1.1 christos my $dir = srctop_dir("test", "certs"); 258 1.1 christos 259 1.1 christos ok(run(app([@storeutl, "-noout", $dir]))); 260 1.1 christos ok(run(app([@storeutl, "-noout", to_abs_file($dir, 1)]))); 261 1.1 christos SKIP: 262 1.1 christos { 263 1.1 christos skip "file: tests disabled on MingW", 1 if $^O =~ /^msys$/; 264 1.1 christos 265 1.1 christos ok(run(app([@storeutl, "-noout", 266 1.1 christos to_abs_file_uri($dir, 1)]))); 267 1.1 christos } 268 1.1 christos } 269 1.1 christos 270 1.1 christos ok(!run(app([@storeutl, '-noout', 271 1.1 christos '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', 272 1.1 christos srctop_file('test', 'testx509.pem')])), 273 1.1 christos "Checking that -subject can't be used with a single file"); 274 1.1 christos 275 1.1 christos ok(run(app([@storeutl, '-certs', '-noout', 276 1.1 christos srctop_file('test', 'testx509.pem')])), 277 1.1 christos "Checking that -certs returns 1 object on a certificate file"); 278 1.1 christos ok(run(app([@storeutl, '-certs', '-noout', 279 1.1 christos srctop_file('test', 'testcrl.pem')])), 280 1.1 christos "Checking that -certs returns 0 objects on a CRL file"); 281 1.1 christos 282 1.1 christos ok(run(app([@storeutl, '-crls', '-noout', 283 1.1 christos srctop_file('test', 'testx509.pem')])), 284 1.1 christos "Checking that -crls returns 0 objects on a certificate file"); 285 1.1 christos ok(run(app([@storeutl, '-crls', '-noout', 286 1.1 christos srctop_file('test', 'testcrl.pem')])), 287 1.1 christos "Checking that -crls returns 1 object on a CRL file"); 288 1.1 christos 289 1.1 christos SKIP: { 290 1.1 christos skip "failed rehash initialisation", 6 unless $rehash; 291 1.1 christos 292 1.1 christos # subject from testx509.pem: 293 1.1 christos # '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert' 294 1.1 christos # issuer from testcrl.pem: 295 1.1 christos # '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority' 296 1.1 christos ok(run(app([@storeutl, '-noout', 297 1.1 christos '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', 298 1.1 christos catdir(curdir(), 'rehash')]))); 299 1.1 christos ok(run(app([@storeutl, '-noout', 300 1.1 christos '-subject', 301 1.1 christos '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', 302 1.1 christos catdir(curdir(), 'rehash')]))); 303 1.1 christos ok(run(app([@storeutl, '-noout', '-certs', 304 1.1 christos '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', 305 1.1 christos catdir(curdir(), 'rehash')]))); 306 1.1 christos ok(run(app([@storeutl, '-noout', '-crls', 307 1.1 christos '-subject', '/C=AU/ST=QLD/CN=SSLeay\/rsa test cert', 308 1.1 christos catdir(curdir(), 'rehash')]))); 309 1.1 christos ok(run(app([@storeutl, '-noout', '-certs', 310 1.1 christos '-subject', 311 1.1 christos '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', 312 1.1 christos catdir(curdir(), 'rehash')]))); 313 1.1 christos ok(run(app([@storeutl, '-noout', '-crls', 314 1.1 christos '-subject', 315 1.1 christos '/C=US/O=RSA Data Security, Inc./OU=Secure Server Certification Authority', 316 1.1 christos catdir(curdir(), 'rehash')]))); 317 1.1 christos } 318 1.1 christos } 319 1.1 christos } 320 1.1 christos }, create => 1, cleanup => 1; 321 1.1 christos 322 1.1 christos sub init { 323 1.1 christos my $cnf = srctop_file('test', 'ca-and-certs.cnf'); 324 1.1 christos my $cakey = srctop_file('test', 'certs', 'ca-key.pem'); 325 1.1 christos my @std_args = qw(-provider default); 326 1.1 christos push @std_args, qw(-provider legacy) 327 1.1 christos unless disabled('legacy'); 328 1.1 christos return ( 329 1.1 christos # rsa-key-pkcs1.pem 330 1.1 christos run(app(["openssl", "pkey", @std_args, 331 1.1 christos "-in", data_file("rsa-key-2432.pem"), 332 1.1 christos "-out", "rsa-key-pkcs1.pem"])) 333 1.1 christos # rsa-key-pkcs1-aes128.pem 334 1.1 christos && run(app(["openssl", "rsa", @std_args, 335 1.1 christos "-passout", "pass:password", "-aes128", 336 1.1 christos "-in", "rsa-key-pkcs1.pem", 337 1.1 christos "-out", "rsa-key-pkcs1-aes128.pem"])) 338 1.1 christos # dsa-key-pkcs1.pem 339 1.1 christos && (!$use_dsa 340 1.1 christos || run(app(["openssl", "gendsa", @std_args, 341 1.1 christos "-out", "dsa-key-pkcs1.pem", 342 1.1 christos data_file("dsaparam.pem")]))) 343 1.1 christos # dsa-key-pkcs1-aes128.pem 344 1.1 christos && (!$use_dsa 345 1.1 christos || run(app(["openssl", "dsa", @std_args, 346 1.1 christos "-passout", "pass:password", "-aes128", 347 1.1 christos "-in", "dsa-key-pkcs1.pem", 348 1.1 christos "-out", "dsa-key-pkcs1-aes128.pem"]))) 349 1.1 christos # ec-key-pkcs1.pem (one might think that 'genec' would be practical) 350 1.1 christos && (!$use_ecc 351 1.1 christos || run(app(["openssl", "ecparam", @std_args, 352 1.1 christos "-genkey", 353 1.1 christos "-name", "prime256v1", 354 1.1 christos "-out", "ec-key-pkcs1.pem"]))) 355 1.1 christos # ec-key-pkcs1-aes128.pem 356 1.1 christos && (!$use_ecc 357 1.1 christos || run(app(["openssl", "ec", @std_args, 358 1.1 christos "-passout", "pass:password", "-aes128", 359 1.1 christos "-in", "ec-key-pkcs1.pem", 360 1.1 christos "-out", "ec-key-pkcs1-aes128.pem"]))) 361 1.1 christos # *-key-pkcs8.pem 362 1.1 christos && runall(sub { 363 1.1 christos my $dstfile = shift; 364 1.1 christos (my $srcfile = $dstfile) 365 1.1 christos =~ s/-key-pkcs8\.pem$/-key-pkcs1.pem/i; 366 1.1 christos run(app(["openssl", "pkcs8", @std_args, 367 1.1 christos "-topk8", "-nocrypt", 368 1.1 christos "-in", $srcfile, "-out", $dstfile])); 369 1.1 christos }, grep(/-key-pkcs8\.pem$/, @generated_files)) 370 1.1 christos # *-key-pkcs8-pbes1-sha1-3des.pem 371 1.1 christos && runall(sub { 372 1.1 christos my $dstfile = shift; 373 1.1 christos (my $srcfile = $dstfile) 374 1.1 christos =~ s/-key-pkcs8-pbes1-sha1-3des\.pem$ 375 1.1 christos /-key-pkcs8.pem/ix; 376 1.1 christos run(app(["openssl", "pkcs8", @std_args, 377 1.1 christos "-topk8", 378 1.1 christos "-passout", "pass:password", 379 1.1 christos "-v1", "pbeWithSHA1And3-KeyTripleDES-CBC", 380 1.1 christos "-in", $srcfile, "-out", $dstfile])); 381 1.1 christos }, grep(/-key-pkcs8-pbes1-sha1-3des\.pem$/, @generated_files)) 382 1.1 christos # *-key-pkcs8-pbes1-md5-des.pem 383 1.1 christos && runall(sub { 384 1.1 christos my $dstfile = shift; 385 1.1 christos (my $srcfile = $dstfile) 386 1.1 christos =~ s/-key-pkcs8-pbes1-md5-des\.pem$ 387 1.1 christos /-key-pkcs8.pem/ix; 388 1.1 christos run(app(["openssl", "pkcs8", @std_args, 389 1.1 christos "-topk8", 390 1.1 christos "-passout", "pass:password", 391 1.1 christos "-v1", "pbeWithSHA1And3-KeyTripleDES-CBC", 392 1.1 christos "-in", $srcfile, "-out", $dstfile])); 393 1.1 christos }, grep(/-key-pkcs8-pbes1-md5-des\.pem$/, @generated_files)) 394 1.1 christos # *-key-pkcs8-pbes2-sha1.pem 395 1.1 christos && runall(sub { 396 1.1 christos my $dstfile = shift; 397 1.1 christos (my $srcfile = $dstfile) 398 1.1 christos =~ s/-key-pkcs8-pbes2-sha1\.pem$ 399 1.1 christos /-key-pkcs8.pem/ix; 400 1.1 christos run(app(["openssl", "pkcs8", @std_args, 401 1.1 christos "-topk8", 402 1.1 christos "-passout", "pass:password", 403 1.1 christos "-v2", "aes256", "-v2prf", "hmacWithSHA1", 404 1.1 christos "-in", $srcfile, "-out", $dstfile])); 405 1.1 christos }, grep(/-key-pkcs8-pbes2-sha1\.pem$/, @generated_files)) 406 1.1 christos # *-key-pkcs8-pbes2-sha1.pem 407 1.1 christos && runall(sub { 408 1.1 christos my $dstfile = shift; 409 1.1 christos (my $srcfile = $dstfile) 410 1.1 christos =~ s/-key-pkcs8-pbes2-sha256\.pem$ 411 1.1 christos /-key-pkcs8.pem/ix; 412 1.1 christos run(app(["openssl", "pkcs8", @std_args, 413 1.1 christos "-topk8", 414 1.1 christos "-passout", "pass:password", 415 1.1 christos "-v2", "aes256", "-v2prf", "hmacWithSHA256", 416 1.1 christos "-in", $srcfile, "-out", $dstfile])); 417 1.1 christos }, grep(/-key-pkcs8-pbes2-sha256\.pem$/, @generated_files)) 418 1.1 christos # *-cert.pem (intermediary for the .p12 inits) 419 1.1 christos && run(app(["openssl", "req", "-x509", @std_args, 420 1.1 christos "-config", $cnf, "-reqexts", "v3_ca", "-noenc", 421 1.1 christos "-key", $cakey, "-out", "cacert.pem"])) 422 1.1 christos && runall(sub { 423 1.1 christos my $srckey = shift; 424 1.1 christos (my $dstfile = $srckey) =~ s|-key-pkcs8\.|-cert.|; 425 1.1 christos (my $csr = $dstfile) =~ s|\.pem|.csr|; 426 1.1 christos 427 1.1 christos (run(app(["openssl", "req", "-new", @std_args, 428 1.1 christos "-config", $cnf, "-section", "userreq", 429 1.1 christos "-key", $srckey, "-out", $csr])) 430 1.1 christos && 431 1.1 christos run(app(["openssl", "x509", @std_args, 432 1.1 christos "-days", "3650", 433 1.1 christos "-CA", "cacert.pem", 434 1.1 christos "-CAkey", $cakey, 435 1.1 christos "-set_serial", time(), "-req", 436 1.1 christos "-in", $csr, "-out", $dstfile]))); 437 1.1 christos }, grep(/-key-pkcs8\.pem$/, @generated_files)) 438 1.1 christos # *.p12 439 1.1 christos && runall(sub { 440 1.1 christos my $dstfile = shift; 441 1.1 christos my ($type, $certpbe_index, $keypbe_index, 442 1.1 christos $macalg_index) = 443 1.1 christos $dstfile =~ m{^(.*)-key-(?| 444 1.1 christos # cert and key PBE are same 445 1.1 christos () # 446 1.1 christos ([^-]*-[^-]*)- # key & cert PBE 447 1.1 christos ([^-]*) # MACalg 448 1.1 christos | 449 1.1 christos # cert and key PBE are not same 450 1.1 christos ([^-]*-[^-]*)- # cert PBE 451 1.1 christos ([^-]*-[^-]*)- # key PBE 452 1.1 christos ([^-]*) # MACalg 453 1.1 christos )\.}x; 454 1.1 christos if (!$certpbe_index) { 455 1.1 christos $certpbe_index = $keypbe_index; 456 1.1 christos } 457 1.1 christos my $srckey = "$type-key-pkcs8.pem"; 458 1.1 christos my $srccert = "$type-cert.pem"; 459 1.1 christos my %pbes = 460 1.1 christos ( 461 1.1 christos "sha1-3des" => "pbeWithSHA1And3-KeyTripleDES-CBC", 462 1.1 christos "md5-des" => "pbeWithMD5AndDES-CBC", 463 1.1 christos "aes256-cbc" => "AES-256-CBC", 464 1.1 christos ); 465 1.1 christos my %macalgs = 466 1.1 christos ( 467 1.1 christos "sha1" => "SHA1", 468 1.1 christos "sha256" => "SHA256", 469 1.1 christos ); 470 1.1 christos my $certpbe = $pbes{$certpbe_index}; 471 1.1 christos my $keypbe = $pbes{$keypbe_index}; 472 1.1 christos my $macalg = $macalgs{$macalg_index}; 473 1.1 christos if (!defined($certpbe) || !defined($keypbe) 474 1.1 christos || !defined($macalg)) { 475 1.1 christos print STDERR "Cert PBE for $certpbe_index not defined\n" 476 1.1 christos unless defined $certpbe; 477 1.1 christos print STDERR "Key PBE for $keypbe_index not defined\n" 478 1.1 christos unless defined $keypbe; 479 1.1 christos print STDERR "MACALG for $macalg_index not defined\n" 480 1.1 christos unless defined $macalg; 481 1.1 christos print STDERR "(destination file was $dstfile)\n"; 482 1.1 christos return 0; 483 1.1 christos } 484 1.1 christos run(app(["openssl", "pkcs12", @std_args, 485 1.1 christos "-inkey", $srckey, 486 1.1 christos "-in", $srccert, "-passout", "pass:password", 487 1.1 christos "-chain", "-CAfile", "cacert.pem", 488 1.1 christos "-export", "-macalg", $macalg, 489 1.1 christos "-certpbe", $certpbe, "-keypbe", $keypbe, 490 1.1 christos "-out", $dstfile])); 491 1.1 christos }, grep(/\.p12/, @generated_files)) 492 1.1 christos # *.der (the end all init) 493 1.1 christos && runall(sub { 494 1.1 christos my $dstfile = shift; 495 1.1 christos (my $srcfile = $dstfile) =~ s/\.der$/.pem/i; 496 1.1 christos if (! -f $srcfile) { 497 1.1 christos $srcfile = srctop_file("test", $srcfile); 498 1.1 christos } 499 1.1 christos my $infh; 500 1.1 christos unless (open $infh, $srcfile) { 501 1.1 christos return 0; 502 1.1 christos } 503 1.1 christos my $l; 504 1.1 christos while (($l = <$infh>) !~ /^-----BEGIN\s/ 505 1.1 christos || $l =~ /^-----BEGIN.*PARAMETERS-----/) { 506 1.1 christos } 507 1.1 christos my $b64 = ""; 508 1.1 christos while (($l = <$infh>) !~ /^-----END\s/) { 509 1.1 christos $l =~ s|\R$||; 510 1.1 christos $b64 .= $l unless $l =~ /:/; 511 1.1 christos } 512 1.1 christos close $infh; 513 1.1 christos my $der = decode_base64($b64); 514 1.1 christos unless (length($b64) / 4 * 3 - length($der) < 3) { 515 1.1 christos print STDERR "Length error, ",length($b64), 516 1.1 christos " bytes of base64 became ",length($der), 517 1.1 christos " bytes of der? ($srcfile => $dstfile)\n"; 518 1.1 christos return 0; 519 1.1 christos } 520 1.1 christos my $outfh; 521 1.1 christos unless (open $outfh, ">:raw", $dstfile) { 522 1.1 christos return 0; 523 1.1 christos } 524 1.1 christos print $outfh $der; 525 1.1 christos close $outfh; 526 1.1 christos return 1; 527 1.1 christos }, grep(/\.der$/, @generated_files)) 528 1.1 christos && runall(sub { 529 1.1 christos my $srcfile = shift; 530 1.1 christos my $dstfile = $generated_file_files{$srcfile}; 531 1.1 christos 532 1.1 christos unless (copy srctop_file($srcfile), $dstfile) { 533 1.1 christos warn "$!\n"; 534 1.1 christos return 0; 535 1.1 christos } 536 1.1 christos return 1; 537 1.1 christos }, keys %generated_file_files) 538 1.1 christos ); 539 1.1 christos } 540 1.1 christos 541 1.1 christos sub init_rehash { 542 1.1 christos return ( 543 1.1 christos mkdir(catdir(curdir(), 'rehash')) 544 1.1 christos && copy(srctop_file('test', 'testx509.pem'), 545 1.1 christos catdir(curdir(), 'rehash')) 546 1.1 christos && copy(srctop_file('test', 'testcrl.pem'), 547 1.1 christos catdir(curdir(), 'rehash')) 548 1.1 christos && run(app(['openssl', 'rehash', catdir(curdir(), 'rehash')])) 549 1.1 christos ); 550 1.1 christos } 551 1.1 christos 552 1.1 christos sub runall { 553 1.1 christos my ($function, @items) = @_; 554 1.1 christos 555 1.1 christos foreach (@items) { 556 1.1 christos return 0 unless $function->($_); 557 1.1 christos } 558 1.1 christos return 1; 559 1.1 christos } 560 1.1 christos 561 1.1 christos # According to RFC8089, a relative file: path is invalid. We still produce 562 1.1 christos # them for testing purposes. 563 1.1 christos sub to_file_uri { 564 1.1 christos my ($file, $isdir, $authority) = @_; 565 1.1 christos my $vol; 566 1.1 christos my $dir; 567 1.1 christos 568 1.1 christos die "to_file_uri: No file given\n" if !defined($file) || $file eq ''; 569 1.1 christos 570 1.1 christos ($vol, $dir, $file) = File::Spec->splitpath($file, $isdir // 0); 571 1.1 christos 572 1.1 christos # Make sure we have a Unix style directory. 573 1.1 christos $dir = join('/', File::Spec->splitdir($dir)); 574 1.1 christos # Canonicalise it (note: it seems to be only needed on Unix) 575 1.1 christos while (1) { 576 1.1 christos my $newdir = $dir; 577 1.1 christos $newdir =~ s|/[^/]*[^/\.]+[^/]*/\.\./|/|g; 578 1.1 christos last if $newdir eq $dir; 579 1.1 christos $dir = $newdir; 580 1.1 christos } 581 1.1 christos # Take care of the corner cases the loop can't handle, and that $dir 582 1.1 christos # ends with a / unless it's empty 583 1.1 christos $dir =~ s|/[^/]*[^/\.]+[^/]*/\.\.$|/|; 584 1.1 christos $dir =~ s|^[^/]*[^/\.]+[^/]*/\.\./|/|; 585 1.1 christos $dir =~ s|^[^/]*[^/\.]+[^/]*/\.\.$||; 586 1.1 christos if ($isdir // 0) { 587 1.1 christos $dir =~ s|/$|| if $dir ne '/'; 588 1.1 christos } else { 589 1.1 christos $dir .= '/' if $dir ne '' && $dir !~ m|/$|; 590 1.1 christos } 591 1.1 christos 592 1.1 christos # If the file system has separate volumes (at present, Windows and VMS) 593 1.1 christos # we need to handle them. In URIs, they are invariably the first 594 1.1 christos # component of the path, which is always absolute. 595 1.1 christos # On VMS, user:[foo.bar] translates to /user/foo/bar 596 1.1 christos # On Windows, c:\Users\Foo translates to /c:/Users/Foo 597 1.1 christos if ($vol ne '') { 598 1.1 christos $vol =~ s|:||g if ($^O eq "VMS"); 599 1.1 christos $dir = '/' . $dir if $dir ne '' && $dir !~ m|^/|; 600 1.1 christos $dir = '/' . $vol . $dir; 601 1.1 christos } 602 1.1 christos $file = $dir . $file; 603 1.1 christos 604 1.1 christos return "file://$authority$file" if defined $authority; 605 1.1 christos return "file:$file"; 606 1.1 christos } 607 1.1 christos 608 1.1 christos sub to_abs_file { 609 1.1 christos my ($file) = @_; 610 1.1 christos 611 1.1 christos return File::Spec->rel2abs($file); 612 1.1 christos } 613 1.1 christos 614 1.1 christos sub to_abs_file_uri { 615 1.1 christos my ($file, $isdir, $authority) = @_; 616 1.1 christos 617 1.1 christos die "to_abs_file_uri: No file given\n" if !defined($file) || $file eq ''; 618 1.1 christos return to_file_uri(to_abs_file($file), $isdir, $authority); 619 1.1 christos } 620