2-Way-TLS support - perl

Server application is using following code to get the request from client to process. Now I got a requirement to make this call secure using HTTPS (2-way-tls). I need to convert this call to secure call in Perl and implement client authentication for trusted client. I am not sure how can I do that and how to provide certificates.
my $daemonname = "SOAP::Transport::HTTP::Daemon";
$daemon = $daemonname
->new(Scheme => 'http', LocalPort => 8080, Listen => 128)
->dispatch_to('MyCode')
->options({compress_threshold => 10000});
$daemon->handle;

Related

IO::Socket::SSL - establishing client connection

As per the documentation of IO::Socket::SSL (PERL) I understand that if I want to just send command to specific server-program that running on port 9999 on my host, Ican do it this way:
my $cl=IO::Socket::SSL->new("localhost:9999"); # locallost is my real case, anyway
if($cl) {
$cl->connect_SSL or die $#;
# Something about certificates?
$cl->syswrite("Command");
close($cl);
}
But the error I get is: "SSL connect attempt failed with unknown error error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol at blabla.cgi line 888"
The server initialized thi way (in another pl program):
use IO::Socket::SSL;
use Net::WebSocket::Server;
my $CON={};
my #crt=&SSLCerts(); die 'E101' if(#crt==0);
my $ssl=IO::Socket::SSL->new(
Listen => 10000,
Timeout => 45,
LocalPort => 9999,
Proto => 'tcp',
SSL_cert_file => "$EF::Base/ssl/certs/$crt[0][0].crt",
SSL_key_file => "$EF::Base/ssl/keys/$crt[1][0].key"
) or die "E102: $!";
Net::WebSocket::Server->new(
listen => $ssl,
silence_max=> 3600,
tick_period => 5,
on_tick => sub {
# Empty for now
},
on_connect => sub {
my($serv,$conn)=#_; my($cid,$sid);
$conn->on(
handshake => sub {
my($cnc,$hdk)=#_;
my $nsn=$hdk->req->resource_name;
$cid=substr($nsn,4,index($nsn,'&L=')-4);
$CON->{$cid}=$cnc; # Register incomming connection
},
binary => sub {
# Handle incomming message from the client
},
disconnect => sub {
delete $CON->{$cid};
}
);
}
)->start;
Typical Websocket client that is connecting from the browser via "wss://" connects without any trouble.... The server MUST be SSL...
Here I am just trying to do the same from within perl.
What I am doing wrong? Nothing mentioned about certificates in client, only in server - the server is working fine. Maybe configuration? I have purchased SSL certificates and I use them for the server that running ok on that port.
The host is Linux (CentOS - if it matters).
... SSL23_GET_SERVER_HELLO:unknown protocol
This is the kind of error you get if the client tries to do a SSL handshake and the server responds with something which is not SSL. Typically this happens if you connect to a server which is not (properly) SSL enabled (at least not on this port) or requires some plain text to upgrade to SSL (like in case of SMTP STARTTLS and similar).
This kind of error has usually nothing to do with certificates.
This kind of error can only happen if you try to do an SSL handshake on an already established SSL socket but the server does not expect this. This seems to happen in your case:
my $cl=IO::Socket::SSL->new("localhost:9999"); # locallost is my real case, anyway
if($cl) {
$cl->connect_SSL or die $#;
...
The SSL connection is already being established by IO::Socket::SSL->new. This is the same with IO::Socket::INET or similar: if the target is given it will already connect inside new and an additional connect or connect_SSL should not be done. This is also reflected in the documentation and examples.
Since version 2.045 (released 02/2017) IO::Socket::SSL will simply ignore a connect_SSL if the SSL handshake is already done. You are likely using an older version of IO::Socket::SSL where connect_SSL will start a new handshake even if the TLS handshake was already finished. This handshake inside the TLS connection will result in the strange error you see.

Perl WWW::Mechanize for HTTPS over proxy

I am trying to scrape a website using WWW::Mechanize module. I have configured the mechanize agent with a proxy URL and setting the proxy credentials using credentials method.
Code snippet :
my $url = 'https://abcde.com';
my $proxy_username = 'abc';
my $proxy_password = 'xyz';
my $proxy_url = 'http://xx.xxx.xxx.xxx:13228';
my $mechanize_agent = new WWW::Mechanize('cookie_jar' => {}, 'noproxy' => 1, 'ssl_opts' => { 'verify_hostname' => 0 });
$mechanize_agent->credentials( $proxy_username, $proxy_password );
$mechanize_agent->proxy(['http', 'https'], $proxy_url);
$mechanize_agent->get($url) or die 'Error in get request of $url: $#';
When URL is a plain HTTP, the script fetches and gives back the result. But when I try to hit HTTPS url I get the error
establishing SSL tunnel failed: 407 Proxy Authentication Required
I credentials are valid and I can view the website using proxy URL in Mozilla browser. Also i need t avoid using call to env_proxy() function since the proxy URL is dynamic. How can I get let my script fetch HTTPS request?
All suggestions are welcome!
thanks in advance.

Perl Webservice SSL Negotiation Failure

I am trying to call a web service using ssl. It gives following error:
500 SSL negotiation failed:
I searched forums and applied offered methods but none of them worked.
2 methods I applied are listed below:
1-) setting enviroment before call:
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
2-) passing parameter ssl_opts => [ SSL_verify_mode => 0 ] to proxy:
my $soap = SOAP::Lite
-> on_action( .... )
-> uri($uri)
-> proxy($proxy, ssl_opts => [ SSL_verify_mode => 0 ])
-> ns("http://schemas.xmlsoap.org/soap/envelope/","soapenv")
-> ns("http://tempuri.org/","tem");
$soap->serializer()->encodingStyle(undef);
Is there any solution for this?
... Connection reset by peer at /usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi/Net‌​/SSL.pm line 145
You are running a very old version of Perl (from 2004) together with an old version of the SSL libraries (i.e. Crypt::SSLeay instead of IO::Socket::SSL) and my guess is that this goes together with using a very old version of the OpenSSL libraries for TLS support. This combination means that there is no support for SNI, no support for TLS 1.2 and no support for ECDHE ciphers. Many modern servers need at least one of these things supported. But connection reset by peer could also mean that some firewall is blocking connections or that there is no server listening on the endpoint you've specified. Or it could mean that the server is expecting you to authorize with a client certificate. Hard to tell but with a packet capture of the connection one might provide more information. And, if the URL is publicly accessible publishing it would help too in debugging the problem.

How to add SSL Encryption to my http rest server on Spray

I'm building a http rest server on spray that routes Post Requests and I want to make it encrypted with ssl.
This is the example from official spray webstie i used to builed the server and i want to change it to be with ssl :
https://github.com/spray/spray-template/tree/on_spray-can_1.3/src/main/scala/com/example.
I have read here : http://spray.io/documentation/1.2.3/spray-can/http-server/#ssl-support
That i need to add ServerSSLEngineProvider Parameter to Http.Bind (its in the Boot.scala in example git above ) . But i don't know how to build right the ServerSSLEngineProvider and what to give it .
IO(Http) ? Http.Bind(service, interface = "0.0.0.0", port = 81 , ServerSSLEngineProvider = ???)
My question is what i need to put insted of the ??? here so my server will be ssl secured .
Thanks to the helpers.

Fiddler Error Connecting to HTTPS Applications !SecureClientPipeDirect failed

Fiddler Error Connecting to HTTPS Applications
Fiddler Log:
!SecureClientPipeDirect failed: Authentication failed because the remote party has closed the transport stream. on pipe to (CN=services.bigpond.com, O=DO_NOT_TRUST_BC, OU=Created by http://www.fiddler2.com)
I have followed other posts but no answers
The typical explanation for this message, as documented in many places, is that the client application has not been configured to trust Fiddler's root certificate. As such, the client closes the connection to Fiddler when it sees the untrusted certificate.
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/TrustFiddlerRootCert
In Kestrel I'm using an SSL cert.
I 'downgraded' the TLS protocol in order to get this to work.
This is not something you'd do in production - but in production you shouldn't be using kestrel. I'm not saying this is the best overall config, but this is mainly to show the SslProtocols option.
WebHost.CreateDefaultBuilder(args)
.UseKestrel(options =>
{
options.Listen(IPAddress.Any, 5000); // http:localhost:5000
options.Listen(IPAddress.Any, 44300, listenOptions =>
{
// https://dotnetthoughts.net/enable-http2-on-kestrel/
//listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
listenOptions.UseHttps(#"S:\WORK\SSL\example.com.pfx", "cert-password", httpsOptions =>
{
httpsOptions.SslProtocols = System.Security.Authentication.SslProtocols.Tls;
});
});
})
.UseStartup<Startup>();