Hello community,
here is the log from the commit of package perl-IO-Socket-SSL for
openSUSE:Factory checked in at 2014-03-27 06:08:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-IO-Socket-SSL (Old)
and /work/SRC/openSUSE:Factory/.perl-IO-Socket-SSL.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-IO-Socket-SSL"
Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-IO-Socket-SSL/perl-IO-Socket-SSL.changes
2014-02-12 17:32:13.000000000 +0100
+++
/work/SRC/openSUSE:Factory/.perl-IO-Socket-SSL.new/perl-IO-Socket-SSL.changes
2014-03-27 06:08:53.000000000 +0100
@@ -1,0 +2,27 @@
+Sat Mar 22 19:05:20 UTC 2014 - [email protected]
+
+- updated to 1.970
+ - fix rt#93987 by making sure sub default_ca does use a local $_ and not a
+ version of an outer scope which might be read-only. Thanks to gshank
+ 1.969 2014/03/13
+ - fix set_defaults to match documentation regarding short names
+ - new function set_args_filter_hack to make it possible to override bad SSL
+ settings from other code at the last moment.
+ - determine default_ca on module load (and not on first use in each thread)
+ - don't try default hostname verification if verify_mode 0
+ - fix hostname verification when reusing context
+ 1.968 2014/03/13
+ - BEHAVIOR CHANGE: removed implicit defaults of certs/server-{cert,key}.pem
+ for SSL_{cert,key}_file and ca/,certs/my-ca.pem for SSL_ca_file.
+ These defaults were depreceated since 1.951 (2013/7/3).
+ - Usable CA verification path on Windows etc:
+ Do not use Net::SSLeay::CTX_set_default_verify_paths any longer to set
+ system/build dependended default verification path, because there was no
+ way to retrieve these default values and check if they contained usable
+ CA. Instead re-implement the same algorithm and export the results with
+ public function default_ca() and make it possible to overwrite it.
+ Also check for usable verification path during build.
+ If no usable path are detected require Mozilla::CA at build and try to
+ use it at runtime.
+
+-------------------------------------------------------------------
Old:
----
IO-Socket-SSL-1.967.tar.gz
New:
----
IO-Socket-SSL-1.970.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-IO-Socket-SSL.spec ++++++
--- /var/tmp/diff_new_pack.rJkw6c/_old 2014-03-27 06:08:54.000000000 +0100
+++ /var/tmp/diff_new_pack.rJkw6c/_new 2014-03-27 06:08:54.000000000 +0100
@@ -17,7 +17,7 @@
Name: perl-IO-Socket-SSL
-Version: 1.967
+Version: 1.970
Release: 0
%define cpan_name IO-Socket-SSL
Summary: Nearly transparent SSL encapsulation for IO::Socket::INET.
++++++ IO-Socket-SSL-1.967.tar.gz -> IO-Socket-SSL-1.970.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/Changes
new/IO-Socket-SSL-1.970/Changes
--- old/IO-Socket-SSL-1.967/Changes 2014-02-06 22:22:04.000000000 +0100
+++ new/IO-Socket-SSL-1.970/Changes 2014-03-19 06:01:41.000000000 +0100
@@ -1,3 +1,26 @@
+1.970 2014/03/19
+- fix rt#93987 by making sure sub default_ca does use a local $_ and not a
+ version of an outer scope which might be read-only. Thanks to gshank
+1.969 2014/03/13
+- fix set_defaults to match documentation regarding short names
+- new function set_args_filter_hack to make it possible to override bad SSL
+ settings from other code at the last moment.
+- determine default_ca on module load (and not on first use in each thread)
+- don't try default hostname verification if verify_mode 0
+- fix hostname verification when reusing context
+1.968 2014/03/13
+- BEHAVIOR CHANGE: removed implicit defaults of certs/server-{cert,key}.pem
+ for SSL_{cert,key}_file and ca/,certs/my-ca.pem for SSL_ca_file.
+ These defaults were depreceated since 1.951 (2013/7/3).
+- Usable CA verification path on Windows etc:
+ Do not use Net::SSLeay::CTX_set_default_verify_paths any longer to set
+ system/build dependended default verification path, because there was no
+ way to retrieve these default values and check if they contained usable
+ CA. Instead re-implement the same algorithm and export the results with
+ public function default_ca() and make it possible to overwrite it.
+ Also check for usable verification path during build.
+ If no usable path are detected require Mozilla::CA at build and try to
+ use it at runtime.
1.967 2014/02/06
- verify the hostname inside a certificate by default with a superset of
common verification schemes instead of not verifying identity at all.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/MANIFEST
new/IO-Socket-SSL-1.970/MANIFEST
--- old/IO-Socket-SSL-1.967/MANIFEST 2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/MANIFEST 2014-03-19 06:02:43.000000000 +0100
@@ -51,6 +51,7 @@
t/mitm.t
t/ecdhe.t
t/verify_fingerprint.t
+t/external/usable_ca.t
util/export_certs.pl
META.yml Module YAML meta-data (added by
MakeMaker)
META.json Module JSON meta-data (added by
MakeMaker)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/META.json
new/IO-Socket-SSL-1.970/META.json
--- old/IO-Socket-SSL-1.967/META.json 2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/META.json 2014-03-19 06:02:43.000000000 +0100
@@ -1,7 +1,7 @@
{
"abstract" : "Nearly transparent SSL encapsulation for IO::Socket::INET.",
"author" : [
- "Steffen Ullrich <sullr.org>, Peter Behroozi, Marko Asplund"
+ "Steffen Ullrich <[email protected]>, Peter Behroozi, Marko Asplund"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter
version 2.120921",
@@ -50,5 +50,5 @@
"url" : "https://github.com/noxxi/p5-io-socket-ssl"
}
},
- "version" : "1.967"
+ "version" : "1.970"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/META.yml
new/IO-Socket-SSL-1.970/META.yml
--- old/IO-Socket-SSL-1.967/META.yml 2014-02-06 23:00:55.000000000 +0100
+++ new/IO-Socket-SSL-1.970/META.yml 2014-03-19 06:02:43.000000000 +0100
@@ -1,7 +1,7 @@
---
abstract: 'Nearly transparent SSL encapsulation for IO::Socket::INET.'
author:
- - 'Steffen Ullrich <sullr.org>, Peter Behroozi, Marko Asplund'
+ - 'Steffen Ullrich <[email protected]>, Peter Behroozi, Marko Asplund'
build_requires:
ExtUtils::MakeMaker: 0
configure_requires:
@@ -25,4 +25,4 @@
homepage: https://github.com/noxxi/p5-io-socket-ssl
license: http://dev.perl.org/licenses/
repository: https://github.com/noxxi/p5-io-socket-ssl
-version: 1.967
+version: 1.970
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/Makefile.PL
new/IO-Socket-SSL-1.970/Makefile.PL
--- old/IO-Socket-SSL-1.967/Makefile.PL 2014-02-05 20:30:16.000000000 +0100
+++ new/IO-Socket-SSL-1.970/Makefile.PL 2014-03-13 07:14:46.000000000 +0100
@@ -76,21 +76,60 @@
EOM
}
+# check if we have usable CA store
+# on windows we might need to install Mozilla::CA
+# settings for default path from openssl crypto/cryptlib.h
+my %usable_ca;
+{
+ my $openssldir = eval {
+ require Net::SSLeay;
+ Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} && $1 || '';
+ };
+ my $dir = $ENV{SSL_CERT_DIR}
+ || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" );
+ if ( opendir(my $dh,$dir)) {
+ FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) ) {
+ open( my $fh,'<',"$dir/$f") or next;
+ while (<$fh>) {
+ m{^-+BEGIN CERTIFICATE-} or next;
+ $usable_ca{SSL_ca_path} = $dir;
+ last FILES;
+ }
+ }
+ }
+ my $file = $ENV{SSL_CERT_FILE}
+ || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" );
+ if ( open(my $fh,'<',$file)) {
+ while (<$fh>) {
+ m{^-+BEGIN CERTIFICATE-} or next;
+ $usable_ca{SSL_ca_file} = $file;
+ last;
+ }
+ }
+}
+
+my $xt = prompt( "Should I do external tests?\n".
+ "These tests will fail if there is no internet connection or if a
firewall\n".
+ "blocks some traffic, does SSL interception or if a HTTP proxy is
needed.\n".
+ "[y/N]", 'n' );
+
# 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 <[email protected]>, Peter Behroozi, Marko
Asplund",
+ 'AUTHOR' => 'Steffen Ullrich <[email protected]>, 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 ):(),
},
'dist' => { COMPRESS => 'gzip', SUFFIX => 'gz', },
+ $xt =~m{^y}i ? ( test => { TESTS => 't/*.t t/external/*.t' }):(),
$ExtUtils::MakeMaker::VERSION >= 6.46 ? (
'META_MERGE' => {
resources => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/lib/IO/Socket/SSL.pm
new/IO-Socket-SSL-1.970/lib/IO/Socket/SSL.pm
--- old/IO-Socket-SSL-1.967/lib/IO/Socket/SSL.pm 2014-02-06
22:58:10.000000000 +0100
+++ new/IO-Socket-SSL-1.970/lib/IO/Socket/SSL.pm 2014-03-19
06:01:55.000000000 +0100
@@ -20,7 +20,7 @@
use Carp;
use strict;
-our $VERSION = '1.967';
+our $VERSION = '1.970';
use constant SSL_VERIFY_NONE => Net::SSLeay::VERIFY_NONE();
use constant SSL_VERIFY_PEER => Net::SSLeay::VERIFY_PEER();
@@ -48,8 +48,8 @@
SSL_check_crl => 0,
SSL_version => 'SSLv23:!SSLv2',
SSL_verify_callback => undef,
- SSL_verifycn_scheme => undef, # don't verify cn
- SSL_verifycn_name => undef, # use from PeerAddr/PeerHost
+ SSL_verifycn_scheme => undef, # fallback cn verification
+ #SSL_verifycn_name => undef, # use from PeerAddr/PeerHost - do not
override in set_filter_args_hack 'use_defaults'
SSL_npn_protocols => undef, # meaning depends whether on server or
client side
SSL_cipher_list =>
'EECDH+AESGCM+ECDSA EECDH+AESGCM EECDH+ECDSA +AES256 EECDH EDH+AESGCM '.
@@ -60,6 +60,10 @@
%DEFAULT_SSL_ARGS,
SSL_verify_mode => SSL_VERIFY_PEER,
+ SSL_ca_file => undef,
+ SSL_ca_path => undef,
+ default_ca(),
+
# older versions of F5 BIG-IP hang when getting SSL client hello >255 bytes
# http://support.f5.com/kb/en-us/solutions/public/13000/000/sol13037.html
# http://guest:[email protected]/Ticket/Display.html?id=2771
@@ -70,7 +74,7 @@
# RC4-SHA is already bad enough. Also, we have a different sort order
# compared to IE11, because we put ciphers supporting forward secrecy on
top
- SSL_cipher_list => join(" ",
+ SSL_cipher_list => join(" ",
qw(
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-ECDSA-AES128-SHA256
@@ -130,6 +134,9 @@
my $GLOBAL_SSL_CLIENT_ARGS = {};
my $GLOBAL_SSL_SERVER_ARGS = {};
+# hack which is used to filter bad settings from used modules
+my $FILTER_SSL_ARGS = undef;
+
# non-XS Versions of Scalar::Util will fail
BEGIN{
local $SIG{__DIE__}; local $SIG{__WARN__}; # be silent
@@ -148,7 +155,7 @@
}
our $DEBUG;
-use vars qw(@ISA $SSL_ERROR @EXPORT );
+use vars qw(@ISA $SSL_ERROR @EXPORT);
{
# These constants will be used in $! at return from SSL_connect,
@@ -197,9 +204,8 @@
# if we have IO::Socket::INET6 we will use this not IO::Socket::INET
# because it can handle both IPv4 and IPv6
- # require at least 2.55 because of
- # https://rt.cpan.org/Ticket/Display.html?id=39550
- } elsif( eval { require IO::Socket::INET6;
IO::Socket::INET6->VERSION(2.55) } ) {
+ # require at least 2.62 because of several problems before that version
+ } elsif( eval { require IO::Socket::INET6;
IO::Socket::INET6->VERSION(2.62) } ) {
@ISA = qw(IO::Socket::INET6);
constant->import( CAN_IPV6 => "IO::Socket::INET6" );
} else {
@@ -266,6 +272,67 @@
}
}
+{
+ my %default_ca;
+ my $ca_detected; # 0: never detect, undef: need to (re)detect
+ my $openssldir;
+ sub default_ca {
+ if (@_) {
+ # user defined default CA or reset
+ if ( @_ > 1 ) {
+ %default_ca = @_;
+ $ca_detected = 0;
+ } elsif ( my $path = shift ) {
+ %default_ca =
+ -d $path ? ( SSL_ca_path => $path ) :
+ -f $path ? ( SSL_ca_file => $path ) :
+ die "no such file or directory $path";
+ $ca_detected = 0;
+ } else {
+ $ca_detected = undef;
+ }
+ }
+ return %default_ca if defined $ca_detected;
+
+ $openssldir ||= eval {
+ require Net::SSLeay;
+ Net::SSLeay::SSLeay_version(5) =~m{^OPENSSLDIR: "(.+)"$} && $1 ||
'';
+ };
+
+ # (re)detect according to openssl crypto/cryptlib.h
+ my $dir = $ENV{SSL_CERT_DIR}
+ || ( $^O =~m{vms}i ? "SSLCERTS:":"$openssldir/certs" );
+ if ( opendir(my $dh,$dir)) {
+ FILES: for my $f ( grep { m{^[a-f\d]{8}(\.\d+)?$} } readdir($dh) )
{
+ open( my $fh,'<',"$dir/$f") or next;
+ local $_;
+ while (<$fh>) {
+ m{^-+BEGIN CERTIFICATE-} or next;
+ $default_ca{SSL_ca_path} = $dir;
+ last FILES;
+ }
+ }
+ }
+ my $file = $ENV{SSL_CERT_FILE}
+ || ( $^O =~m{vms}i ? "SSLCERTS:cert.pem":"$openssldir/cert.pem" );
+ if ( open(my $fh,'<',$file)) {
+ local $_;
+ while (<$fh>) {
+ m{^-+BEGIN CERTIFICATE-} or next;
+ $default_ca{SSL_ca_file} = $file;
+ last;
+ }
+ }
+
+ $default_ca{SSL_ca_file} = Mozilla::CA::SSL_ca_file()
+ if ! %default_ca && eval { require Mozilla::CA };
+
+ $ca_detected = 1;
+ return %default_ca;
+ }
+}
+
+
# Export some stuff
# inet4|inet6|debug will be handled by myself, everything
# else will be handled the Exporter way
@@ -346,12 +413,18 @@
$is_server = $arg_hash->{SSL_server} = $arg_hash->{Listen} || 0;
}
- # add user defined defaults
- %$arg_hash = (
+ # add user defined defaults, maybe after filtering
+ $FILTER_SSL_ARGS->($is_server,$arg_hash) if $FILTER_SSL_ARGS;
+ my %defaults = (
%$GLOBAL_SSL_ARGS,
$is_server ? %$GLOBAL_SSL_SERVER_ARGS : %$GLOBAL_SSL_CLIENT_ARGS,
- %$arg_hash
);
+ 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)$} } keys %$arg_hash;
+ }
+ %$arg_hash = ( %defaults, %$arg_hash ) if %defaults;
my $ctx = $arg_hash->{'SSL_reuse_ctx'};
if ($ctx) {
@@ -462,6 +535,17 @@
}
$arg_hash->{PeerAddr} || $self->_update_peer;
+ if ( $ctx->{verify_name_ref} ) {
+ # need target name for update
+ my $host = $arg_hash->{SSL_verifycn_name};
+ if ( ! defined $host ) {
+ if ( $host = $arg_hash->{PeerHost} || $arg_hash->{PeerAddr} ) {
+ $host =~s{:[a-zA-Z0-9_\-]+$}{};
+ }
+ }
+ ${$ctx->{verify_name_ref}} = $host;
+ }
+
my $session = $ctx->session_cache( $arg_hash->{SSL_session_key} ?
( $arg_hash->{SSL_session_key},1 ) :
( $arg_hash->{PeerAddr}, $arg_hash->{PeerPort} )
@@ -958,7 +1042,7 @@
while (1) {
if ( $status & SSL_SENT_SHUTDOWN and
# don't care for received if fast shutdown
- $status & SSL_RECEIVED_SHUTDOWN
+ $status & SSL_RECEIVED_SHUTDOWN
|| $stop_args->{SSL_fast_shutdown}) {
# shutdown complete
last;
@@ -1077,7 +1161,7 @@
# upgrade to SSL failed, downgrade socket to original class
if ( $original_class ) {
bless($socket,$original_class);
- $socket->blocking(0) if ! $was_blocking
+ $socket->blocking(0) if ! $was_blocking
&& $socket->can('blocking');
}
return;
@@ -1455,29 +1539,58 @@
$GLOBAL_SSL_ARGS->{SSL_session_cache} = shift;
}
-sub set_defaults {
- my %args = @_;
- while ( my ($k,$v) = each %args ) {
- $k =~s{^(SSL_)?}{SSL_};
- $GLOBAL_SSL_ARGS->{$k} = $v;
- }
-}
-{ # deprecated API
- no warnings;
- *set_ctx_defaults = \&set_defaults;
-}
-sub set_client_defaults {
- my %args = @_;
- while ( my ($k,$v) = each %args ) {
- $k =~s{^(SSL_)?}{SSL_};
- $GLOBAL_SSL_CLIENT_ARGS->{$k} = $v;
- }
-}
-sub set_server_defaults {
- my %args = @_;
- while ( my ($k,$v) = each %args ) {
- $k =~s{^(SSL_)?}{SSL_};
- $GLOBAL_SSL_SERVER_ARGS->{$k} = $v;
+
+{
+ my $set_defaults = sub {
+ my $args = shift;
+ for(my $i=0;$i<@$args;$i+=2 ) {
+ my ($k,$v) = @{$args}[$i,$i+1];
+ if ( $k =~m{^SSL_} ) {
+ $_->{$k} = $v for(@_);
+ } elsif ( $k =~m{^(name|scheme)$} ) {
+ $_->{"SSL_verifycn_$k"} = $v for (@_);
+ } elsif ( $k =~m{^(callback|mode)$} ) {
+ $_->{"SSL_verify_$k"} = $v for(@_);
+ } else {
+ $_->{"SSL_$k"} = $v for(@_);
+ }
+ }
+ };
+ sub set_defaults {
+ my %args = @_;
+ $set_defaults->(\@_,
+ $GLOBAL_SSL_ARGS,
+ $GLOBAL_SSL_CLIENT_ARGS,
+ $GLOBAL_SSL_SERVER_ARGS
+ );
+ }
+ { # deprecated API
+ no warnings;
+ *set_ctx_defaults = \&set_defaults;
+ }
+ sub set_client_defaults {
+ my %args = @_;
+ $set_defaults->(\@_, $GLOBAL_SSL_CLIENT_ARGS );
+ }
+ sub set_server_defaults {
+ my %args = @_;
+ $set_defaults->(\@_, $GLOBAL_SSL_SERVER_ARGS );
+ }
+}
+
+sub set_args_filter_hack {
+ my $sub = shift;
+ if ( ref $sub ) {
+ $FILTER_SSL_ARGS = shift;
+ } elsif ( $sub eq 'use_defaults' ) {
+ # override args with defaults
+ $FILTER_SSL_ARGS = sub {
+ my ($is_server,$args) = @_;
+ %$args = ( %$args, $is_server
+ ? ( %DEFAULT_SSL_SERVER_ARGS, %$GLOBAL_SSL_SERVER_ARGS )
+ : ( %DEFAULT_SSL_CLIENT_ARGS, %$GLOBAL_SSL_CLIENT_ARGS )
+ );
+ }
}
}
@@ -1592,6 +1705,14 @@
$arg_hash->{SSL_use_cert} = 1
}
+ # if any of SSL_ca_path or SSL_ca_file is set don't set the other SSL_ca_*
+ # from defaults
+ if ( $arg_hash->{SSL_ca_path} ) {
+ $arg_hash->{SSL_ca_file} ||= undef
+ } elsif ( $arg_hash->{SSL_ca_file} ) {
+ $arg_hash->{SSL_ca_path} ||= undef;
+ }
+
# add library defaults
%$arg_hash = (
SSL_use_cert => $is_server,
@@ -1602,113 +1723,83 @@
# Avoid passing undef arguments to Net::SSLeay
defined($arg_hash->{$_}) or delete($arg_hash->{$_}) for(keys %$arg_hash);
- # use default path to certs and ca unless another one was given
- # don't mix default path with user specified path, either we use all
- # or no defaults
- {
- my $use_default = 1;
- for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file
- SSL_ca_file SSL_ca_path
- SSL_fingerprint )) {
- next if ! defined $arg_hash->{$_};
- # some apps set keys '' to signal that it is not set, replace with
undef
- if ( $arg_hash->{$_} eq '' ) {
- $arg_hash->{$_} = undef;
- next;
- }
- $use_default = 0;
+ # check SSL CA, cert etc arguments
+ # some apps set keys '' to signal that it is not set, replace with undef
+ for (qw( SSL_cert SSL_cert_file SSL_key SSL_key_file
+ SSL_ca_file SSL_ca_path
+ SSL_fingerprint )) {
+ $arg_hash->{$_} = undef if defined $arg_hash->{$_}
+ and $arg_hash->{$_} eq '';
+ }
+ for(qw(SSL_cert_file SSL_key_file)) {
+ defined( my $file = $arg_hash->{$_} ) or next;
+ for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) {
+ die "$_ $f does not exist" if ! -f $f;
+ die "$_ $f is not accessible" if ! -r _;
}
+ }
- $use_default = 0 if $use_default
- and ! $is_server
- and ! $arg_hash->{SSL_verify_mode};
-
- if ( $use_default ) {
-
- my %ca =
- -f 'certs/my-ca.pem' ? ( SSL_ca_file => 'certs/my-ca.pem' ) :
- -d 'ca/' ? ( SSL_ca_path => 'ca/' ) :
- ();
- my %certs = $is_server ? (
- SSL_key_file => 'certs/server-key.pem',
- SSL_cert_file => 'certs/server-cert.pem',
- ) : $arg_hash->{SSL_use_cert} ? (
- SSL_key_file => 'certs/client-key.pem',
- SSL_cert_file => 'certs/client-cert.pem',
- ) :();
- %$arg_hash = ( %$arg_hash, %ca, %certs );
-
- carp(
-
"*******************************************************************\n".
- " The implicite use of IO::Socket::SSL specific default
settings for \n".
- " CA, cert and key is depreceated.\n".
- " Please explicitly specify your own CA, cert and key using:\n".
- " - SSL_ca_file or SSL_ca_path for the CA\n".
- " - SSL_cert_file and SSL_key_file for cert and key\n".
- " To specify your own system wide defaults you can use \n".
- " set_defaults, set_client_defaults and set_server_defaults.\n".
-
"*******************************************************************\n".
- " "
- ) if %ca or %certs;
-
- } else {
- for(qw(SSL_cert_file SSL_key_file)) {
- defined( my $file = $arg_hash->{$_} ) or next;
- for my $f (ref($file) eq 'HASH' ? values(%$file):$file ) {
- die "$_ $f does not exist" if ! -f $f;
- die "$_ $f is not accessible" if ! -r _;
- }
- }
- if ( defined( my $f = $arg_hash->{SSL_ca_file} )) {
- die "SSL_ca_file $f does not exist" if ! -f $f;
- die "SSL_ca_file $f is not accessible" if ! -r _;
- }
- if ( defined( my $d = $arg_hash->{SSL_ca_path} )) {
- die "only SSL_ca_path or SSL_ca_file should be given"
- if defined $arg_hash->{SSL_ca_file};
- die "SSL_ca_path $d does not exist" if ! -d $d;
- die "SSL_ca_path $d is not accessible" if ! -r _;
- }
+ my $verify_mode = $arg_hash->{SSL_verify_mode};
+ if ( $verify_mode != Net::SSLeay::VERIFY_NONE()) {
+ if ( defined( my $f = $arg_hash->{SSL_ca_file} )) {
+ ref($f) and ! $$f and next; # explicitly ignore
+ die "SSL_ca_file $f does not exist" if ! -f $f;
+ die "SSL_ca_file $f is not accessible" if ! -r _;
+ }
+ if ( defined( my $d = $arg_hash->{SSL_ca_path} )) {
+ ref($d) and ! $$d and next; # explicitly ignore
+ die "only SSL_ca_path or SSL_ca_file should be given"
+ if defined $arg_hash->{SSL_ca_file};
+ die "SSL_ca_path $d does not exist" if ! -d $d;
+ die "SSL_ca_path $d is not accessible" if ! -r _;
}
}
+ my $self = bless {},$class;
+
my $vcn_scheme = delete $arg_hash->{SSL_verifycn_scheme};
- if ( ! $vcn_scheme or $vcn_scheme ne 'none' ) {
- # don't access ${*self} inside callback - this seems to create
- # circular references from the ssl object to the context and back
-
- # use SSL_verifycn_name or determine from PeerAddr
- my $host = $arg_hash->{SSL_verifycn_name};
- if (not defined($host)) {
- if ( $host = $arg_hash->{PeerAddr} || $arg_hash->{PeerHost} ) {
- $host =~s{:[a-zA-Z0-9_\-]+$}{};
+ if ( ! $is_server and $verify_mode & 0x01 and
+ ! $vcn_scheme || $vcn_scheme ne 'none' ) {
+
+ # gets updated during configure_SSL
+ my $verify_name;
+ $self->{verify_name_ref} = \$verify_name;
+
+ my $vcb = $arg_hash->{SSL_verify_callback};
+ $arg_hash->{SSL_verify_callback} = sub {
+ my ($ok,$ctx_store,$certname,$error,$cert) = @_;
+ $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert) if $vcb;
+ $ok or return 0;
+
+ return $ok if
+ Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store) !=0;
+
+ my $host = $verify_name || ref($vcn_scheme) &&
$vcn_scheme->{callback} && 'unknown';
+ if ( ! $host ) {
+ if ( $vcn_scheme ) {
+ IO::Socket::SSL->error(
+ "Cannot determine peer hostname for verification" );
+ return 0;
+ }
+ warn "Cannot determine hostname if 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;
+ } elsif ( ! $vcn_scheme && $host =~m{^[\d.]+$|:} ) {
+ # don't try to verify IP by default
+ return $ok;
}
- }
- $host ||= ref($vcn_scheme) && $vcn_scheme->{callback} && 'unknown';
- if ( ! $host ) {
- return IO::Socket::SSL->error(
- "Cannot determine peer hostname for verification" )
- if $vcn_scheme;
- } elsif ( ! $vcn_scheme && $host =~m{^[\d.]+$|:} ) {
- # don't try to verify IP by default
- } else {
- my $vcb = $arg_hash->{SSL_verify_callback};
- $arg_hash->{SSL_verify_callback} = sub {
- my ($ok,$ctx_store,$certname,$error,$cert) = @_;
- $ok = $vcb->($ok,$ctx_store,$certname,$error,$cert) if $vcb;
- $ok or return 0;
- return $ok if
- Net::SSLeay::X509_STORE_CTX_get_error_depth($ctx_store) !=0;
-
- # verify name
- my $rv = IO::Socket::SSL::verify_hostname_of_cert(
- $host,$cert,$vcn_scheme );
- if ( ! $rv && ! $vcn_scheme ) {
- # For now we use the default hostname verification if none
- # was specified and complain loudly but return ok if it does
- # not match. In the future we will enforce checks and users
- # should better specify and explicite verification scheme.
- warn <<WARN;
+
+
+ # verify name
+ my $rv = IO::Socket::SSL::verify_hostname_of_cert(
+ $host,$cert,$vcn_scheme );
+ if ( ! $rv && ! $vcn_scheme ) {
+ # For now we use the default hostname verification if none
+ # was specified and complain loudly but return ok if it does
+ # not match. In the future we will enforce checks and users
+ # should better specify and explicite verification scheme.
+ warn <<WARN;
The verification of cert '$certname'
failed against the host '$host' with the default verification scheme.
@@ -1719,11 +1810,14 @@
the name of the host you expect in the certificate.
WARN
- return 1;
- }
- return $rv;
- };
- }
+ return $ok;
+ }
+ if ( ! $rv ) {
+ IO::Socket::SSL->error(
+ "hostname verification failed" );
+ }
+ return $rv;
+ };
}
my $ssl_op = Net::SSLeay::OP_ALL();
@@ -1790,15 +1884,23 @@
}
}
- my $verify_mode = $arg_hash->{SSL_verify_mode};
if ( $verify_mode != Net::SSLeay::VERIFY_NONE()) {
if ( defined $arg_hash->{SSL_ca_file} || defined
$arg_hash->{SSL_ca_path} ) {
- return IO::Socket::SSL->error("Invalid certificate authority
locations")
- if ! Net::SSLeay::CTX_load_verify_locations( $ctx,
- $arg_hash->{SSL_ca_file} || '',$arg_hash->{SSL_ca_path} ||
'');
- } else {
+ my $file = $arg_hash->{SSL_ca_file};
+ $file = undef if ref($file) && ! $$file;
+ my $dir = $arg_hash->{SSL_ca_path};
+ $dir = undef if ref($dir) && ! $$dir;
+ if ( $file || $dir and ! Net::SSLeay::CTX_load_verify_locations(
+ $ctx, $file || '', $dir || '')) {
+ return IO::Socket::SSL->error(
+ "Invalid certificate authority locations")
+ }
+ } elsif ( my %ca = IO::Socket::SSL::default_ca()) {
# no CA path given, continue with system defaults
- Net::SSLeay::CTX_set_default_verify_paths($ctx);
+ return IO::Socket::SSL->error(
+ "Invalid default certificate authority locations")
+ if ! Net::SSLeay::CTX_load_verify_locations( $ctx,
+ $ca{SSL_ca_file} || '',$ca{SSL_ca_path} || '');
}
}
@@ -1952,7 +2054,7 @@
if ( $cert && @accept_fp ) {
my %fp;
for(@accept_fp) {
- my $fp = $fp{$_->[0]} ||=
+ my $fp = $fp{$_->[0]} ||=
Net::SSLeay::X509_get_fingerprint($cert,$_->[0]);
return 1 if $fp eq $_->[1];
}
@@ -1972,7 +2074,7 @@
$cb->($ctx);
}
- my $self = bless { context => $ctx },$class;
+ $self->{context} = $ctx;
$self->{has_verifycb} = 1 if $verify_callback;
$DEBUG>=3 && DEBUG( "new ctx $ctx" );
$CTX_CREATED_IN_THIS_THREAD{$ctx} = 1;
@@ -2108,8 +2210,13 @@
# certificate verification
SSL_verify_mode => SSL_VERIFY_PEER,
+
+ # location of CA store
SSL_ca_path => '/etc/ssl/certs', # typical CA path on Linux
- # on OpenBSD instead: SSL_ca_file => '/etc/ssl/cert.pem'
+ 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
SSL_verifycn_name => 'foo.bar', # defaults to PeerHost
@@ -2236,7 +2343,7 @@
Data are transmitted inside the SSL protocol using encrypted frames, which can
only be decrypted once the full frame is received. So if you use C<read> or
C<sysread> to receive less data than the SSL frame contains, it will read the
-whole frame, return part of it and buffer the rest for later reads.
+whole frame, return part of it and buffer the rest for later reads.
This does not make a difference for simple programs, but if you use
select-loops or polling or non-blocking I/O please read the related sections.
@@ -2321,7 +2428,7 @@
=item SSL_version
-Sets the version of the SSL protocol used to transmit data.
+Sets the version of the SSL protocol used to transmit data.
'SSLv23' auto-negotiates between SSLv2 and SSLv3, while 'SSLv2', 'SSLv3',
'TLSv1', 'TLSv1_1' or 'TLSv1_2' restrict the protocol to the specified version.
All values are case-insensitive. Instead of 'TLSv1_1' and 'TLSv1_2' one can
@@ -2454,10 +2561,11 @@
trusted certificate authority. In this case you should use this option to
specify the file (SSL_ca_file) or directory (SSL_ca_path) containing the
certificateZ<>(s) of the trusted certificate authorities.
-If both SSL_ca_file and SSL_ca_path are undefined and builtin defaults (see
-"Defaults for Cert, Key and CA".) can not be used, the system
-defaults built into the OpenSSL library will be tried.
-If you really don't want to set a CA set this key to C<''>.
+If both SSL_ca_file and SSL_ca_path are unset 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 this key to C<\undef> (unfortunatly
+C<''> is used by some modules using IO::Socket::SSL when CA is not exlicitly
+given).
=item SSL_fingerprint
@@ -2466,7 +2574,7 @@
verification at all. In this case you can specify the fingerprint of the
certificate as C<'algo$hex_fingerprint'>. C<algo> is a fingerprint algorithm
supported by OpenSSL, e.g. 'sha1','sha256'... and C<hex_fingerprint> is the
-hexadecimal representation of the binary fingerprint.
+hexadecimal representation of the binary fingerprint.
To get the fingerprint of an established connection you can use
C<get_fingerprint>.
@@ -2663,7 +2771,7 @@
non-blocking socket, the SSL handshake on the new file object will be done in a
blocking way. Please see the section about non-blocking I/O for details.
If you don't like this behavior you should do accept on the TCP socket and then
-upgrade it with C<start_SSL> later.
+upgrade it with C<start_SSL> later.
=item B<connect(...)>
@@ -2713,7 +2821,7 @@
=item B<sysread( BUF, LEN, [ OFFSET ] )>
This function behaves from the outside the same as B<sysread> in other
-L<IO::Socket> objects, e.g. it returns at most LEN bytes of data.
+L<IO::Socket> objects, e.g. it returns at most LEN bytes of data.
But in reality it reads not only LEN bytes from the underlying socket, but at
a single SSL frame. It then returns up to LEN bytes it decrypted from this SSL
frame. If the frame contained more data than requested it will return only LEN
@@ -2738,12 +2846,12 @@
This functions behaves from the outside the same as B<syswrite> in other
L<IO::Socket> objects, e.g. it will write at most LEN bytes to the socket, but
there is no guarantee, that all LEN bytes are written. It will return the
number
-of bytes written.
+of bytes written.
syswrite will write all the data within a single SSL frame, which means, that
no more than 16.384 bytes, which is the maximum size of an SSL frame, can be
written at once.
-For non-blocking sockets SSL specific behavior applies.
+For non-blocking sockets SSL specific behavior applies.
Pease read the specific section in this documentation.
=item B<peek( BUF, LEN, [ OFFSET ])>
@@ -2969,6 +3077,29 @@
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
+the directory specified in environment variable SSL_CERT_DIR or the path
+OPENSSLDIR/certs (SSLCERTS: on VMS) and the file specified in environment
+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
@@ -2989,19 +3120,18 @@
=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.
+the context, like the SSL_verify* parameter. Any SSL_* parameter can be given
+or the following short versions:
=over 8
-=item mode - set default SSL_verify_mode
-
-=item callback - set default SSL_verify_callback
+=item mode - SSL_verify_mode
-=item scheme - set default SSL_verifycn_scheme
+=item callback - SSL_verify_callback
-=item name - set default SSL_verifycn_name
+=item scheme - SSL_verifycn_scheme
-If not given and scheme is hash reference with key callback it will be set to
'unknown'
+=item name - SSL_verifycn_name
=back
@@ -3013,6 +3143,35 @@
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
+ )};
+ # and add some fingerprints for known certs which are signed by
+ # unknown CAs or are self-signed
+ $args->{SSL_fingerprint} = ...
+ }
+ });
+
+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
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/t/external/usable_ca.t
new/IO-Socket-SSL-1.970/t/external/usable_ca.t
--- old/IO-Socket-SSL-1.967/t/external/usable_ca.t 1970-01-01
01:00:00.000000000 +0100
+++ new/IO-Socket-SSL-1.970/t/external/usable_ca.t 2014-03-13
07:24:47.000000000 +0100
@@ -0,0 +1,42 @@
+use strict;
+use warnings;
+use Test::More;
+use IO::Socket::SSL;
+
+my $ipclass = 'IO::Socket::INET';
+for( qw( IO::Socket::IP IO::Socket::INET6 )) {
+ eval { require $_ } or next;
+ $ipclass = $_;
+ last;
+}
+
+my @hosts = qw( www.google.com www.live.com );
+plan tests => 0+@hosts;
+
+for my $host (@hosts) {
+ SKIP: {
+ # first check if we can connect at all
+ my $cl = $ipclass->new(
+ PeerAddr => $host,
+ PeerPort => 443,
+ Timeout => 15,
+ );
+
+ skip "cannot connect to $host:443 with $ipclass: $!",1
+ if ! $cl;
+ diag("connection to $host ok");
+
+ # then try to upgrade with SSL using default CA path
+ my $upgrade_ok = IO::Socket::SSL->start_SSL($cl,
+ SSL_verify_mode => 1,
+ SSL_verifycn_name => $host,
+ SSL_verifycn_scheme => 'http',
+ );
+ ok($upgrade_ok,"SSL upgrade with default CA");
+ }
+}
+
+
+
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/IO-Socket-SSL-1.967/t/sessions.t
new/IO-Socket-SSL-1.970/t/sessions.t
--- old/IO-Socket-SSL-1.967/t/sessions.t 2014-02-05 20:30:16.000000000
+0100
+++ new/IO-Socket-SSL-1.970/t/sessions.t 2014-03-16 17:35:26.000000000
+0100
@@ -51,7 +51,7 @@
SSL_ca_path => '',
SSL_version => 'TLSv1',
SSL_cipher_list => 'HIGH',
- SSL_session_cache_size => 4
+ SSL_session_cache_size => 4,
);
@@ -104,19 +104,13 @@
my $sock3 = IO::Socket::INET->new($saddr[2]);
my @clients = (
- IO::Socket::SSL->new(
- PeerAddr => $saddr[0],
- SSL_verify_mode => 0
- ),
- IO::Socket::SSL->new(
- PeerAddr => $saddr[1],
- SSL_verify_mode => 0
- ),
- IO::Socket::SSL->start_SSL( $sock3 , SSL_verify_mode => 0),
+ IO::Socket::SSL->new($saddr[0]),
+ IO::Socket::SSL->new($saddr[1]),
+ IO::Socket::SSL->start_SSL( $sock3 ),
);
if ( grep { !$_ } @clients >0 ) {
- print "not ok \# Client init\n";
+ print "not ok \# Client init $SSL_ERROR\n";
exit;
}
&ok("Client init");
@@ -153,10 +147,7 @@
}
@clients = map {
- IO::Socket::SSL->new(
- PeerAddr => $_,
- SSL_verify_mode => 0,
- )
+ IO::Socket::SSL->new($_)
} @saddr;
if (keys(%$cache) != 6) {
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]