perlsni

perl - Net::SSLeay and Server Name Indications


Hello my friendly stackoverflow users,

I have the following code that "should" print out the cert for 'cyclingnews.com'

#!/usr/bin/env perl                                                 
                                                                    
use strict;                                                         
use Net::SSLeay qw(get_https get_https3 make_headers);              
                                                                    
my $site = "cyclingnews.com";                                       
my ($p, $resp, $headers, $server_cert) = get_https3($site, 443, '/');                     
print "$headers\n";                                                 
my $PEM = Net::SSLeay::PEM_get_string_X509( $server_cert);          
print $PEM, "\n";                                                                                                                

Upon inspection of the .pem, I see that the cert belongs to:

Subject: CN = *.ssl.hwcdn.net
X509v3 Subject Alternative Name:
                DNS:*.ssl.hwcdn.net, DNS:ssl.hwcdn.net

So what I understand, this looks like a problem with SNI where Net::SSLeay is not passing a SSL_hostname to 'cyclingnews.com'. With IO::SOCKETS::SSL this can be done with SSL_hostname ( https://metacpan.org/pod/IO::Socket::SSL#Basic-SSL-Client )

The Net::SSLeay doc ( https://metacpan.org/pod/Net::SSLeay#Basic-set-of-functions ) says "By default get_https() supplies Host (to make virtual hosting easy) and Accept (reportedly needed by IIS) headers."

I am not sure if this relates to get_https3() so I have also tried:

#!/usr/bin/env perl                                                  
                                                                     
use strict;                                                          
use Net::SSLeay qw(get_https get_https3 make_headers);               
                                                                     
my $site = "cyclingnews.com";                                        
my ($p, $resp, $headers, $server_cert) = get_https3($site, 443, '/', 
              make_headers( 'Host:' => $site));                      
#);                                                                  
print "$headers\n";                                                  
my $PEM = Net::SSLeay::PEM_get_string_X509( $server_cert);           
print $PEM, "\n";                                                    

and this looks to pass the Host header but still same unwanted result.

so I am a bit lost, I'm a noob, so I know the folk on stackoverflow have a reputation for being freindly, maybe y'all could give me some pointers


Solution

  • get_https3 like many similar functions ultimately ends up in https_cat where the SSL context setup and the SSL handshake are done. Unfortunately, setting the server_name extension (SNI) is not done in this really old part of the code, which comes from a time where SNI wasn't that essentially for using HTTPS as it is today.