1*e7be843bSPierre Pronchery#! /usr/bin/env perl 2*e7be843bSPierre Pronchery# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. 3*e7be843bSPierre Pronchery# 4*e7be843bSPierre Pronchery# Licensed under the Apache License 2.0 (the "License"). You may not use 5*e7be843bSPierre Pronchery# this file except in compliance with the License. You can obtain a copy 6*e7be843bSPierre Pronchery# in the file LICENSE in the source distribution or at 7*e7be843bSPierre Pronchery# https://www.openssl.org/source/license.html 8*e7be843bSPierre Pronchery 9*e7be843bSPierre Proncheryuse strict; 10*e7be843bSPierre Proncheryuse warnings; 11*e7be843bSPierre Pronchery 12*e7be843bSPierre Proncheryuse OpenSSL::Test::Utils; 13*e7be843bSPierre Proncheryuse File::Copy; 14*e7be843bSPierre Proncheryuse File::Compare qw(compare_text compare); 15*e7be843bSPierre Proncheryuse OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips is_nofips/; 16*e7be843bSPierre Pronchery 17*e7be843bSPierre Proncherysetup("test_pkcs8"); 18*e7be843bSPierre Pronchery 19*e7be843bSPierre Proncheryplan tests => 18; 20*e7be843bSPierre Pronchery 21*e7be843bSPierre Proncherymy $pc5_key = srctop_file('test', 'certs', 'pc5-key.pem'); 22*e7be843bSPierre Pronchery 23*e7be843bSPierre Proncherymy $inout = 'inout.pem'; 24*e7be843bSPierre Proncherycopy($pc5_key, $inout); 25*e7be843bSPierre Proncheryok(run(app(['openssl', 'pkcs8', '-topk8', '-in', $inout, 26*e7be843bSPierre Pronchery '-out', $inout, '-passout', 'pass:password'])), 27*e7be843bSPierre Pronchery "identical infile and outfile, to PKCS#8"); 28*e7be843bSPierre Proncheryok(run(app(['openssl', 'pkcs8', '-in', $inout, 29*e7be843bSPierre Pronchery '-out', $inout, '-passin', 'pass:password'])), 30*e7be843bSPierre Pronchery "identical infile and outfile, from PKCS#8"); 31*e7be843bSPierre Proncheryis(compare_text($pc5_key, $inout), 0, 32*e7be843bSPierre Pronchery "Same file contents after converting forth and back"); 33*e7be843bSPierre Pronchery 34*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'pkcs8', '-topk8', 35*e7be843bSPierre Pronchery '-in', $pc5_key, 36*e7be843bSPierre Pronchery '-out', 'pbkdf2_default_saltlen.pem', 37*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 38*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v2.0 format using PBKDF2 with the default saltlen"); 39*e7be843bSPierre Pronchery 40*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687" 41*e7be843bSPierre Pronchery# i.e. 2 byte header + 16 byte salt. 42*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'asn1parse', 43*e7be843bSPierre Pronchery '-in', 'pbkdf2_default_saltlen.pem', 44*e7be843bSPierre Pronchery '-offset', '34', '-length', '18']))), 45*e7be843bSPierre Pronchery "Check the default size of the PBKDF2 PARAM 'salt length' is 16"); 46*e7be843bSPierre Pronchery 47*e7be843bSPierre ProncherySKIP: { 48*e7be843bSPierre Pronchery skip "scrypt is not supported by this OpenSSL build", 4 49*e7be843bSPierre Pronchery if disabled("scrypt"); 50*e7be843bSPierre Pronchery 51*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'pkcs8', '-topk8', 52*e7be843bSPierre Pronchery '-in', $pc5_key, 53*e7be843bSPierre Pronchery '-scrypt', 54*e7be843bSPierre Pronchery '-out', 'scrypt_default_saltlen.pem', 55*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 56*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v2.0 format using scrypt with the default saltlen"); 57*e7be843bSPierre Pronchery 58*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687" 59*e7be843bSPierre Pronchery# i.e. 2 byte header + 16 byte salt. 60*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'asn1parse', 61*e7be843bSPierre Pronchery '-in', 'scrypt_default_saltlen.pem', 62*e7be843bSPierre Pronchery '-offset', '34', '-length', '18']))), 63*e7be843bSPierre Pronchery "Check the default size of the SCRYPT PARAM 'salt length' = 16"); 64*e7be843bSPierre Pronchery 65*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'pkcs8', '-topk8', 66*e7be843bSPierre Pronchery '-in', $pc5_key, 67*e7be843bSPierre Pronchery '-scrypt', 68*e7be843bSPierre Pronchery '-saltlen', '8', 69*e7be843bSPierre Pronchery '-out', 'scrypt_64bit_saltlen.pem', 70*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 71*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v2.0 format using scrypt with a salt length of 8 bytes"); 72*e7be843bSPierre Pronchery 73*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:3C1147976A2B61CA" 74*e7be843bSPierre Pronchery# i.e. 2 byte header + 8 byte salt. 75*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'asn1parse', 76*e7be843bSPierre Pronchery '-in', 'scrypt_64bit_saltlen.pem', 77*e7be843bSPierre Pronchery '-offset', '34', '-length', '10']))), 78*e7be843bSPierre Pronchery "Check the size of the SCRYPT PARAM 'salt length' is 8"); 79*e7be843bSPierre Pronchery} 80*e7be843bSPierre Pronchery 81*e7be843bSPierre ProncherySKIP: { 82*e7be843bSPierre Pronchery skip "legacy provider is not supported by this OpenSSL build", 4 83*e7be843bSPierre Pronchery if disabled('legacy') || disabled("des"); 84*e7be843bSPierre Pronchery 85*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'pkcs8', '-topk8', 86*e7be843bSPierre Pronchery '-in', $pc5_key, 87*e7be843bSPierre Pronchery '-v1', "PBE-MD5-DES", 88*e7be843bSPierre Pronchery '-provider', 'legacy', 89*e7be843bSPierre Pronchery '-provider', 'default', 90*e7be843bSPierre Pronchery '-out', 'pbe1.pem', 91*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 92*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v1.5 format using pbeWithMD5AndDES-CBC with the default saltlen"); 93*e7be843bSPierre Pronchery 94*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'asn1parse', 95*e7be843bSPierre Pronchery '-in', 'pbe1.pem', 96*e7be843bSPierre Pronchery '-offset', '19', '-length', '10']))), 97*e7be843bSPierre Pronchery "Check the default size of the PBE PARAM 'salt length' = 8"); 98*e7be843bSPierre Pronchery 99*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'pkcs8', '-topk8', 100*e7be843bSPierre Pronchery '-in', $pc5_key, 101*e7be843bSPierre Pronchery '-v1', "PBE-MD5-DES", 102*e7be843bSPierre Pronchery '-saltlen', '16', 103*e7be843bSPierre Pronchery '-provider', 'legacy', 104*e7be843bSPierre Pronchery '-provider', 'default', 105*e7be843bSPierre Pronchery '-out', 'pbe1_128bitsalt.pem', 106*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 107*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v1.5 format using pbeWithMD5AndDES-CBC with the 16 byte saltlen"); 108*e7be843bSPierre Pronchery 109*e7be843bSPierre Pronchery ok(run(app(([ 'openssl', 'asn1parse', 110*e7be843bSPierre Pronchery '-in', 'pbe1_128bitsalt.pem', 111*e7be843bSPierre Pronchery '-offset', '19', '-length', '18']))), 112*e7be843bSPierre Pronchery "Check the size of the PBE PARAM 'salt length' = 16"); 113*e7be843bSPierre Pronchery}; 114*e7be843bSPierre Pronchery 115*e7be843bSPierre Pronchery 116*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'pkcs8', '-topk8', 117*e7be843bSPierre Pronchery '-in', $pc5_key, 118*e7be843bSPierre Pronchery '-saltlen', '8', 119*e7be843bSPierre Pronchery '-out', 'pbkdf2_64bit_saltlen.pem', 120*e7be843bSPierre Pronchery '-passout', 'pass:password']))), 121*e7be843bSPierre Pronchery "Convert a private key to PKCS5 v2.0 format using pbkdf2 with a salt length of 8 bytes"); 122*e7be843bSPierre Pronchery 123*e7be843bSPierre Pronchery# We expect the output to be of the form "0:d=0 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:3C1147976A2B61CA" 124*e7be843bSPierre Pronchery# i.e. 2 byte header + 8 byte salt. 125*e7be843bSPierre Proncheryok(run(app(([ 'openssl', 'asn1parse', 126*e7be843bSPierre Pronchery '-in', 'pbkdf2_64bit_saltlen.pem', 127*e7be843bSPierre Pronchery '-offset', '34', '-length', '10']))), 128*e7be843bSPierre Pronchery "Check the size of the PBKDF2 PARAM 'salt length' is 8"); 129*e7be843bSPierre Pronchery 130*e7be843bSPierre Pronchery 131*e7be843bSPierre ProncherySKIP: { 132*e7be843bSPierre Pronchery skip "SM2, SM3 or SM4 is not supported by this OpenSSL build", 3 133*e7be843bSPierre Pronchery if disabled("sm2") || disabled("sm3") || disabled("sm4"); 134*e7be843bSPierre Pronchery 135*e7be843bSPierre Pronchery ok_nofips(run(app(([ 'openssl', 'pkcs8', '-topk8', 136*e7be843bSPierre Pronchery '-in', srctop_file('test', 'certs', 'sm2.key'), 137*e7be843bSPierre Pronchery '-out', 'sm2-pbes2-sm4-hmacWithSM3.key', 138*e7be843bSPierre Pronchery '-passout', 'pass:password', 139*e7be843bSPierre Pronchery '-v2', 'sm4', '-v2prf', 'hmacWithSM3']))), 140*e7be843bSPierre Pronchery "Convert a private key to PKCS#5 v2.0 format using SM4 and hmacWithSM3"); 141*e7be843bSPierre Pronchery 142*e7be843bSPierre Pronchery ok_nofips(run(app(([ 'openssl', 'pkcs8', '-topk8', 143*e7be843bSPierre Pronchery '-in', 'sm2-pbes2-sm4-hmacWithSM3.key', 144*e7be843bSPierre Pronchery '-out', 'sm2.key', 145*e7be843bSPierre Pronchery '-passin', 'pass:password', '-nocrypt', 146*e7be843bSPierre Pronchery '-v2', 'sm4', '-v2prf', 'hmacWithSM3']))), 147*e7be843bSPierre Pronchery "Convert from PKCS#5 v2.0 format to PKCS#8 unencrypted format"); 148*e7be843bSPierre Pronchery 149*e7be843bSPierre Pronchery is_nofips(compare_text(srctop_file('test', 'certs', 'sm2.key'), 'sm2.key', 150*e7be843bSPierre Pronchery sub { 151*e7be843bSPierre Pronchery my $in1 = $_[0]; 152*e7be843bSPierre Pronchery my $in2 = $_[1]; 153*e7be843bSPierre Pronchery $in1 =~ s/\r\n/\n/g; 154*e7be843bSPierre Pronchery $in2 =~ s/\r\n/\n/g; 155*e7be843bSPierre Pronchery $in1 ne $in2 156*e7be843bSPierre Pronchery }), 0, "compare test/certs/sm2.key to sm2.key") 157*e7be843bSPierre Pronchery} 158