Home | History | Annotate | Line # | Download | only in recipes
      1      1.1  christos #! /usr/bin/env perl
      2  1.1.1.8  christos # Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos #
      4  1.1.1.6  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 OpenSSL::Test::Utils;
     14      1.1  christos use OpenSSL::Test qw/:DEFAULT srctop_file/;
     15      1.1  christos 
     16      1.1  christos setup("test_req");
     17      1.1  christos 
     18  1.1.1.8  christos plan tests => 50;
     19      1.1  christos 
     20  1.1.1.6  christos require_ok(srctop_file('test', 'recipes', 'tconversion.pl'));
     21      1.1  christos 
     22  1.1.1.6  christos my @certs = qw(test certs);
     23      1.1  christos 
     24  1.1.1.2  christos # What type of key to generate?
     25  1.1.1.2  christos my @req_new;
     26  1.1.1.2  christos if (disabled("rsa")) {
     27  1.1.1.2  christos     @req_new = ("-newkey", "dsa:".srctop_file("apps", "dsa512.pem"));
     28  1.1.1.2  christos } else {
     29  1.1.1.2  christos     @req_new = ("-new");
     30  1.1.1.2  christos     note("There should be a 2 sequences of .'s and some +'s.");
     31  1.1.1.2  christos     note("There should not be more that at most 80 per line");
     32  1.1.1.2  christos }
     33  1.1.1.2  christos 
     34  1.1.1.6  christos # Prevent MSys2 filename munging for arguments that look like file paths but
     35  1.1.1.6  christos # aren't
     36  1.1.1.6  christos $ENV{MSYS2_ARG_CONV_EXCL} = "/CN=";
     37  1.1.1.6  christos 
     38  1.1.1.2  christos # Check for duplicate -addext parameters, and one "working" case.
     39  1.1.1.2  christos my @addext_args = ( "openssl", "req", "-new", "-out", "testreq.pem",
     40  1.1.1.6  christos                     "-key",  srctop_file("test", "certs", "ee-key.pem"),
     41  1.1.1.2  christos     "-config", srctop_file("test", "test.cnf"), @req_new );
     42  1.1.1.2  christos my $val = "subjectAltName=DNS:example.com";
     43  1.1.1.8  christos my $val1 = "subjectAltName=otherName:1.2.3.4;UTF8:test,email:info\@example.com";
     44  1.1.1.2  christos my $val2 = " " . $val;
     45  1.1.1.2  christos my $val3 = $val;
     46  1.1.1.2  christos $val3 =~ s/=/    =/;
     47  1.1.1.2  christos ok( run(app([@addext_args, "-addext", $val])));
     48  1.1.1.8  christos ok( run(app([@addext_args, "-addext", $val1])));
     49  1.1.1.8  christos $val1 =~ s/UTF8/XXXX/; # execute the error handling in do_othername
     50  1.1.1.8  christos ok(!run(app([@addext_args, "-addext", $val1])));
     51  1.1.1.2  christos ok(!run(app([@addext_args, "-addext", $val, "-addext", $val])));
     52  1.1.1.2  christos ok(!run(app([@addext_args, "-addext", $val, "-addext", $val2])));
     53  1.1.1.2  christos ok(!run(app([@addext_args, "-addext", $val, "-addext", $val3])));
     54  1.1.1.2  christos ok(!run(app([@addext_args, "-addext", $val2, "-addext", $val3])));
     55  1.1.1.8  christos ok(run(app([@addext_args, "-addext", "SXNetID=1:one, 2:two, 3:three"])));
     56  1.1.1.8  christos ok(run(app([@addext_args, "-addext", "subjectAltName=dirName:dirname_sec"])));
     57  1.1.1.2  christos 
     58  1.1.1.6  christos # If a CSR is provided with neither of -key or -CA/-CAkey, this should fail.
     59  1.1.1.6  christos ok(!run(app(["openssl", "req", "-x509",
     60  1.1.1.6  christos                 "-in", srctop_file(@certs, "x509-check.csr"),
     61  1.1.1.6  christos                 "-out", "testreq.pem"])));
     62  1.1.1.6  christos 
     63  1.1.1.6  christos subtest "generating alt certificate requests with RSA" => sub {
     64  1.1.1.6  christos     plan tests => 3;
     65  1.1.1.3  christos 
     66  1.1.1.3  christos     SKIP: {
     67  1.1.1.3  christos         skip "RSA is not supported by this OpenSSL build", 2
     68  1.1.1.3  christos             if disabled("rsa");
     69  1.1.1.3  christos 
     70  1.1.1.3  christos         ok(run(app(["openssl", "req",
     71  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
     72  1.1.1.6  christos                     "-section", "altreq",
     73  1.1.1.6  christos                     "-new", "-out", "testreq-rsa.pem", "-utf8",
     74  1.1.1.3  christos                     "-key", srctop_file("test", "testrsa.pem")])),
     75  1.1.1.3  christos            "Generating request");
     76  1.1.1.3  christos 
     77  1.1.1.3  christos         ok(run(app(["openssl", "req",
     78  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
     79  1.1.1.6  christos                     "-verify", "-in", "testreq-rsa.pem", "-noout"])),
     80  1.1.1.3  christos            "Verifying signature on request");
     81  1.1.1.5  christos 
     82  1.1.1.5  christos         ok(run(app(["openssl", "req",
     83  1.1.1.5  christos                     "-config", srctop_file("test", "test.cnf"),
     84  1.1.1.6  christos                     "-section", "altreq",
     85  1.1.1.6  christos                     "-verify", "-in", "testreq-rsa.pem", "-noout"])),
     86  1.1.1.6  christos            "Verifying signature on request");
     87  1.1.1.6  christos     }
     88  1.1.1.6  christos };
     89  1.1.1.6  christos 
     90  1.1.1.6  christos 
     91  1.1.1.6  christos subtest "generating certificate requests with RSA" => sub {
     92  1.1.1.6  christos     plan tests => 8;
     93  1.1.1.6  christos 
     94  1.1.1.6  christos     SKIP: {
     95  1.1.1.6  christos         skip "RSA is not supported by this OpenSSL build", 2
     96  1.1.1.6  christos             if disabled("rsa");
     97  1.1.1.6  christos 
     98  1.1.1.6  christos         ok(!run(app(["openssl", "req",
     99  1.1.1.6  christos                      "-config", srctop_file("test", "test.cnf"),
    100  1.1.1.6  christos                      "-new", "-out", "testreq-rsa.pem", "-utf8",
    101  1.1.1.6  christos                      "-key", srctop_file("test", "testrsa.pem"),
    102  1.1.1.6  christos                      "-keyform", "DER"])),
    103  1.1.1.6  christos            "Checking that mismatching keyform fails");
    104  1.1.1.6  christos 
    105  1.1.1.6  christos         ok(run(app(["openssl", "req",
    106  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    107  1.1.1.6  christos                     "-new", "-out", "testreq-rsa.pem", "-utf8",
    108  1.1.1.6  christos                     "-key", srctop_file("test", "testrsa.pem"),
    109  1.1.1.6  christos                     "-keyform", "PEM"])),
    110  1.1.1.6  christos            "Generating request");
    111  1.1.1.6  christos 
    112  1.1.1.6  christos         ok(run(app(["openssl", "req",
    113  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    114  1.1.1.6  christos                     "-verify", "-in", "testreq-rsa.pem", "-noout"])),
    115  1.1.1.6  christos            "Verifying signature on request");
    116  1.1.1.6  christos 
    117  1.1.1.6  christos         ok(run(app(["openssl", "req",
    118  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    119  1.1.1.6  christos                     "-modulus", "-in", "testreq-rsa.pem", "-noout"])),
    120  1.1.1.6  christos            "Printing a modulus of the request key");
    121  1.1.1.6  christos 
    122  1.1.1.6  christos         ok(run(app(["openssl", "req",
    123  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    124  1.1.1.5  christos                     "-new", "-out", "testreq_withattrs_pem.pem", "-utf8",
    125  1.1.1.5  christos                     "-key", srctop_file("test", "testrsa_withattrs.pem")])),
    126  1.1.1.5  christos            "Generating request from a key with extra attributes - PEM");
    127  1.1.1.5  christos 
    128  1.1.1.5  christos         ok(run(app(["openssl", "req",
    129  1.1.1.5  christos                     "-config", srctop_file("test", "test.cnf"),
    130  1.1.1.5  christos                     "-verify", "-in", "testreq_withattrs_pem.pem", "-noout"])),
    131  1.1.1.5  christos            "Verifying signature on request from a key with extra attributes - PEM");
    132  1.1.1.5  christos 
    133  1.1.1.5  christos         ok(run(app(["openssl", "req",
    134  1.1.1.5  christos                     "-config", srctop_file("test", "test.cnf"),
    135  1.1.1.5  christos                     "-new", "-out", "testreq_withattrs_der.pem", "-utf8",
    136  1.1.1.5  christos                     "-key", srctop_file("test", "testrsa_withattrs.der"),
    137  1.1.1.6  christos                     "-keyform", "DER"])),
    138  1.1.1.5  christos            "Generating request from a key with extra attributes - PEM");
    139  1.1.1.5  christos 
    140  1.1.1.5  christos         ok(run(app(["openssl", "req",
    141  1.1.1.5  christos                     "-config", srctop_file("test", "test.cnf"),
    142  1.1.1.5  christos                     "-verify", "-in", "testreq_withattrs_der.pem", "-noout"])),
    143  1.1.1.5  christos            "Verifying signature on request from a key with extra attributes - PEM");
    144  1.1.1.3  christos     }
    145  1.1.1.3  christos };
    146  1.1.1.3  christos 
    147  1.1.1.6  christos subtest "generating certificate requests with RSA-PSS" => sub {
    148  1.1.1.6  christos     plan tests => 12;
    149  1.1.1.6  christos 
    150  1.1.1.6  christos     SKIP: {
    151  1.1.1.6  christos         skip "RSA is not supported by this OpenSSL build", 2
    152  1.1.1.6  christos             if disabled("rsa");
    153  1.1.1.6  christos 
    154  1.1.1.6  christos         ok(run(app(["openssl", "req",
    155  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    156  1.1.1.6  christos                     "-new", "-out", "testreq-rsapss.pem", "-utf8",
    157  1.1.1.6  christos                     "-key", srctop_file("test", "testrsapss.pem")])),
    158  1.1.1.6  christos            "Generating request");
    159  1.1.1.6  christos         ok(run(app(["openssl", "req",
    160  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    161  1.1.1.6  christos                     "-verify", "-in", "testreq-rsapss.pem", "-noout"])),
    162  1.1.1.6  christos            "Verifying signature on request");
    163  1.1.1.6  christos 
    164  1.1.1.6  christos         ok(run(app(["openssl", "req",
    165  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    166  1.1.1.6  christos                     "-new", "-out", "testreq-rsapss2.pem", "-utf8",
    167  1.1.1.6  christos                     "-sigopt", "rsa_padding_mode:pss",
    168  1.1.1.6  christos                     "-sigopt", "rsa_pss_saltlen:-1",
    169  1.1.1.6  christos                     "-key", srctop_file("test", "testrsapss.pem")])),
    170  1.1.1.6  christos            "Generating request");
    171  1.1.1.6  christos         ok(run(app(["openssl", "req",
    172  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    173  1.1.1.6  christos                     "-verify", "-in", "testreq-rsapss2.pem", "-noout"])),
    174  1.1.1.6  christos            "Verifying signature on request");
    175  1.1.1.6  christos 
    176  1.1.1.6  christos         ok(run(app(["openssl", "req",
    177  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    178  1.1.1.6  christos                     "-new", "-out", "testreq-rsapssmand.pem", "-utf8",
    179  1.1.1.6  christos                     "-sigopt", "rsa_padding_mode:pss",
    180  1.1.1.6  christos                     "-key", srctop_file("test", "testrsapssmandatory.pem")])),
    181  1.1.1.6  christos            "Generating request");
    182  1.1.1.6  christos         ok(run(app(["openssl", "req",
    183  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    184  1.1.1.6  christos                     "-verify", "-in", "testreq-rsapssmand.pem", "-noout"])),
    185  1.1.1.6  christos            "Verifying signature on request");
    186  1.1.1.6  christos 
    187  1.1.1.6  christos         ok(run(app(["openssl", "req",
    188  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    189  1.1.1.6  christos                     "-new", "-out", "testreq-rsapssmand2.pem", "-utf8",
    190  1.1.1.6  christos                     "-sigopt", "rsa_pss_saltlen:100",
    191  1.1.1.6  christos                     "-key", srctop_file("test", "testrsapssmandatory.pem")])),
    192  1.1.1.6  christos            "Generating request");
    193  1.1.1.6  christos         ok(run(app(["openssl", "req",
    194  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    195  1.1.1.6  christos                     "-verify", "-in", "testreq-rsapssmand2.pem", "-noout"])),
    196  1.1.1.6  christos            "Verifying signature on request");
    197  1.1.1.6  christos 
    198  1.1.1.6  christos         ok(!run(app(["openssl", "req",
    199  1.1.1.6  christos                      "-config", srctop_file("test", "test.cnf"),
    200  1.1.1.6  christos                      "-new", "-out", "testreq-rsapss3.pem", "-utf8",
    201  1.1.1.6  christos                      "-sigopt", "rsa_padding_mode:pkcs1",
    202  1.1.1.6  christos                      "-key", srctop_file("test", "testrsapss.pem")])),
    203  1.1.1.6  christos            "Generating request with expected failure");
    204  1.1.1.6  christos 
    205  1.1.1.6  christos         ok(!run(app(["openssl", "req",
    206  1.1.1.6  christos                      "-config", srctop_file("test", "test.cnf"),
    207  1.1.1.6  christos                      "-new", "-out", "testreq-rsapss3.pem", "-utf8",
    208  1.1.1.6  christos                      "-sigopt", "rsa_pss_saltlen:-4",
    209  1.1.1.6  christos                      "-key", srctop_file("test", "testrsapss.pem")])),
    210  1.1.1.6  christos            "Generating request with expected failure");
    211  1.1.1.6  christos 
    212  1.1.1.6  christos         ok(!run(app(["openssl", "req",
    213  1.1.1.6  christos                      "-config", srctop_file("test", "test.cnf"),
    214  1.1.1.6  christos                      "-new", "-out", "testreq-rsapssmand3.pem", "-utf8",
    215  1.1.1.6  christos                      "-sigopt", "rsa_pss_saltlen:10",
    216  1.1.1.6  christos                      "-key", srctop_file("test", "testrsapssmandatory.pem")])),
    217  1.1.1.6  christos            "Generating request with expected failure");
    218  1.1.1.6  christos 
    219  1.1.1.6  christos         ok(!run(app(["openssl", "req",
    220  1.1.1.6  christos                      "-config", srctop_file("test", "test.cnf"),
    221  1.1.1.6  christos                      "-new", "-out", "testreq-rsapssmand3.pem", "-utf8",
    222  1.1.1.6  christos                      "-sha256",
    223  1.1.1.6  christos                      "-key", srctop_file("test", "testrsapssmandatory.pem")])),
    224  1.1.1.6  christos            "Generating request with expected failure");
    225  1.1.1.6  christos     }
    226  1.1.1.6  christos };
    227  1.1.1.6  christos 
    228  1.1.1.3  christos subtest "generating certificate requests with DSA" => sub {
    229  1.1.1.3  christos     plan tests => 2;
    230  1.1.1.3  christos 
    231  1.1.1.3  christos     SKIP: {
    232  1.1.1.3  christos         skip "DSA is not supported by this OpenSSL build", 2
    233  1.1.1.3  christos             if disabled("dsa");
    234  1.1.1.3  christos 
    235  1.1.1.3  christos         ok(run(app(["openssl", "req",
    236  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
    237  1.1.1.6  christos                     "-new", "-out", "testreq-dsa.pem", "-utf8",
    238  1.1.1.3  christos                     "-key", srctop_file("test", "testdsa.pem")])),
    239  1.1.1.3  christos            "Generating request");
    240  1.1.1.3  christos 
    241  1.1.1.3  christos         ok(run(app(["openssl", "req",
    242  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
    243  1.1.1.6  christos                     "-verify", "-in", "testreq-dsa.pem", "-noout"])),
    244  1.1.1.3  christos            "Verifying signature on request");
    245  1.1.1.3  christos     }
    246  1.1.1.3  christos };
    247  1.1.1.3  christos 
    248  1.1.1.3  christos subtest "generating certificate requests with ECDSA" => sub {
    249  1.1.1.3  christos     plan tests => 2;
    250  1.1.1.3  christos 
    251  1.1.1.3  christos     SKIP: {
    252  1.1.1.3  christos         skip "ECDSA is not supported by this OpenSSL build", 2
    253  1.1.1.3  christos             if disabled("ec");
    254  1.1.1.3  christos 
    255  1.1.1.3  christos         ok(run(app(["openssl", "req",
    256  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
    257  1.1.1.6  christos                     "-new", "-out", "testreq-ec.pem", "-utf8",
    258  1.1.1.3  christos                     "-key", srctop_file("test", "testec-p256.pem")])),
    259  1.1.1.3  christos            "Generating request");
    260  1.1.1.3  christos 
    261  1.1.1.3  christos         ok(run(app(["openssl", "req",
    262  1.1.1.3  christos                     "-config", srctop_file("test", "test.cnf"),
    263  1.1.1.6  christos                     "-verify", "-in", "testreq-ec.pem", "-noout"])),
    264  1.1.1.3  christos            "Verifying signature on request");
    265  1.1.1.3  christos     }
    266  1.1.1.3  christos };
    267  1.1.1.3  christos 
    268  1.1.1.4  christos subtest "generating certificate requests with Ed25519" => sub {
    269  1.1.1.4  christos     plan tests => 2;
    270  1.1.1.4  christos 
    271  1.1.1.4  christos     SKIP: {
    272  1.1.1.4  christos         skip "Ed25519 is not supported by this OpenSSL build", 2
    273  1.1.1.4  christos             if disabled("ec");
    274  1.1.1.4  christos 
    275  1.1.1.4  christos         ok(run(app(["openssl", "req",
    276  1.1.1.4  christos                     "-config", srctop_file("test", "test.cnf"),
    277  1.1.1.6  christos                     "-new", "-out", "testreq-ed25519.pem", "-utf8",
    278  1.1.1.4  christos                     "-key", srctop_file("test", "tested25519.pem")])),
    279  1.1.1.4  christos            "Generating request");
    280  1.1.1.4  christos 
    281  1.1.1.4  christos         ok(run(app(["openssl", "req",
    282  1.1.1.4  christos                     "-config", srctop_file("test", "test.cnf"),
    283  1.1.1.6  christos                     "-verify", "-in", "testreq-ed25519.pem", "-noout"])),
    284  1.1.1.4  christos            "Verifying signature on request");
    285  1.1.1.4  christos     }
    286  1.1.1.4  christos };
    287  1.1.1.4  christos 
    288  1.1.1.4  christos subtest "generating certificate requests with Ed448" => sub {
    289  1.1.1.4  christos     plan tests => 2;
    290  1.1.1.4  christos 
    291  1.1.1.4  christos     SKIP: {
    292  1.1.1.4  christos         skip "Ed448 is not supported by this OpenSSL build", 2
    293  1.1.1.4  christos             if disabled("ec");
    294  1.1.1.4  christos 
    295  1.1.1.4  christos         ok(run(app(["openssl", "req",
    296  1.1.1.4  christos                     "-config", srctop_file("test", "test.cnf"),
    297  1.1.1.6  christos                     "-new", "-out", "testreq-ed448.pem", "-utf8",
    298  1.1.1.4  christos                     "-key", srctop_file("test", "tested448.pem")])),
    299  1.1.1.4  christos            "Generating request");
    300  1.1.1.4  christos 
    301  1.1.1.4  christos         ok(run(app(["openssl", "req",
    302  1.1.1.4  christos                     "-config", srctop_file("test", "test.cnf"),
    303  1.1.1.6  christos                     "-verify", "-in", "testreq-ed448.pem", "-noout"])),
    304  1.1.1.4  christos            "Verifying signature on request");
    305  1.1.1.4  christos     }
    306  1.1.1.4  christos };
    307  1.1.1.4  christos 
    308  1.1.1.2  christos subtest "generating certificate requests" => sub {
    309      1.1  christos     plan tests => 2;
    310      1.1  christos 
    311      1.1  christos     ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
    312  1.1.1.6  christos                 "-key", srctop_file("test", "certs", "ee-key.pem"),
    313  1.1.1.3  christos                 @req_new, "-out", "testreq.pem"])),
    314      1.1  christos        "Generating request");
    315      1.1  christos 
    316      1.1  christos     ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
    317  1.1.1.3  christos                 "-verify", "-in", "testreq.pem", "-noout"])),
    318      1.1  christos        "Verifying signature on request");
    319      1.1  christos };
    320      1.1  christos 
    321  1.1.1.6  christos subtest "generating SM2 certificate requests" => sub {
    322  1.1.1.6  christos     plan tests => 4;
    323  1.1.1.6  christos 
    324  1.1.1.6  christos     SKIP: {
    325  1.1.1.6  christos         skip "SM2 is not supported by this OpenSSL build", 4
    326  1.1.1.6  christos         if disabled("sm2");
    327  1.1.1.6  christos         ok(run(app(["openssl", "req",
    328  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    329  1.1.1.6  christos                     "-new", "-key", srctop_file(@certs, "sm2.key"),
    330  1.1.1.6  christos                     "-sigopt", "distid:1234567812345678",
    331  1.1.1.6  christos                     "-out", "testreq-sm2.pem", "-sm3"])),
    332  1.1.1.6  christos            "Generating SM2 certificate request");
    333  1.1.1.6  christos 
    334  1.1.1.6  christos         ok(run(app(["openssl", "req",
    335  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    336  1.1.1.6  christos                     "-verify", "-in", "testreq-sm2.pem", "-noout",
    337  1.1.1.6  christos                     "-vfyopt", "distid:1234567812345678", "-sm3"])),
    338  1.1.1.6  christos            "Verifying signature on SM2 certificate request");
    339  1.1.1.6  christos 
    340  1.1.1.6  christos         ok(run(app(["openssl", "req",
    341  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    342  1.1.1.6  christos                     "-new", "-key", srctop_file(@certs, "sm2.key"),
    343  1.1.1.6  christos                     "-sigopt", "hexdistid:DEADBEEF",
    344  1.1.1.6  christos                     "-out", "testreq-sm2.pem", "-sm3"])),
    345  1.1.1.6  christos            "Generating SM2 certificate request with hex id");
    346  1.1.1.6  christos 
    347  1.1.1.6  christos         ok(run(app(["openssl", "req",
    348  1.1.1.6  christos                     "-config", srctop_file("test", "test.cnf"),
    349  1.1.1.6  christos                     "-verify", "-in", "testreq-sm2.pem", "-noout",
    350  1.1.1.6  christos                     "-vfyopt", "hexdistid:DEADBEEF", "-sm3"])),
    351  1.1.1.6  christos            "Verifying signature on SM2 certificate request");
    352  1.1.1.6  christos     }
    353  1.1.1.6  christos };
    354  1.1.1.6  christos 
    355      1.1  christos my @openssl_args = ("req", "-config", srctop_file("apps", "openssl.cnf"));
    356      1.1  christos 
    357      1.1  christos run_conversion('req conversions',
    358  1.1.1.3  christos                "testreq.pem");
    359      1.1  christos run_conversion('req conversions -- testreq2',
    360  1.1.1.3  christos                srctop_file("test", "testreq2.pem"));
    361      1.1  christos 
    362      1.1  christos sub run_conversion {
    363      1.1  christos     my $title = shift;
    364      1.1  christos     my $reqfile = shift;
    365      1.1  christos 
    366      1.1  christos     subtest $title => sub {
    367  1.1.1.3  christos         run(app(["openssl", @openssl_args,
    368  1.1.1.3  christos                  "-in", $reqfile, "-inform", "p",
    369  1.1.1.3  christos                  "-noout", "-text"],
    370  1.1.1.3  christos                 stderr => "req-check.err", stdout => undef));
    371  1.1.1.3  christos         open DATA, "req-check.err";
    372  1.1.1.3  christos         SKIP: {
    373  1.1.1.3  christos             plan skip_all => "skipping req conversion test for $reqfile"
    374  1.1.1.3  christos                 if grep /Unknown Public Key/, map { s/\R//; } <DATA>;
    375  1.1.1.3  christos 
    376  1.1.1.6  christos             tconversion( -type => 'req', -in => $reqfile,
    377  1.1.1.6  christos                          -args => [ @openssl_args ] );
    378  1.1.1.3  christos         }
    379  1.1.1.3  christos         close DATA;
    380  1.1.1.3  christos         unlink "req-check.err";
    381      1.1  christos 
    382  1.1.1.3  christos         done_testing();
    383      1.1  christos     };
    384      1.1  christos }
    385  1.1.1.6  christos 
    386  1.1.1.6  christos # Test both generation and verification of certs w.r.t. RFC 5280 requirements
    387  1.1.1.6  christos 
    388  1.1.1.6  christos my $ca_cert; # will be set below
    389  1.1.1.6  christos sub generate_cert {
    390  1.1.1.6  christos     my $cert = shift @_;
    391  1.1.1.6  christos     my $ss = $cert =~ m/self-signed/;
    392  1.1.1.6  christos     my $is_ca = $cert =~ m/CA/;
    393  1.1.1.6  christos     my $cn = $is_ca ? "CA" : "EE";
    394  1.1.1.6  christos     my $ca_key = srctop_file(@certs, "ca-key.pem");
    395  1.1.1.6  christos     my $key = $is_ca ? $ca_key : srctop_file(@certs, "ee-key.pem");
    396  1.1.1.6  christos     my @cmd = ("openssl", "req", "-config", "", "-x509",
    397  1.1.1.6  christos                "-subj", "/CN=$cn", @_, "-out", $cert);
    398  1.1.1.6  christos     push(@cmd, ("-key", $key)) if $ss;
    399  1.1.1.6  christos     push(@cmd, ("-CA", $ca_cert, "-CAkey", $ca_key)) unless $ss;
    400  1.1.1.6  christos     ok(run(app([@cmd])), "generate $cert");
    401  1.1.1.6  christos }
    402  1.1.1.6  christos sub has_SKID {
    403  1.1.1.6  christos     my $cert = shift @_;
    404  1.1.1.6  christos     my $expect = shift @_;
    405  1.1.1.6  christos     cert_contains($cert, "Subject Key Identifier", $expect);
    406  1.1.1.6  christos }
    407  1.1.1.6  christos sub has_AKID {
    408  1.1.1.6  christos     my $cert = shift @_;
    409  1.1.1.6  christos     my $expect = shift @_;
    410  1.1.1.6  christos     cert_contains($cert, "Authority Key Identifier", $expect);
    411  1.1.1.6  christos }
    412  1.1.1.6  christos sub has_keyUsage {
    413  1.1.1.6  christos     my $cert = shift @_;
    414  1.1.1.6  christos     my $expect = shift @_;
    415  1.1.1.6  christos     cert_contains($cert, "Key Usage", $expect);
    416  1.1.1.6  christos }
    417  1.1.1.6  christos sub strict_verify {
    418  1.1.1.6  christos     my $cert = shift @_;
    419  1.1.1.6  christos     my $expect = shift @_;
    420  1.1.1.6  christos     my $trusted = shift @_;
    421  1.1.1.6  christos     $trusted = $cert unless $trusted;
    422  1.1.1.6  christos     ok(run(app(["openssl", "verify", "-x509_strict", "-trusted", $trusted,
    423  1.1.1.6  christos                 "-partial_chain", $cert])) == $expect,
    424  1.1.1.6  christos        "strict verify allow $cert");
    425  1.1.1.6  christos }
    426  1.1.1.6  christos 
    427  1.1.1.6  christos my @v3_ca = ("-addext", "basicConstraints = critical,CA:true",
    428  1.1.1.6  christos              "-addext", "keyUsage = keyCertSign");
    429  1.1.1.6  christos my $SKID_AKID = "subjectKeyIdentifier,authorityKeyIdentifier";
    430  1.1.1.6  christos my $cert = "self-signed_v1_CA_no_KIDs.pem";
    431  1.1.1.6  christos generate_cert($cert);
    432  1.1.1.6  christos cert_ext_has_n_different_lines($cert, 0, $SKID_AKID); # no SKID and no AKID
    433  1.1.1.6  christos #TODO strict_verify($cert, 1); # self-signed v1 root cert should be accepted as CA
    434  1.1.1.6  christos 
    435  1.1.1.6  christos $ca_cert = "self-signed_v3_CA_default_SKID.pem";
    436  1.1.1.6  christos generate_cert($ca_cert, @v3_ca);
    437  1.1.1.6  christos has_SKID($ca_cert, 1);
    438  1.1.1.6  christos has_AKID($ca_cert, 0);
    439  1.1.1.6  christos strict_verify($ca_cert, 1);
    440  1.1.1.6  christos 
    441  1.1.1.6  christos $cert = "self-signed_v3_CA_no_SKID.pem";
    442  1.1.1.6  christos generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = none");
    443  1.1.1.6  christos cert_ext_has_n_different_lines($cert, 0, $SKID_AKID); # no SKID and no AKID
    444  1.1.1.6  christos #TODO strict_verify($cert, 0);
    445  1.1.1.6  christos 
    446  1.1.1.6  christos $cert = "self-signed_v3_CA_both_KIDs.pem";
    447  1.1.1.6  christos generate_cert($cert, @v3_ca, "-addext", "subjectKeyIdentifier = hash",
    448  1.1.1.6  christos             "-addext", "authorityKeyIdentifier = keyid:always");
    449  1.1.1.6  christos cert_ext_has_n_different_lines($cert, 3, $SKID_AKID); # SKID == AKID
    450  1.1.1.6  christos strict_verify($cert, 1);
    451  1.1.1.6  christos 
    452  1.1.1.6  christos $cert = "self-signed_v3_EE_wrong_keyUsage.pem";
    453  1.1.1.6  christos generate_cert($cert, "-addext", "keyUsage = keyCertSign");
    454  1.1.1.6  christos #TODO strict_verify($cert, 1); # should be accepted because RFC 5280 does not apply
    455  1.1.1.6  christos 
    456  1.1.1.6  christos $cert = "v3_EE_default_KIDs.pem";
    457  1.1.1.6  christos generate_cert($cert, "-addext", "keyUsage = dataEncipherment",
    458  1.1.1.6  christos               "-key", srctop_file(@certs, "ee-key.pem"));
    459  1.1.1.6  christos cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
    460  1.1.1.6  christos strict_verify($cert, 1, $ca_cert);
    461  1.1.1.6  christos 
    462  1.1.1.6  christos $cert = "v3_EE_no_AKID.pem";
    463  1.1.1.6  christos generate_cert($cert, "-addext", "authorityKeyIdentifier = none",
    464  1.1.1.6  christos               "-key", srctop_file(@certs, "ee-key.pem"));
    465  1.1.1.6  christos has_SKID($cert, 1);
    466  1.1.1.6  christos has_AKID($cert, 0);
    467  1.1.1.6  christos strict_verify($cert, 0, $ca_cert);
    468  1.1.1.6  christos 
    469  1.1.1.6  christos $cert = "self-issued_v3_EE_default_KIDs.pem";
    470  1.1.1.6  christos generate_cert($cert, "-addext", "keyUsage = dataEncipherment",
    471  1.1.1.6  christos     "-in", srctop_file(@certs, "x509-check.csr"));
    472  1.1.1.6  christos cert_ext_has_n_different_lines($cert, 4, $SKID_AKID); # SKID != AKID
    473  1.1.1.6  christos strict_verify($cert, 1);
    474  1.1.1.6  christos 
    475  1.1.1.6  christos my $cert = "self-signed_CA_no_keyUsage.pem";
    476  1.1.1.6  christos generate_cert($cert, "-in", srctop_file(@certs, "ext-check.csr"));
    477  1.1.1.6  christos has_keyUsage($cert, 0);
    478  1.1.1.6  christos my $cert = "self-signed_CA_with_keyUsages.pem";
    479  1.1.1.6  christos generate_cert($cert, "-in", srctop_file(@certs, "ext-check.csr"),
    480  1.1.1.6  christos     "-copy_extensions", "copy");
    481  1.1.1.6  christos has_keyUsage($cert, 1);
    482  1.1.1.7  christos 
    483  1.1.1.7  christos # Generate cert using req with '-modulus'
    484  1.1.1.7  christos ok(run(app(["openssl", "req", "-x509", "-new", "-days", "365",
    485  1.1.1.7  christos             "-key", srctop_file("test", "testrsa.pem"),
    486  1.1.1.7  christos             "-config", srctop_file('test', 'test.cnf'),
    487  1.1.1.7  christos             "-out", "testreq-cert.pem",
    488  1.1.1.7  christos             "-modulus"])), "cert req creation - with -modulus");
    489  1.1.1.7  christos 
    490  1.1.1.7  christos # Verify cert
    491  1.1.1.7  christos ok(run(app(["openssl", "x509", "-in", "testreq-cert.pem",
    492  1.1.1.7  christos             "-noout", "-text"])), "cert verification");
    493