xref: /freebsd-src/crypto/openssl/util/perl/OpenSSL/Test/Utils.pm (revision a7148ab39c03abd4d1a84997c70bf96f15dd2a09)
1*a7148ab3SEnji Cooper# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved.
2e0c4386eSCy Schubert#
3e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License").  You may not use
4e0c4386eSCy Schubert# this file except in compliance with the License.  You can obtain a copy
5e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at
6e0c4386eSCy Schubert# https://www.openssl.org/source/license.html
7e0c4386eSCy Schubert
8e0c4386eSCy Schubertpackage OpenSSL::Test::Utils;
9e0c4386eSCy Schubert
10e0c4386eSCy Schubertuse strict;
11e0c4386eSCy Schubertuse warnings;
12e0c4386eSCy Schubert
13e0c4386eSCy Schubertuse Exporter;
14e0c4386eSCy Schubertuse vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
15e0c4386eSCy Schubert$VERSION = "0.1";
16e0c4386eSCy Schubert@ISA = qw(Exporter);
17e0c4386eSCy Schubert@EXPORT = qw(alldisabled anydisabled disabled config available_protocols
18e0c4386eSCy Schubert             have_IPv4 have_IPv6);
19e0c4386eSCy Schubert
20e0c4386eSCy Schubert=head1 NAME
21e0c4386eSCy Schubert
22e0c4386eSCy SchubertOpenSSL::Test::Utils - test utility functions
23e0c4386eSCy Schubert
24e0c4386eSCy Schubert=head1 SYNOPSIS
25e0c4386eSCy Schubert
26e0c4386eSCy Schubert  use OpenSSL::Test::Utils;
27e0c4386eSCy Schubert
28e0c4386eSCy Schubert  my @tls = available_protocols("tls");
29e0c4386eSCy Schubert  my @dtls = available_protocols("dtls");
30e0c4386eSCy Schubert  alldisabled("dh", "dsa");
31e0c4386eSCy Schubert  anydisabled("dh", "dsa");
32e0c4386eSCy Schubert
33e0c4386eSCy Schubert  config("fips");
34e0c4386eSCy Schubert
35e0c4386eSCy Schubert  have_IPv4();
36e0c4386eSCy Schubert  have_IPv6();
37e0c4386eSCy Schubert
38e0c4386eSCy Schubert=head1 DESCRIPTION
39e0c4386eSCy Schubert
40e0c4386eSCy SchubertThis module provides utility functions for the testing framework.
41e0c4386eSCy Schubert
42e0c4386eSCy Schubert=cut
43e0c4386eSCy Schubert
44e0c4386eSCy Schubertuse OpenSSL::Test qw/:DEFAULT bldtop_file/;
45e0c4386eSCy Schubert
46e0c4386eSCy Schubert=over 4
47e0c4386eSCy Schubert
48e0c4386eSCy Schubert=item B<available_protocols STRING>
49e0c4386eSCy Schubert
50e0c4386eSCy SchubertReturns a list of strings for all the available SSL/TLS versions if
51e0c4386eSCy SchubertSTRING is "tls", or for all the available DTLS versions if STRING is
52e0c4386eSCy Schubert"dtls".  Otherwise, it returns the empty list.  The strings in the
53e0c4386eSCy Schubertreturned list can be used with B<alldisabled> and B<anydisabled>.
54e0c4386eSCy Schubert
55e0c4386eSCy Schubert=item B<alldisabled ARRAY>
56e0c4386eSCy Schubert
57e0c4386eSCy Schubert=item B<anydisabled ARRAY>
58e0c4386eSCy Schubert
59e0c4386eSCy SchubertIn an array context returns an array with each element set to 1 if the
60e0c4386eSCy Schubertcorresponding feature is disabled and 0 otherwise.
61e0c4386eSCy Schubert
62e0c4386eSCy SchubertIn a scalar context, alldisabled returns 1 if all of the features in
63e0c4386eSCy SchubertARRAY are disabled, while anydisabled returns 1 if any of them are
64e0c4386eSCy Schubertdisabled.
65e0c4386eSCy Schubert
66e0c4386eSCy Schubert=item B<config STRING>
67e0c4386eSCy Schubert
68e0c4386eSCy SchubertReturns an item from the %config hash in \$TOP/configdata.pm.
69e0c4386eSCy Schubert
70e0c4386eSCy Schubert=item B<have_IPv4>
71e0c4386eSCy Schubert
72e0c4386eSCy Schubert=item B<have_IPv6>
73e0c4386eSCy Schubert
74e0c4386eSCy SchubertReturn true if IPv4 / IPv6 is possible to use on the current system.
75*a7148ab3SEnji CooperAdditionally, B<have_IPv6> also checks how OpenSSL was configured,
76*a7148ab3SEnji Cooperi.e. if IPv6 was explicitly disabled with -DOPENSSL_USE_IPv6=0.
77e0c4386eSCy Schubert
78e0c4386eSCy Schubert=back
79e0c4386eSCy Schubert
80e0c4386eSCy Schubert=cut
81e0c4386eSCy Schubert
82e0c4386eSCy Schubertour %available_protocols;
83e0c4386eSCy Schubertour %disabled;
84e0c4386eSCy Schubertour %config;
85*a7148ab3SEnji Cooperour %target;
86e0c4386eSCy Schubertmy $configdata_loaded = 0;
87e0c4386eSCy Schubert
88e0c4386eSCy Schubertsub load_configdata {
89e0c4386eSCy Schubert    # We eval it so it doesn't run at compile time of this file.
90e0c4386eSCy Schubert    # The latter would have bldtop_file() complain that setup() hasn't
91e0c4386eSCy Schubert    # been run yet.
92e0c4386eSCy Schubert    my $configdata = bldtop_file("configdata.pm");
93e0c4386eSCy Schubert    eval { require $configdata;
94e0c4386eSCy Schubert	   %available_protocols = %configdata::available_protocols;
95e0c4386eSCy Schubert	   %disabled = %configdata::disabled;
96e0c4386eSCy Schubert	   %config = %configdata::config;
97*a7148ab3SEnji Cooper	   %target = %configdata::target;
98e0c4386eSCy Schubert    };
99e0c4386eSCy Schubert    $configdata_loaded = 1;
100e0c4386eSCy Schubert}
101e0c4386eSCy Schubert
102e0c4386eSCy Schubert# args
103e0c4386eSCy Schubert#  list of 1s and 0s, coming from check_disabled()
104e0c4386eSCy Schubertsub anyof {
105e0c4386eSCy Schubert    my $x = 0;
106e0c4386eSCy Schubert    foreach (@_) { $x += $_ }
107e0c4386eSCy Schubert    return $x > 0;
108e0c4386eSCy Schubert}
109e0c4386eSCy Schubert
110e0c4386eSCy Schubert# args
111e0c4386eSCy Schubert#  list of 1s and 0s, coming from check_disabled()
112e0c4386eSCy Schubertsub allof {
113e0c4386eSCy Schubert    my $x = 1;
114e0c4386eSCy Schubert    foreach (@_) { $x *= $_ }
115e0c4386eSCy Schubert    return $x > 0;
116e0c4386eSCy Schubert}
117e0c4386eSCy Schubert
118e0c4386eSCy Schubert# args
119e0c4386eSCy Schubert#  list of strings, all of them should be names of features
120e0c4386eSCy Schubert#  that can be disabled.
121e0c4386eSCy Schubert# returns a list of 1s (if the corresponding feature is disabled)
122e0c4386eSCy Schubert#  and 0s (if it isn't)
123e0c4386eSCy Schubertsub check_disabled {
124e0c4386eSCy Schubert    return map { exists $disabled{lc $_} ? 1 : 0 } @_;
125e0c4386eSCy Schubert}
126e0c4386eSCy Schubert
127e0c4386eSCy Schubert# Exported functions #################################################
128e0c4386eSCy Schubert
129e0c4386eSCy Schubert# args:
130e0c4386eSCy Schubert#  list of features to check
131e0c4386eSCy Schubertsub anydisabled {
132e0c4386eSCy Schubert    load_configdata() unless $configdata_loaded;
133e0c4386eSCy Schubert    my @ret = check_disabled(@_);
134e0c4386eSCy Schubert    return @ret if wantarray;
135e0c4386eSCy Schubert    return anyof(@ret);
136e0c4386eSCy Schubert}
137e0c4386eSCy Schubert
138e0c4386eSCy Schubert# args:
139e0c4386eSCy Schubert#  list of features to check
140e0c4386eSCy Schubertsub alldisabled {
141e0c4386eSCy Schubert    load_configdata() unless $configdata_loaded;
142e0c4386eSCy Schubert    my @ret = check_disabled(@_);
143e0c4386eSCy Schubert    return @ret if wantarray;
144e0c4386eSCy Schubert    return allof(@ret);
145e0c4386eSCy Schubert}
146e0c4386eSCy Schubert
147e0c4386eSCy Schubert# !!! Kept for backward compatibility
148e0c4386eSCy Schubert# args:
149e0c4386eSCy Schubert#  single string
150e0c4386eSCy Schubertsub disabled {
151e0c4386eSCy Schubert    anydisabled(@_);
152e0c4386eSCy Schubert}
153e0c4386eSCy Schubert
154e0c4386eSCy Schubertsub available_protocols {
155e0c4386eSCy Schubert    load_configdata() unless $configdata_loaded;
156e0c4386eSCy Schubert    my $protocol_class = shift;
157e0c4386eSCy Schubert    if (exists $available_protocols{lc $protocol_class}) {
158e0c4386eSCy Schubert	return @{$available_protocols{lc $protocol_class}}
159e0c4386eSCy Schubert    }
160e0c4386eSCy Schubert    return ();
161e0c4386eSCy Schubert}
162e0c4386eSCy Schubert
163e0c4386eSCy Schubertsub config {
164e0c4386eSCy Schubert    load_configdata() unless $configdata_loaded;
165e0c4386eSCy Schubert    return $config{$_[0]};
166e0c4386eSCy Schubert}
167e0c4386eSCy Schubert
168e0c4386eSCy Schubert# IPv4 / IPv6 checker
169e0c4386eSCy Schubertmy $have_IPv4 = -1;
170e0c4386eSCy Schubertmy $have_IPv6 = -1;
171e0c4386eSCy Schubertmy $IP_factory;
172e0c4386eSCy Schubertsub check_IP {
173e0c4386eSCy Schubert    my $listenaddress = shift;
174e0c4386eSCy Schubert
175e0c4386eSCy Schubert    eval {
176e0c4386eSCy Schubert        require IO::Socket::IP;
177e0c4386eSCy Schubert        my $s = IO::Socket::IP->new(
178e0c4386eSCy Schubert            LocalAddr => $listenaddress,
179e0c4386eSCy Schubert            LocalPort => 0,
180e0c4386eSCy Schubert            Listen=>1,
181e0c4386eSCy Schubert            );
182e0c4386eSCy Schubert        $s or die "\n";
183e0c4386eSCy Schubert        $s->close();
184e0c4386eSCy Schubert    };
185e0c4386eSCy Schubert    if ($@ eq "") {
186e0c4386eSCy Schubert        return 1;
187e0c4386eSCy Schubert    }
188e0c4386eSCy Schubert
189e0c4386eSCy Schubert    eval {
190e0c4386eSCy Schubert        require IO::Socket::INET6;
191e0c4386eSCy Schubert        my $s = IO::Socket::INET6->new(
192e0c4386eSCy Schubert            LocalAddr => $listenaddress,
193e0c4386eSCy Schubert            LocalPort => 0,
194e0c4386eSCy Schubert            Listen=>1,
195e0c4386eSCy Schubert            );
196e0c4386eSCy Schubert        $s or die "\n";
197e0c4386eSCy Schubert        $s->close();
198e0c4386eSCy Schubert    };
199e0c4386eSCy Schubert    if ($@ eq "") {
200e0c4386eSCy Schubert        return 1;
201e0c4386eSCy Schubert    }
202e0c4386eSCy Schubert
203e0c4386eSCy Schubert    eval {
204e0c4386eSCy Schubert        require IO::Socket::INET;
205e0c4386eSCy Schubert        my $s = IO::Socket::INET->new(
206e0c4386eSCy Schubert            LocalAddr => $listenaddress,
207e0c4386eSCy Schubert            LocalPort => 0,
208e0c4386eSCy Schubert            Listen=>1,
209e0c4386eSCy Schubert            );
210e0c4386eSCy Schubert        $s or die "\n";
211e0c4386eSCy Schubert        $s->close();
212e0c4386eSCy Schubert    };
213e0c4386eSCy Schubert    if ($@ eq "") {
214e0c4386eSCy Schubert        return 1;
215e0c4386eSCy Schubert    }
216e0c4386eSCy Schubert
217e0c4386eSCy Schubert    return 0;
218e0c4386eSCy Schubert}
219e0c4386eSCy Schubert
220e0c4386eSCy Schubertsub have_IPv4 {
221e0c4386eSCy Schubert    if ($have_IPv4 < 0) {
222e0c4386eSCy Schubert        $have_IPv4 = check_IP("127.0.0.1");
223e0c4386eSCy Schubert    }
224e0c4386eSCy Schubert    return $have_IPv4;
225e0c4386eSCy Schubert}
226e0c4386eSCy Schubert
227e0c4386eSCy Schubertsub have_IPv6 {
228e0c4386eSCy Schubert    if ($have_IPv6 < 0) {
229*a7148ab3SEnji Cooper        load_configdata() unless $configdata_loaded;
230*a7148ab3SEnji Cooper        # If OpenSSL is configured with IPv6 explicitly disabled, no IPv6
231*a7148ab3SEnji Cooper        # related tests should be performed.  In other words, pretend IPv6
232*a7148ab3SEnji Cooper        # isn't present.
233*a7148ab3SEnji Cooper        $have_IPv6 = 0
234*a7148ab3SEnji Cooper            if grep { $_ eq 'OPENSSL_USE_IPV6=0' } @{$config{CPPDEFINES}};
235*a7148ab3SEnji Cooper        # Similarly, if a config target has explicitly disabled IPv6, no
236*a7148ab3SEnji Cooper        # IPv6 related tests should be performed.
237*a7148ab3SEnji Cooper        $have_IPv6 = 0
238*a7148ab3SEnji Cooper            if grep { $_ eq 'OPENSSL_USE_IPV6=0' } @{$target{defines}};
239*a7148ab3SEnji Cooper    }
240*a7148ab3SEnji Cooper    if ($have_IPv6 < 0) {
241e0c4386eSCy Schubert        $have_IPv6 = check_IP("::1");
242e0c4386eSCy Schubert    }
243e0c4386eSCy Schubert    return $have_IPv6;
244e0c4386eSCy Schubert}
245e0c4386eSCy Schubert
246e0c4386eSCy Schubert=head1 SEE ALSO
247e0c4386eSCy Schubert
248e0c4386eSCy SchubertL<OpenSSL::Test>
249e0c4386eSCy Schubert
250e0c4386eSCy Schubert=head1 AUTHORS
251e0c4386eSCy Schubert
252e0c4386eSCy SchubertStephen Henson E<lt>steve@openssl.orgE<gt> and
253e0c4386eSCy SchubertRichard Levitte E<lt>levitte@openssl.orgE<gt>
254e0c4386eSCy Schubert
255e0c4386eSCy Schubert=cut
256e0c4386eSCy Schubert
257e0c4386eSCy Schubert1;
258