1#! /usr/bin/env perl 2# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. 3# 4# Licensed under the Apache License 2.0 (the "License"). You may not use 5# this file except in compliance with the License. You can obtain a copy 6# in the file LICENSE in the source distribution or at 7# https://www.openssl.org/source/license.html 8 9 10use strict; 11use warnings; 12 13use File::Spec; 14use OpenSSL::Test::Utils; 15use OpenSSL::Test qw/:DEFAULT srctop_file/; 16 17setup("test_x509"); 18 19plan tests => 138; 20 21# Prevent MSys2 filename munging for arguments that look like file paths but 22# aren't 23$ENV{MSYS2_ARG_CONV_EXCL} = "/CN="; 24 25require_ok(srctop_file("test", "recipes", "tconversion.pl")); 26 27my @certs = qw(test certs); 28my $pem = srctop_file(@certs, "cyrillic.pem"); 29my $out_msb = "out-cyrillic.msb"; 30my $out_utf8 = "out-cyrillic.utf8"; 31my $der = "cyrillic.der"; 32my $der2 = "cyrillic.der"; 33my $msb = srctop_file(@certs, "cyrillic.msb"); 34my $utf = srctop_file(@certs, "cyrillic.utf8"); 35 36ok(run(app(["openssl", "x509", "-text", "-in", $pem, "-out", $out_msb, 37 "-nameopt", "esc_msb"]))); 38is(cmp_text($out_msb, $msb), 39 0, 'Comparing esc_msb output with cyrillic.msb'); 40ok(run(app(["openssl", "x509", "-text", "-in", $pem, "-out", $out_utf8, 41 "-nameopt", "utf8"]))); 42is(cmp_text($out_utf8, $utf), 43 0, 'Comparing utf8 output with cyrillic.utf8'); 44 45SKIP: { 46 skip "EdDSA disabled", 2 if disabled("ecx"); 47 48 $pem = srctop_file(@certs, "tab-in-dn.pem"); 49 my $out_text = "out-tab-in-dn.text"; 50 my $text = srctop_file(@certs, "tab-in-dn.text"); 51 ok(run(app(["openssl", "x509", "-text", "-noout", 52 "-in", $pem, "-out", $out_text]))); 53 is(cmp_text($out_text, $text), 54 0, 'Comparing default output with tab-in-dn.text'); 55} 56 57SKIP: { 58 skip "DES disabled", 1 if disabled("des"); 59 skip "Platform doesn't support command line UTF-8", 1 if $^O =~ /^(VMS|msys)$/; 60 61 my $p12 = srctop_file("test", "shibboleth.pfx"); 62 my $p12pass = "σύνθημα γνώρισμα"; 63 my $out_pem = "out.pem"; 64 ok(run(app(["openssl", "x509", "-text", "-in", $p12, "-out", $out_pem, 65 "-passin", "pass:$p12pass"]))); 66 # not unlinking $out_pem 67} 68 69ok(!run(app(["openssl", "x509", "-in", $pem, "-inform", "DER", 70 "-out", $der, "-outform", "DER"])), 71 "Checking failure of mismatching -inform DER"); 72ok(run(app(["openssl", "x509", "-in", $pem, "-inform", "PEM", 73 "-out", $der, "-outform", "DER"])), 74 "Conversion to DER"); 75ok(!run(app(["openssl", "x509", "-in", $der, "-inform", "PEM", 76 "-out", $der2, "-outform", "DER"])), 77 "Checking failure of mismatching -inform PEM"); 78 79# producing and checking self-issued (but not self-signed) cert 80my $subj = "/CN=CA"; # using same DN as in issuer of ee-cert.pem 81my $extfile = srctop_file("test", "v3_ca_exts.cnf"); 82my $pkey = srctop_file(@certs, "ca-key.pem"); # issuer private key 83my $pubkey = "ca-pubkey.pem"; # the corresponding issuer public key 84# use any (different) key for signing our self-issued cert: 85my $key = srctop_file(@certs, "serverkey.pem"); 86my $selfout = "self-issued.out"; 87my $testcert = srctop_file(@certs, "ee-cert.pem"); 88ok(run(app(["openssl", "pkey", "-in", $pkey, "-pubout", "-out", $pubkey])) 89&& run(app(["openssl", "x509", "-new", "-force_pubkey", $pubkey, "-subj", $subj, 90 "-extfile", $extfile, "-key", $key, "-out", $selfout])) 91&& run(app(["openssl", "verify", "-no_check_time", 92 "-trusted", $selfout, "-partial_chain", $testcert]))); 93# not unlinking $pubkey 94# not unlinking $selfout 95 96# test -set_issuer option 97my $ca_issu = srctop_file(@certs, "ca-cert.pem"); # issuer cert 98my $caout_issu = "ca-issu.out"; 99ok(run(app(["openssl", "x509", "-new", "-force_pubkey", $key, "-subj", "/CN=EE", 100 "-set_issuer", "/CN=TEST-CA", "-extfile", $extfile, "-CA", $ca_issu, 101 "-CAkey", $pkey, "-text", "-out", $caout_issu]))); 102ok(get_issuer($caout_issu) =~ /CN=TEST-CA/); 103# not unlinking $caout 104 105# simple way of directly producing a CA-signed cert with private/pubkey input 106my $ca = srctop_file(@certs, "ca-cert.pem"); # issuer cert 107my $caout = "ca-issued.out"; 108ok(run(app(["openssl", "x509", "-new", "-force_pubkey", $key, "-subj", "/CN=EE", 109 "-extfile", $extfile, "-CA", $ca, "-CAkey", $pkey, "-out", $caout])) 110&& run(app(["openssl", "verify", "-no_check_time", 111 "-trusted", $ca, "-partial_chain", $caout]))); 112 113# test trust decoration 114ok(run(app(["openssl", "x509", "-in", $ca, "-addtrust", "emailProtection", 115 "-out", "ca-trusted.pem"]))); 116cert_contains("ca-trusted.pem", "Trusted Uses: E-mail Protection", 117 1, 'trusted use - E-mail Protection'); 118ok(run(app(["openssl", "x509", "-in", $ca, "-addreject", "emailProtection", 119 "-out", "ca-rejected.pem"]))); 120cert_contains("ca-rejected.pem", "Rejected Uses: E-mail Protection", 121 1, 'rejected use - E-mail Protection'); 122 123subtest 'x509 -- x.509 v1 certificate' => sub { 124 tconversion( -type => 'x509', -prefix => 'x509v1', 125 -in => srctop_file("test", "testx509.pem") ); 126}; 127subtest 'x509 -- first x.509 v3 certificate' => sub { 128 tconversion( -type => 'x509', -prefix => 'x509v3-1', 129 -in => srctop_file("test", "v3-cert1.pem") ); 130}; 131subtest 'x509 -- second x.509 v3 certificate' => sub { 132 tconversion( -type => 'x509', -prefix => 'x509v3-2', 133 -in => srctop_file("test", "v3-cert2.pem") ); 134}; 135 136subtest 'x509 -- pathlen' => sub { 137 ok(run(test(["v3ext", srctop_file(@certs, "pathlen.pem")]))); 138}; 139 140cert_contains(srctop_file(@certs, "fake-gp.pem"), 141 "2.16.528.1.1003.1.3.5.5.2-1-0000006666-Z-12345678-01.015-12345678", 142 1, 'x500 -- subjectAltName'); 143 144cert_contains(srctop_file(@certs, "ext-noAssertion.pem"), 145 "No Assertion", 146 1, 'X.509 Not Assertion Extension'); 147 148cert_contains(srctop_file(@certs, "ext-groupAC.pem"), 149 "Group Attribute Certificate", 150 1, 'X.509 Group Attribute Certificate Extension'); 151 152cert_contains(srctop_file(@certs, "ext-sOAIdentifier.pem"), 153 "Source of Authority", 154 1, 'X.509 Source of Authority Extension'); 155 156cert_contains(srctop_file(@certs, "ext-noRevAvail.pem"), 157 "No Revocation Available", 158 1, 'X.509 No Revocation Available'); 159 160cert_contains(srctop_file(@certs, "ext-singleUse.pem"), 161 "Single Use", 162 1, 'X509v3 Single Use'); 163 164cert_contains(srctop_file(@certs, "ext-indirectIssuer.pem"), 165 "Indirect Issuer", 166 1, 'X.509 Indirect Issuer'); 167 168my $tgt_info_cert = srctop_file(@certs, "ext-targetingInformation.pem"); 169cert_contains($tgt_info_cert, 170 "AC Targeting", 171 1, 'X.509 Targeting Information Extension'); 172cert_contains($tgt_info_cert, 173 "Targets:", 174 1, 'X.509 Targeting Information Targets'); 175cert_contains($tgt_info_cert, 176 "Target:", 177 1, 'X.509 Targeting Information Target'); 178cert_contains($tgt_info_cert, 179 "Target Name: DirName:CN = W", 180 1, 'X.509 Targeting Information Target Name'); 181cert_contains($tgt_info_cert, 182 "Target Group: DNS:wildboarsoftware.com", 183 1, 'X.509 Targeting Information Target Name'); 184cert_contains($tgt_info_cert, 185 "Issuer Names:", 186 1, 'X.509 Targeting Information Issuer Names'); 187cert_contains($tgt_info_cert, 188 "Issuer Serial: 01020304", 189 1, 'X.509 Targeting Information Issuer Serial'); 190cert_contains($tgt_info_cert, 191 "Issuer UID: B0", 192 1, 'X.509 Targeting Information Issuer UID'); 193cert_contains($tgt_info_cert, 194 "Digest Type: Public Key", 195 1, 'X.509 Targeting Information Object Digest Type'); 196 197my $hnc_cert = srctop_file(@certs, "ext-holderNameConstraints.pem"); 198cert_contains($hnc_cert, 199 "X509v3 Holder Name Constraints", 200 1, 'X.509 Holder Name Constraints'); 201cert_contains($hnc_cert, 202 "Permitted:", 203 1, 'X.509 Holder Name Constraints Permitted'); 204cert_contains($hnc_cert, 205 "DirName:CN = Wildboar", 206 1, 'X.509 Holder Name Constraint'); 207 208my $dnc_cert = srctop_file(@certs, "ext-delegatedNameConstraints.pem"); 209cert_contains($dnc_cert, 210 "X509v3 Delegated Name Constraints", 211 1, 'X.509 Delegated Name Constraints'); 212cert_contains($dnc_cert, 213 "Permitted:", 214 1, 'X.509 Delegated Name Constraints Permitted'); 215cert_contains($dnc_cert, 216 "DirName:CN = Wildboar", 217 1, 'X.509 Delegated Name Constraint'); 218my $sda_cert = srctop_file(@certs, "ext-subjectDirectoryAttributes.pem"); 219cert_contains($sda_cert, 220 "Steve Brule", 221 1, 'X.509 Subject Directory Attributes'); 222cert_contains($sda_cert, 223 "CN=Hi mom", 224 1, 'X.509 Subject Directory Attributes'); 225cert_contains($sda_cert, 226 "<No Values>", 227 1, 'X.509 Subject Directory Attributes'); 228cert_contains($sda_cert, 229 "Funkytown", 230 1, 'X.509 Subject Directory Attributes'); 231cert_contains($sda_cert, 232 "commonName", 233 1, 'X.509 Subject Directory Attributes'); 234cert_contains($sda_cert, 235 "owner", 236 1, 'X.509 Subject Directory Attributes'); 237cert_contains($sda_cert, 238 "givenName", 239 1, 'X.509 Subject Directory Attributes'); 240cert_contains($sda_cert, 241 "localityName", 242 1, 'X.509 Subject Directory Attributes'); 243 244my $ass_info_cert = srctop_file(@certs, "ext-associatedInformation.pem"); 245cert_contains($ass_info_cert, 246 "Steve Brule", 247 1, 'X509v3 Associated Information'); 248cert_contains($ass_info_cert, 249 "CN=Hi mom", 250 1, 'X509v3 Associated Information'); 251cert_contains($ass_info_cert, 252 "<No Values>", 253 1, 'X509v3 Associated Information'); 254cert_contains($ass_info_cert, 255 "Funkytown", 256 1, 'X509v3 Associated Information'); 257cert_contains($ass_info_cert, 258 "commonName", 259 1, 'X509v3 Associated Information'); 260cert_contains($ass_info_cert, 261 "owner", 262 1, 'X509v3 Associated Information'); 263cert_contains($sda_cert, 264 "givenName", 265 1, 'X509v3 Associated Information'); 266cert_contains($ass_info_cert, 267 "localityName", 268 1, 'X509v3 Associated Information'); 269 270my $acc_cert_pol = srctop_file(@certs, "ext-acceptableCertPolicies.pem"); 271cert_contains($acc_cert_pol, 272 "X509v3 Acceptable Certification Policies", 273 1, 'X509v3 Acceptable Certification Policies'); 274# Yes, I know these OIDs make no sense in a policies extension. It's just a test. 275cert_contains($acc_cert_pol, 276 "organizationalUnitName", 277 1, 'X509v3 Acceptable Certification Policies'); 278cert_contains($acc_cert_pol, 279 "description", 280 1, 'X509v3 Acceptable Certification Policies'); 281 282my $acc_priv_pol = srctop_file(@certs, "ext-acceptablePrivilegePolicies.pem"); 283cert_contains($acc_priv_pol, 284 "X509v3 Acceptable Privilege Policies", 285 1, 'X509v3 Acceptable Privilege Policies'); 286# Yes, I know these OIDs make no sense in a policies extension. It's just a test. 287cert_contains($acc_priv_pol, 288 "commonName", 289 1, 'X509v3 Acceptable Certification Policies'); 290cert_contains($acc_priv_pol, 291 "organizationName", 292 1, 'X509v3 Acceptable Certification Policies'); 293 294my $user_notice_cert = srctop_file(@certs, "ext-userNotice.pem"); 295cert_contains($user_notice_cert, 296 "Organization: Wildboar Software", 297 1, 'X509v3 User Notice'); 298cert_contains($user_notice_cert, 299 "Numbers: 123, 456", 300 1, 'X509v3 User Notice'); 301cert_contains($user_notice_cert, 302 "Explicit Text: Hey there big boi", 303 1, 'X509v3 User Notice'); 304cert_contains($user_notice_cert, 305 "Number: 50505", 306 1, 'X509v3 User Notice'); 307cert_contains($user_notice_cert, 308 "Explicit Text: Ice ice baby", 309 1, 'X509v3 User Notice'); 310 311my $battcons_cert = srctop_file(@certs, "ext-basicAttConstraints.pem"); 312cert_contains($battcons_cert, 313 "authority:TRUE", 314 1, 'X.509 Basic Attribute Constraints Authority'); 315cert_contains($battcons_cert, 316 "pathlen:3", 317 1, 'X.509 Basic Attribute Constraints Path Length'); 318 319my $audit_id_cert = srctop_file(@certs, "ext-auditIdentity.pem"); 320cert_contains($audit_id_cert, 321 "09:08:07", 322 1, 'X509v3 Audit Identity'); 323 324my $iobo_cert = srctop_file(@certs, "ext-issuedOnBehalfOf.pem"); 325cert_contains($iobo_cert, 326 "DirName:CN = Wildboar", 327 1, 'X.509 Issued On Behalf Of'); 328 329my $auth_att_id_cert = srctop_file(@certs, "ext-authorityAttributeIdentifier.pem"); 330cert_contains($auth_att_id_cert, 331 "DirName:CN = Wildboar", 332 1, 'X.509 Authority Attribute Identifier'); 333cert_contains($auth_att_id_cert, 334 "Issuer Serial: 01030507", 335 1, 'X.509 Authority Attribute Identifier'); 336cert_contains($auth_att_id_cert, 337 "Issuer UID: B2", 338 1, 'X.509 Authority Attribute Identifier'); 339 340my $role_spec_cert = srctop_file(@certs, "ext-roleSpecCertIdentifier.pem"); 341cert_contains($role_spec_cert, 342 "Role Name: DirName:CN = Wildboar", 343 1, 'X.509 Role Spec Certificate Identifier'); 344cert_contains($role_spec_cert, 345 "Role Certificate Issuer: DirName:CN", 346 1, 'X.509 Role Spec Certificate Identifier'); 347cert_contains($role_spec_cert, 348 "Role Certificate Serial Number: 33818120 \\(0x2040608\\)", 349 1, 'X.509 Role Spec Certificate Identifier'); 350cert_contains($role_spec_cert, 351 "DNS:wildboarsoftware.com", 352 1, 'X.509 Role Spec Certificate Identifier'); 353cert_contains($role_spec_cert, 354 "Registered ID:description", 355 1, 'X.509 Role Spec Certificate Identifier'); 356 357my $attr_desc_cert = srctop_file(@certs, "ext-attributeDescriptor.pem"); 358cert_contains($attr_desc_cert, 359 "Identifier: 2.5.4.3", 360 1, 'X.509 Attribute Descriptor'); 361# This comes from the syntax field, which starts on the next line. 362cert_contains($attr_desc_cert, 363 "UnboundedDirectoryString", 364 1, 'X.509 Attribute Descriptor'); 365cert_contains($attr_desc_cert, 366 "Name: commonName", 367 1, 'X.509 Attribute Descriptor'); 368# These comes from the dominationRule field. 369cert_contains($attr_desc_cert, 370 "Privilege Policy Identifier: 2.5.4.10", 371 1, 'X.509 Attribute Descriptor'); 372cert_contains($attr_desc_cert, 373 "DirName:CN = Wildboar", 374 1, 'X.509 Attribute Descriptor'); 375cert_contains($attr_desc_cert, 376 "Algorithm: sha256", 377 1, 'X.509 Attribute Descriptor'); 378 379my $time_spec_abs_cert = srctop_file(@certs, "ext-timeSpecification-absolute.pem"); 380cert_contains($time_spec_abs_cert, 381 "Timezone: UTC-05:00", 382 1, 'X.509 Time Specification (Absolute)'); 383cert_contains($time_spec_abs_cert, 384 "Absolute: Any time between Dec 20 13:07:21 2022 GMT and Dec 20 13:07:21 2022 GMT", 385 1, 'X.509 Time Specification (Absolute)'); 386 387my $time_spec_per_cert = srctop_file(@certs, "ext-timeSpecification-periodic.pem"); 388cert_contains($time_spec_per_cert, 389 "Timezone: UTC-05:00", 390 1, 'X.509 Time Specification (Periodic)'); 391cert_contains($time_spec_per_cert, 392 "NOT this time:", 393 1, 'X.509 Time Specification (Periodic)'); 394cert_contains($time_spec_per_cert, 395 "05:43:21 - 12:34:56", 396 1, 'X.509 Time Specification (Periodic)'); 397cert_contains($time_spec_per_cert, 398 "Days of the week: SUN, MON", 399 1, 'X.509 Time Specification (Periodic)'); 400cert_contains($time_spec_per_cert, 401 "Weeks of the month: 3, 4", 402 1, 'X.509 Time Specification (Periodic)'); 403cert_contains($time_spec_per_cert, 404 "Months: MAY, JUN", 405 1, 'X.509 Time Specification (Periodic)'); 406cert_contains($time_spec_per_cert, 407 "Years: 2022, 2023", 408 1, 'X.509 Time Specification (Periodic)'); 409cert_contains($time_spec_per_cert, 410 "Months: JUL, AUG", 411 1, 'X.509 Time Specification (Periodic)'); 412cert_contains($time_spec_per_cert, 413 "Years: 2023, 2024", 414 1, 'X.509 Time Specification (Periodic)'); 415 416my $attr_map_cert = srctop_file(@certs, "ext-attributeMappings.pem"); 417cert_contains($attr_map_cert, 418 "commonName == localityName", 419 1, 'X.509 Attribute Mappings'); 420# localityName has an INTEGER value here, which was intentional to test the 421# display of non-string values. 422cert_contains($attr_map_cert, 423 "commonName:asdf == localityName:03:3E", 424 1, 'X.509 Attribute Mappings'); 425 426my $aaa_cert = srctop_file(@certs, "ext-allowedAttributeAssignments.pem"); 427cert_contains($aaa_cert, 428 "Attribute Type: commonName", 429 1, 'X.509 Allowed Attribute Assignments'); 430cert_contains($aaa_cert, 431 "Holder Domain: email:jonathan.wilbur", 432 1, 'X.509 Allowed Attribute Assignments'); 433 434my $aa_idp_cert = srctop_file(@certs, "ext-aAissuingDistributionPoint.pem"); 435cert_contains($aa_idp_cert, 436 "DirName:CN = Wildboar", 437 1, 'X.509 Attribute Authority Issuing Distribution Point'); 438cert_contains($aa_idp_cert, 439 "CA Compromise", 440 1, 'X.509 Attribute Authority Issuing Distribution Point'); 441cert_contains($aa_idp_cert, 442 "Indirect CRL: TRUE", 443 1, 'X.509 Attribute Authority Issuing Distribution Point'); 444cert_contains($aa_idp_cert, 445 "Contains User Attribute Certificates: TRUE", 446 1, 'X.509 Attribute Authority Issuing Distribution Point'); 447cert_contains($aa_idp_cert, 448 "Contains Attribute Authority \\(AA\\) Certificates: TRUE", 449 1, 'X.509 Attribute Authority Issuing Distribution Point'); 450cert_contains($aa_idp_cert, 451 "Contains Source Of Authority \\(SOA\\) Public Key Certificates: TRUE", 452 1, 'X.509 Attribute Authority Issuing Distribution Point'); 453 454sub test_errors { # actually tests diagnostics of OSSL_STORE 455 my ($expected, $cert, @opts) = @_; 456 my $infile = srctop_file(@certs, $cert); 457 my @args = qw(openssl x509 -in); 458 push(@args, $infile, @opts); 459 my $tmpfile = 'out.txt'; 460 my $res = grep(/-text/, @opts) ? run(app([@args], stdout => $tmpfile)) 461 : !run(app([@args], stderr => $tmpfile)); 462 my $found = 0; 463 open(my $in, '<', $tmpfile) or die "Could not open file $tmpfile"; 464 while(<$in>) { 465 print; # this may help debugging 466 $res &&= !m/asn1 encoding/; # output must not include ASN.1 parse errors 467 $found = 1 if m/$expected/; # output must include $expected 468 } 469 close $in; 470 # $tmpfile is kept to help with investigation in case of failure 471 return $res && $found; 472} 473 474# 3 tests for non-existence of spurious OSSL_STORE ASN.1 parse error output. 475# This requires provoking a failure exit of the app after reading input files. 476ok(test_errors("Bad output format", "root-cert.pem", '-outform', 'http'), 477 "load root-cert errors"); 478ok(test_errors("RC2-40-CBC", "v3-certs-RC2.p12", '-passin', 'pass:v3-certs'), 479 "load v3-certs-RC2 no asn1 errors"); # error msg should mention "RC2-40-CBC" 480SKIP: { 481 skip "sm2 not disabled", 1 if !disabled("sm2"); 482 483 ok(test_errors("Unable to load Public Key", "sm2.pem", '-text'), 484 "error loading unsupported sm2 cert"); 485} 486 487# 3 tests for -dateopts formats 488ok(run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "rfc_822", 489 "-in", srctop_file("test/certs", "ca-cert.pem")])), 490 "Run with rfc_8222 -dateopt format"); 491ok(run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "iso_8601", 492 "-in", srctop_file("test/certs", "ca-cert.pem")])), 493 "Run with iso_8601 -dateopt format"); 494ok(!run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "invalid_format", 495 "-in", srctop_file("test/certs", "ca-cert.pem")])), 496 "Run with invalid -dateopt format"); 497 498# Tests for signing certs (broken in 1.1.1o) 499my $a_key = "a-key.pem"; 500my $a_cert = "a-cert.pem"; 501my $a2_cert = "a2-cert.pem"; 502my $ca_key = "ca-key.pem"; 503my $ca_cert = "ca-cert.pem"; 504my $cnf = srctop_file('apps', 'openssl.cnf'); 505 506# Create cert A 507ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:2048", 508 "-config", $cnf, 509 "-keyout", $a_key, "-out", $a_cert, "-days", "365", 510 "-nodes", "-subj", "/CN=test.example.com"]))); 511# Create cert CA - note key size 512ok(run(app(["openssl", "req", "-x509", "-newkey", "rsa:4096", 513 "-config", $cnf, 514 "-keyout", $ca_key, "-out", $ca_cert, "-days", "3650", 515 "-nodes", "-subj", "/CN=ca.example.com"]))); 516# Sign cert A with CA (errors on 1.1.1o) 517ok(run(app(["openssl", "x509", "-in", $a_cert, "-CA", $ca_cert, 518 "-CAkey", $ca_key, "-set_serial", "1234567890", 519 "-preserve_dates", "-sha256", "-text", "-out", $a2_cert]))); 520# verify issuer is CA 521ok(get_issuer($a2_cert) =~ /CN=ca.example.com/); 522 523my $in_csr = srctop_file('test', 'certs', 'x509-check.csr'); 524my $in_key = srctop_file('test', 'certs', 'x509-check-key.pem'); 525my $invextfile = srctop_file('test', 'invalid-x509.cnf'); 526# Test that invalid extensions settings fail 527ok(!run(app(["openssl", "x509", "-req", "-in", $in_csr, "-signkey", $in_key, 528 "-out", "/dev/null", "-days", "3650" , "-extensions", "ext", 529 "-extfile", $invextfile]))); 530 531# Tests for issue #16080 (fixed in 1.1.1o) 532my $b_key = "b-key.pem"; 533my $b_csr = "b-cert.csr"; 534my $b_cert = "b-cert.pem"; 535# Create the CSR 536ok(run(app(["openssl", "req", "-new", "-newkey", "rsa:4096", 537 "-keyout", $b_key, "-out", $b_csr, "-nodes", 538 "-config", $cnf, 539 "-subj", "/CN=b.example.com"]))); 540# Sign it - position of "-text" matters! 541ok(run(app(["openssl", "x509", "-req", "-text", "-CAcreateserial", 542 "-CA", $ca_cert, "-CAkey", $ca_key, 543 "-in", $b_csr, "-out", $b_cert]))); 544# Verify issuer is CA 545ok(get_issuer($b_cert) =~ /CN=ca.example.com/); 546 547# although no explicit extensions given: 548has_version($b_cert, 3); 549has_SKID($b_cert, 1); 550has_AKID($b_cert, 1); 551 552# Tests for https://github.com/openssl/openssl/issues/10442 (fixed in 1.1.1a) 553# (incorrect default `-CAcreateserial` if `-CA` path has a dot in it) 554my $folder_with_dot = "test_x509.folder"; 555ok(mkdir $folder_with_dot); 556my $ca_cert_dot_in_dir = File::Spec->catfile($folder_with_dot, "ca-cert.pem"); 557ok(copy($ca_cert,$ca_cert_dot_in_dir)); 558my $ca_serial_dot_in_dir = File::Spec->catfile($folder_with_dot, "ca-cert.srl"); 559 560ok(run(app(["openssl", "x509", "-req", "-text", "-CAcreateserial", 561 "-CA", $ca_cert_dot_in_dir, "-CAkey", $ca_key, 562 "-in", $b_csr]))); 563ok(-e $ca_serial_dot_in_dir); 564 565# Tests for explicit start and end dates of certificates 566my %today = (strftime("%Y-%m-%d", gmtime) => 1); 567my $enddate; 568ok(run(app(["openssl", "x509", "-req", "-text", 569 "-key", $b_key, 570 "-not_before", "20231031000000Z", 571 "-not_after", "today", 572 "-in", $b_csr, "-out", $b_cert])) 573&& get_not_before($b_cert) =~ /Oct 31 00:00:00 2023 GMT/ 574&& ++$today{strftime("%Y-%m-%d", gmtime)} 575&& (grep { defined $today{$_} } get_not_after_date($b_cert))); 576# explicit start and end dates 577ok(run(app(["openssl", "x509", "-req", "-text", 578 "-key", $b_key, 579 "-not_before", "20231031000000Z", 580 "-not_after", "20231231000000Z", 581 "-days", "99", 582 "-in", $b_csr, "-out", $b_cert])) 583&& get_not_before($b_cert) =~ /Oct 31 00:00:00 2023 GMT/ 584&& get_not_after($b_cert) =~ /Dec 31 00:00:00 2023 GMT/); 585# start date today and days 586%today = (strftime("%Y-%m-%d", gmtime) => 1); 587$enddate = strftime("%Y-%m-%d", gmtime(time + 99 * 24 * 60 * 60)); 588ok(run(app(["openssl", "x509", "-req", "-text", 589 "-key", $b_key, 590 "-not_before", "today", 591 "-days", "99", 592 "-in", $b_csr, "-out", $b_cert])) 593&& ++$today{strftime("%Y-%m-%d", gmtime)} 594&& (grep { defined $today{$_} } get_not_before_date($b_cert)) 595&& get_not_after_date($b_cert) eq $enddate); 596# end date before start date 597ok(!run(app(["openssl", "x509", "-req", "-text", 598 "-key", $b_key, 599 "-not_before", "today", 600 "-not_after", "20231031000000Z", 601 "-in", $b_csr, "-out", $b_cert]))); 602# default days option 603%today = (strftime("%Y-%m-%d", gmtime) => 1); 604$enddate = strftime("%Y-%m-%d", gmtime(time + 30 * 24 * 60 * 60)); 605ok(run(app(["openssl", "x509", "-req", "-text", 606 "-key", $b_key, 607 "-in", $b_csr, "-out", $b_cert])) 608&& ++$today{strftime("%Y-%m-%d", gmtime)} 609&& (grep { defined $today{$_} } get_not_before_date($b_cert)) 610&& get_not_after_date($b_cert) eq $enddate); 611 612SKIP: { 613 skip "EC is not supported by this OpenSSL build", 1 614 if disabled("ec"); 615 my $psscert = srctop_file(@certs, "ee-self-signed-pss.pem"); 616 617 ok(run(test(["x509_test", $psscert])), "running x509_test"); 618} 619