1 1.1 christos #! /usr/bin/env perl 2 1.1 christos # Copyright 2017-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 10 1.1 christos use strict; 11 1.1 christos use warnings; 12 1.1 christos 13 1.1 christos use File::Spec; 14 1.1 christos use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file/; 15 1.1 christos use OpenSSL::Test::Utils; 16 1.1 christos 17 1.1 christos BEGIN { 18 1.1 christos setup("test_genrsa"); 19 1.1 christos } 20 1.1 christos 21 1.1 christos use lib srctop_dir('Configurations'); 22 1.1 christos use lib bldtop_dir('.'); 23 1.1 christos 24 1.1 christos my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); 25 1.1 christos 26 1.1 christos plan tests => 27 1.1 christos ($no_fips ? 0 : 5) # Extra FIPS related tests 28 1.1 christos + 16; 29 1.1 christos 30 1.1 christos # We want to know that an absurdly small number of bits isn't support 31 1.1 christos is(run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem', 32 1.1 christos '-algorithm', 'RSA', '-pkeyopt', 'rsa_keygen_bits:8', 33 1.1 christos '-pkeyopt', 'rsa_keygen_pubexp:3'])), 34 1.1 christos 0, "genpkey 8"); 35 1.1 christos is(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', '8'])), 36 1.1 christos 0, "genrsa -3 8"); 37 1.1 christos 38 1.1 christos # Depending on the shared library, we might have different lower limits. 39 1.1 christos # Let's find it! This is a simple binary search 40 1.1 christos # ------------------------------------------------------------ 41 1.1 christos # NOTE: $good may need an update in the future 42 1.1 christos # ------------------------------------------------------------ 43 1.1 christos note "Looking for lowest amount of bits"; 44 1.1 christos my $bad = 3; # Log2 of number of bits (2 << 3 == 8) 45 1.1 christos my $good = 11; # Log2 of number of bits (2 << 11 == 2048) 46 1.1 christos my $fin; 47 1.1 christos while ($good > $bad + 1) { 48 1.1 christos my $checked = int(($good + $bad + 1) / 2); 49 1.1 christos my $bits = 2 ** $checked; 50 1.1 christos $fin = run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem', 51 1.1 christos '-algorithm', 'RSA', '-pkeyopt', 'rsa_keygen_pubexp:65537', 52 1.1 christos '-pkeyopt', "rsa_keygen_bits:$bits", 53 1.1 christos ], stderr => undef)); 54 1.1 christos if ($fin) { 55 1.1 christos note 2 ** $checked, " bits is good"; 56 1.1 christos $good = $checked; 57 1.1 christos } else { 58 1.1 christos note 2 ** $checked, " bits is bad"; 59 1.1 christos $bad = $checked; 60 1.1 christos } 61 1.1 christos } 62 1.1 christos $good++ if $good == $bad; 63 1.1 christos $good = 2 ** $good; 64 1.1 christos note "Found lowest allowed amount of bits to be $good"; 65 1.1 christos 66 1.1 christos ok(run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', 67 1.1 christos '-pkeyopt', 'rsa_keygen_pubexp:65537', 68 1.1 christos '-pkeyopt', "rsa_keygen_bits:$good", 69 1.1 christos '-out', 'genrsatest.pem' ])), 70 1.1 christos "genpkey $good"); 71 1.1 christos ok(run(app([ 'openssl', 'pkey', '-check', '-in', 'genrsatest.pem', '-noout' ])), 72 1.1 christos "pkey -check"); 73 1.1 christos 74 1.1 christos ok(run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', 75 1.1 christos '-pkeyopt', 'rsa_keygen_bits:2048', 76 1.1 christos '-out', 'genrsatest2048.pem' ])), 77 1.1 christos "genpkey 2048 bits"); 78 1.1 christos ok(run(app([ 'openssl', 'pkey', '-check', '-in', 'genrsatest2048.pem', '-noout' ])), 79 1.1 christos "pkey -check"); 80 1.1 christos 81 1.1 christos ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', 82 1.1 christos '-pkeyopt', 'hexe:02', 83 1.1 christos '-out', 'genrsatest.pem' ])), 84 1.1 christos "genpkey with a bad public exponent should fail"); 85 1.1 christos ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'RSA', 86 1.1 christos '-pkeyopt', 'e:65538', 87 1.1 christos '-out', 'genrsatest.pem' ])), 88 1.1 christos "genpkey with a even public exponent should fail"); 89 1.1 christos ok(!run(app([ 'openssl', 'genpkey', '-propquery', 'unknown', 90 1.1 christos '-algorithm', 'RSA' ])), 91 1.1 christos "genpkey requesting unknown=yes property should fail"); 92 1.1 christos 93 1.1 christos SKIP: { 94 1.1 christos skip "Skipping rsa command line test", 2 if disabled("deprecated-3.0"); 95 1.1 christos 96 1.1 christos ok(run(app([ 'openssl', 'genrsa', '-3', '-out', 'genrsatest.pem', $good ])), 97 1.1 christos "genrsa -3 $good"); 98 1.1 christos ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), 99 1.1 christos "rsa -check"); 100 1.1 christos } 101 1.1 christos 102 1.1 christos ok(run(app([ 'openssl', 'genrsa', '-f4', '-out', 'genrsatest.pem', $good ])), 103 1.1 christos "genrsa -f4 $good"); 104 1.1 christos ok(run(app([ 'openssl', 'rsa', '-check', '-in', 'genrsatest.pem', '-noout' ])), 105 1.1 christos "rsa -check"); 106 1.1 christos ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest.pem', '-out', 'genrsatest-enc.pem', 107 1.1 christos '-aes256', '-passout', 'pass:x' ])), 108 1.1 christos "rsa encrypt"); 109 1.1 christos # Check the default salt length for PBKDF2 is 16 bytes 110 1.1 christos # We expect the output to be of the form "0:d=0 hl=2 l= 16 prim: OCTET STRING [HEX DUMP]:FAC7F37508E6B7A805BF4B13861B3687" 111 1.1 christos # i.e. 2 byte header + 16 byte salt. 112 1.1 christos ok(run(app(([ 'openssl', 'asn1parse', 113 1.1 christos '-in', 'genrsatest-enc.pem', 114 1.1 christos '-offset', '34', '-length', '18']))), 115 1.1 christos "Check the default size of the PBKDF2 PARAM 'salt length' is 16"); 116 1.1 christos ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest-enc.pem', '-passin', 'pass:x' ])), 117 1.1 christos "rsa decrypt"); 118 1.1 christos 119 1.1 christos unless ($no_fips) { 120 1.1 christos my $provconf = srctop_file("test", "fips-and-base.cnf"); 121 1.1 christos my $provpath = bldtop_dir("providers"); 122 1.1 christos my @prov = ( "-provider-path", $provpath, 123 1.1 christos "-config", $provconf); 124 1.1 christos 125 1.1 christos $ENV{OPENSSL_TEST_LIBCTX} = "1"; 126 1.1 christos ok(run(app(['openssl', 'genpkey', 127 1.1 christos @prov, 128 1.1 christos '-algorithm', 'RSA', 129 1.1 christos '-pkeyopt', 'bits:2080', 130 1.1 christos '-out', 'genrsatest2080.pem'])), 131 1.1 christos "Generating RSA key with > 2048 bits and < 3072 bits"); 132 1.1 christos ok(run(app(['openssl', 'genpkey', 133 1.1 christos @prov, 134 1.1 christos '-algorithm', 'RSA', 135 1.1 christos '-pkeyopt', 'bits:3072', 136 1.1 christos '-out', 'genrsatest3072.pem'])), 137 1.1 christos "Generating RSA key with 3072 bits"); 138 1.1 christos 139 1.1 christos ok(!run(app(['openssl', 'genrsa', @prov, '512'])), 140 1.1 christos "Generating RSA key with 512 bits should fail in FIPS provider"); 141 1.1 christos 142 1.1 christos ok(!run(app(['openssl', 'genrsa', 143 1.1 christos @prov, 144 1.1 christos '-provider', 'default', 145 1.1 christos '-propquery', '?fips!=yes', 146 1.1 christos '512'])), 147 1.1 christos "Generating RSA key with 512 bits should succeed with FIPS provider as". 148 1.1 christos " default with a non-FIPS property query"); 149 1.1 christos 150 1.1 christos # We want to know that an absurdly large number of bits fails the RNG check 151 1.1 christos is(run(app([ 'openssl', 'genpkey', 152 1.1 christos @prov, 153 1.1 christos '-algorithm', 'RSA', 154 1.1 christos '-pkeyopt', 'bits:1000000000', 155 1.1 christos '-out', 'genrsatest.pem'])), 156 1.1 christos 0, "genpkey 1000000000"); 157 1.1 christos } 158