view release on metacpan or search on metacpan
It doesn't work together with Storable::fd_retrieve|fd_store, see
https://rt.cpan.org/Ticket/Display.html?id=23419.
You need to use freeze/nfreeze/thaw and syswrite/sysread the data
yourself. See the bug for examples how to do it.
---------------------
Note that a random number generator is required for the proper
operation of this module. Systems that have /dev/random or
/dev/urandom are fine, but those that do not, like most versions
of Solaris, will need to fetch one before installing IO::Socket::SSL.
If you don't already have a favorite, try EGD (egd.sourceforge.net).
---------------------
Versions of perl-ldap below v0.26 do not work with this version
of IO::Socket::SSL because they contain a workaround for old
versions of IO::Socket::SSL that breaks new versions.
---------------------
One user mentioned that the following did not work as it should in
IO::Socket::SSL, but worked in IO::Socket::INET:
chomp($var = <$socket>);
print ord(chop($var)); # Prints "10" for people using ASCII
This is due to a bug in Perl that is fixed in 5.8.1. If you need
a workaround, try one of the following:
chomp($var = $socket->getline());
chomp($var = scalar <$socket>);
chomp($var = $var = <$socket>);
SSL error keep the original error
- small tests fixes
2.074
- add SSL_ciphersuites option for TLS 1.3 ciphers
- no longer use own default for ciphers, instead use system default but disable
some weak ciphers which might still be enabled on older systems
2.073
- fix behavior and tests for openssl 3.0.1
- fix #110 - prevent internal error warning in some cases
2.072
- add PEM_certs2file and PEM_file2certs in IO::Socket::SSL::Utils based
on idea by rovo89 in #101
- certs/*.p12 used for testing should now work with OpenSSL 3.0 too #108
- update public suffix database
2.071 2021/05/23
- fix t/nonblock.t race on some systems. Fixes issue #102, maybe #98 too.
2.070 2021/02/26
- changed bugtracker in Makefile.PL to github, away from obsolete rt.cpan.org
2.069 2021/01/22
- IO::Socket::Utils CERT_asHash and CERT_create now support subject and issuer
with multiple same parts (like multiple OU). In this case an array ref instead
2.058 2018/07/19
- fix t/session_ticket.t: it failed with OpenSSL 1.1.* since this version
expects the extKeyUsage of clientAuth in the client cert also to be allowed
by the CA if CA uses extKeyUsage
2.057 2018/07/18
- fix memory leak which occurred with explicit stop_SSL in connection with
non-blocking sockets or timeout - https://rt.cpan.org/Ticket/Display.html?id=125867
Thanks to Paul Evans for reporting
- fix redefine warnings in case Socket6 is installed but neither IO::Socket::IP
nor IO::Socket::INET6 - https://rt.cpan.org/Ticket/Display.html?id=124963
- IO::Socket::SSL::Intercept - optional 'serial' argument can be starting number
or callback to create serial number based on the original certificate
- new function get_session_reused to check if a session got reused
- IO::Socket::SSL::Utils::CERT_asHash: fingerprint_xxx now set to the correct value
2.056 2018/02/19
- Intercept - fix creation of serial number: base it on binary digest instead of
treating hex fingerprint as binary. Allow use of own serial numbers again.
- t/io-socket-ip.t - skip test if no IPv6 support on system RT#124464
- update PublicSuffix
2.055 2018/02/15
- use SNI also if hostname was given all-uppercase
- Utils::CERT_create - don't add authority key for issuer since Chrome does
not like this
- Intercept:
objects -> github pull#55
- optimization: don't track SSL objects and CTX in *CREATED_IN_THIS_THREAD
if perl is compiled w/o thread support
- small fix in t/protocol_version.t to use older versions of Net::SSLeay
with openssl build w/o SSLv3 support
- when setting SSL_keepSocketOnError to true the socket will not be closed
on fatal error. This is a modified version of
https://github.com/noxxi/p5-io-socket-ssl/pull/53/
2.044 2017/01/26
- protect various 'eval'-based capability detections at startup with a localized
__DIE__ handler. This way dynamically requiring IO::Socket::SSL as done by
various third party software should cause less problems even if there is a
global __DIE__ handler which does not properly deal with 'eval'.
2.043 2017/01/06
- make t/session_ticket.t work with OpenSSL 1.1.0. With this version the
session does not get reused any longer if it was not properly closed which
is now done using an explicit close by the client which causes a
proper SSL_shutdown
2.042 2017/01/05
- enable session ticket callback with Net::SSLeay>=1.80
2.041 2017/01/04
- move initialization of OpenSSL-internals out of INIT again because this
breaks if module is used with require. Since there is no right place to
work in all circumstances just document the work-arounds needed for
perlcc. RT#97166
1.995 2014/07/11
- RT#95452 - move initialization and creation of OpenSSL-internals into INIT
section, so they get executed after compilation and perlcc is happy.
- refresh option for peer_certificate, so that it checks if the certificate
changed in the mean time (on renegotiation)
- fix fingerprint checking - now applies only to topmost certificate
- IO::Socket::SSL::Utils - accept extensions within CERT_create
- documentations fixes thanks to frioux
- fix documentation bug RT#96765, thanks to Salvatore Bonaccorso.
1.994 2014/06/22
- IO::Socket::SSL can now be used as dual-use socket, e.g. start plain, upgrade
to SSL and downgrade again all with the same object. See documentation of
SSL_startHandshake and chapter Advanced Usage.
- try to apply SSL_ca* even if verify_mode is 0, but don't complain if this
fails. This is needed if one wants to explicitly verify OCSP lookups even if
verification is otherwise off, because otherwise the signature check would
fail. This is mostly useful for testing.
- reorder documentation of attributes for new, so that the more important ones
are at the top.
1.993 2014/06/13
- major rewrite of documentation, now in separate file
DNS and because we enforce a public suffix list (and thus *.co.uk should
not be allowed)
1.985 2014/05/15
- make OCSP callback return 1 even if it was called on the server side
because of bad setup of the socket. Otherwise we get an endless calling
of the OCSP callback.
- consider an OCSP response which is not yet or no longer valid a soft error
instead of a hard error
- fix skip in t/external/ocsp.t in case fingerprint does not match
- RT#95633 call EVP_PKEY_free not EVP_KEY_free in
IO::Socket::SSL::Utils::KEY_free. Thanks to paul[AT]city-fan[DOT]org
- util/analyze.pl - with --show-chain check if chain with SNI is different
from chain w/o SNI.
1.984 2014/05/10
- added OCSP support:
- needs Net::SSLeay >=1.59
- for usage see documentation of IO::Socket::SSL (examples and anything with
OCSP in the name)
- new tool util/analyze-ssl.pl which is intended to help in debugging of SSL
problems and to get information about capabilities of server. Works also
as en example of how to use various features (like OCSP, SNI..)
- fix peer_certificates (returns leaf certificate only once on client side)
- added timeout for stop_SSL (either with Timeout or with the default
timeout for IO::Socket)
- fix IO::Socket::SSL::Utils mapping between ASN1_TIME and time_t when local
time is not GMT. Use Net::SSLeay::ASN1_TIME_timet if available.
- fix t/external/usable_ca.t for system with junk in CA files
1.983 2014/05/03
- fix public suffix handling: ajax.googleapis.com should be ok even if googleapis.com
is in public suffix list (e.g. check one level less)
#95317, thanks to purification[AT]ukr[DOT]net
- usable_ca.t - update fingerprints after heartbleed attack
- usable_ca.t - make sure we have usable CA for tested hosts in CA store
1.982 2014/04/24
- fix for using subroutine as argument to set_args_filter_hack
1.981 2014/04/08
- #95432 fix ecdhe Test for openssl1.0.1d, thanks to paul[AT]city-fan[DOT]org
- fix detection of openssl1.0.1d (detected 1.0.1e instead)
- new function can_ecdh in IO::Socket::SSL
1.980 2014/04/08
- fixed incorrect calculation of certificate fingerprint in get_fingerprint*
and comparison in SSL_fingerprint. Thanks to
david[DT]palmer[AT]gradwell[DOT]com for reporting.
- disable elliptic curve support for openssl 1.0.1d on 64bit because of
openssl rt#2975
1.979 2014/04/06
- hostname checking:
- configuration of 'leftmost' is renamed to 'full_label', but the old
version is kept for compatibility reasons.
- fix publicsuffix for IDNA, more tests with various IDNA libs
RT#94424. Thanks to paul[AT]city-fan[DOT]org
- reuse result of IDN lib detection from PublicSuffix.pm in SSL.pm
- add more checks to external/usable_ca.t. Now it is enough that at least
one of the hosts verifies against the builtin CA store
- add openssl and Net::SSleay version to diagnostics in load test
1.976 2014/04/03
- added public prefix checking to verification of wildcard certificates,
e.g. accept *.foo.com but not *.co.uk.
See documentation of SSL_verifycn_publicsuffix and
IO::Socket::SSL::PublicSuffix
Thanks to noloader for pointing out the problem.
1.975 2014/04/02
- BEHAVIOR CHANGE: work around TEA misfeature on OS X builtin openssl, e.g.
guarantee that only the explicitly given CA or the openssl default CA will
be used. This means that certificates inside the OS X keyring will no
longer be used, because there is no way to control the use by openssl
(e.g. certificate pinning etc)
- make external tests run by default to make sure default CA works on all
platforms, it skips automatically on network problems like timeouts or ssl
interception, can also use http(s)_proxy environment variables
blocking method, thanks to tokuhirom
- documentation enhancements:
- special section for differences to IO::Socket
- describe problem with blocking accept on non-blocking socket
- describe arguments to new_from_fd and make clear, that for upgrading an
existing IO::Socket start_SSL should be used directly
1.962 2013/11/27
- work around problems with older F5 BIG-IP by offering fewer ciphers on the
client side by default, so that the client hello stays below 255 byte
1.961 2013/11/26
- IO::Socket::SSL::Utils::CERT_create can now create CA-certificates which
are not self-signed (by giving issuer_*)
1.960 2013/11/12
only documentation enhancements:
- clarify with text and example code, that within event loops not only
select/poll should be used, but also pending has to be called.
- better introduction into SSL, at least mention anonymous authentication as
something you don't want and should take care with the right cipher
- make it more clear, that user better does not change the cipher list, unless
he really know what he is doing
1.959 2013/11/12
with 'xn--')
- fix crash of Utils::CERT_free
- support TLSv11, TLSv12 as handshake protocols
1.955 2013/10/11
- support for forward secrecy using ECDH, if the Net::SSLeay/openssl version
supports it.
1.954 2013/9/15
- accept older versions of ExtUtils::MakeMaker and add meta information
like link to repository only for newer versions.
1.953 2013/7/22
- fixes to IO::Socket::SSL::Utils, thanks to rurban[AT]x-ray[DOT]at,
RT#87052
1.952 2013/7/11
- fix t/acceptSSL-timeout.t on Win32, RT#86862
1.951 2013/7/3
- better document builtin defaults for key,cert,CA and how they are depreceated
- use Net::SSLeay::CTX_set_default_verify_paths to use openssl's builtin
defaults for CA unless CA path/file was given (or IO::Socket::SSL builtins
used)
1.950 2013/7/3
- MAJOR BEHAVIOR CHANGE:
ssl_verify_mode now defaults to verify_peer for client.
Until now it used verify_none, but loudly complained since 1.79 about it.
It will not complain any longer, but the connection might probably fail.
Please don't simply disable ssl verification, but instead set SSL_ca_file
etc so that verification succeeds!
- MAJOR BEHAVIOR CHANGE:
it will now complain if the builtin defaults of certs/my-ca.pem or ca/
- Makefile.PL reported wrong version of openssl, if Net::SSLeay was not
installed instead of reporting missing dependency to Net::SSLeay.
v1.93 2013.05.31
- need at least OpenSSL version 0.9.8 now, since last 0.9.7 was released 6
years ago. Remove code to work around older releases.
- changed AUTHOR in Makefile.PL from array back to string, because the
array feature is not available in MakeMaker shipped with 5.8.9 (RT#85739)
v1.92 2013.05.30
- Intercept: use sha1-fingerprint of original cert for id into cache unless
otherwise given
- Fix pod error in IO::Socket::SSL::Utils RT#85733
v1.91 2013.05.30
- added IO::Socket::SSL::Utils for easier manipulation of certificates and keys
- moved SSL interception into IO::Socket::SSL::Intercept and simplified it
using IO::Socket::SSL::Utils
- enhance meta information in Makefile.PL
v1.90 2013.05.27
- RT#85290, support more digest, especially SHA-2.
Thanks to ujvari[AT]microsec[DOT]hu
- added support for easy SSL interception (man in the middle) based
on ideas found in mojo-mitm proxy (which was written by Karel Miko)
- make 1.46 the minimal required version for Net::SSLeay, because it
introduced lots of useful functions.
v1.89 2013.05.14
- if IO::Socket::IP is used it should be at least version 0.20, otherwise
See https://github.com/noxxi/p5-io-socket-ssl/issues/1, thanks to
mytram
v1.83 2013.02.03
- Server Name Indication (SNI) support on the server side, inspired by
patch provided by karel[DOT]miko[AT]gmail[DOT]com.
https://rt.cpan.org/Ticket/Display.html?id=82761
- reworked part of the documentation, like providing better examples.
v1.82 2013.01.28
- sub error sets $SSL_ERROR etc only if there really is an error,
otherwise it will keep the latest error. This causes
IO::Socket::SSL->new.. to report the correct problem, even if
the problem is deeper in the code (like in connect)
- correct spelling, rt#8270. Thanks to ETHER
v1.81 2012.12.06
- deprecated set_ctx_defaults, new name ist set_defaults (but old name
still available)
- changed handling of default path for SSL_(ca|cert|key)* keys: either
if one of these keys is user defined don't add defaults for the
others, e.g. don't mix user settings and defaults
- cleaner handling of module defaults vs. global settings vs. socket
specific settings. Global and socket specific settings are both
- fix t/nonblock.t on systems which have by default a larger
socket buffer. Set SO_SNDBUF explicitly with setsockopt
to force smaller writes on the socket
v1.06
- instead of setting undef args to '' in configure_SSL drop
them. This makes Net::SMTP::SSL working again because it
does not give LocalPort of '' to IO::Socket::INET any more
v1.05
- make session cache working even if the IO::Socket::SSL object
was not created with IO::Socket::SSL->new but with
IO::Socket::SSL->start_SSL on an established socket
v1.04
- added way to create SSL object with predefined session
cache, thus making it possible to share the cache between
objects even if the rest of the context is not shared
key SSL_session_cache
Note that the arguments of IO::Socket::SSL::SessionCache::new
changed (but you should never have used this class directly
because it's internal to IO::Socket::SSL)
v1.03
- add CLONE_SKIP as proposed by
Jarrod Johnson jbjohnso at us dot ibm dot com
v1.02
- added some info to BUGS and to BUGS section of pod
- added TELL and BINMODE to IO::Socket::SSL::SSL_HANDLE, even
if they do nothing useful.
- all tests allocate now the ports dynamically, so there should
be no longer a conflict with open ports on the system where
the tests run
v1.01
- work around Bug in Net::HTTPS where it defines sub blocking
as {}, e.g. force scalar context when calling sub blocking
(in IO::Socket::SSL::write)
see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=383106
v1.0
- fix deprecated and practically undocumented function
get_peer_certificate so that LWP Net::HTTPS works again
- set arg 'Blocking' while calling SUPER::configure only
if it was set by the caller to work around Problem in LWP
Net::HTTPS
v0.999
before. The old value included ADH and this might be
a bad idea, see BUGS why.
v0.998
- declare socket as opened before calling fatal_ssl_error
because the SSL_error_trap set up from HTTP::Daemon
needs this
- accept_SSL sets errors on $socket (the accepted socket)
not $self (the listening socket if called from accept)
so it can be queried from SSL_error_trap
- note in BUGS section that IO::Socket::SSL is not thread-safe
v0.997
- fix readline (e.g. getline,getlines,<>) so that it behaves
regarding $/ like written in the $/ documentation.
v0.996
- removed links and comments to unofficial release of
Net::SSLeay, because there is a newer version already
v0.995
write $! will be set to EAGAIN and $SSL_ERROR will be set
to SSL_WANT_READ or SSL_WANT_WRITE
. syswrite returns undef and sets $!,$SSL_ERROR if it fails
to write instead of returning 0.
- Bugfixes (http://rt.cpan.org/Public/Bug/Display.html?id=Bugid)
. Bug 18439: fileno 0 should be valid
. Bug 15001: sysread interprets buffer "0" as ""
- peer_certificate returns X509 struct string if no field
for extraction was specified
- get_peer_certificate returns the certificate instead of the
IO::Socket::SSL object
v0.97
- Writes now correctly return errors. (Problem noted by
Dominique Quatravaux <dom at idealx.com>).
- CA paths now work without passing an empty SSL_ca_file
argument. (Problem found by Phil Pennock, <phil.pennock
at globnix.org>).
- IO::Socket::SSL now automatically passes Proto => tcp (if
not already specified) to IO::Socket::INET to work around
/etc/services files with udp entries listed first. (Fix
suggested by Phil Pennock).
- $socket->accept() now returns the peer address in array
context for better conformance with IO::Socket::INET.
However, if you were doing "map { $_->accept } (@sockets)",
or similar tricks, you will need to use "scalar" to get the
old behavior back. (Problem noted by Nils Sowen, <n.sowen
at kon.de>).
- IO::Socket::SSL should now properly block on reads larger
than the buffer size of Net::SSLeay. (Problem found by Eric
Jergensen, <eric at dvns.com>).
- IO::Socket::SSL should now send CA Certs (if necessary)
along with certificates. (Problem found by <roy at
momentous.ca>).
- Timeouts should now work, but be aware that if multiple
reads/writes are necessary to complete a connection, then
each one may have a separate timeout. (Request from
Dominique Quatravaux <dom at idealx.com>).
- In certain cases, start_SSL() would misplace a socket's
fileno, causing problems with starting SSL. This should now
be fixed. (Problem found by <russ at zerotech.net>).
- IO::Socket::SSL now requires a minimum of Net::SSLeay 1.21.
--- Old Versions --------------------------------------------------
v0.96 2004.4.30
- Makefile's error messages now correct if output is
redirected (patch from Ilya Zakharevich <ilya at
math.berkeley.edu>).
- Non-blocking connects/accepts now work (Problem found by
Uri Guttman <uri at stemsystems.com>).
- new_from_fd() now works.
- Tests should proceed much more quickly, and a semi-race was
fixed, meaning that on slow machines the tests should be
more reliable.
- Check for Scalar::Util and Weakref now uses default
$SIG{__DIE__} instead of a potentially user-altered one
(suggestion from Olaf Schneider <Olaf.Schneider at
iwr.fzk.de>). This only applies to Perl 5.6.0 & above.
- Session caching support (patch from Marko Asplund
<marko.asplund at kronodoc.fi>).
- set_default_context() added to alter the behavior of
modules that use IO::Socket::SSL from the main program.
- get_ssl_object() renamed to _get_ssl_object() to reflect
the fact that it's only supposed to be used internally
(not that you should have cared, of course).
- Added patch for Net::SSLeay to take advantage of
client-side session caching.
v0.95 2003.8.25
- Changed PeerAddr in example/ssl_client.pl back to localhost.
- Update of examples to automatically switch to the proper
directory if they cannot find the necessary SSL certificates.
- Minor documentation update with more INET6 info.
- Corrected some error messages for IO::Socket::INET6.
- Better opened() behavior when sockets close unexpectedly.
- Added note about random number generators for Solaris users
(Problem found by Christian Gilmore <cag at us.ibm.com>).
- Added support for WeakRef and Scalar::Util to allow
IO::Socket::SSL objects to auto-destroy themselves when
they go out of scope.
- Added croak()ing for unimplemented send() and recv() methods
so they are not accidentally used to transmit unencrypted
data. The Perl builtin functions cannot be reliably trapped
and are still dangerous, a fact that the POD now reflects
(Problem noted by Michal Ludvig <michal at logix.cx>).
v0.94 2003.6.26
- Changed accept() to use inherited accept() instead of
IO::Socket::accept, so that IPv6 inheritance is possible.
(SSL_verify_callback option in new(), suggestion from
Dariush Pietrzak <eyck at ghost.anime.pl>).
- accept()/connect()/socket_to_SSL() now fail immediately if
the socket in question does not have a fileno.
- Added the kill_socket() method to guarantee that a socket dies.
- Fixed extra warning when printing errors in debug mode.
- Deprecated socket_to_SSL() in favor of the class method
start_SSL() (Class method suggestion from Graham Barr
<gbarr at pobox.com>).
- Added the class method start_SSL() to allow for cases when
the desired class of the socket is not IO::Socket::SSL
(Request from Dariush Pietrzak <eyck at ghost.anime.pl>)
- Changed socket_to_SSL to rebless socket to original class
if SSL negotiation failed (Request from Graham Barr
<gbarr at pobox.com>)
- Removed the daemon.pl example, as it did not work with the
standard distribution of HTTP::Daemon (use HTTP::Daemon::SSL
instead).
v0.92 2002.10.22
- Changed the fileno() function to support returning the fileno
- Added support for SSL_peek and SSL_pending (peek() and
pending()). Updated documentation, tests, etc. to reflect
this.
v0.901 2002.08.19
- Fixed the warning that happens when sockets are not explicitly
closed() before the program terminates.
v0.90 2002.08.13
- This version is a complete rewrite of IO::Socket::SSL. It now
has about half the lines of code, twice the amount of documentation,
and a slightly more polished interface.
- IO::Socket::SSL now works properly with mod_perl and taint mode.
- Major documentation update.
- Update of the BUGS file to reflect changes made in the rewrite.
- Update of the test suite for Perl v5.8.0 (or, more precisely,
for Scalar::Util).
- Update of the test suite for Perl v5.00503 (or, more precisely,
for the lack of several nice features added in v5.6.0) (Marko
Asplund <aspa at kronodoc.fi>).
- New test suite that does not need the Internet to function.
- Update of all the files in example/ to use more current features
of IO::Socket::SSL.
- Removal of SSL_SSL and X509_Certificate classes.
- There have been a few name changes (like socketToSSL ->
socket_to_SSL) for better consistency.
- The functionality of get_peer_certificate() and friends is deprecated.
- The functionality of want_write() and want_read() is deprecated.
- The functionality of context_init() is deprecated for normal use.
- Support for all SSL context options in the new() call.
- SSL contexts are no longer global. The SSL_reuse_ctx option
is provided for those who want to re-use a context.
- The default verify mode is now VERIFY_NONE.
- IO::Socket::SSL::DEBUG is now linked to Net::SSLeay::trace to
provide different levels of debugging information.
- There is a uniform interface for error reporting, so on error
all functions will return undef and the error will be available
by calling errstr().
- The dump_peer_certificate() and peer_certificate() functions
have been added.
- sysread() will now behave correctly if the offset argument is
greater than the length of the read buffer. It also will truncate
the read buffer properly, according to the Perl documentation for
sysread().
class to prevent problems resulting from self-tying filehandles.
Harmon S. Nine <hnine at netarx.com>.
- docs/debugging.txt file added
- require Net::SSLeay v1.08
- preliminary support for non-blocking read/write
- socketToSSL() now respects context's SSL verify setting
reported by Uri Guttman <uri at stemsystems.com>.
v0.80 2001.08.19
- fixed startTLS support (socketToSSL) (Graham Barr <gbarr at pobox.com>)
- make accept() set fileno attribute on newly created IO::Socket::SSL
object (Martin Oldfield <m at mail.tc>).
- certificate updates.
- use SSL_CTX_use_PrivateKey_file in SSL_Context::new.
v0.79 2001.06.04
- angle bracket readline operator support
(David Darville <david at dark.x.dtu.dk>).
- eliminate warnings in choosing SSL protocol version.
- implement our own opened method and make length parameter optional
in syswrite (Robert Bihlmeyer <robbe at orcus.priv.at>).
- include the Apache CA bundle file in the distribution (my-ca.pem).
- BUGS file added.
v0.77 2001.01.15
- don't setup SSL CA verification unless cert verification is
actually used for the connections.
- default SSL protocol version selection in SSL.pm.
v0.76 2000.11.17
- patch from Kwok Chern Yue <chernyue at post1.com> for
making IO::Socket::SSL work with HTTP::Daemon.
v0.75 2000.07.26
- IO::Socket::SSL should now work with perl v5.6.0
- demo/*.pl and t/*.t now turn module debugging on if
DEBUG command line argument is given
- default certificates changed
v0.74 2000.07.05
- Changes file added
- bugfix in IO::Socket::SSL::sysread() (zliu2 at acsu.buffalo.edu)
- libwww-perl and IO::Socket::SSL UML models added in docs
- URL changes in test scripts
- preliminary support for startTLS in IO::Socket::SSL::socketToSSL()
- miscellaneous patches for Net::SSLeay added in diffs
Makefile.PL view on Meta::CPAN
my $xt = $ENV{NO_NETWORK_TESTING} && 'n';
$xt ||= $yesno->( "Should I do external tests?\n".
"These test will detect if there are network problems and fail soft,\n".
"so please disable them only if you definitely don't want to have any\n".
"network traffic to external sites. [Y/n]", 'y' );
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
'NAME' => 'IO::Socket::SSL',
'ABSTRACT' => 'Nearly transparent SSL encapsulation for IO::Socket::INET.',
'AUTHOR' => 'Steffen Ullrich <sullr@cpan.org>, Peter Behroozi, Marko Asplund',
'LICENSE' => 'perl',
'DISTNAME' => 'IO-Socket-SSL',
'VERSION_FROM' => 'lib/IO/Socket/SSL.pm',
'PREREQ_PM' => {
'Net::SSLeay' => 1.46,
'Scalar::Util' => 0,
! %usable_ca ? ( 'Mozilla::CA' => 0 ):(),
},
IO::Socket::SSL is a class implementing an object oriented
interface to SSL sockets. The class is a descendent of
IO::Socket::INET.
In order to use IO::Socket::SSL you need to have Net::SSLeay
v1.46 or newer installed.
To use ECDH curves (needed for perfect forward secrecy) you need
to use Net::SSLeay >= 1.56.
To use OCSP to check for certificate revocations you need
OpenSSL 1.0.0 or better and Net::SSLeay>=1.59.
For those who do not have a built-in random number generator
(including most users of Solaris), you should install one
before attempting to install IO::Socket::SSL. If you don't
already have a favorite, try "egd" (egd.sourceforge.net) or
one of the other "Related Projects" listed on its home page.
If you want to bypass the test for existence of the RNG, then
set the "SKIP_RNG_TEST" environment variable to a true value.
In addition to providing a general OO interface to SSL sockets,
this package can be used with libwww-perl.
installation:
perl Makefile.PL
docs/debugging.txt view on Meta::CPAN
- check that IO::Socket::SSL and Net::SSLeay are properly installed,
and that the versions are recently new:
perl -MIO::Socket::SSL -e 'print "$IO::Socket::SSL::VERSION\n"'
perl -MNet::SSLeay -e 'print "$Net::SSLeay::VERSION\n"'
- run the tests in IO::Socket::SSL directory
try running the tests with 'make test'. if some of the tests fail run
the scripts one by one e.g.:
perl -Ilib t/core.t
- try running the demos using the DEBUG option
- use the OpenSSL client and server for debugging the demo client and server.
'openssl s_client' and 'openssl s_server' against tests/demos
testing the demo server:
openssl s_client -connect localhost:9000 \
example/async_https_server.pl view on Meta::CPAN
##########################################################
# example HTTPS server using nonblocking sockets
# requires Event::Lib
# at the moment the response consists only of the HTTP
# request, send back as text/plain
##########################################################
use strict;
use IO::Socket;
use IO::Socket::SSL;
use Event::Lib;
use Errno ':POSIX';
#$Net::SSLeay::trace=3;
eval 'use Debug';
*{DEBUG} = sub {} if !defined(&DEBUG);
# create server socket
my $server = IO::Socket::INET->new(
example/async_https_server.pl view on Meta::CPAN
event_mainloop;
##########################################################
### accept new client on server socket
##########################################################
sub _s_accept {
my $fds = shift->fh;
my $fdc = $fds->accept || return;
DEBUG( "new client" );
$fdc = IO::Socket::SSL->start_SSL( $fdc,
SSL_startHandshake => 0,
SSL_server => 1,
) || die $!;
$fdc->blocking(0);
_ssl_accept( undef,$fdc );
}
##########################################################
### ssl handshake with client
example/lwp-with-verifycn.pl view on Meta::CPAN
use strict;
use warnings;
## !!! make sure that Net::SSL never gets loaded, otherwise it will
## be used instead of IO::Socket::SSL from LWP
use IO::Socket::SSL 'debug0';
use LWP::Simple;
IO::Socket::SSL::set_ctx_defaults(
SSL_verifycn_scheme => 'www',
SSL_verify_mode => 1,
SSL_ca_file => 'verisign.pem', # root CA of verisign
);
print get( 'https://signin.ebay.com' );
example/simulate_proxy.pl view on Meta::CPAN
use strict;
use warnings;
use IO::Socket::SSL;
use IO::Socket::SSL::Utils;
use IO::Select;
use Socket 'MSG_PEEK';
use Getopt::Long qw(:config posix_default bundling);
my $DEBUG;
{
my $addr = '0.0.0.0:8080';
my $ciphers;
my $version;
example/simulate_proxy.pl view on Meta::CPAN
debug("got TLSv1.2 handshake - cut!");
goto ACCEPT;
} elsif ( $args{deny_tls11} && $buf =~m{^.{9}\x03\x02}s ) {
debug("got TLSv1.1 handshake - cut!");
goto ACCEPT;
}
}
my ($cert,$key) = $get_cert->($ssl_host);
debug("upgrade to SSL with certificate for $ssl_host");
IO::Socket::SSL->start_SSL( $cl,
SSL_server => 1,
SSL_cert => $cert,
SSL_key => $key,
%sslargs,
) or do {
debug("SSL handshake failed: $SSL_ERROR");
goto ACCEPT;
};
$got_ciphers = $cl->get_cipher;
}
example/simulate_proxy.pl view on Meta::CPAN
return;
}
$$rbuf .= $lbuf;
}
return 1;
}
# ----------------------------------------------------------------------------
# this was used to create CA cert
# ----------------------------------------------------------------------------
#| use IO::Socket::SSL::Utils;
#| my ($cacert,$key) = CERT_create( CA => 1,
#| subject => { organizationName => 'genua mbh', commonName => 'Test CA' }
#| );
#| print PEM_cert2string($cacert).PEM_key2string($key);
__DATA__
-----BEGIN CERTIFICATE-----
MIICVjCCAb+gAwIBAgIFAIbQ7t4wDQYJKoZIhvcNAQEFBQAwJjEQMA4GA1UEAxMH
VGVzdCBDQTESMBAGA1UEChMJZ2VudWEgbWJoMB4XDTEzMTAyMzA4MjI0MFoXDTE0
MTAyMzA4MjI0MFowJjEQMA4GA1UEAxMHVGVzdCBDQTESMBAGA1UEChMJZ2VudWEg
example/ssl_client.pl view on Meta::CPAN
#
# a test client for testing IO::Socket::SSL-class's behavior
use strict;
use warnings;
use IO::Socket::SSL;
use Getopt::Long qw(:config posix_default bundling);
use Digest::MD5 'md5_hex';
my ($cert_file,$key_file,$key_pass,$ca,$name,$no_verify);
GetOptions(
'd|debug:i' => \$IO::Socket::SSL::DEBUG,
'h|help' => sub { usage() },
'C|cert=s' => \$cert_file,
'K|key=s' => \$key_file,
'P|pass=s' => \$key_pass,
'ca=s' => \$ca,
'name=s' => \$name,
'no-verify' => \$no_verify,
) or usage("bad option");
sub usage {
example/ssl_client.pl view on Meta::CPAN
--name hostname use hostname for SNI and certificate check
--no-verify don't verify certificate
USAGE
exit(2);
}
my $addr = shift(@ARGV) or usage("no target address given");
@ARGV and usage("too much arguments");
$key_file ||= $cert_file;
my $cl = IO::Socket::SSL->new(
PeerAddr => $addr,
$ca ? ( -d $ca ? ( SSL_ca_path => $ca ):( SSL_ca_file => $ca ) ):(),
$name ? ( SSL_hostname => $name ):(),
$no_verify ? ( SSL_verify_mode => 0 ):(),
$cert_file ? (
SSL_cert_file => $cert_file,
SSL_key_file => $key_file,
defined($key_pass) ? ( SSL_passwd_cb => sub { $key_pass } ):(),
):(),
SSL_startHandshake => 0,
example/ssl_mitm.pl view on Meta::CPAN
#!/usr/bin/perl
# simple HTTPS proxy with SSL bridging, uses Net::PcapWriter to
# to log unencrypted traffic
my $listen = '127.0.0.1:8443'; # where to listen
my $connect = 'www.google.com:443'; # where to connect
use strict;
use warnings;
use IO::Socket::SSL;
use IO::Socket::SSL::Intercept;
use IO::Socket::SSL::Utils;
my ($proxy_cert,$proxy_key) = CERT_create(
CA => 1,
subject => { commonName => 'foobar' }
);
my $mitm = IO::Socket::SSL::Intercept->new(
proxy_cert => $proxy_cert,
proxy_key => $proxy_key,
);
my $listener = IO::Socket::INET->new(
LocalAddr => $listen,
Listen => 10,
Reuse => 1,
) or die "failed to create listener: $!";
while (1) {
# get connection from client
my $toc = $listener->accept or next;
# create new connection to server
my $tos = IO::Socket::SSL->new(
PeerAddr => $connect,
SSL_verify_mode => 1,
SSL_ca_path => '/etc/ssl/certs',
) or die "ssl connect to $connect failed: $!,$SSL_ERROR";
# clone cert from server
my ($cert,$key) = $mitm->clone_cert( $tos->peer_certificate );
# and upgrade connection to client to SSL with cloned cert
IO::Socket::SSL->start_SSL($toc,
SSL_server => 1,
SSL_cert => $cert,
SSL_key => $key,
) or die "failed to ssl upgrade: $SSL_ERROR";
# transfer data
my $readmask = '';
vec($readmask,fileno($tos),1) = 1;
vec($readmask,fileno($toc),1) = 1;
while (1) {
example/ssl_server.pl view on Meta::CPAN
#
# a test server for testing IO::Socket::SSL-class's behavior
use strict;
use warnings;
use IO::Socket::SSL;
use Getopt::Long qw(:config posix_default bundling);
use Digest::MD5 'md5_hex';
my ($cert_file,$key_file,$key_pass,$ca,$http);
GetOptions(
'd|debug:i' => \$IO::Socket::SSL::DEBUG,
'h|help' => sub { usage() },
'C|cert=s' => \$cert_file,
'K|key=s' => \$key_file,
'P|pass=s' => \$key_pass,
'ca=s' => \$ca,
'http' => \$http,
) or usage("bad option");
sub usage {
print STDERR "Error: @_\n" if @_;
example/ssl_server.pl view on Meta::CPAN
@ARGV and usage("too much arguments");
$cert_file or usage("no certificate given");
$key_file ||= $cert_file;
my $server = IO::Socket::IP->new(
Listen => 5,
LocalAddr => $addr,
ReuseAddr => 1,
) or die "failed to create SSL server at $addr: $!";
my $ctx = IO::Socket::SSL::SSL_Context->new(
SSL_server => 1,
SSL_cert_file => $cert_file,
SSL_key_file => $key_file,
defined($key_pass) ? ( SSL_passwd_cb => sub { $key_pass } ):(),
$ca ? (
SSL_verify_mode => SSL_VERIFY_PEER,
-d $ca ? ( SSL_ca_path => $ca ):( SSL_ca_file => $ca, SSL_client_ca_file => $ca )
):(),
) or die "cannot create context: $SSL_ERROR";
while (1) {
warn "waiting for next connection.\n";
my $cl = $server->accept or do {
warn "failed to accept: $!\n";
next;
};
IO::Socket::SSL->start_SSL($cl,
SSL_server => 1,
SSL_reuse_ctx => $ctx,
SSL_startHandshake => 0
) or do {
warn "ssl handshake failed: $SSL_ERROR\n";
next;
};
my $ja3;
$cl->set_msg_callback(\&msgcb, \$ja3);
lib/IO/Socket/SSL.pm view on Meta::CPAN
#vim: set sts=4 sw=4 ts=8 ai:
#
# IO::Socket::SSL:
# provide an interface to SSL connections similar to IO::Socket modules
#
# Current Code Shepherd: Steffen Ullrich <sullr at cpan.org>
# Code Shepherd before: Peter Behroozi, <behrooz at fas.harvard.edu>
#
# The original version of this module was written by
# Marko Asplund, <marko.asplund at kronodoc.fi>, who drew from
# Crypt::SSLeay (Net::SSL) by Gisle Aas.
#
package IO::Socket::SSL;
our $VERSION = '2.094';
use IO::Socket;
use Net::SSLeay 1.46;
use IO::Socket::SSL::PublicSuffix;
use Exporter ();
use Errno qw( EWOULDBLOCK EAGAIN ETIMEDOUT EINTR EPIPE EPERM );
use Carp;
use strict;
my $use_threads;
BEGIN {
die "no support for weaken - please install Scalar::Util" if ! do {
local $SIG{__DIE__};
eval { require Scalar::Util; Scalar::Util->import("weaken"); 1 }
lib/IO/Socket/SSL.pm view on Meta::CPAN
*DEBUG = \$Net::SSLeay::trace;
#Compatibility
*ERROR = \$SSL_ERROR;
}
sub DEBUG {
$DEBUG or return;
my (undef,$file,$line,$sub) = caller(1);
if ($sub =~m{^IO::Socket::SSL::(?:error|(_internal_error))$}) {
(undef,$file,$line) = caller(2) if $1;
} else {
(undef,$file,$line) = caller;
}
my $msg = shift;
$file = '...'.substr( $file,-17 ) if length($file)>20;
$msg = sprintf $msg,@_ if @_;
print STDERR "DEBUG: $file:$line: $msg\n";
}
lib/IO/Socket/SSL.pm view on Meta::CPAN
my %const = (
NID_CommonName => 13,
GEN_DNS => 2,
GEN_IPADD => 7,
);
while ( my ($name,$value) = each %const ) {
no strict 'refs';
*{$name} = UNIVERSAL::can( 'Net::SSLeay', $name ) || sub { $value };
}
*idn_to_ascii = \&IO::Socket::SSL::PublicSuffix::idn_to_ascii;
*idn_to_unicode = \&IO::Socket::SSL::PublicSuffix::idn_to_unicode;
}
my $OPENSSL_LIST_SEPARATOR = $^O =~m{^(?:(dos|os2|mswin32|netware)|vms)$}i
? $1 ? ';' : ',' : ':';
my $CHECK_SSL_PATH = sub {
my %args = (@_ == 1) ? ('',@_) : @_;
for my $type (keys %args) {
my $path = $args{$type};
if (!$type) {
delete $args{$type};
lib/IO/Socket/SSL.pm view on Meta::CPAN
# not how IO::Socket::INET works. All configuration gets performed in
# the calls to configure() and either connect() or accept().
#Call to configure occurs when a new socket is made using
#IO::Socket::INET. Returns false (empty list) on failure.
sub configure {
my ($self, $arg_hash) = @_;
return _invalid_object() unless($self);
# force initial blocking
# otherwise IO::Socket::SSL->new might return undef if the
# socket is nonblocking and it fails to connect immediately
# for real nonblocking behavior one should create a nonblocking
# socket and later call connect explicitly
my $blocking = delete $arg_hash->{Blocking};
# because Net::HTTPS simple redefines blocking() to {} (e.g.
# return undef) and IO::Socket::INET does not like this we
# set Blocking only explicitly if it was set
$arg_hash->{Blocking} = 1 if defined ($blocking);
lib/IO/Socket/SSL.pm view on Meta::CPAN
}
# add user defined defaults, maybe after filtering
$FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS;
_cleanup_ssl($self); # in case there was something left
${*$self}{_SSL_opened} = $is_server;
${*$self}{_SSL_arguments} = $arg_hash;
# this adds defaults to $arg_hash as a side effect!
${*$self}{'_SSL_ctx'} = IO::Socket::SSL::SSL_Context->new($arg_hash)
or return;
return $self;
}
sub _skip_rw_error {
my ($self,$ssl,$rv) = @_;
my $err = Net::SSLeay::get_error($ssl,$rv);
if ( $err == $Net_SSLeay_ERROR_WANT_READ) {
lib/IO/Socket/SSL.pm view on Meta::CPAN
}
if (!%sess_cb and $ctx->{session_cache}
and my $session = Net::SSLeay::get1_session($ssl)) {
$ctx->{session_cache}->add_session(
${*$self}{_SSL_arguments}{SSL_session_key},
$session
);
}
tie *{$self}, "IO::Socket::SSL::SSL_HANDLE", $self;
return $self;
}
# called if PeerAddr is not set in ${*$self}{'_SSL_arguments'}
# this can be the case if start_SSL is called with a normal IO::Socket::INET
# so that PeerAddr|PeerPort are not set from args
# returns PeerAddr
sub _update_peer {
my $self = shift;
lib/IO/Socket/SSL.pm view on Meta::CPAN
$arg_hash->{PeerAddr} = $host;
} else {
my ($port,$addr) = sockaddr_in( $sockaddr);
$arg_hash->{PeerPort} = $port;
$arg_hash->{PeerAddr} = inet_ntoa( $addr );
}
}
}
#Call to accept occurs when a new client connects to a server using
#IO::Socket::SSL
sub accept {
my $self = shift || return _invalid_object();
my $class = shift || 'IO::Socket::SSL';
my $socket = ${*$self}{'_SSL_opening'};
if ( ! $socket ) {
# underlying socket not done
$DEBUG>=2 && DEBUG('no socket yet' );
$socket = $self->SUPER::accept($class) || return;
$DEBUG>=2 && DEBUG('accept created normal socket '.$socket );
# don't continue with accept_SSL if SSL_startHandshake is set to 0
my $sh = ${*$self}{_SSL_arguments}{SSL_startHandshake};
lib/IO/Socket/SSL.pm view on Meta::CPAN
$DEBUG>=2 && DEBUG('handshake done, socket ready' );
# socket opened
delete ${*$self}{'_SSL_opening'};
${*$socket}{'_SSL_opened'} = 1;
if (defined($timeout)) {
$socket->blocking(1); # reset back to blocking
$! = undef; # reset errors from non-blocking
}
tie *{$socket}, "IO::Socket::SSL::SSL_HANDLE", $socket;
return $socket;
}
# support user defined message callback but also internal debugging
sub _msg_callback {
## my ($direction, $ssl_ver, $content_type, $buf, $len, $ssl, $userp) = @_;
IO::Socket::SSL::Trace::ossl_trace(@_) if $DEBUG>=2;
my $self = ($SSL_OBJECT{$_[5]} || return)->[0] || return;
if (my $cb = ${*$self}{_SSL_msg_callback}) {
my ($sub,@arg) = @$cb;
$sub->($self, @_[0..5], @arg);
}
}
my $ssleay_set_msg_callback = defined &Net::SSLeay::set_msg_callback
&& \&Net::SSLeay::set_msg_callback;
lib/IO/Socket/SSL.pm view on Meta::CPAN
sub fileno {
my $self = shift;
my $fn = ${*$self}{'_SSL_fileno'};
return defined($fn) ? $fn : $self->SUPER::fileno();
}
####### IO::Socket::SSL specific functions #######
# get access to SSL handle for use with Net::SSLeay. Use with caution!
sub _get_ssl_object {
my $self = shift;
return ${*$self}{'_SSL_object'} ||
IO::Socket::SSL->_internal_error("Undefined SSL object",9);
}
# get access to SSL handle for use with Net::SSLeay. Use with caution!
sub _get_ctx_object {
my $self = shift;
my $ctx_object = ${*$self}{_SSL_ctx};
return $ctx_object && $ctx_object->{context};
}
# default error for undefined arguments
sub _invalid_object {
return IO::Socket::SSL->_internal_error("Undefined IO::Socket::SSL object",9);
}
sub pending {
my $ssl = shift()->_get_ssl_object || return;
return Net::SSLeay::pending($ssl);
}
sub start_SSL {
my ($class,$socket) = (shift,shift);
lib/IO/Socket/SSL.pm view on Meta::CPAN
if ( $wtyp eq 'anywhere' and $name =~m{^([a-zA-Z0-9_\-]*)\*(.+)} ) {
return if $1 ne '' and substr($identity,0,4) eq 'xn--'; # IDNA
$pattern = qr{^\Q$1\E[a-zA-Z0-9_\-]+\Q$2\E$}i;
} elsif ( $wtyp =~ m{^(?:full_label|leftmost)$}
and $name =~m{^\*(\..+)$} ) {
$pattern = qr{^[a-zA-Z0-9_\-]+\Q$1\E$}i;
} else {
return lc($identity) eq lc($name);
}
if ( $identity =~ $pattern ) {
$publicsuffix = IO::Socket::SSL::PublicSuffix->default
if ! defined $publicsuffix;
return 1 if $publicsuffix eq '';
my @labels = split( m{\.+}, $identity );
my $tld = $publicsuffix->public_suffix(\@labels,+1);
return 1 if @labels > ( $tld ? 0+@$tld : 1 );
}
return;
};
lib/IO/Socket/SSL.pm view on Meta::CPAN
return Net::SSLeay::session_reused(
shift()->_get_ssl_object || return);
}
if ($can_ocsp) {
no warnings 'once';
*ocsp_resolver = sub {
my $self = shift;
my $ssl = $self->_get_ssl_object || return;
my $ctx = ${*$self}{_SSL_ctx};
return IO::Socket::SSL::OCSP_Resolver->new(
$ssl,
$ctx->{ocsp_cache} ||= IO::Socket::SSL::OCSP_Cache->new,
$ctx->{ocsp_mode} & SSL_OCSP_FAIL_HARD,
@_ ? \@_ :
$ctx->{ocsp_mode} & SSL_OCSP_FULL_CHAIN ? [ $self->peer_certificates ]:
[ $self->peer_certificate ]
);
};
}
sub errstr {
my $self = shift;
lib/IO/Socket/SSL.pm view on Meta::CPAN
delete $SSL_OBJECT{$ssl};
if (!$use_threads or delete $CREATED_IN_THIS_THREAD{$ssl}) {
$self->close(_SSL_in_DESTROY => 1, SSL_no_shutdown => 1);
}
}
delete @{*$self}{keys %all_my_keys};
}
#######Extra Backwards Compatibility Functionality#######
sub socket_to_SSL { IO::Socket::SSL->start_SSL(@_); }
sub socketToSSL { IO::Socket::SSL->start_SSL(@_); }
sub kill_socket { shift->close }
sub issuer_name { return(shift()->peer_certificate("issuer")) }
sub subject_name { return(shift()->peer_certificate("subject")) }
sub get_peer_certificate { return shift() }
sub context_init {
return($GLOBAL_SSL_ARGS = (ref($_[0]) eq 'HASH') ? $_[0] : {@_});
}
lib/IO/Socket/SSL.pm view on Meta::CPAN
}
#Useless IO::Handle functionality
sub truncate { croak("Use of truncate() not allowed with SSL") }
sub stat { croak("Use of stat() not allowed with SSL" ) }
sub setbuf { croak("Use of setbuf() not allowed with SSL" ) }
sub setvbuf { croak("Use of setvbuf() not allowed with SSL" ) }
sub fdopen { croak("Use of fdopen() not allowed with SSL" ) }
#Unsupported socket functionality
sub ungetc { croak("Use of ungetc() not implemented in IO::Socket::SSL") }
sub send { croak("Use of send() not implemented in IO::Socket::SSL; use print/printf/syswrite instead") }
sub recv { croak("Use of recv() not implemented in IO::Socket::SSL; use read/sysread instead") }
package IO::Socket::SSL::SSL_HANDLE;
use strict;
use Errno 'EBADF';
*weaken = *IO::Socket::SSL::weaken;
sub TIEHANDLE {
my ($class, $handle) = @_;
weaken($handle);
bless \$handle, $class;
}
sub READ { ${shift()}->sysread(@_) }
sub READLINE { ${shift()}->readline(@_) }
sub GETC { ${shift()}->getc(@_) }
lib/IO/Socket/SSL.pm view on Meta::CPAN
sub TELL { $! = EBADF; return -1 }
sub BINMODE { return 0 } # not perfect, but better than not implementing the method
sub CLOSE { #<---- Do not change this function!
my $ssl = ${$_[0]};
local @_;
$ssl->close();
}
package IO::Socket::SSL::SSL_Context;
use Carp;
use strict;
my %CTX_CREATED_IN_THIS_THREAD;
*DEBUG = *IO::Socket::SSL::DEBUG;
*_errstack = \&IO::Socket::SSL::_errstack;
use constant SSL_MODE_ENABLE_PARTIAL_WRITE => 1;
use constant SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER => 2;
use constant FILETYPE_PEM => Net::SSLeay::FILETYPE_PEM();
use constant FILETYPE_ASN1 => Net::SSLeay::FILETYPE_ASN1();
my $DEFAULT_SSL_OP = &Net::SSLeay::OP_ALL
| &Net::SSLeay::OP_SINGLE_DH_USE
| ($can_ecdh ? &Net::SSLeay::OP_SINGLE_ECDH_USE : 0);
lib/IO/Socket/SSL.pm view on Meta::CPAN
? (%DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_SERVER_ARGS)
: (%DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_ARGS, %$GLOBAL_SSL_CLIENT_ARGS);
if ( $defaults{SSL_reuse_ctx} ) {
# ignore default context if there are args to override it
delete $defaults{SSL_reuse_ctx}
if grep { m{^SSL_(?!verifycn_name|hostname)$} } keys %$arg_hash;
}
%$arg_hash = ( %defaults, %$arg_hash ) if %defaults;
if (my $ctx = $arg_hash->{'SSL_reuse_ctx'}) {
if ($ctx->isa('IO::Socket::SSL::SSL_Context')) {
return $ctx if $ctx->{context};
} elsif (eval { $ctx = ${*$ctx}{_SSL_ctx} }) {
# reuse context from existing SSL object
return $ctx;
}
die "invalid context to reuse: $ctx";
}
# common problem forgetting to set SSL_use_cert
# if client cert is given by user but SSL_use_cert is undef, assume that it
lib/IO/Socket/SSL.pm view on Meta::CPAN
$arg_hash->{SSL_verify_callback} = sub {
my ($ok,$ctx_store,$certname,$error,$cert,$depth) = @_;
$ok = $vcb->($ok,$ctx_store,$certname,$error,$cert,$depth) if $vcb;
$ok or return 0;
return $ok if $depth != 0;
my $host = $verify_name || ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown';
if ( ! $host ) {
if ( $vcn_scheme ) {
IO::Socket::SSL->_internal_error(
"Cannot determine peer hostname for verification",8);
return 0;
}
warn "Cannot determine hostname of peer for verification. ".
"Disabling default hostname verification for now. ".
"Please specify hostname with SSL_verifycn_name and better set SSL_verifycn_scheme too.\n";
return $ok;
}
# verify name
my $rv = IO::Socket::SSL::verify_hostname_of_cert(
$host,$cert,$vcn_scheme,$vcn_publicsuffix );
if ( ! $rv ) {
IO::Socket::SSL->_internal_error(
"hostname verification failed",5);
}
return $rv;
};
}
if ($is_server) {
if ($arg_hash->{SSL_ticket_keycb} && !$can_tckt_keycb) {
warn "Ticket Key Callback is not supported - ignoring option SSL_ticket_keycb\n";
delete $arg_hash->{SSL_ticket_keycb};
lib/IO/Socket/SSL.pm view on Meta::CPAN
my $ctx_new_sub =
$ver eq 'TLSv1_3' ? $CTX_tlsv1_3_new :
UNIVERSAL::can( 'Net::SSLeay',
$ver eq 'SSLv2' ? 'CTX_v2_new' :
$ver eq 'SSLv3' ? 'CTX_v3_new' :
$ver eq 'TLSv1' ? 'CTX_tlsv1_new' :
$ver eq 'TLSv1_1' ? 'CTX_tlsv1_1_new' :
$ver eq 'TLSv1_2' ? 'CTX_tlsv1_2_new' :
'CTX_new'
)
or return IO::Socket::SSL->_internal_error("SSL Version $ver not supported",9);
# For SNI in server mode we need a separate context for each certificate.
my %ctx;
if ($is_server) {
my %sni;
for my $opt (qw(SSL_key SSL_key_file SSL_cert SSL_cert_file)) {
my $val = $arg_hash->{$opt} or next;
if ( ref($val) eq 'HASH' ) {
while ( my ($host,$v) = each %$val ) {
$sni{lc($host)}{$opt} = $v;
lib/IO/Socket/SSL.pm view on Meta::CPAN
while (my ($host,$v) = each %sni) {
$ctx{$host} = $host =~m{%} ? $v : { %$arg_hash, %$v };
}
}
$ctx{''} = $arg_hash if ! %ctx;
for my $host (sort keys %ctx) {
my $arg_hash = delete $ctx{$host};
my $ctx;
if ($host =~m{^([^%]*)%}) {
$ctx = $ctx{$1} or return IO::Socket::SSL->error(
"SSL Context init for $host failed - no config for $1");
if (my @k = grep { !m{^SSL_(?:cert|key)(?:_file)?$} }
keys %$arg_hash) {
return IO::Socket::SSL->error(
"invalid keys @k in configuration '$host' of additional certs");
}
$can_multi_cert or return IO::Socket::SSL->error(
"no support for both RSA and ECC certificate in same context");
$host = $1;
goto just_configure_certs;
}
$ctx = $ctx_new_sub->() or return
IO::Socket::SSL->error("SSL Context init failed");
$CTX_CREATED_IN_THIS_THREAD{$ctx} = 1 if $use_threads;
$ctx{$host} = $ctx; # replace value in %ctx with real context
# SSL_OP_CIPHER_SERVER_PREFERENCE
$ssl_op |= 0x00400000 if $arg_hash->{SSL_honor_cipher_order};
if ($ver eq 'SSLv23' && !($ssl_op & $SSL_OP_NO{SSLv3})) {
# At least LibreSSL disables SSLv3 by default in SSL_CTX_new.
# If we really want SSL3.0 we need to explicitly allow it with
# SSL_CTX_clear_options.
lib/IO/Socket/SSL.pm view on Meta::CPAN
# buffer was written and not block for the rest
# SSL_MODE_ENABLE_PARTIAL_WRITE can be necessary for non-blocking because we
# cannot guarantee, that the location of the buffer stays constant
Net::SSLeay::CTX_set_mode( $ctx,
SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
SSL_MODE_ENABLE_PARTIAL_WRITE |
($arg_hash->{SSL_mode_release_buffers} ? $ssl_mode_release_buffers : 0)
);
if ( my $proto_list = $arg_hash->{SSL_npn_protocols} ) {
return IO::Socket::SSL->_internal_error("NPN not supported in Net::SSLeay",9)
if ! $can_npn;
if($arg_hash->{SSL_server}) {
# on server side SSL_npn_protocols means a list of advertised protocols
Net::SSLeay::CTX_set_next_protos_advertised_cb($ctx, $proto_list);
} else {
# on client side SSL_npn_protocols means a list of preferred protocols
# negotiation algorithm used is "as-openssl-implements-it"
Net::SSLeay::CTX_set_next_proto_select_cb($ctx, $proto_list);
}
}
if ( my $proto_list = $arg_hash->{SSL_alpn_protocols} ) {
return IO::Socket::SSL->_internal_error("ALPN not supported in Net::SSLeay",9)
if ! $can_alpn;
if($arg_hash->{SSL_server}) {
Net::SSLeay::CTX_set_alpn_select_cb($ctx, $proto_list);
} else {
Net::SSLeay::CTX_set_alpn_protos($ctx, $proto_list);
}
}
if ($arg_hash->{SSL_ticket_keycb}) {
my $cb = $arg_hash->{SSL_ticket_keycb};
($cb,my $arg) = ref($cb) eq 'CODE' ? ($cb):@$cb;
Net::SSLeay::CTX_set_tlsext_ticket_getkey_cb($ctx,$cb,$arg);
}
if ($arg_hash->{SSL_psk}) {
my $psk = $arg_hash->{SSL_psk};
if ($arg_hash->{SSL_server}) {
$can_server_psk or return IO::Socket::SSL->_internal_error(
"no support for server side PSK");
Net::SSLeay::CTX_set_psk_server_callback($ctx, sub {
my ($ssl,$identity,$psklen) = @_;
if (ref($psk) eq 'HASH') {
return $psk->{$identity} || $psk->{''} ||
IO::Socket::SSL->_internal_error(
"no PSK for given identity '$identity' and no default");
} else {
return $psk;
}
});
} else {
$can_client_psk or return IO::Socket::SSL->_internal_error(
"no support for client side PSK");
Net::SSLeay::CTX_set_psk_client_callback($ctx, sub {
my $hint = shift;
my ($i,$p);
if (ref($psk) eq 'HASH') {
$hint = '' if ! defined $hint;
$p = $psk->{$hint} or return IO::Socket::SSL->_internal_error(
"no PSK for given hint '$hint'");
$i = $hint;
} elsif (ref($psk)) { # [identity,psk]
($i,$p) = @$psk;
} else {
($i,$p) = ('io_socket_ssl', $psk)
}
# for some reason this expects the PSK in hex whereas the server
# side function expects the PSK in binary
return ($i, unpack("H*",$p));
lib/IO/Socket/SSL.pm view on Meta::CPAN
|| defined $arg_hash->{SSL_ca_file}
|| defined $arg_hash->{SSL_ca_path} ) {
my $file = $arg_hash->{SSL_ca_file};
$file = undef if ref($file) eq 'SCALAR' && ! $$file;
my $dir = $arg_hash->{SSL_ca_path};
$dir = undef if ref($dir) eq 'SCALAR' && ! $$dir;
if ( $arg_hash->{SSL_ca} ) {
my $store = Net::SSLeay::CTX_get_cert_store($ctx);
for (@{$arg_hash->{SSL_ca}}) {
Net::SSLeay::X509_STORE_add_cert($store,$_) or
return IO::Socket::SSL->error(
"Failed to add certificate to CA store");
}
}
$dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir);
if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations(
$ctx, $file || '', $dir || '')) {
return IO::Socket::SSL->error(
"Invalid certificate authority locations")
if $verify_mode != $Net_SSLeay_VERIFY_NONE;
}
} elsif ( my %ca = IO::Socket::SSL::default_ca()) {
# no CA path given, continue with system defaults
my $dir = $ca{SSL_ca_path};
$dir = join($OPENSSL_LIST_SEPARATOR,@$dir) if ref($dir);
if (! Net::SSLeay::CTX_load_verify_locations( $ctx,
$ca{SSL_ca_file} || '',$dir || '')
&& $verify_mode != $Net_SSLeay_VERIFY_NONE) {
return IO::Socket::SSL->error(
"Invalid default certificate authority locations")
}
}
if ($is_server && ($verify_mode & $Net_SSLeay_VERIFY_PEER)) {
if ($arg_hash->{SSL_client_ca}) {
for (@{$arg_hash->{SSL_client_ca}}) {
return IO::Socket::SSL->error(
"Failed to add certificate to client CA list") if
! Net::SSLeay::CTX_add_client_CA($ctx,$_);
}
}
if ($arg_hash->{SSL_client_ca_file}) {
my $list = Net::SSLeay::load_client_CA_file(
$arg_hash->{SSL_client_ca_file}) or
return IO::Socket::SSL->error(
"Failed to load certificate to client CA list");
Net::SSLeay::CTX_set_client_CA_list($ctx,$list);
}
}
my $X509_STORE_flags = $DEFAULT_X509_STORE_flags;
if ($arg_hash->{'SSL_check_crl'}) {
$X509_STORE_flags |= Net::SSLeay::X509_V_FLAG_CRL_CHECK();
if ($arg_hash->{'SSL_crl_file'}) {
my $bio = Net::SSLeay::BIO_new_file($arg_hash->{'SSL_crl_file'}, 'r');
my $crl = Net::SSLeay::PEM_read_bio_X509_CRL($bio);
Net::SSLeay::BIO_free($bio);
if ( $crl ) {
Net::SSLeay::X509_STORE_add_crl(Net::SSLeay::CTX_get_cert_store($ctx), $crl);
Net::SSLeay::X509_CRL_free($crl);
} else {
return IO::Socket::SSL->error("Invalid certificate revocation list");
}
}
}
Net::SSLeay::X509_STORE_set_flags(
Net::SSLeay::CTX_get_cert_store($ctx),
$X509_STORE_flags
) if $X509_STORE_flags;
Net::SSLeay::CTX_set_default_passwd_cb($ctx,$arg_hash->{SSL_passwd_cb})
lib/IO/Socket/SSL.pm view on Meta::CPAN
just_configure_certs:
my ($havekey,$havecert);
if ( my $x509 = $arg_hash->{SSL_cert} ) {
# binary, e.g. X509*
# we have either a single certificate or a list with
# a chain of certificates
my @x509 = ref($x509) eq 'ARRAY' ? @$x509: ($x509);
my $cert = shift @x509;
Net::SSLeay::CTX_use_certificate( $ctx,$cert )
|| return IO::Socket::SSL->error("Failed to use Certificate");
foreach my $ca (@x509) {
Net::SSLeay::CTX_add_extra_chain_cert( $ctx,$ca )
|| return IO::Socket::SSL->error("Failed to use Certificate");
}
$havecert = 'OBJ';
} elsif ( my $f = $arg_hash->{SSL_cert_file} ) {
# try to load chain from PEM or certificate from ASN1
my @err;
if (Net::SSLeay::CTX_use_certificate_chain_file($ctx,$f)) {
$havecert = 'PEM';
} elsif (do {
push @err, [ PEM => _errstack() ];
Net::SSLeay::CTX_use_certificate_file($ctx,$f,FILETYPE_ASN1)
lib/IO/Socket/SSL.pm view on Meta::CPAN
# don't free @chain, because CTX_add_extra_chain_cert
# did not duplicate the certificates
}
if (!$havecert) {
push @err, [ PKCS12 => _errstack() ];
my $err = "Failed to load certificate from file $f:";
for(@err) {
my ($type,@e) = @$_;
$err .= " [format:$type] @e **" if @e;
}
return IO::Socket::SSL->error($err);
}
}
if (!$havecert || $havekey) {
# skip SSL_key_*
} elsif ( my $pkey = $arg_hash->{SSL_key} ) {
# binary, e.g. EVP_PKEY*
Net::SSLeay::CTX_use_PrivateKey($ctx, $pkey)
|| return IO::Socket::SSL->error("Failed to use Private Key");
$havekey = 'MEM';
} elsif ( my $f = $arg_hash->{SSL_key_file}
|| (($havecert eq 'PEM') ? $arg_hash->{SSL_cert_file}:undef) ) {
for my $ft ( FILETYPE_PEM, FILETYPE_ASN1 ) {
if (Net::SSLeay::CTX_use_PrivateKey_file($ctx,$f,$ft)) {
$havekey = ($ft == FILETYPE_PEM) ? 'PEM':'DER';
last;
}
}
$havekey or return IO::Socket::SSL->error(
"Failed to load key from file (no PEM or DER)");
}
Net::SSLeay::CTX_set_post_handshake_auth($ctx,1)
if (!$is_server && $can_pha && $havecert && $havekey);
}
if ($arg_hash->{SSL_server}) {
if ( my $f = $arg_hash->{SSL_dh_file} ) {
my $bio = Net::SSLeay::BIO_new_file( $f,'r' )
|| return IO::Socket::SSL->error( "Failed to open DH file $f" );
my $dh = Net::SSLeay::PEM_read_bio_DHparams($bio);
Net::SSLeay::BIO_free($bio);
$dh || return IO::Socket::SSL->error( "Failed to read PEM for DH from $f - wrong format?" );
my $rv;
for (values (%ctx)) {
$rv = Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) or last;
}
Net::SSLeay::DH_free( $dh );
$rv || return IO::Socket::SSL->error( "Failed to set DH from $f" );
} elsif ( my $dh = $arg_hash->{SSL_dh} ) {
# binary, e.g. DH*
for( values %ctx ) {
Net::SSLeay::CTX_set_tmp_dh( $_,$dh ) || return
IO::Socket::SSL->error( "Failed to set DH from SSL_dh" );
}
}
}
if ( my $curve = $arg_hash->{SSL_ecdh_curve} ) {
return IO::Socket::SSL->_internal_error(
"ECDH curve needs Net::SSLeay>=1.56 and OpenSSL>=1.0",9)
if ! $can_ecdh;
for(values %ctx) {
if ($arg_hash->{SSL_server} and $curve eq 'auto') {
if ($can_ecdh eq 'can_auto') {
Net::SSLeay::CTX_set_ecdh_auto($_,1) or
return IO::Socket::SSL->error(
"failed to set ECDH curve context");
} elsif ($can_ecdh eq 'auto') {
# automatically enabled anyway
} else {
return IO::Socket::SSL->error(
"SSL_CTX_set_ecdh_auto not implemented");
}
} elsif ($set_groups_list) {
$set_groups_list->($_,$curve) or return IO::Socket::SSL->error(
"failed to set ECDH groups/curves on context");
# needed for OpenSSL 1.0.2 if ($can_ecdh eq 'can_auto') {
Net::SSLeay::CTX_set_ecdh_auto($_,1) if $can_ecdh eq 'can_auto';
} elsif ($curve =~m{:}) {
return IO::Socket::SSL->error(
"SSL_CTX_groups_list or SSL_CTX_curves_list not implemented");
} elsif ($arg_hash->{SSL_server}) {
if ( $curve !~ /^\d+$/ ) {
# name of curve, find NID
$curve = Net::SSLeay::OBJ_txt2nid($curve)
|| return IO::Socket::SSL->error(
"cannot find NID for curve name '$curve'");
}
my $ecdh = Net::SSLeay::EC_KEY_new_by_curve_name($curve) or
return IO::Socket::SSL->error(
"cannot create curve for NID $curve");
for( values %ctx ) {
Net::SSLeay::CTX_set_tmp_ecdh($_,$ecdh) or
return IO::Socket::SSL->error(
"failed to set ECDH curve context");
}
Net::SSLeay::EC_KEY_free($ecdh);
}
}
}
my $verify_cb = $arg_hash->{SSL_verify_callback};
my @accept_fp;
if ( my $fp = $arg_hash->{SSL_fingerprint} ) {
for( ref($fp) ? @$fp : $fp) {
my ($algo,$pubkey,$digest) = m{^(?:([\w-]+)\$)?(pub\$)?([a-f\d:]+)$}i
or return IO::Socket::SSL->_internal_error("invalid fingerprint '$_'",9);
( $digest = lc($digest) ) =~s{:}{}g;
$algo ||=
length($digest) == 32 ? 'md5' :
length($digest) == 40 ? 'sha1' :
length($digest) == 64 ? 'sha256' :
return IO::Socket::SSL->_internal_error(
"cannot detect hash algorithm from fingerprint '$_'",9);
$algo = lc($algo);
push @accept_fp,[ $algo, $pubkey || '', pack('H*',$digest) ]
}
}
my $verify_fingerprint = @accept_fp && do {
my $fail;
my $force = $arg_hash->{SSL_force_fingerprint};
sub {
my ($ok,$cert,$depth) = @_;
lib/IO/Socket/SSL.pm view on Meta::CPAN
}
Net::SSLeay::CTX_set_verify($_, $verify_mode, $verify_callback)
for (values %ctx);
my $staple_callback = $arg_hash->{SSL_ocsp_staple_callback};
if ( !$is_server && $can_ocsp_staple && ! $verify_fingerprint) {
$self->{ocsp_cache} = $arg_hash->{SSL_ocsp_cache};
my $status_cb = sub {
my ($ssl,$resp) = @_;
my $iossl = $SSL_OBJECT{$ssl} or
die "no IO::Socket::SSL object found for SSL $ssl";
$iossl->[1] and do {
# we must return with 1 or it will be called again
# and because we have no SSL object we must make the error global
Carp::cluck($IO::Socket::SSL::SSL_ERROR
= "OCSP callback on server side");
return 1;
};
$iossl = $iossl->[0];
# if we have a callback use this
# callback must not free or copy $resp !!
if ( $staple_callback ) {
$staple_callback->($iossl,$resp);
return 1;
lib/IO/Socket/SSL.pm view on Meta::CPAN
return 1;
};
Net::SSLeay::CTX_set_tlsext_status_cb($_,$status_cb) for (values %ctx);
}
if ( my $cl = $arg_hash->{SSL_cipher_list} ) {
for (keys %ctx) {
Net::SSLeay::CTX_set_cipher_list($ctx{$_}, ref($cl)
? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next
: $cl
) || return IO::Socket::SSL->error("Failed to set SSL cipher list");
}
}
if ( my $cl = $arg_hash->{SSL_ciphersuites} ) {
return IO::Socket::SSL->error("no support for SSL_ciphersuites in Net::SSLeay")
if ! $can_ciphersuites;
for (keys %ctx) {
Net::SSLeay::CTX_set_ciphersuites($ctx{$_}, ref($cl)
? $cl->{$_} || $cl->{''} || $DEFAULT_SSL_ARGS{SSL_cipher_list} || next
: $cl
) || return IO::Socket::SSL->error("Failed to set SSL cipher list");
}
}
# Main context is default context or any other if no default context.
my $ctx = $ctx{''} || (values %ctx)[0];
if (keys(%ctx) > 1 || ! exists $ctx{''}) {
$can_server_sni or return IO::Socket::SSL->_internal_error(
"Server side SNI not supported for this openssl/Net::SSLeay",9);
Net::SSLeay::CTX_set_tlsext_servername_callback($ctx, sub {
my $ssl = shift;
my $host = Net::SSLeay::get_servername($ssl);
$host = '' if ! defined $host;
my $snictx = $ctx{lc($host)} || $ctx{''} or do {
$DEBUG>1 and DEBUG(
"cannot get context from servername '$host'");
return 2; # SSL_TLSEXT_ERR_ALERT_FATAL
lib/IO/Socket/SSL.pm view on Meta::CPAN
}
if ( my $cb = $arg_hash->{SSL_create_ctx_callback} ) {
$cb->($_) for values (%ctx);
}
$self->{context} = $ctx;
$self->{verify_mode} = $arg_hash->{SSL_verify_mode};
$self->{ocsp_mode} =
defined($arg_hash->{SSL_ocsp_mode}) ? $arg_hash->{SSL_ocsp_mode} :
$self->{verify_mode} ? IO::Socket::SSL::SSL_OCSP_TRY_STAPLE() :
0;
$DEBUG>=3 && DEBUG( "new ctx $ctx" );
if ( my $cache = $arg_hash->{SSL_session_cache} ) {
# use predefined cache
$self->{session_cache} = $cache
} elsif ( my $size = $arg_hash->{SSL_session_cache_size}) {
$self->{session_cache} = IO::Socket::SSL::Session_Cache->new( $size );
}
if ($self->{session_cache} and %sess_cb) {
Net::SSLeay::CTX_set_session_cache_mode($ctx,
Net::SSLeay::SESS_CACHE_CLIENT());
my $cache = $self->{session_cache};
$sess_cb{new}($ctx, sub {
my ($ssl,$session) = @_;
my $self = ($SSL_OBJECT{$ssl} || do {
lib/IO/Socket/SSL.pm view on Meta::CPAN
$DEBUG>=3 && DEBUG("free ctx $ctx tlsext_status_cb" );
Net::SSLeay::CTX_set_tlsext_status_cb($ctx,undef);
}
$DEBUG>=3 && DEBUG("OK free ctx $ctx" );
Net::SSLeay::CTX_free($ctx);
}
}
delete(@{$self}{'context','session_cache'});
}
package IO::Socket::SSL::Session_Cache;
*DEBUG = *IO::Socket::SSL::DEBUG;
# The cache is consisting of one list which contains all sessions and then
# for each session key another list containing all sessions for same key.
# The order of the list is by use, i.e. last used are put on top.
# self.ghead points to the top of the global list while
# self.shead{key} to the top of the session key specific list
# All lists are cyclic
# Each element in the list consists of an array with slots for ...
use constant {
SESSION => 0, # session object
lib/IO/Socket/SSL.pm view on Meta::CPAN
while ($v) {
Net::SSLeay::SESSION_free($v->[SESSION]) if $v->[SESSION];
my $next = $v->[GNEXT];
@$v = ();
$v = $next;
}
}
package IO::Socket::SSL::OCSP_Cache;
sub new {
my ($class,$size) = @_;
return bless {
'' => { _lru => 0, size => $size || 100 }
},$class;
}
sub get {
my ($self,$id) = @_;
my $e = $self->{$id} or return;
lib/IO/Socket/SSL.pm view on Meta::CPAN
$self->{$id} = $e;
$e->{_lru} = $self->{''}{_lru}++;
my $del = keys(%$self) - $self->{''}{size};
if ($del>0) {
my @k = sort { $self->{$a}{_lru} <=> $self->{$b}{_lru} } keys %$self;
delete @{$self}{ splice(@k,0,$del) };
}
return $e;
}
package IO::Socket::SSL::OCSP_Resolver;
*DEBUG = *IO::Socket::SSL::DEBUG;
# create a new resolver
# $ssl - the ssl object
# $cache - OCSP_Cache object (put,get)
# $failhard - flag if we should fail hard on OCSP problems
# $certs - list of certs to verify
sub new {
my ($class,$ssl,$cache,$failhard,$certs) = @_;
my (%todo,$done,$hard_error,@soft_error);
for my $cert (@$certs) {
lib/IO/Socket/SSL.pm view on Meta::CPAN
$DEBUG && DEBUG("got OCSP response from $uri code=$resp->{status}");
defined ($self->add_response($uri,
$resp->{success} && $resp->{content}))
&& last;
}
}
$DEBUG>=2 && DEBUG("no more open OCSP requests");
return $self->{hard_error};
}
package IO::Socket::SSL::Trace;
*DEBUG = *IO::Socket::SSL::DEBUG;
# Exhaustive list of constants we need for tracing
my %trace_constants = map { $_ => eval { Net::SSLeay->$_ } || -1 } qw(
SSL2_VERSION
SSL3_VERSION
TLS1_VERSION
TLS1_1_VERSION
TLS1_2_VERSION
TLS1_3_VERSION
DTLS1_VERSION
lib/IO/Socket/SSL.pod view on Meta::CPAN
CK
=head1 NAME
IO::Socket::SSL - SSL sockets with IO::Socket interface
=head1 SYNOPSIS
use strict;
use IO::Socket::SSL;
# simple client
my $cl = IO::Socket::SSL->new('www.google.com:443');
print $cl "GET / HTTP/1.0\r\n\r\n";
print <$cl>;
# simple server
my $srv = IO::Socket::SSL->new(
LocalAddr => '0.0.0.0:1234',
Listen => 10,
SSL_cert_file => 'server-cert.pem',
SSL_key_file => 'server-key.pem',
);
$srv->accept;
=head1 DESCRIPTION
IO::Socket::SSL makes using SSL/TLS much easier by wrapping the necessary
functionality into the familiar L<IO::Socket> interface and providing secure
defaults whenever possible.
This way, existing applications can be made SSL-aware without much effort, at
least if you do blocking I/O and don't use select or poll.
But, under the hood, SSL is a complex beast.
So there are lots of methods to make it do what you need if the default
behavior is not adequate.
Because it is easy to inadvertently introduce critical security bugs or just
hard to debug problems, I would recommend studying the following
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item * L</"Integration Into Own Modules">
=item * L</"Description Of Methods">
=back
Additional documentation can be found in
=over 4
=item * L<IO::Socket::SSL::Intercept> - Doing Man-In-The-Middle with SSL
=item * L<IO::Socket::SSL::Utils> - Useful functions for certificates etc
=back
=head1 Essential Information About SSL/TLS
SSL (Secure Socket Layer) or its successor TLS (Transport Layer Security) are
protocols to facilitate end-to-end security. These protocols are used when
accessing web sites (https), delivering or retrieving email, and in lots of other
use cases.
lib/IO/Socket/SSL.pod view on Meta::CPAN
talks to the right server, but the server usually does not care which client it
talks to.
But, sometimes the server wants to identify the client too and will request a
certificate from the client which the server must verify in a similar way.
=head1 Basic SSL Client
A basic SSL client is simple:
my $client = IO::Socket::SSL->new('www.example.com:443')
or die "error=$!, ssl_error=$SSL_ERROR";
This will take the OpenSSL default CA store as the store for the trusted CA.
This usually works on UNIX systems.
If there are no certificates in the store it will try use L<Mozilla::CA> which
provides the default CAs of Firefox.
In the default settings, L<IO::Socket::SSL> will use a safer cipher set and SSL
version, do a proper hostname check against the certificate, and use SNI (server
name indication) to send the hostname inside the SSL handshake. This is
necessary to work with servers which have different certificates behind the
same IP address.
It will also check the revocation of the certificate with OCSP, but currently
only if the server provides OCSP stapling (for deeper checks see
C<ocsp_resolver> method).
Lots of options can be used to change ciphers, SSL version, location of CA and
much more. See documentation of methods for details.
With protocols like SMTP it is necessary to upgrade an existing socket to SSL.
This can be done like this:
my $client = IO::Socket::INET->new('mx.example.com:25') or die $!;
# .. read greeting from server
# .. send EHLO and read response
# .. send STARTTLS command and read response
# .. if response was successful we can upgrade the socket to SSL now:
IO::Socket::SSL->start_SSL($client,
# explicitly set hostname we should use for SNI
SSL_hostname => 'mx.example.com'
) or die $SSL_ERROR;
A more complete example for a simple HTTP client:
my $client = IO::Socket::SSL->new(
# where to connect
PeerHost => "www.example.com",
PeerPort => "https",
# certificate verification - VERIFY_PEER is default
SSL_verify_mode => SSL_VERIFY_PEER,
# location of CA store
# need only be given if default store should not be used
SSL_ca_path => '/etc/ssl/certs', # typical CA path on Linux
SSL_ca_file => '/etc/ssl/cert.pem', # typical CA file on BSD
# or just use default path on system:
IO::Socket::SSL::default_ca(), # either explicitly
# or implicitly by not giving SSL_ca_*
# easy hostname verification
# It will use PeerHost as default name a verification
# scheme as default, which is safe enough for most purposes.
SSL_verifycn_name => 'foo.bar',
SSL_verifycn_scheme => 'http',
# SNI support - defaults to PeerHost
SSL_hostname => 'foo.bar',
lib/IO/Socket/SSL.pod view on Meta::CPAN
) or die "failed connect or ssl handshake: $!,$SSL_ERROR";
# send and receive over SSL connection
print $client "GET / HTTP/1.0\r\n\r\n";
print <$client>;
And to do revocation checks with OCSP (only available with OpenSSL 1.0.0 or
higher and L<Net::SSLeay> 1.59 or higher):
# default will try OCSP stapling and check only leaf certificate
my $client = IO::Socket::SSL->new($dst);
# better yet: require checking of full chain
my $client = IO::Socket::SSL->new(
PeerAddr => $dst,
SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN,
);
# even better: make OCSP errors fatal
# (this will probably fail with lots of sites because of bad OCSP setups)
# also use common OCSP response cache
my $ocsp_cache = IO::Socket::SSL::OCSP_Cache->new;
my $client = IO::Socket::SSL->new(
PeerAddr => $dst,
SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN|SSL_OCSP_FAIL_HARD,
SSL_ocsp_cache => $ocsp_cache,
);
# disable OCSP stapling in case server has problems with it
my $client = IO::Socket::SSL->new(
PeerAddr => $dst,
SSL_ocsp_mode => SSL_OCSP_NO_STAPLE,
);
# check any certificates which are not yet checked by OCSP stapling or
# where we have already cached results. For your own resolving combine
# $ocsp->requests with $ocsp->add_response(uri,response).
my $ocsp = $client->ocsp_resolver();
my $errors = $ocsp->resolve_blocking();
if ($errors) {
warn "OCSP verification failed: $errors";
close($client);
}
=head1 Basic SSL Server
A basic SSL server looks similar to other L<IO::Socket> servers, only that it
also contains settings for certificate and key:
# simple server
my $server = IO::Socket::SSL->new(
# where to listen
LocalAddr => '127.0.0.1',
LocalPort => 8080,
Listen => 10,
# which certificate to offer
# with SNI support there can be different certificates per hostname
SSL_cert_file => 'cert.pem',
SSL_key_file => 'key.pem',
) or die "failed to listen: $!";
lib/IO/Socket/SSL.pod view on Meta::CPAN
# where to listen
LocalAddr => '127.0.0.1',
LocalPort => 8080,
Listen => 10,
);
# accept client
my $client = $server->accept or die;
# SSL upgrade client (in new process/thread)
IO::Socket::SSL->start_SSL($client,
SSL_server => 1,
SSL_cert_file => 'cert.pem',
SSL_key_file => 'key.pem',
) or die "failed to ssl handshake: $SSL_ERROR";
Like with normal sockets, neither forking nor threading servers scale well.
It is recommended to use non-blocking sockets instead, see
L</"Using Non-Blocking Sockets">
=head1 Common Usage Errors
This is a list of typical errors seen with the use of L<IO::Socket::SSL>:
=over 4
=item *
Disabling verification with C<SSL_verify_mode>.
As described in L</"Essential Information About SSL/TLS">, a proper
identification of the peer is essential and failing to verify makes
Man-In-The-Middle attacks possible.
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item *
If the validation failed because the hostname does not match and you cannot
access the host with the name given in the certificate, you can use
C<SSL_verifycn_name> to specify the hostname you expect in the certificate.
=back
A common error pattern is also to disable verification if they found no CA
store (different modules look at different "default" places).
Because L<IO::Socket::SSL> is now able to provide a usable CA store on most
platforms (UNIX, Mac OSX and Windows) it is better to use the defaults provided
by L<IO::Socket::SSL>.
If necessary these can be checked with the C<default_ca> method.
=item *
Polling of SSL sockets (e.g. select, poll and other event loops).
If you sysread one byte on a normal socket it will result in a syscall to read
one byte. Thus, if more than one byte is available on the socket it will be kept
in the network stack of your OS and the next select or poll call will return the
socket as readable.
lib/IO/Socket/SSL.pod view on Meta::CPAN
from only a single SSL frame you can guarantee that there are no pending
data.
Additionally, contrary to plain sockets the data delivered on the socket are
not necessarily application payload.
It might be a TLS handshake, it might just be the beginning of a TLS record or
it might be TLS session tickets which are send after the TLS handshake in TLS
1.3.
In such situations select will return that data are available for read since it
only looks at the plain socket.
A sysread on the IO::Socket::SSL socket will not return any data though since it
is an abstraction which only returns application data.
This causes the sysread to hang in case the socket was blocking or to return
an error with EAGAIN on non-blocking sockets.
Applications using select or similar should therefore set the socket to
non-blocking and also expect that the sysread might temporarily fail with
EAGAIN.
See also L</"Using Non-Blocking Sockets">.
=item *
Expecting exactly the same behavior as plain sockets.
IO::Socket::SSL tries to emulate the usual socket behavior as good as possible,
but full emulation can not be done. Specifically a read on the SSL socket might
also result in a write on the TCP socket or a write on the SSL socket might
result in a read on the TCP socket. Also C<accept> and B<close> on the SSL
socket will result in writing and reading data to the TCP socket too.
Especially the hidden writes might result in a connection reset if the
underlying TCP socket is already closed by the peer. Unless signal PIPE is
explicitly handled by the application this will usually result in the
application crashing. It is thus recommended to explicitly IGNORE signal PIPE so
that the errors get propagated as EPIPE instead of causing a crash of the
application.
=item *
Set 'SSL_version' or 'SSL_cipher_list' to a "better" value.
L<IO::Socket::SSL> tries to set these values to reasonable, secure values which
are compatible with the rest of the world.
But, there are some scripts or modules out there which tried to be smart and
get more secure or compatible settings.
Unfortunately, they did this years ago and never updated these values, so they
are still forced to do only 'TLSv1' (instead of also using TLSv12 or TLSv11).
Or they set 'HIGH' as the cipher list and thought they were secure, but did not
notice that 'HIGH' includes anonymous ciphers, e.g. without identification of
the peer.
So it is recommended to leave the settings at the secure defaults which
L<IO::Socket::SSL> sets and which get updated from time to time to
better fit the real world.
=item *
Make SSL settings inaccessible by the user, together with bad builtin settings.
Some modules use L<IO::Socket::SSL>, but don't make the SSL settings available
to the user. This is often combined with bad builtin settings or defaults (like
switching verification off).
Thus the user needs to hack around these restrictions by using
C<set_args_filter_hack> or similar.
=item *
Use of constants as strings.
lib/IO/Socket/SSL.pod view on Meta::CPAN
=head1 Common Problems with SSL
SSL is a complex protocol with multiple implementations and each of these has
their own quirks. While most of these implementations work together, it often
gets problematic with older versions, minimal versions in load balancers, or plain
wrong setups.
Unfortunately these problems are hard to debug.
Helpful for debugging are a knowledge of SSL internals, wireshark and the use of
the debug settings of L<IO::Socket::SSL> and L<Net::SSLeay>, which can both be
set with C<$IO::Socket::SSL::DEBUG>.
The following debugs levels are defined, but used not in any consistent way:
=over 4
=item *
0 - No debugging (default).
=item *
1 - Print out errors from L<IO::Socket::SSL> and ciphers from L<Net::SSLeay>.
=item *
2 - Print also information about call flow from L<IO::Socket::SSL>, progress
information from L<Net::SSLeay> and state information from OpenSSL.
=item *
3 - Print also some data dumps from L<IO::Socket::SSL> and from L<Net::SSLeay>.
=back
Also, C<analyze-ssl.pl> from the ssl-tools repository at
L<https://github.com/noxxi/p5-ssl-tools> might be a helpful tool when debugging
SSL problems, as do the C<openssl> command line tool and a check with a
different SSL implementation (e.g. a web browser).
The following problems are not uncommon:
lib/IO/Socket/SSL.pod view on Meta::CPAN
It is a regular problem that administrators fail to include all necessary
certificates into their server setup, e.g. everything needed to build the trust
chain from the trusted root.
If they check the setup with the browser everything looks ok, because browsers
work around these problems by caching any intermediate certificates and apply
them to new connections if certificates are missing.
But, fresh browser profiles which have never seen these intermediates cannot
fill in the missing certificates and fail to verify; the same is true with
L<IO::Socket::SSL>.
=item *
Old versions of servers or load balancers which do not understand specific TLS
versions or croak on specific data.
From time to time one encounters an SSL peer, which just closes the connection
inside the SSL handshake. This can usually be worked around by downgrading the
SSL version, e.g. by setting C<SSL_version>. Modern Browsers usually deal with
such servers by automatically downgrading the SSL version and repeat the
lib/IO/Socket/SSL.pod view on Meta::CPAN
A cause of such problems are often load balancers or security devices, which
have hardware acceleration and only a minimal (and less robust) SSL stack. They
can often be detected because they support much fewer ciphers than other
implementations.
=item *
Bad or old OpenSSL versions.
L<IO::Socket::SSL> uses OpenSSL with the help of the L<Net::SSLeay> library. It
is recommend to have a recent version of this library, because it has more
features and usually fewer known bugs.
=item *
Validation of client certificates fail.
Make sure that the purpose of the certificate allows use as ssl client (check
with C<< openssl x509 -purpose >>, that the necessary root certificate is in the
path specified by C<SSL_ca*> (or the default path) and that any intermediate
lib/IO/Socket/SSL.pod view on Meta::CPAN
And, while the behavior is not documented for other L<IO::Socket> classes, it
will try to emulate the behavior seen there, e.g. to return the received data
instead of blocking, even if the line is not complete. If an unrecoverable error
occurs it will return nothing, even if it already received some data.
Also, I would advise against using C<accept> with a non-blocking SSL object
because it might block and this is not what most would expect. The reason for
this is that C<accept> on a non-blocking TCP socket (e.g. L<IO::Socket::IP>,
L<IO::Socket::INET>..) results in a new TCP socket which does not inherit the
non-blocking behavior of the master socket. And thus, the initial SSL handshake
on the new socket inside C<IO::Socket::SSL::accept> will be done in a blocking
way. To work around this you are safer by doing a TCP accept and later upgrade the
TCP socket in a non-blocking way with C<start_SSL> and C<accept_SSL>.
my $cl = IO::Socket::SSL->new($dst);
$cl->blocking(0);
my $sel = IO::Select->new($cl);
while (1) {
# with SSL a call for reading n bytes does not result in reading of n
# bytes from the socket, but instead it must read at least one full SSL
# frame. If the socket has no new bytes, but there are unprocessed data
# from the SSL frame can_read will block!
# wait for data on socket
$sel->can_read();
lib/IO/Socket/SSL.pod view on Meta::CPAN
=head1 Advanced Usage
=head2 SNI Support
Newer extensions to SSL can distinguish between multiple hostnames on the same
IP address using Server Name Indication (SNI).
Support for SNI on the client side was added somewhere in the OpenSSL 0.9.8
series, but with 1.0 a bug was fixed when the server could not decide about
its hostname. Therefore client side SNI is only supported with OpenSSL 1.0 or
higher in L<IO::Socket::SSL>.
With a supported version, SNI is used automatically on the client side, if it
can determine the hostname from C<PeerAddr> or C<PeerHost> (which are synonyms
in the underlying IO::Socket:: classes and thus should never be set both or at
least not to different values).
On unsupported OpenSSL versions it will silently not use SNI.
The hostname can also be given explicitly given with C<SSL_hostname>, but in
this case it will throw in error, if SNI is not supported.
To check for support you might call C<< IO::Socket::SSL->can_client_sni() >>.
On the server side, earlier versions of OpenSSL are supported, but only together
with L<Net::SSLeay> version >= 1.50.
To check for support you might call C<< IO::Socket::SSL->can_server_sni() >>.
If server side SNI is supported, you might specify different certificates per
host with C<SSL_cert*> and C<SSL_key*>, and check the requested name using
C<get_servername>.
=head2 Talk Plain and SSL With The Same Socket
It is often required to first exchange some plain data and then upgrade the
socket to SSL after some kind of STARTTLS command. Protocols like FTPS even
need a way to downgrade the socket again back to plain.
The common way to do this would be to create a normal socket and use C<start_SSL>
to upgrade and stop_SSL to downgrade:
my $sock = IO::Socket::INET->new(...) or die $!;
... exchange plain data on $sock until starttls command ...
IO::Socket::SSL->start_SSL($sock,%sslargs) or die $SSL_ERROR;
... now $sock is an IO::Socket::SSL object ...
... exchange data with SSL on $sock until stoptls command ...
$sock->stop_SSL or die $SSL_ERROR;
... now $sock is again an IO::Socket::INET object ...
But, lots of modules just derive directly from L<IO::Socket::INET>.
While this base class can be replaced with L<IO::Socket::SSL>, these modules cannot
easily support different base classes for SSL and plain data and switch between
these classes on a starttls command.
To help in this case, L<IO::Socket::SSL> can be reduced to a plain socket on
startup, and connect_SSL/accept_SSL/start_SSL can be used to enable SSL and
C<stop_SSL> to talk plain again:
my $sock = IO::Socket::SSL->new(
PeerAddr => ...
SSL_startHandshake => 0,
%sslargs
) or die $!;
... exchange plain data on $sock until starttls command ...
$sock->connect_SSL or die $SSL_ERROR;
... now $sock is an IO::Socket::SSL object ...
... exchange data with SSL on $sock until stoptls command ...
$sock->stop_SSL or die $SSL_ERROR;
... $sock is still an IO::Socket::SSL object ...
... but data exchanged again in plain ...
=head1 Integration Into Own Modules
L<IO::Socket::SSL> behaves similarly to other L<IO::Socket> modules and thus could
be integrated in the same way, but you have to take special care when using
non-blocking I/O (like for handling timeouts) or using select or poll.
Please study the documentation on how to deal with these differences.
Also, it is recommended to not set or touch most of the C<SSL_*> options, so
that they keep their secure defaults. It is also recommended to let the user
override these SSL specific settings without the need of global settings or hacks
like C<set_args_filter_hack>.
The notable exception is C<SSL_verifycn_scheme>.
This should be set to the hostname verification scheme required by the module or
protocol.
=head1 Description Of Methods
L<IO::Socket::SSL> inherits from another L<IO::Socket> module.
The choice of the super class depends on the installed modules:
=over 4
=item *
If L<IO::Socket::IP> with at least version 0.20 is installed it will use this
module as super class, transparently providing IPv6 and IPv4 support.
=item *
lib/IO/Socket/SSL.pod view on Meta::CPAN
=back
Please be aware that with the IPv6 capable super classes, it will look first
for the IPv6 address of a given hostname. If the resolver provides an IPv6
address, but the host cannot be reached by IPv6, there will be no automatic
fallback to IPv4.
To avoid these problems you can enforce IPv4 for a specific socket by
using the C<Domain> or C<Family> option with the value AF_INET as described in
L<IO::Socket::IP>. Alternatively you can enforce IPv4 globally by loading
L<IO::Socket::SSL> with the option 'inet4', in which case it will use the IPv4
only class L<IO::Socket::INET> as the super class.
L<IO::Socket::SSL> will provide all of the methods of its super class, but
sometimes it will override them to match the behavior expected from SSL or to
provide additional arguments.
The new or changed methods are described below, but please also read the
section about SSL specific error handling.
=over 4
=item Error Handling
If an SSL specific error occurs, the global variable C<$SSL_ERROR> will be set.
If the error occurred on an existing SSL socket, the method C<errstr> will
give access to the latest socket specific error.
Both C<$SSL_ERROR> and the C<errstr> method give a dualvar similar to C<$!>, e.g.
providing an error number in numeric context or an error description in string
context.
=item B<new(...)>
Creates a new L<IO::Socket::SSL> object. You may use all the friendly options
that came bundled with the super class (e.g. L<IO::Socket::IP>,
L<IO::Socket::INET>, ...) plus (optionally) the ones described below.
If you don't specify any SSL related options it will do its best in using
secure defaults, e.g. choosing good ciphers, enabling proper verification, etc.
=over 2
=item SSL_server
Set this option to a true value if the socket should be used as a server.
lib/IO/Socket/SSL.pod view on Meta::CPAN
trusted certificate authority. In this case you should use this option to
specify the file (C<SSL_ca_file>) or directory (C<SSL_ca_path>) containing the
certificateZ<>(s) of the trusted certificate authorities.
C<SSL_ca_path> can also be an array or a string containing multiple path, where
the path are separated by the platform specific separator. This separator is
C<;> on DOS, Windows, Netware, C<,> on VMS and C<:> for all the other systems.
If multiple path are given at least one of these must be accessible.
You can also give a list of X509* certificate handles (like you get from
L<Net::SSLeay> or L<IO::Socket::SSL::Utils::PEM_xxx2cert>) with C<SSL_ca>. These
will be added to the CA store before path and file and thus take precedence.
If neither SSL_ca, nor SSL_ca_file or SSL_ca_path are set it will use
C<default_ca()> to determine the user-set or system defaults.
If you really don't want to set a CA set SSL_ca_file or SSL_ca_path to
C<\undef> or SSL_ca to an empty list. (unfortunately C<''> is used by some
modules using L<IO::Socket::SSL> when CA is not explicitly given).
=item SSL_client_ca | SSL_client_ca_file
If verify_mode is VERIFY_PEER on the server side these options can be used to
set the list of acceptable CAs for the client. This way the client can select
they required certificate from a list of certificates.
The value for these options is similar to C<SSL_ca> and C<SSL_ca_file>.
=item SSL_fingerprint
lib/IO/Socket/SSL.pod view on Meta::CPAN
This option should be set to true if a failed fingerprint validation should
override an otherwise successful certificate validation.
=item SSL_cert_file | SSL_cert | SSL_key_file | SSL_key
If you create a server you usually need to specify a server certificate which
should be verified by the client. Same is true for client certificates, which
should be verified by the server.
The certificate can be given as a file with SSL_cert_file or as an internal
representation of an X509* object (like you get from L<Net::SSLeay> or
L<IO::Socket::SSL::Utils::PEM_xxx2cert>) with SSL_cert.
If given as a file it will automatically detect the format.
Supported file formats are PEM, DER and PKCS#12, where PEM and PKCS#12 can
contain the certificate and the chain to use, while DER can only contain a single
certificate.
If given as a list of X509* please note, that the all the chain certificates
(e.g. all except the first) will be "consumed" by openssl and will be freed
if the SSL context gets destroyed - so you should never free them yourself. But
the servers certificate (e.g. the first) will not be consumed by openssl and
thus must be freed by the application.
For each certificate a key is need, which can either be given as a file with
SSL_key_file or as an internal representation of an EVP_PKEY* object with
SSL_key (like you get from L<Net::SSLeay> or
L<IO::Socket::SSL::Utils::PEM_xxx2key>).
If a key was already given within the PKCS#12 file specified by SSL_cert_file
it will ignore any SSL_key or SSL_key_file.
If no SSL_key or SSL_key_file was given it will try to use the PEM file given
with SSL_cert_file again, maybe it contains the key too.
If your SSL server should be able to use different certificates on the same IP
address, depending on the name given by SNI, you can use a hash reference
instead of a file with C<<hostname => cert_file>>.
If your SSL server should be able to use both RSA and ECDSA certificates for the
lib/IO/Socket/SSL.pod view on Meta::CPAN
}
=item SSL_passwd_cb
If your private key is encrypted, you might not want the default password prompt
from Net::SSLeay. This option takes a reference to a subroutine that should
return the password required to decrypt your private key.
=item SSL_use_cert
If this is true, it forces IO::Socket::SSL to use a certificate and key, even if
you are setting up an SSL client. If this is set to 0 (the default), then you
will only need a certificate and key if you are setting up a server.
SSL_use_cert will implicitly be set if SSL_server is set.
For convenience it is also set if it was not given but a cert was given for use
(SSL_cert_file or similar).
=item SSL_version
lib/IO/Socket/SSL.pod view on Meta::CPAN
If setting groups or curves is supported by Net::SSLeay (needs at least
version 1.86) then multiple curves can be given here in the order of the
preference, i.e. C<P-521:P-384:P-256>. When used at the client side this
will include the supported curves as extension in the TLS handshake.
If you don't want to have ECDH key exchange this could be set to undef or
set C<SSL_ciphers> to exclude all of these ciphers.
You can check if ECDH support is available by calling
C<< IO::Socket::SSL->can_ecdh >>.
=item SSL_verify_mode
This option sets the verification mode for the peer certificate.
You may combine SSL_VERIFY_PEER (verify_peer), SSL_VERIFY_FAIL_IF_NO_PEER_CERT
(fail verification if no peer certificate exists; ignored for clients),
SSL_VERIFY_CLIENT_ONCE (verify client once; ignored for clients).
Note that SSL_VERIFY_FAIL_IF_NO_PEER_CERT and SSL_VERIFY_CLIENT_ONCE must be
used together with SSL_VERIFY_PEER.
See OpenSSL man page for SSL_CTX_set_verify for more information.
lib/IO/Socket/SSL.pod view on Meta::CPAN
alternative forms of verification, like a certificate fingerprint or do a manual
verification later by calling B<verify_hostname> yourself.
=item SSL_verifycn_publicsuffix
This option is used to specify the behavior when checking wildcards certificates
for public suffixes, e.g. no wildcard certificates for *.com or *.co.uk should
be accepted, while *.example.com or *.example.co.uk is ok.
If not specified it will simply use the builtin default of
L<IO::Socket::SSL::PublicSuffix>, you can create another object with
from_string or from_file of this module.
To disable verification of public suffix set this option to C<''>.
=item SSL_verifycn_name
Set the name which is used in verification of hostname. If SSL_verifycn_scheme
is set and no SSL_verifycn_name is given it will try to use SSL_hostname or
PeerHost and PeerAddr settings and fail if no name can be determined.
If SSL_verifycn_scheme is not set it will use a default scheme and warn if it
cannot determine a hostname, but it will not fail.
Using PeerHost or PeerAddr works only if you create the connection directly
with C<< IO::Socket::SSL->new >>, if an IO::Socket::INET object is upgraded
with B<start_SSL> the name has to be given in B<SSL_verifycn_name> or
B<SSL_hostname>.
=item SSL_check_crl
If you want to verify that the peer certificate has not been revoked
by the signing authority, set this value to true. OpenSSL will search
for the CRL in your SSL_ca_path, or use the file specified by
SSL_crl_file. See the Net::SSLeay documentation for more details.
Note that this functionality appears to be broken with OpenSSL <
lib/IO/Socket/SSL.pod view on Meta::CPAN
response and uses it to check if the certificate(s) of the connection got
revoked.
=item SSL_ocsp_cache
With this option a cache can be given for caching OCSP responses, which could
be shared between different SSL contexts. If not given a cache specific to the
SSL context only will be used.
You can either create a new cache with
C<< IO::Socket::SSL::OCSP_Cache->new([size]) >> or implement your own cache,
which needs to have methods C<put($key,\%entry)> and C<get($key)> (returning
C<\%entry>) where entry is the hash representation of the OCSP response with
fields like C<nextUpdate>. The default implementation of the cache will consider
responses valid as long as C<nextUpdate> is less then the current time.
=item SSL_psk
PSK to use instead of certificate. Requires the peer to use the same PSK.
On the client side the identity and psk need to be provided as array-ref with
lib/IO/Socket/SSL.pod view on Meta::CPAN
is implicit, but with TLS 1.2 and lower explicitly add PSK to C<SSL_cipher_list>
since it is not enabled by default.
Note that the given psk is expected to be binary and not hexadecimal as some
other tools do. To convert hex to binary use C<pack("H*",hexstring)>.
Also note that the error messages one gets if either identity or psk don't match
the configuration in the peer can be useless ("handshake failure") or misleading
("bad mac").
PSK support needs respective API functionality in Net::SSLeay, which was
only fully included in 1.94. C<< IO::Socket::SSL->can_psk() >> returns undef if
functionality is not available and a hash-ref with details otherwise: key
C<client> in the hash signals support for using PSK in a SSL client (available
since Net::SSLeay 1.82) while key server for support of PSK in SSL server (since
Net::SSLeay 1.94).
=item SSL_reuse_ctx
If you have already set the above options for a previous instance of
IO::Socket::SSL, then you can reuse the SSL context of that instance by passing
it as the value for the SSL_reuse_ctx parameter. You may also create a
new instance of the IO::Socket::SSL::SSL_Context class, using any context
options that you desire without specifying connection options, and pass that
here instead.
If you use this option, all other context-related options that you pass
in the same call to new() will be ignored unless the context supplied was
invalid. Note that, contrary to versions of IO::Socket::SSL below v0.90, a
global SSL context will not be implicitly used unless you use the
set_default_context() function.
=item SSL_create_ctx_callback
With this callback you can make individual settings to the context after it
got created and the default setup was done.
The callback will be called with the CTX object from Net::SSLeay as the single
argument.
lib/IO/Socket/SSL.pod view on Meta::CPAN
Note that session caching with TLS 1.3 needs at least Net::SSLeay 1.86.
=item SSL_session_cache
Specifies session cache object which should be used instead of creating a new.
Overrules SSL_session_cache_size.
This option is useful if you want to reuse the cache, but not the rest of
the context.
A session cache object can be created using
C<< IO::Socket::SSL::Session_Cache->new( cachesize ) >>.
Use set_default_session_cache() to set a global cache object.
=item SSL_session_key
Specifies a key to use for lookups and inserts into client-side session cache.
Per default ip:port of destination will be used, but sometimes you want to
share the same session over multiple ports on the same server (like with FTPS).
=item SSL_session_id_context
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item SSL_npn_protocols
If used on the server side it specifies list of protocols advertised by SSL
server as an array ref, e.g. ['spdy/2','http1.1'].
On the client side it specifies the protocols offered by the client for NPN
as an array ref.
See also method C<next_proto_negotiated>.
Next Protocol Negotiation (NPN) is available with Net::SSLeay 1.46+ and
openssl-1.0.1+. NPN is unavailable in TLSv1.3 protocol.
To check support you might call C<< IO::Socket::SSL->can_npn() >>.
If you use this option with an unsupported Net::SSLeay/OpenSSL it will
throw an error.
=item SSL_alpn_protocols
If used on the server side it specifies list of protocols supported by the SSL
server as an array ref, e.g. ['http/2.0', 'spdy/3.1','http/1.1'].
On the client side it specifies the protocols advertised by the client for ALPN
as an array ref.
See also method C<alpn_selected>.
Application-Layer Protocol Negotiation (ALPN) is available with Net::SSLeay
1.56+ and openssl-1.0.2+. More details about the extension are in RFC7301. To
check support you might call C<< IO::Socket::SSL->can_alpn() >>. If you use
this option with an unsupported Net::SSLeay/OpenSSL it will throw an error.
Note that some client implementations may encounter problems if both NPN and
ALPN are specified. Since ALPN is intended as a replacement for NPN, try
providing ALPN protocols then fall back to NPN if that fails.
=item SSL_ticket_keycb => [$sub,$data] | $sub
This is a callback used for stateless session reuse (Session Tickets, RFC 5077).
lib/IO/Socket/SSL.pod view on Meta::CPAN
# the given name
for(my $i = 0; $i<@$mykeys; $i++) {
next if $name ne $mykeys->[$i][0];
return ($mykeys->[$i][1],$mykeys->[0][0]);
}
# no matching key found
return;
},\@keys ];
my $srv = IO::Socket::SSL->new(..., SSL_ticket_keycb => $keycb);
=item SSL_on_peer_shutdown CODE
This defines a callback which gets called on receiving SSL shutdown (close
notify) from the peer. This can be used to override the default behavior, see
C<stop_SSL> for more.
=item SSL_mode_release_buffers 1|0
This enables or disables the SSL_MODE_RELEASE_BUFFERS option on the SSL object.
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item B<get_fingerprint_bin([algo,certificate,pubkey])>
This methods returns the binary fingerprint of the given certificate by using
the algorithm C<algo>, default 'sha256'.
If no certificate is given the peer certificate of the connection is used.
If C<pubkey> is true it will not return the fingerprint of the certificate but
instead the fingerprint of the pubkey inside the certificate.
=item B<get_cipher()>
Returns the string form of the cipher that the IO::Socket::SSL object is using.
=item B<get_sslversion()>
Returns the string representation of the SSL version of an established
connection.
=item B<get_sslversion_int()>
Returns the integer representation of the SSL version of an established
connection.
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item commonName (alias cn) - only for Net::SSLeay version >=1.30
The common name, usually the server name for SSL certificates.
=item subjectAltNames - only for Net::SSLeay version >=1.33
Alternative names for the subject, usually different names for the same
server, like example.org, example.com, *.example.com.
It returns a list of (typ,value) with typ GEN_DNS, GEN_IPADD etc (these
constants are exported from IO::Socket::SSL).
See Net::SSLeay::X509_get_subjectAltNames.
=back
=item B<sock_certificate($field)>
This is similar to C<peer_certificate> but will return the sites own
certificate. The same arguments for B<$field> can be used.
If no B<$field> is given the certificate handle from the underlying OpenSSL will
be returned. This handle will only be valid as long as the SSL connection exists
and if used afterwards it might result in strange crashes of the application.
=item B<peer_certificates>
This returns all the certificates send by the peer, e.g. first the peers own
certificate and then the rest of the chain. You might use B<CERT_asHash> from
L<IO::Socket::SSL::Utils> to inspect each of the certificates.
This function depends on a version of Net::SSLeay >= 1.58 .
=item B<get_servername>
This gives the name requested by the client if Server Name Indication
(SNI) was used.
=item B<verify_hostname($hostname,$scheme,$publicsuffix)>
lib/IO/Socket/SSL.pod view on Meta::CPAN
All other arguments for the verification scheme will be ignored in this case.
=back
=item B<next_proto_negotiated()>
This method returns the name of negotiated protocol - e.g. 'http/1.1'. It works
for both client and server side of SSL connection.
NPN support is available with Net::SSLeay 1.46+ and openssl-1.0.1+.
To check support you might call C<< IO::Socket::SSL->can_npn() >>.
=item B<alpn_selected()>
Returns the protocol negotiated via ALPN as a string, e.g. 'http/1.1',
'http/2.0' or 'spdy/3.1'.
ALPN support is available with Net::SSLeay 1.56+ and openssl-1.0.2+.
To check support, use C<< IO::Socket::SSL->can_alpn() >>.
=item B<errstr()>
Returns the last error (in string form) that occurred. If you do not have a
real object to perform this method on, call IO::Socket::SSL::errstr() instead.
For read and write errors on non-blocking sockets, this method may include the
string C<SSL wants a read first!> or C<SSL wants a write first!> meaning that
the other side is expecting to read from or write to the socket and wants to be
satisfied before you get to do anything. But with version 0.98 you are better
comparing the global exported variable $SSL_ERROR against the exported symbols
SSL_WANT_READ and SSL_WANT_WRITE.
=item B<opened()>
lib/IO/Socket/SSL.pod view on Meta::CPAN
IO::Handle is open, but the SSL handshake failed.
=item B<is_SSL()>
This returns undefined if there is no SSL object associated with the socket.
It will return C<rw> if the state of the SSL object has SSL active for both
directions, C<r> if there was a locally initiated SSL shutdown (close notify),
C<w> if a remote SSL shutdown was received and C<> (empty string but defined) if
a bidirectional SSL shutdown was done.
=item B<< IO::Socket::SSL->start_SSL($socket, ... ) >>
This will convert a glob reference or a socket that you provide to an
IO::Socket::SSL object. You may also pass parameters to specify context or
connection options as with a call to new(). If you are using this function on
an accept()ed socket, you must set the parameter "SSL_server" to 1, i.e.
IO::Socket::SSL->start_SSL($socket, SSL_server => 1). If you have a class that
inherits from IO::Socket::SSL and you want the $socket to be blessed into your
own class instead, use MyClass->start_SSL($socket) to achieve the desired
effect.
Note that if start_SSL() fails in SSL negotiation, $socket will remain blessed
in its original class. For non-blocking sockets you better just upgrade the
socket to IO::Socket::SSL and call accept_SSL or connect_SSL and the upgraded
object. To just upgrade the socket set B<SSL_startHandshake> explicitly to 0. If
you call start_SSL w/o this parameter it will revert to blocking behavior for
accept_SSL and connect_SSL.
If given the parameter "Timeout" it will stop if after the timeout no SSL
connection was established. This parameter is only used for blocking sockets, if
it is not given the default Timeout from the underlying IO::Socket will be
used.
=item B<stop_SSL(...)>
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item B<set_msg_callback>
This will add/remove a user defined callback for each message, internally using
openssl SSL_set_msg_callback API. To make sure that the callback is active
before the handshake starts, combine it with C<< SSL_startHandshake => 0 >> in
the preceding setup of the SSL object. To remove callback explicitly call it
with an empty callback function.
Example:
$sock = IO::Socket::SSL->new( .... , SSL_startHandshake => 0);
# set callback
$sock->set_msg_callback(\&cb, $cbarg1, $cbarg2);
$sock->connect_SSL();
sub cb {
my ($sock,
# see SSL_set_msg_callback for the following args
$direction, $ssl_ver, $content_type, $buf, $len, $ssl,
$cbarg1, $cbarg2)
= @_;
lib/IO/Socket/SSL.pod view on Meta::CPAN
=item requests
This will return a hash consisting of C<(url,request)>-tuples, e.g. which
contain the OCSP request string and the URL where it should be sent too. The
usual way to send such a request is as HTTP POST request with a content-type
of C<application/ocsp-request> or as a GET request with the base64 and
url-encoded request is added to the path of the URL.
After you've handled all these requests and added the response with
C<add_response> you should better call this method again to make sure, that no
more requests are outstanding. IO::Socket::SSL will combine multiple OCSP
requests for the same server inside a single request, but some server don't
give a response to all these requests, so that one has to ask again with the
remaining requests.
=item add_response($uri,$response)
This method takes the HTTP body of the response which got received when sending
the OCSP request to C<$uri>. If no response was received or an error occurred
one should either retry or consider C<$response> as empty which will trigger a
soft error.
lib/IO/Socket/SSL.pod view on Meta::CPAN
necessary requests in a blocking way. C<%args> will be given to L<HTTP::Tiny>
so that you can put proxy settings etc here. L<HTTP::Tiny> will be called with
C<verify_SSL> of false, because the OCSP responses have their own signatures so
no extra SSL verification is needed.
If you don't want to use blocking requests you need to roll your own user agent
with C<requests> and C<add_response>.
=back
=item B<< IO::Socket::SSL->new_from_fd($fd, [mode], %sslargs) >>
This will convert a socket identified via a file descriptor into an SSL socket.
Note that the argument list does not include a "MODE" argument; if you supply
one, it will be thoughtfully ignored (for compatibility with IO::Socket::INET).
Instead, a mode of '+<' is assumed, and the file descriptor passed must be able
to handle such I/O because the initial SSL handshake requires bidirectional
communication.
Internally the given $fd will be upgraded to a socket object using the
C<new_from_fd> method of the super class (L<IO::Socket::INET> or similar) and
then C<start_SSL> will be called using the given C<%sslargs>.
If C<$fd> is already an IO::Socket object you should better call C<start_SSL>
directly.
=item B<IO::Socket::SSL::default_ca([ path|dir| SSL_ca_file => ..., SSL_ca_path => ... ])>
Determines or sets the default CA path.
If existing path or dir or a hash is given it will set the default CA path to
this value and never try to detect it automatically.
If C<undef> is given it will forget any stored defaults and continue with
detection of system defaults.
If no arguments are given it will start detection of system defaults, unless it
has already stored user-set or previously detected values.
The detection of system defaults works similar to OpenSSL, e.g. it will check
lib/IO/Socket/SSL.pod view on Meta::CPAN
variable SSL_CERT_FILE or the path OPENSSLDIR/cert.pem (SSLCERTS:cert.pem on
VMS). Contrary to OpenSSL it will check if the SSL_ca_path contains PEM files
with the hash as file name and if the SSL_ca_file looks like PEM.
If no usable system default can be found it will try to load and use
L<Mozilla::CA> and if not available give up detection.
The result of the detection will be saved to speed up future calls.
The function returns the saved default CA as hash with SSL_ca_file and
SSL_ca_path.
=item B<IO::Socket::SSL::set_default_context(...)>
You may use this to make IO::Socket::SSL automatically re-use a given context
(unless specifically overridden in a call to new()).
It accepts one argument, which should be either an IO::Socket::SSL object or an
IO::Socket::SSL::SSL_Context object.
See the SSL_reuse_ctx option of new() for more details.
Note that this sets the default context globally, so use with caution (esp. in
mod_perl scripts).
=item B<IO::Socket::SSL::set_default_session_cache(...)>
You may use this to make IO::Socket::SSL automatically re-use a given session
cache (unless specifically overridden in a call to new()).
It accepts one argument, which should be an IO::Socket::SSL::Session_Cache
object or similar (e.g. something which implements get_session, add_session and
del_session like IO::Socket::SSL::Session_Cache does).
See the SSL_session_cache option of new() for more details.
Note that this sets the default cache globally, so use with caution.
=item B<IO::Socket::SSL::set_defaults(%args)>
With this function one can set defaults for all SSL_* parameter used for
creation of the context, like the SSL_verify* parameter. Any SSL_* parameter can
be given or the following short versions:
=over 8
=item mode - SSL_verify_mode
=item callback - SSL_verify_callback
=item scheme - SSL_verifycn_scheme
=item name - SSL_verifycn_name
=back
=item B<IO::Socket::SSL::set_client_defaults(%args)>
Similar to C<set_defaults>, but only sets the defaults for client mode.
=item B<IO::Socket::SSL::set_server_defaults(%args)>
Similar to C<set_defaults>, but only sets the defaults for server mode.
=item B<IO::Socket::SSL::set_args_filter_hack(\&code|'use_defaults')>
Sometimes one has to use code which uses unwanted or invalid arguments for SSL,
typically disabling SSL verification or setting wrong ciphers or SSL versions.
With this hack it is possible to override these settings and restore sanity.
Example:
IO::Socket::SSL::set_args_filter_hack( sub {
my ($is_server,$args) = @_;
if ( ! $is_server ) {
# client settings - enable verification with default CA
# and fallback hostname verification etc
delete @{$args}{qw(
SSL_verify_mode
SSL_ca_file
SSL_ca_path
SSL_verifycn_scheme
SSL_version
lib/IO/Socket/SSL.pod view on Meta::CPAN
}
});
With the short setting C<set_args_filter_hack('use_defaults')> it will prefer
the default settings in all cases. These default settings can be modified with
C<set_defaults>, C<set_client_defaults> and C<set_server_defaults>.
=back
The following methods are unsupported (not to mention futile!) and
IO::Socket::SSL will emit a large CROAK() if you are silly enough to use them:
=over 4
=item truncate
=item stat
=item ungetc
=item setbuf
=item setvbuf
=item fdopen
=item send/recv
Note that send() and recv() cannot be reliably trapped by a tied filehandle
(such as that used by IO::Socket::SSL) and so may send unencrypted data over the
socket. Object-oriented calls to these functions will fail, telling you to use
the print/printf/syswrite and read/sysread families instead.
=back
=head1 ACCESS TO INTERNALS
C<IO::Socket::SSL> uses internally C<Net::SSLeay> which provides a lower level
API to OpenSSL and provides functions which work directly with OpenSSL SSL and
CTX handles. Sometimes it might be necessary to get direct access to these
handles from C<IO::Socket::SSL> in order to apply functionality available only
with C<Net::SSLeay>.
For this C<_get_ssl_object> can be used on the C<IO::Socket::SSL> object to get
access to the OpenSSL SSL handle and C<_get_ctx_object> can be used on
C<IO::Socket::SSL> and C<IO::Socket::SSL_Context> objects to access the OpenSSL
CTX handle. Use very carefully since OpenSSL memory/reference management must be
done manually with C<Net::SSLeay>.
=head1 DEPRECATIONS
The following functions are deprecated and are only retained for compatibility:
=over 2
=item context_init()
use the SSL_reuse_ctx option if you want to re-use a context
=item socketToSSL() and socket_to_SSL()
use IO::Socket::SSL->start_SSL() instead
=item kill_socket()
use close() instead
=item get_peer_certificate()
use the peer_certificate() function instead.
Used to return X509_Certificate with methods subject_name and issuer_name.
Now simply returns $self which has these methods (although deprecated).
lib/IO/Socket/SSL.pod view on Meta::CPAN
=back
=head1 EXAMPLES
See the 'example' directory, the tests in 't' and also the tools in 'util'.
=head1 BUGS
If you use IO::Socket::SSL together with threads you should load it (e.g. use or
require) inside the main thread before creating any other threads which use it.
This way it is much faster because it will be initialized only once. Also there
are reports that it might crash the other way.
Creating an IO::Socket::SSL object in one thread and closing it in another
thread will not work.
IO::Socket::SSL does not work together with Storable::fd_retrieve/fd_store.
See BUGS file for more information and how to work around the problem.
If you have a server and it looks like you have a memory leak you might
check the size of your session cache. Default for Net::SSLeay seems to be
20480, see the example for SSL_create_ctx_callback for how to limit it.
TLS 1.3 support regarding session reuse is incomplete.
=head1 SEE ALSO
IO::Socket::INET, IO::Socket::INET6, IO::Socket::IP, Net::SSLeay.
=head1 THANKS
Many thanks to all who added patches or reported bugs or helped IO::Socket::SSL
another way. Please keep reporting bugs and help with patches, even if they just
fix the documentation.
Special thanks to the team of Net::SSLeay for the good cooperation.
=head1 AUTHORS
Steffen Ullrich, <sullr at cpan.org> is the current maintainer.
Peter Behroozi, <behrooz at fas.harvard.edu> (Note the lack of an "i" at the end of "behrooz")
Marko Asplund, <marko.asplund at kronodoc.fi>, was the original author of IO::Socket::SSL.
Patches incorporated from various people, see file Changes.
=head1 COPYRIGHT
The original versions of this module are Copyright (C) 1999-2002 Marko Asplund.
The rewrite of this module is Copyright (C) 2002-2005 Peter Behroozi.
lib/IO/Socket/SSL/Intercept.pm view on Meta::CPAN
package IO::Socket::SSL::Intercept;
use strict;
use warnings;
use Carp 'croak';
use IO::Socket::SSL::Utils;
use Net::SSLeay;
our $VERSION = '2.056';
sub new {
my ($class,%args) = @_;
my $cacert = delete $args{proxy_cert};
if ( ! $cacert ) {
lib/IO/Socket/SSL/Intercept.pm view on Meta::CPAN
}
return $self;
}
1;
__END__
=head1 NAME
IO::Socket::SSL::Intercept -- SSL interception (man in the middle)
=head1 SYNOPSIS
use IO::Socket::SSL::Intercept;
# create interceptor with proxy certificates
my $mitm = IO::Socket::SSL::Intercept->new(
proxy_cert_file => 'proxy_cert.pem',
proxy_key_file => 'proxy_key.pem',
...
);
my $listen = IO::Socket::INET->new( LocalAddr => .., Listen => .. );
while (1) {
# TCP accept new client
my $client = $listen->accept or next;
# SSL connect to server
my $server = IO::Socket::SSL->new(
PeerAddr => ..,
SSL_verify_mode => ...,
...
) or die "ssl connect failed: $!,$SSL_ERROR";
# clone server certificate
my ($cert,$key) = $mitm->clone_cert( $server->peer_certificate );
# and upgrade client side to SSL with cloned certificate
IO::Socket::SSL->start_SSL($client,
SSL_server => 1,
SSL_cert => $cert,
SSL_key => $key
) or die "upgrade failed: $SSL_ERROR";
# now transfer data between $client and $server and analyze
# the unencrypted data
...
}
lib/IO/Socket/SSL/Intercept.pm view on Meta::CPAN
=item *
Accept the TCP connection from the client, e.g. don't do any SSL handshakes with
the client yet.
=item *
Establish the SSL connection to the server and verify the servers certificate as
usually. Then create a new certificate based on the original servers
certificate, but signed by your proxy CA.
This is the step where IO::Socket::SSL::Intercept helps.
=item *
Upgrade the TCP connection to the client to SSL using the cloned certificate
from the server. If the client trusts your proxy CA it will accept the upgrade
to SSL.
=item *
Transfer data between client and server. While the connections to client and
server are both encrypted with SSL you will read/write the unencrypted data in
your proxy application.
=back
=head1 METHODS
IO::Socket::SSL::Intercept helps creating the cloned certificate with the
following methods:
=over 4
=item B<< $mitm = IO::Socket::SSL::Intercept->new(%args) >>
This creates a new interceptor object. C<%args> should be
=over 8
=item proxy_cert X509 | proxy_cert_file filename
This is the proxy certificate.
It can be either given by an X509 object from L<Net::SSLeay>s internal
representation, or using a file in PEM format.
lib/IO/Socket/SSL/Intercept.pm view on Meta::CPAN
created certificates).
=item B<< $string = $mitm->serialize >>
This creates a serialized version of the object (e.g. a string) which can then
be used to persistently store created certificates over restarts of the
application. The cache will only be serialized if it is a HASH.
To work together with L<Storable> the C<STORABLE_freeze> function is defined to
call C<serialize>.
=item B<< $mitm = IO::Socket::SSL::Intercept->unserialize($string) >>
This restores an Intercept object from a serialized string.
To work together with L<Storable> the C<STORABLE_thaw> function is defined to
call C<unserialize>.
=back
=head1 AUTHOR
Steffen Ullrich
lib/IO/Socket/SSL/PublicSuffix.pm view on Meta::CPAN
use strict;
use warnings;
package IO::Socket::SSL::PublicSuffix;
use Carp;
# for updates
use constant URL => 'http://publicsuffix.org/list/effective_tld_names.dat';
=head1 NAME
IO::Socket::SSL::PublicSuffix - provide access to Mozilla's list of effective TLD names
=head1 SYNOPSIS
# use builtin default
use IO::Socket::SSL::PublicSuffix;
$ps = IO::Socket::SSL::PublicSuffix->default;
# load from string
$ps = IO::Socket::SSL::PublicSuffix->from_string("*.uk\n*");
# load from file or file handle
$ps = IO::Socket::SSL::PublicSuffix->from_file($filename);
$ps = IO::Socket::SSL::PublicSuffix->from_file(\*STDIN);
# --- string in -> string out
# $rest -> whatever.host
# $tld -> co.uk
my ($rest,$tld) = $ps->public_suffix('whatever.host.co.uk');
my $tld = $ps->public_suffix('whatever.host.co.uk');
# $root_domain -> host.co.uk
my $root_domain = $ps->public_suffix('whatever.host.co.uk', 1);
# --- array in -> array out
# $rest -> [qw(whatever host)]
# $tld -> [qw(co uk)]
my ($rest,$tld) = $ps->public_suffix([qw(whatever host co uk)]);
----
# To update this file with the current list:
perl -MIO::Socket::SSL::PublicSuffix -e 'IO::Socket::SSL::PublicSuffix::update_self_from_url()'
=head1 DESCRIPTION
This module uses the list of effective top level domain names from the mozilla
project to determine the public top level domain for a given hostname.
=head2 Method
lib/IO/Socket/SSL/PublicSuffix.pm view on Meta::CPAN
=head1 SEE ALSO
Domain::PublicSuffix, Mozilla::PublicSuffix
=head1 BUGS
Q: Why yet another module, we already have L<Domain::PublicSuffix> and
L<Mozilla::PublicSuffix>.
A: Because the public suffix data change more often than these modules do,
IO::Socket::SSL needs this list and it is more easy this way to keep it
up-to-date.
=head1 AUTHOR
Steffen Ullrich
=cut
lib/IO/Socket/SSL/Utils.pm view on Meta::CPAN
package IO::Socket::SSL::Utils;
use strict;
use warnings;
use Carp 'croak';
use Net::SSLeay;
# old versions of Exporter do not export 'import' yet
require Exporter;
*import = \&Exporter::import;
our $VERSION = '2.015';
lib/IO/Socket/SSL/Utils.pm view on Meta::CPAN
# not_after default to now+365 days
Net::SSLeay::ASN1_TIME_set(
Net::SSLeay::X509_get_notAfter($cert),
delete $args{not_after} || time() + 365*86400
);
# set subject
my $subj_e = Net::SSLeay::X509_get_subject_name($cert);
my $subj = delete $args{subject} || {
organizationName => 'IO::Socket::SSL',
commonName => 'IO::Socket::SSL Test'
};
while ( my ($k,$v) = each %$subj ) {
# Not everything we get is nice - try with MBSTRING_UTF8 first and if it
# fails try V_ASN1_T61STRING and finally V_ASN1_OCTET_STRING
for (ref($v) ? @$v : ($v)) {
Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,0x1000,$_,-1,0)
or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,20,$_,-1,0)
or Net::SSLeay::X509_NAME_add_entry_by_txt($subj_e,$k,4,$_,-1,0)
or croak("failed to add entry for $k - ".
lib/IO/Socket/SSL/Utils.pm view on Meta::CPAN
}
}
1;
__END__
=head1 NAME
IO::Socket::SSL::Utils -- loading, storing, creating certificates and keys
=head1 SYNOPSIS
use IO::Socket::SSL::Utils;
$cert = PEM_file2cert('cert.pem'); # load certificate from file
my $hash = CERT_asHash($cert); # get details from certificate
PEM_cert2file($cert,'cert.pem'); # write certificate to file
CERT_free($cert); # free memory within OpenSSL
@certs = PEM_file2certs('chain.pem'); # load multiple certificates from file
PEM_certs2file('chain.pem', @certs); # write multiple certificates to file
CERT_free(@certs); # free memory for all within OpenSSL
lib/IO/Socket/SSL/Utils.pm view on Meta::CPAN
Creates a certificate based on the given hash.
If the issuer is not specified the certificate will be self-signed.
The following keys can be given:
=over 8
=item subject
Hash with the parts of the subject, e.g. commonName, countryName, ... as
described in C<CERT_asHash>.
Default points to IO::Socket::SSL.
=item not_before
A time_t value when the certificate starts to be valid. Defaults to current
time.
=item not_after
A time_t value when the certificate ends to be valid. Defaults to current
time plus one 365 days.
t/01loadmodule.t view on Meta::CPAN
use strict;
use warnings;
no warnings 'once';
use Test::More;
plan tests => 3;
ok( eval { require IO::Socket::SSL },"loaded");
diag( sprintf( "openssl version compiled=0x%0x linked=0x%0x -- %s",
Net::SSLeay::OPENSSL_VERSION_NUMBER(),
Net::SSLeay::SSLeay(),
Net::SSLeay::SSLeay_version(0)));
diag( sprintf( "Net::SSLeay version=%s", $Net::SSLeay::VERSION));
diag( sprintf( "parent %s version=%s", $_, $_->VERSION))
for (@IO::Socket::SSL::ISA);
IO::Socket::SSL->import(':debug1');
is( $IO::Socket::SSL::DEBUG,1, "IO::Socket::SSL::DEBUG 1");
is( $Net::SSLeay::trace,1, "Net::SSLeay::trace 1");
t/acceptSSL-timeout.t view on Meta::CPAN
use strict;
use warnings;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
$|=1;
print "1..15\n";
# first use SSL client
{
my ($server,$saddr) = create_listen_socket();
ok(1, "listening \@$saddr" );
my $srv = fork_sub( 'server',$server );
t/acceptSSL-timeout.t view on Meta::CPAN
fd_grep_ok( 'Connected', $cl );
fd_grep_ok( 'SSL Handshake FAILED', $srv );
}
sub server {
my $server = shift;
print "Waiting\n";
my $client = $server->accept || die "accept failed: $!";
print "Connect from ".$client->peerhost.':'.$client->peerport."\n";
if ( IO::Socket::SSL->start_SSL( $client,
SSL_server => 1,
Timeout => 5,
SSL_cert_file => 't/certs/server-cert.pem',
SSL_key_file => 't/certs/server-key.pem',
)) {
print "SSL Handshake OK\n";
print $client "Hi!\n";
} else {
print "SSL Handshake FAILED - $!\n"
}
t/acceptSSL-timeout.t view on Meta::CPAN
sub client_no_ssl {
my $saddr = shift;
my $c = IO::Socket::INET->new( $saddr ) || die "connect failed: $!";
print "Connected\n";
while ( sysread( $c,my $buf,8000 )) {}
}
sub client_ssl {
my $saddr = shift;
my $c = IO::Socket::SSL->new(
PeerAddr => $saddr,
Domain => AF_INET,
SSL_verify_mode => 0
) || die "connect failed: $!|$SSL_ERROR";
print "Connected\n";
while ( sysread( $c,my $buf,8000 )) { print $buf }
}
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/alpn.t'
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
# check if we have ALPN available
# if it is available
if ( ! IO::Socket::SSL->can_alpn ) {
print "1..0 # Skipped: ALPN not available in Net::SSLeay\n";
exit;
}
print "1..5\n";
# first create simple ssl-server
my $ID = 'server';
my $addr = '127.0.0.1';
my $server = IO::Socket::SSL->new(
LocalAddr => $addr,
Listen => 2,
SSL_cert_file => 't/certs/server-cert.pem',
SSL_key_file => 't/certs/server-key.pem',
SSL_alpn_protocols => [qw(one two)],
) || do {
ok(0,"server creation failed: $!");
exit;
};
ok(1,"Server Initialization at $addr");
print "# server at $addr\n";
my $pid = fork();
if ( !defined $pid ) {
die $!; # fork failed
} elsif ( !$pid ) { ###### Client
$ID = 'client';
close($server);
my $to_server = IO::Socket::SSL->new(
PeerAddr => $addr,
Domain => AF_INET,
SSL_verify_mode => 0,
SSL_alpn_protocols => [qw(two three)],
) or do {
ok(0,"connect failed: ".IO::Socket::SSL->errstr());
exit;
};
ok(1,"client connected" );
my $proto = $to_server->alpn_selected;
ok($proto eq "two","negotiated $proto");
} else { ###### Server
my $to_client = $server->accept or do {
ok(0,"accept failed: ".$server->errstr());
kill(9,$pid);
exit;
t/auto_verify_hostname.t view on Meta::CPAN
#!perl
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
use Test::More;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
plan tests => 1 + 7 + 4 + 7*2 + 4;
my @tests = qw(
example.com www FAIL
server.local ldap OK
server.local www FAIL
bla.server.local www OK
www7.other.local www OK
www7.other.local ldap FAIL
bla.server.local ldap OK
);
my $server = IO::Socket::SSL->new(
LocalAddr => '127.0.0.1',
LocalPort => 0,
Listen => 2,
ReuseAddr => 1,
SSL_server => 1,
SSL_cert_file => "t/certs/server-wildcard.pem",
SSL_key_file => "t/certs/server-wildcard.pem",
);
warn "\$!=$!, \$\@=$@, S\$SSL_ERROR=$SSL_ERROR" if ! $server;
ok( $server, "Server Initialization");
t/auto_verify_hostname.t view on Meta::CPAN
defined( my $pid = fork() ) || die $!;
if ( $pid == 0 ) {
while (1) {
my $csock = $server->accept || next;
print $csock "hallo\n";
}
}
close($server);
IO::Socket::SSL::default_ca('t/certs/test-ca.pem');
for( my $i=0;$i<@tests;$i+=3 ) {
my ($name,$scheme,$result) = @tests[$i,$i+1,$i+2];
my $cl = IO::Socket::SSL->new(
PeerAddr => $saddr,
Domain => AF_INET,
SSL_verify_mode => 1,
SSL_verifycn_scheme => $scheme,
SSL_verifycn_name => $name,
);
if ( $result eq 'FAIL' ) {
ok( !$cl, "connection to $name/$scheme failed" );
} else {
ok( $cl, "connection to $name/$scheme succeeded" );
}
$cl || next;
is( <$cl>, "hallo\n", "received hallo" );
}
for( my $i=0;$i<@tests;$i+=3 ) {
my ($name,$scheme,$result) = @tests[$i,$i+1,$i+2];
my $cl = IO::Socket::INET->new($saddr);
ok( $cl, "tcp connect" );
$cl = IO::Socket::SSL->start_SSL( $cl,
SSL_verify_mode => 1,
SSL_verifycn_scheme => $scheme,
SSL_verifycn_name => $name,
);
if ( $result eq 'FAIL' ) {
ok( !$cl, "ssl upgrade of connection to $name/$scheme failed" );
} else {
ok( $cl, "ssl upgrade of connection to $name/$scheme succeeded" );
}
$cl || next;
t/cert_formats.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use IO::Socket::SSL;
use File::Temp 'tempfile';
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
my $srv = IO::Socket::INET->new(
LocalAddr => '127.0.0.1',
Listen => 10,
);
plan skip_all => "server creation failed: $!" if ! $srv;
my $saddr = $srv->sockhost.':'.$srv->sockport;
t/cert_formats.t view on Meta::CPAN
SSL_passwd_cb => sub { "bluebell" },
},
);
plan tests => @tests/2;
while (my ($name,$sslargs) = splice(@tests,0,2)) {
defined(my $pid = fork()) or die "fork failed: $!";
if ($pid == 0) {
# child = server
my $cl = $srv->accept or die "accept $!";
if (!IO::Socket::SSL->start_SSL($cl,
SSL_server => 1,
Timeout => 10,
%$sslargs
)) {
diag("start_SSL failed: $SSL_ERROR");
}
exit(0);
} else {
# parent = client
my $cl = IO::Socket::INET->new($saddr) or die "connect: $!";
if (!IO::Socket::SSL->start_SSL($cl,
SSL_verify_mode => 0
)) {
fail("[$name] ssl connect failed: $SSL_ERROR");
} else {
pass("[$name] ssl connect success");
}
wait;
}
}
t/cert_no_file.t view on Meta::CPAN
# create a server with SSL_cert_file and get the X509 from it using
# Net::SSLeay::get_certificate.
# Test should also test if SSL_cert is an array of X509*
# and if SSL_key is an EVP_PKEY* but with the current function in
# Net::SSLeay I don't see a way to test it
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
use Test::More tests => 9;
Test::More->builder->use_numbers(0);
Test::More->builder->no_ending(1);
my $ID = 'server';
my %server_args = (
LocalAddr => '127.0.0.1',
t/cert_no_file.t view on Meta::CPAN
$spec = 'Using SSL_cert';
} elsif ( $test == 3 ) {
# 3rd test: empty SSL_cert, so that default
# SSL_cert_file gets not used
# server creation should fail
$spec = 'Empty SSL_cert';
$args{SSL_cert} = undef;
}
# create server
my $server = IO::Socket::SSL->new( %args ) || do {
fail( "$spec: $!" );
next;
};
my $saddr = $server->sockhost.':'.$server->sockport;
pass("Server Initialization $spec");
push @server,$server;
# then connect to it from a child
defined( my $pid = fork() ) || die $!;
if ( $pid == 0 ) {
close($server);
$ID = 'client';
my $to_server = IO::Socket::SSL->new(
PeerAddr => $saddr,
Domain => AF_INET,
SSL_verify_mode => 0x00,
);
if ( $test == 3 ) {
ok( !$to_server, "$spec: connect succeeded" );
exit;
} elsif ( ! $to_server ) {
fail("connect failed: $!");
exit;
t/certs/create-certs.pl view on Meta::CPAN
use strict;
use warnings;
use IO::Socket::SSL::Utils;
use Net::SSLeay;
my $dir = "./";
my $now = time();
my $later = $now + 10*365*86400;
Net::SSLeay::SSLeay_add_ssl_algorithms();
my $sha256 = Net::SSLeay::EVP_get_digestbyname('sha256') or die;
my $printfp = sub {
my ($w,$cert) = @_;
print $w.' sha256$'.unpack('H*',Net::SSLeay::X509_digest($cert, $sha256))."\n"
};
my %time_valid = (not_before => $now, not_after => $later);
my @ca = CERT_create(
CA => 1,
subject => { CN => 'IO::Socket::SSL Demo CA' },
%time_valid,
);
save('test-ca.pem',PEM_cert2string($ca[0]));
my @server = CERT_create(
CA => 0,
subject => { CN => 'server.local' },
subjectAltNames => [ [ DNS => 'server.local' ], [ IP => '127.0.0.1' ] ],
purpose => 'server',
issuer => \@ca,
t/certs/create-certs.pl view on Meta::CPAN
[ DNS => 'xn--lwe-sna.idntest.local' ]
],
%time_valid,
);
save('server-wildcard.pem',PEM_cert2string($swc[0]),PEM_key2string($swc[1]));
my @subca = CERT_create(
CA => 1,
issuer => \@ca,
subject => { CN => 'IO::Socket::SSL Demo Sub CA' },
%time_valid,
);
save('test-subca.pem',PEM_cert2string($subca[0]));
@server = CERT_create(
CA => 0,
subject => { CN => 'server.local' },
subjectAltNames => [ [ DNS => 'server.local' ], [ IP => '127.0.0.1' ] ],
purpose => 'server',
issuer => \@subca,
%time_valid,
);
save('sub-server.pem',PEM_cert2string($server[0]).PEM_key2string($server[1]));
my @cap = CERT_create(
CA => 1,
subject => { CN => 'IO::Socket::SSL::Intercept' },
%time_valid,
);
save('proxyca.pem',PEM_cert2string($cap[0]).PEM_key2string($cap[1]));
sub save {
my $file = shift;
open(my $fd,'>',$dir.$file) or die $!;
print $fd @_;
}
t/compatibility.t view on Meta::CPAN
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/compatibility.t'
use strict;
use warnings;
use IO::Socket::SSL;
use Socket;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
use Test::More tests => 9;
Test::More->builder->use_numbers(0);
Test::More->builder->no_ending(1);
$SIG{'CHLD'} = "IGNORE";
IO::Socket::SSL::context_init(SSL_verify_mode => 0x01);
my $server = IO::Socket::INET->new(
LocalAddr => '127.0.0.1',
LocalPort => 0,
Listen => 1,
) or do {
plan skip_all => "Bail out!".
"Setup of test IO::Socket::INET client and server failed. All the rest of".
"the tests in this suite will fail also unless you change the values in".
"ssl_settings.req in the t/ directory.";
};
pass("server create");
{
package MyClass;
use IO::Socket::SSL;
our @ISA = "IO::Socket::SSL";
}
my $saddr = $server->sockhost.':'.$server->sockport;
unless (fork) {
close $server;
my $client = IO::Socket::INET->new($saddr);
ok( MyClass->start_SSL($client, SSL_verify_mode => 0), "ssl upgrade");
is( ref( $client ), "MyClass", "class MyClass");
ok( $client->issuer_name, "issuer_name");
ok( $client->subject_name, "subject_name");
ok( $client->opened, "opened");
print $client "Ok to close\n";
close $client;
exit(0);
}
my $contact = $server->accept;
my $socket_to_ssl = IO::Socket::SSL::socketToSSL($contact, {
SSL_server => 1,
SSL_verify_mode => 0,
SSL_cert_file => 't/certs/server-cert.pem',
SSL_key_file => 't/certs/server-key.pem',
});
ok( $socket_to_ssl, "socketToSSL");
<$contact>;
close $contact;
close $server;
bless $contact, "MyClass";
ok( !IO::Socket::SSL::socket_to_SSL($contact, SSL_server => 1), "socket_to_SSL");
is( ref($contact), "MyClass", "upgrade is MyClass");
t/connectSSL-timeout.t view on Meta::CPAN
use strict;
use warnings;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
$|=1;
print "1..16\n";
{
# first use SSL client
my ($server,$saddr) = create_listen_socket();
ok( 1, "listening \@$saddr" );
t/connectSSL-timeout.t view on Meta::CPAN
fd_grep_ok( 'Client SSL Handshake FAILED', $cl );
}
sub server {
my ($behavior,$server) = @_;
print "Waiting\n";
my $client = $server->accept || die "accept failed: $!";
print "Connect from ".$client->peerhost.':'.$client->peerport."\n";
if ( $behavior eq 'ssl' ) {
if ( IO::Socket::SSL->start_SSL( $client,
SSL_server => 1,
Timeout => 30,
SSL_cert_file => 't/certs/server-cert.pem',
SSL_key_file => 't/certs/server-key.pem',
)) {
print "Server SSL Handshake OK\n";
print $client "Hi!\n";
}
} else {
while ( sysread( $client, my $buf,8000 )) {}
}
}
sub client {
my $saddr = shift;
my $c = IO::Socket::INET->new( $saddr ) || die "connect failed: $!";
print "Connected\n";
if ( IO::Socket::SSL->start_SSL( $c,
Timeout => 5,
SSL_ca_file => 't/certs/test-ca.pem',
)) {
print "Client SSL Handshake OK\n";
print <$c>
} else {
print "Client SSL Handshake FAILED - $SSL_ERROR\n";
}
}
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/core.t'
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
use Errno qw( EWOULDBLOCK EAGAIN );
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
use Test::More;
Test::More->builder->use_numbers(0);
Test::More->builder->no_ending(1);
my $CAN_NONBLOCK = eval "use 5.006; use IO::Select; 1";
my $CAN_PEEK = &Net::SSLeay::OPENSSL_VERSION_NUMBER >= 0x0090601f;
for(qw(TLSv1_2 TLSv1_1 TLSv1)) {
my $method = sprintf("Net::SSLeay::CTX_%s_new",lc($_));
next if ! defined &$method;
$tls_version = $_;
last;
}
die "no TLS support" if ! $tls_version;
my $error_trapped = 0;
my $localip = '127.0.0.1';
my $server = IO::Socket::SSL->new(
LocalAddr => $localip,
LocalPort => 0,
Listen => 2,
Timeout => 30,
ReuseAddr => 1,
SSL_verify_mode => 0x00,
SSL_ca_file => "t/certs/test-ca.pem",
SSL_version => $tls_version,
SSL_error_trap => sub {
my $self = shift;
close $server;
my $client = IO::Socket::INET->new(
PeerAddr => $saddr,
LocalAddr => $localip,
);
print $client "Test\n";
like( <$client>, qr/This server is SSL only/, "Client non-SSL connection");
close $client;
$client = IO::Socket::SSL->new(
PeerAddr => $saddr,
LocalAddr => $localip,
Domain => AF_INET,
SSL_verify_mode => 0x01,
SSL_ca_file => "t/certs/test-ca.pem",
SSL_use_cert => 1,
SSL_cert_file => "t/certs/client-cert.pem",
SSL_key_file => "t/certs/client-key.enc",
SSL_passwd_cb => sub { return "opossum" },
SSL_verify_callback => \&verify_sub,
);
sub verify_sub {
my ($ok, $ctx_store, $cert, $error) = @_;
$ok && $ctx_store && $cert && !$error or do {
fail("client failure in verify_sub");
exit;
};
like( $cert, qr/IO::Socket::SSL Demo CA/, "Client Verify-sub Check");
return 1;
}
$client || (print("not ok #client failure\n") && exit);
ok( $client, "Client Initialization");
$client->fileno() || print "not ";
ok( $client->fileno(), "Client Fileno Check");
ok( !<$client>, "Client Finished Reading Check");
$client->close(SSL_no_shutdown => 1);
my $client_2 = IO::Socket::INET->new(
PeerAddr => $saddr,
LocalAddr => $localip
);
ok( $client_2, "Second Client Initialization");
$client_2 = IO::Socket::SSL->new_from_fd($client_2->fileno, '+<>',
SSL_reuse_ctx => $client);
ok( $client_2, "Client Init from Fileno Check");
$buffer = <$client_2>;
is( $buffer, "Boojums\n", "Client (fileno) Readline Check");
$client_2->close(SSL_ctx_free => 1);
if ($CAN_NONBLOCK) {
my $client_3 = IO::Socket::SSL->new(
PeerAddr => $saddr,
LocalAddr => $localip,
Domain => AF_INET,
SSL_verify_mode => 0x01,
SSL_ca_file => "t/certs/test-ca.pem",
SSL_use_cert => 1,
SSL_cert_file => "t/certs/client-cert.pem",
SSL_key_file => "t/certs/client-key.enc",
SSL_passwd_cb => sub { return "opossum" },
Blocking => 0,
);
ok( $client_3, "Client Nonblocking Check 1");
close $client_3;
my $client_4 = IO::Socket::SSL->new(
PeerAddr => $saddr,
LocalAddr => $localip,
Domain => AF_INET,
SSL_reuse_ctx => $client_3,
Blocking => 0
);
ok( $client_4, "Client Nonblocking Check 2");
$client_3->close(SSL_ctx_free => 1);
}
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/dhe.t'
# This tests the use of Diffie Hellman Key Exchange (DHE)
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
$|=1;
print "1..3\n";
# first create simple ssl-server
my $ID = 'server';
my $addr = '127.0.0.1';
my $server = IO::Socket::SSL->new(
LocalAddr => $addr,
Listen => 2,
ReuseAddr => 1,
SSL_cert_file => "t/certs/server-cert.pem",
SSL_key_file => "t/certs/server-key.pem",
SSL_cipher_list => 'DH:!aNULL', # allow only DH ciphers
) || do {
notok($!);
exit
};
$addr.= ':'.(sockaddr_in( getsockname( $server )))[0];
my $pid = fork();
if ( !defined $pid ) {
die $!; # fork failed
} elsif ( !$pid ) { ###### Client
$ID = 'client';
close($server);
my $to_server = IO::Socket::SSL->new(
PeerAddr => $addr,
Domain => AF_INET,
SSL_verify_mode => 0 ) || do {
notok( "connect failed: $SSL_ERROR" );
exit
};
ok( "client connected" );
} else { ###### Server
#!perl
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl t/ecdhe.t'
use strict;
use warnings;
use Net::SSLeay;
use Socket;
use IO::Socket::SSL;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib";
my $can_ecdh = IO::Socket::SSL->can_ecdh;
if (! $can_ecdh) {
print "1..0 # Skipped: no support for ecdh with this openssl/Net::SSLeay\n";
exit
}
$|=1;
print "1..4\n";
# first create simple ssl-server
my $ID = 'server';
my $addr = '127.0.0.1';
my $server = IO::Socket::SSL->new(
LocalAddr => $addr,
Listen => 2,
ReuseAddr => 1,
SSL_cert_file => "t/certs/server-cert.pem",
SSL_key_file => "t/certs/server-key.pem",
(defined &Net::SSLeay::CTX_set1_groups_list || defined &Net::SSLeay::CTX_set1_curves_list)
? (SSL_ecdh_curve => 'prime256v1' ) : (),
) || do {
notok($!);
exit
$addr.= ':'.(sockaddr_in( getsockname( $server )))[0];
my $pid = fork();
if ( !defined $pid ) {
die $!; # fork failed
} elsif ( !$pid ) { ###### Client
$ID = 'client';
close($server);
my $to_server = IO::Socket::SSL->new(
PeerAddr => $addr,
Domain => AF_INET,
(defined &Net::SSLeay::CTX_set1_groups_list || defined &Net::SSLeay::CTX_set1_curves_list)
? (SSL_ecdh_curve => 'prime256v1' ) : (),
SSL_verify_mode => 0 ) || do {
notok( "connect failed: $SSL_ERROR" );
exit
};
ok( "client connected" );
t/external/fingerprint.pl view on Meta::CPAN
# to update fingerprints in this file:
# perl -e 'do q[./t/external/fingerprint.pl]; update_fingerprints()'
use strict;
use warnings;
use IO::Socket::SSL;
# --- BEGIN-FINGERPRINTS ----
my $fingerprints= [
{
_ => 'this should give us OCSP stapling - before LetsEncrypt had disabled OCSP support',
fingerprint => 'sha1$pub$39d64bbaea90c6035e25ff990ba4ce565350bac5',
host => 'www.chksum.de',
_disabled_ocsp => {
staple => 1
},
t/external/fingerprint.pl view on Meta::CPAN
my $changed;
for my $fp (@$fingerprints) {
my $cl = IO::Socket::INET->new(
PeerHost => $fp->{host},
PeerPort => $fp->{port} || 443,
Timeout => 10,
);
my $root;
if (!$cl) {
warn "E $fp->{host}:$fp->{port} - TCP connect failed: $!\n";
} elsif (!IO::Socket::SSL->start_SSL($cl,
Timeout => 10,
SSL_ocsp_mode => 0,
SSL_hostname => $fp->{host},
SSL_verify_callback => sub {
my ($cert,$depth) = @_[4,5];
$root ||= $cert;
return 1;
}
)) {
warn "E $fp->{host}:$fp->{port} - SSL handshake failed: $SSL_ERROR\n";