Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

SSL Version Mystery

by RiscIt (Novice)
on Feb 26, 2009 at 09:14 UTC ( [id://746493] : perlquestion . print w/replies, xml ) Need Help??

RiscIt has asked for the wisdom of the Perl Monks concerning the following question:

Howdy,

In order to remain PCI compliant I need to make sure that our e-commerce web app is submitting data to 3rd party services with SSL 3.0. We are using a simple HTTP::Request::Common "POST" to an HTTPS URL with LWP::UserAgent. The headers of the response don't tell me anything about what SSL version is being used, and I can't find anything in the docs for HTTP::Request::Common (or HTTP::Request, or LWP::UserAgent) which would provide any insight.

Is there any test I can run which would reveal what version of SSL is being used? If it turns out that we're using SSL 2.0 then we have a real problem on our hands as a major 3rd party service we use will be dropping support for SSL 2.0 rather soon.

Any advice is appreciated.

- Phil

If it helps any, this is a stripped down example of how we're making HTTPS POST requests:
use HTTP::Request::Common qw(POST); use LWP::UserAgent; my $ua = LWP::UserAgent->new; my $req = POST "https://some.secure.site.com/script.cgi", [ some_data => 'value 1', more_data=> 'value 2' ]; my $page = $ua->request($req)->as_string; print $page;

Replies are listed 'Best First'.
Re: SSL Version Mystery
by Anonymous Monk on Feb 26, 2009 at 09:23 UTC
    http://cpansearch.perl.org/src/GAAS/libwww-perl-5.825/README.SSL
    http://search.cpan.org/~dland/Crypt-SSLeay-0.57/SSLeay.pm#SSL_versions
    Crypt::SSLeay tries very hard to connect to any SSL web server accomodating servers that are buggy, old or simply not standards-compliant. To this effect, this module will try SSL connections in this order:
    SSL v23 - should allow v2 and v3 servers to pick their best type SSL v3 - best connection type SSL v2 - old connection type
    Unfortunately, some servers seem not to handle a reconnect to SSL v3 after a failed connect of SSL v23 is tried, so you may set before using LWP or Net::SSL:
    $ENV{HTTPS_VERSION} = 3;
    to force a version 3 SSL connection first. At this time only a version 2 SSL connection will be tried after this, as the connection attempt order remains unchanged by this setting.
      Thanks for the reply.

      I've come across those recently, but didn't find them useful for the following reasons:

      1) How can I tell that the SSL being used is provided by Crypt::SSLeay and not IO::Socket::SSL ?

      2) And once we figure that out, we're still not aware of a way to learn which version of SSL is actually being used. It may fail when trying SSL 3.0 and fall back to SSL 2.0... We may have such an old version of (insert dependancy name here) that 3.0 isn't even available. These are our prime concerns we're trying to figure out.

      3) Also, those notes make reference to "$ENV{HTTPS_VERSION}".... As this is a web app, isn't the $ENV variable filled with values associated with the connection between the web app client and our server? The connection we're worried about is between our server and the 3rd party service.

      Connections:

      1. Client -> HTTPS/SSL connection to our server -> our server.
      2. Our server -> HTTPS/SSL connection to 3rd party financial service server -> 3rd party server.

      The $ENV variable we work with in our web app seems to pertain to connection 1. Would the SSL library in use for connection to use the same $ENV variable?

      Thanks in advance.

      - Phil
        1) How can I tell that the SSL being used is provided by Crypt::SSLeay and not IO::Socket::SSL ?
        see which is loaded
        use Crypt::SSLeay 0.57; use Net::SSL 2.84; print "Net::SSL $Net::SSL::VERSION\n"; print "Crypt::SSLeay $Crypt::SSLeay::VERSION\n";
        or you could even go poking around inside
        print $Net::HTTPS::SSL_SOCKET_CLASS;
        2) And once we figure that out, we're still not aware of a way to learn which version of SSL is actually being used. It may fail when trying SSL 3.0 and fall back to SSL 2.0... We may have such an old version of (insert dependancy name here) that 3.0 isn't even available. These are our prime concerns we're trying to figure out.

        Demand up to date versions of modules like shown above. And don't be afraid to dig through the source till you figure it out :)

        3) Also, those notes make reference to "$ENV{HTTPS_VERSION}".... As this is a web app, isn't the $ENV variable filled with values associated with the connection between the web app client and our server? The connection we're worried about is between our server and the 3rd party service.

        %ENV is filled with lots of stuff, and AFAIK, no webserver sets $ENV{HTTPS_VERSION}, which is probably why it was chosen by Crypt::SSLeay

        Heres one way to check

        #!/usr/bin/perl -- use strict; use warnings; use WWW::Mechanize 1.54; use LWP 5.823; use Crypt::SSLeay 0.57; use Net::SSL 2.84; use LWP::Protocol::https; sub LWP::Protocol::https::_get_sock_info { package LWP::Protocol::https; my $self = shift; $self->SUPER::_get_sock_info(@_); my($res, $sock) = @_; $res->header("Client-SSL-Cipher" => $sock->get_cipher); my $cert = $sock->get_peer_certificate; if ($cert) { $res->header("Client-SSL-Cert-Subject" => $cert->subject_name); $res->header("Client-SSL-Cert-Issuer" => $cert->issuer_name); $res->header("Client-SSL-VERSION" => *$sock->{ssl_version}); #ding +dong } if(! eval { $sock->get_peer_verify }) { $res->header("Client-SSL-Warning" => "Peer certificate not veri +fied"); } } use LWP::ConnCache; $Net::SSLeay::ssl_version = 10; # Insist on TLSv1 $Net::SSLeay::ssl_version = 3; # Insist on SSLv3 my $ua = WWW::Mechanize->new(); # keep_alive => 1 $ua->conn_cache(LWP::ConnCache->new); my $uri = URI->new("https://www.modsecurity.org/"); $ua->get( $uri, 'host' => $uri->host, 'Accept' => 'text/html,application/xhtml+xml,application/xml', ); print " ###################################################################### +######## WWW::Mechanize $WWW::Mechanize::VERSION LWP $LWP::VERSION Crypt::SSLeay $Crypt::SSLeay::VERSION; Net::HTTPS::SSL_SOCKET_CLASS = $Net::HTTPS::SSL_SOCKET_CLASS "; for my $con( $ua->conn_cache->get_connections ){ # LWP::Protocol::https::Socket; @ISA = qw(Net::HTTPS LWP::Protocol +::http::SocketMethods); print " ###################################################################### +######## "; print "$con $_ = ${*$con}{$_}\n" for grep /ssl/i, keys %{ *$con }; }; print "\n",'#'x66,"\n", $ua->response->headers->as_string,"\n",'#'x66, +"\n"; #print Data::Dumper->new([$ua])->Indent(1)->Dump();use Data::Dumper; __END__ Subroutine LWP::Protocol::https::_get_sock_info redefined at lwp-ssl-v +ersion.pl line 16. ###################################################################### +######## WWW::Mechanize 1.54 LWP 5.823 Crypt::SSLeay 0.57; Net::HTTPS::SSL_SOCKET_CLASS = Net::SSL ###################################################################### +######## LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_ssl = Crypt::SSLeay:: +Conn=SCALAR(0x215afc0) LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_peer_addr = www.modse +curity.org LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_peer_port = 443 LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_ctx = Crypt::SSLeay:: +CTX=SCALAR(0x215a8f4) LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_arg = HASH(0x1fa1238) LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_debug = 0 LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_new_arg = HASH(0x1f44 +c8c) LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_peer_verify = 0 LWP::Protocol::https::Socket=GLOB(0x215a744) ssl_version = 23 ################################################################## Connection: Keep-Alive Date: Thu, 26 Feb 2009 17:58:28 GMT Accept-Ranges: bytes Server: Apache Content-Type: text/html Content-Type: text/html; charset=UTF-8 Client-Date: Thu, 26 Feb 2009 17:59:54 GMT Client-Peer: 216.75.21.122:443 Client-Response-Num: 1 Client-SSL-Cert-Issuer: /C=US/ST=Arizona/L=Scottsdale/O=GoDaddy.com, I +nc./OU=http://certificates.godaddy.com/repository/ CN=Go Daddy Secure Certification Authority/serialNumber=07969287 Client-SSL-Cert-Subject: /O=www.modsecurity.org/OU=Domain Control Vali +dated/CN=www.modsecurity.org Client-SSL-Cipher: DHE-RSA-AES256-SHA Client-SSL-VERSION: 23 Client-SSL-Warning: Peer certificate not verified Client-Transfer-Encoding: chunked Keep-Alive: timeout=15, max=100 Link: <ms.css>; rel="StyleSheet"; type="text/css" Link: <favicon.ico>; rel="shortcut icon"; type="image/x-icon" Title: ModSecurity: Open Source Web Application Firewall X-Meta-Citydesk: 69C8DF18/12 X-Meta-Description: ModSecurity is an open source web application fire +wall. Working embedded in the web server, or stand alone as a network appliance, it detects and prevents attacks against +web applications. X-Meta-Generator: Fog Creek CityDesk 2.0.25 X-Meta-Keywords: web application firewall, application firewall, intru +sion detection, intrusion prevention, open source, web security, application security, web application security, applica +tion gateway ##################################################################
        Wow, a big real life question that has little to do with Perl. Almost all the ssl stuff is done with libssl2(latest whatever it is) at the bottom. IO::Socket::SSL is a general purpose generator of ssl socket connections, at the lowest level. It can be any port. When you say http or https, you are talking to web servers, which is a special type of socket with a fairly weak 128 bit key encryption.

        If it's important that you get this setup right, hire someone to do it; or read alot of setup docs and tutorials, so it's done right. Google for "libssh tutorials"


        I'm not really a human, but I play one on earth My Petition to the Great Cosmic Conciousness