2 # Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved.
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
13 use File::Compare qw/compare_text/;
15 use OpenSSL::Test qw/:DEFAULT/;
17 use POSIX qw(strftime);
19 my %conversionforms = (
20 # Default conversion forms. Other series may be added with
21 # specific test types as key.
23 "msb" => [ "d", "p", "msblob" ],
24 "pvk" => [ "d", "p", "pvk" ],
29 die "Missing option -type" unless $opts{-type};
30 die "Missing option -in" unless $opts{-in};
31 my $testtype = $opts{-type};
33 my $prefix = $opts{-prefix} // $testtype;
35 defined($conversionforms{$testtype}) ?
36 @{$conversionforms{$testtype}} :
37 @{$conversionforms{"*"}};
39 if (defined $opts{-args}) {
40 @openssl_args = @{$opts{-args}} if ref $opts{-args} eq 'ARRAY';
41 @openssl_args = ($opts{-args}) if ref $opts{-args} eq '';
43 @openssl_args = ($testtype) unless @openssl_args;
45 my $n = scalar @conversionforms;
48 + $n # initial conversions from p to all forms (A)
49 + $n*$n # conversion from result of A to all forms (B)
50 + 1 # comparing original test file to p form of A
51 + $n*($n-1); # comparing first conversion to each form in A with B
52 $totaltests-- if ($testtype eq "p7d"); # no comparison of original test file
53 $totaltests -= $n if ($testtype eq "pvk"); # no comparisons of the pvk form
54 plan tests => $totaltests;
56 my @cmd = ("openssl", @openssl_args);
59 if (scalar @openssl_args > 0 && $openssl_args[0] eq "pkey") {
60 $init = ok(run(app([@cmd, "-in", $t, "-out", "$prefix-fff.p"])),
63 $init = ok(copy($t, "$prefix-fff.p"), 'initializing');
66 diag("Trying to copy $t to $prefix-fff.p : $!");
70 skip "Not initialized, skipping...", 22 unless $init;
72 foreach my $to (@conversionforms) {
74 "-in", "$prefix-fff.p",
76 "-out", "$prefix-f.$to",
81 foreach my $to (@conversionforms) {
82 foreach my $from (@conversionforms) {
84 "-in", "$prefix-f.$from",
86 "-out", "$prefix-ff.$from$to",
92 if ($testtype ne "p7d") {
93 is(cmp_text("$prefix-fff.p", "$prefix-f.p"), 0,
94 'comparing orig to p');
97 foreach my $to (@conversionforms) {
98 next if $to eq "d" or $to eq "pvk";
99 foreach my $from (@conversionforms) {
100 is(cmp_text("$prefix-f.$to", "$prefix-ff.$from$to"), 0,
101 "comparing $to to $from$to");
108 return compare_text(@_, sub {
111 return $_[0] ne $_[1];
117 my $pattern = shift @_;
118 open(DATA, $_) or return 0;
119 $_= join('', <DATA>);
121 s/\s+/ /g; # take multiple whitespace (including newline) as single space
122 return m/$pattern/ ? 1 : 0;
127 my $pattern = shift @_;
128 my $expected = shift @_;
130 my $out = "cert_contains.out";
131 run(app(["openssl", "x509", "-noout", "-text", "-in", $cert, "-out", $out]));
132 is(file_contains($out, $pattern), $expected, ($name ? "$name: " : "").
133 "$cert should ".($expected ? "" : "not ")."contain: \"$pattern\"");
139 my $expect = shift @_;
140 cert_contains($cert, "Version: $expect", 1);
145 my $expect = shift @_;
146 cert_contains($cert, "Subject Key Identifier", $expect);
151 my $expect = shift @_;
152 cert_contains($cert, "Authority Key Identifier", $expect);
157 grep { not $seen{$_}++ } @_;
160 sub file_n_different_lines {
161 my $filename = shift @_;
162 open(DATA, $filename) or return 0;
163 chomp(my @lines = <DATA>);
165 return scalar(uniq @lines);
168 sub cert_ext_has_n_different_lines {
170 my $expected = shift @_;
173 my $out = "cert_n_different_exts.out";
174 run(app(["openssl", "x509", "-noout", "-ext", $exts,
175 "-in", $cert, "-out", $out]));
176 is(file_n_different_lines($out), $expected, ($name ? "$name: " : "").
177 "$cert '$exts' output should contain $expected different lines");
181 # extracts string value of certificate field from a -text formatted-output
183 my ($f, $field) = @_;
185 open my $fh, $f or die;
186 while (my $line = <$fh>) {
187 if ($line =~ /$field:\s+(.*)/) {
196 return get_field(@_, "Issuer");
200 return get_field(@_, "Not Before");
204 sub get_not_before_date {
205 return Time::Piece->strptime(
207 "%b %d %T %Y %Z")->date;
211 return get_field(@_, "Not After ");
215 sub get_not_after_date {
216 return Time::Piece->strptime(
218 "%b %d %T %Y %Z")->date;