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