This question is regarding Perl usage of
IO::Socket::SSL
/
Net::SSLeay
/
LWP::UserAgent
.
To check certificate revocation status with OCSP, one needs to explicitly call the ocsp_resolver
of the socket, e.g. resolve_blocking()
.
That's the strategy I use when connecting via
Net::LDAP
.
But in LWP::UserAgent
, the connection is a private cached attribute of the object.
Can I get the socket reference from within a verify callback, i.e. the second argument of the callback?
If so then
How? I didn't seem to find a fitting Net::SSLeay::X509_Store<somthing>
call.
Can I conduct blocking OCSP at that point?
If not, then
ocsp_resolver
?I need this to check the certificate status of non-stapling web servers, as well as that of chains certificate (normally not stapled).
I think there is (currently, as of IO::Socket::SSL
2.056) no clean way to do is.
But since it is Perl one can do it with some monkey patching. Since the check should best be done immediately after successfully connecting to the server one can use a wrapper around IO::Socket::SSL::connect_SSL
to get the SSL socket, do the OCSP checking and let the connect fail if the OCSP check resulted in errors:
use strict;
use warnings;
use IO::Socket::SSL;
use LWP::UserAgent;
{
my $old = \&IO::Socket::SSL::connect_SSL;
no warnings 'redefine';
*IO::Socket::SSL::connect_SSL = sub {
my $sock = $old->(@_) or return;
my $ocsp = $sock->ocsp_resolver;
if (my $errors = $ocsp->resolve_blocking()) {
warn $errors;
close($sock);
return;
}
return $sock;
}
}
my $ua = LWP::UserAgent->new();
$ua->ssl_opts(SSL_ocsp_mode => SSL_OCSP_FULL_CHAIN|SSL_OCSP_FAIL_HARD|SSL_OCSP_NO_STAPLE);
my $resp = $ua->get('https://revoked.grc.com');
print $resp->decoded_content;
Note that this monkey patching is global, i.e. affects all IO::Socket::SSL
objects and not only the one used within LWP::UserAgent
. So it might have some unintended side effects when using in a more complex program than this example.
A cleaner design would maybe to have some user defined callback after connect. Maybe I'll add this kind of functionality to IO::Socket::SSL
, but for now this hack should work.
Note also that resolve_blocking
is not using the LWP::UserAgent
object but relies on HTTP::Tiny
. Thus any settings specific to LWP::UserAgent
like proxies will have no effect. If this is a problem you can do the requests manually and feed it into the OCSP resolver object using $ocsp->requests
to get the requests and $ocsp->add_response
to feed the response into the resolver object.