QUIC QLOG: Add unit test
[openssl.git] / test / recipes / tconversion.pl
1 #! /usr/bin/env perl
2 # Copyright 2015-2023 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
10 use strict;
11 use warnings;
12
13 use File::Compare qw/compare_text/;
14 use File::Copy;
15 use OpenSSL::Test qw/:DEFAULT/;
16
17 my %conversionforms = (
18     # Default conversion forms.  Other series may be added with
19     # specific test types as key.
20     "*"         => [ "d", "p" ],
21     "msb"       => [ "d", "p", "msblob" ],
22     "pvk"       => [ "d", "p", "pvk" ],
23     );
24 sub tconversion {
25     my %opts = @_;
26
27     die "Missing option -type" unless $opts{-type};
28     die "Missing option -in" unless $opts{-in};
29     my $testtype = $opts{-type};
30     my $t = $opts{-in};
31     my $prefix = $opts{-prefix} // $testtype;
32     my @conversionforms =
33         defined($conversionforms{$testtype}) ?
34         @{$conversionforms{$testtype}} :
35         @{$conversionforms{"*"}};
36     my @openssl_args;
37     if (defined $opts{-args}) {
38         @openssl_args = @{$opts{-args}} if ref $opts{-args} eq 'ARRAY';
39         @openssl_args = ($opts{-args}) if ref $opts{-args} eq '';
40     }
41     @openssl_args = ($testtype) unless @openssl_args;
42
43     my $n = scalar @conversionforms;
44     my $totaltests =
45         1                       # for initializing
46         + $n                    # initial conversions from p to all forms (A)
47         + $n*$n                 # conversion from result of A to all forms (B)
48         + 1                     # comparing original test file to p form of A
49         + $n*($n-1);            # comparing first conversion to each form in A with B
50     $totaltests-- if ($testtype eq "p7d"); # no comparison of original test file
51     $totaltests -= $n if ($testtype eq "pvk"); # no comparisons of the pvk form
52     plan tests => $totaltests;
53
54     my @cmd = ("openssl", @openssl_args);
55
56     my $init;
57     if (scalar @openssl_args > 0 && $openssl_args[0] eq "pkey") {
58         $init = ok(run(app([@cmd, "-in", $t, "-out", "$prefix-fff.p"])),
59                    'initializing');
60     } else {
61         $init = ok(copy($t, "$prefix-fff.p"), 'initializing');
62     }
63     if (!$init) {
64         diag("Trying to copy $t to $prefix-fff.p : $!");
65     }
66
67   SKIP: {
68       skip "Not initialized, skipping...", 22 unless $init;
69
70       foreach my $to (@conversionforms) {
71           ok(run(app([@cmd,
72                       "-in", "$prefix-fff.p",
73                       "-inform", "p",
74                       "-out", "$prefix-f.$to",
75                       "-outform", $to])),
76              "p -> $to");
77       }
78
79       foreach my $to (@conversionforms) {
80           foreach my $from (@conversionforms) {
81               ok(run(app([@cmd,
82                           "-in", "$prefix-f.$from",
83                           "-inform", $from,
84                           "-out", "$prefix-ff.$from$to",
85                           "-outform", $to])),
86                  "$from -> $to");
87           }
88       }
89
90       if ($testtype ne "p7d") {
91           is(cmp_text("$prefix-fff.p", "$prefix-f.p"), 0,
92              'comparing orig to p');
93       }
94
95       foreach my $to (@conversionforms) {
96           next if $to eq "d" or $to eq "pvk";
97           foreach my $from (@conversionforms) {
98               is(cmp_text("$prefix-f.$to", "$prefix-ff.$from$to"), 0,
99                  "comparing $to to $from$to");
100           }
101       }
102     }
103 }
104
105 sub cmp_text {
106     return compare_text(@_, sub {
107         $_[0] =~ s/\R//g;
108         $_[1] =~ s/\R//g;
109         return $_[0] ne $_[1];
110     });
111 }
112
113 sub file_contains {
114     $_ = shift @_;
115     my $pattern = shift @_;
116     open(DATA, $_) or return 0;
117     $_= join('', <DATA>);
118     close(DATA);
119     s/\s+/ /g; # take multiple whitespace (including newline) as single space
120     return m/$pattern/ ? 1 : 0;
121 }
122
123 sub cert_contains {
124     my $cert = shift @_;
125     my $pattern = shift @_;
126     my $expected = shift @_;
127     my $name = shift @_;
128     my $out = "cert_contains.out";
129     run(app(["openssl", "x509", "-noout", "-text", "-in", $cert, "-out", $out]));
130     is(file_contains($out, $pattern), $expected, ($name ? "$name: " : "").
131        "$cert should ".($expected ? "" : "not ")."contain: \"$pattern\"");
132     # not unlinking $out
133 }
134
135 sub has_version {
136     my $cert = shift @_;
137     my $expect = shift @_;
138     cert_contains($cert, "Version: $expect", 1);
139 }
140
141 sub has_SKID {
142     my $cert = shift @_;
143     my $expect = shift @_;
144     cert_contains($cert, "Subject Key Identifier", $expect);
145 }
146
147 sub has_AKID {
148     my $cert = shift @_;
149     my $expect = shift @_;
150     cert_contains($cert, "Authority Key Identifier", $expect);
151 }
152
153 sub uniq (@) {
154     my %seen = ();
155     grep { not $seen{$_}++ } @_;
156 }
157
158 sub file_n_different_lines {
159     my $filename = shift @_;
160     open(DATA, $filename) or return 0;
161     chomp(my @lines = <DATA>);
162     close(DATA);
163     return scalar(uniq @lines);
164 }
165
166 sub cert_ext_has_n_different_lines {
167     my $cert = shift @_;
168     my $expected = shift @_;
169     my $exts = shift @_;
170     my $name = shift @_;
171     my $out = "cert_n_different_exts.out";
172     run(app(["openssl", "x509", "-noout", "-ext", $exts,
173              "-in", $cert, "-out", $out]));
174     is(file_n_different_lines($out), $expected, ($name ? "$name: " : "").
175        "$cert '$exts' output should contain $expected different lines");
176     # not unlinking $out
177 }
178
179 1;