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