这个问题涉及IO::Socket::SSL / Net::SSLeay / LWP::UserAgent的Perl用法。
要使用OCSP检查证书吊销状态,需要显式调用套接字的ocsp_resolver,例如resolve_blocking()。这是我在通过Net::LDAP进行连接时使用的策略。
但是在LWP::UserAgent中,连接是对象的私有缓存属性。
能否从验证回调(即回调的第二个参数)中获得套接字引用?
如果是的话
Net::SSLeay::X509_Store<somthing>电话。如果没有,那么
ocsp_resolver我需要这个来检查非装订web服务器的证书状态,以及链证书(通常不是订书机)的证书状态。
发布于 2018-06-08 06:08:08
我认为(目前,在IO::Socket::SSL 2.056中)没有干净的方法可做。
但是因为它是Perl,所以可以通过一些猴子补丁来完成它。由于检查最好是在成功连接到服务器后立即完成,因此可以使用IO::Socket::SSL::connect_SSL周围的包装器来获取SSL套接字,执行OCSP检查,如果OCSP检查导致错误,则让连接失败:
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;注意,这个猴子补丁是全局的,即影响所有IO::Socket::SSL对象,而不仅仅是LWP::UserAgent中使用的对象。因此,在比本例更复杂的程序中使用时,它可能会产生一些意外的副作用。一个更干净的设计可能会在连接后有一些用户定义的回调。也许我会将这种功能添加到IO::Socket::SSL中,但就目前而言,这一攻击应该是可行的。
还要注意的是,resolve_blocking并不使用LWP::UserAgent对象,而是依赖于HTTP::Tiny。因此,任何特定于LWP::UserAgent (如代理)的设置都不会产生任何效果。如果这是一个问题,您可以手动执行请求并将其输入OCSP解析器对象,使用$ocsp->requests获取请求,并使用$ocsp->add_response将响应提供给解析器对象。
发布于 2018-06-19 14:29:00
最后,我通过修补IO::Socket::SSL来解决这个问题,以支持一个新的SSL_ocsp_check_callback参数。
在所有其他OCSP尝试之后,我就在connect_SSL()中对其进行评估。下面是我使用的修补程序(通过perl-IO-Socket-SSL-2.025-1.noarch)
--- /tmp/SSL.pm 2018-06-13 12:05:17.073787660 +0300
+++ /usr/local/share/perl5/IO/Socket/SSL.pm 2018-06-14 09:33:40.051022329 +0300
@@ -631,11 +631,11 @@
my $args = @_>1 ? {@_}: $_[0]||{};
my ($ssl,$ctx);
+ my $arg_hash = ${*$self}{'_SSL_arguments'};
if ( ! ${*$self}{'_SSL_opening'} ) {
# start ssl connection
$DEBUG>=2 && DEBUG('ssl handshake not started' );
${*$self}{'_SSL_opening'} = 1;
- my $arg_hash = ${*$self}{'_SSL_arguments'};
my $fileno = ${*$self}{'_SSL_fileno'} = fileno($self);
return $self->_internal_error("Socket has no fileno",9)
@@ -820,11 +820,22 @@
$self->_internal_error($ocsp_result->[1],5);
return $self->fatal_ssl_error();
}
+
} elsif ( $ctx->{ocsp_mode} & SSL_OCSP_MUST_STAPLE ) {
$self->_internal_error("did not receive the required stapled OCSP response",5);
return $self->fatal_ssl_error();
+
+ } elsif (exists $arg_hash->{SSL_ocsp_check_callback}) {
+ $DEBUG>=3 && DEBUG( "Checking OCSP with application callback" );
+ my $callback = $arg_hash->{SSL_ocsp_check_callback};
+ my $errors = &$callback($self);
+ if ($errors) {
+ $self->_internal_error($errors,5);
+ return $self->fatal_ssl_error();
+ }
}
+
if ( $ctx->has_session_cache
and my $session = Net::SSLeay::get1_session($ssl)) {
my $arg_hash = ${*$self}{'_SSL_arguments'};https://stackoverflow.com/questions/50721193
复制相似问题