Home | History | Annotate | Line # | Download | only in recipes
      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