OCSP resolve_blocking() 和 LWP::UserAgent
OCSP resolve_blocking() and LWP::UserAgent
这个问题是关于 Perl 用法的
IO::Socket::SSL
/
Net::SSLeay
/
LWP::UserAgent
.
要使用 OCSP 检查证书吊销状态,需要显式调用套接字的 ocsp_resolver
,例如resolve_blocking()
。
这是我通过连接时使用的策略
Net::LDAP
.
但在LWP::UserAgent
中,连接是对象的私有缓存属性。
我能否从验证回调中获取套接字引用,即回调的第二个参数?
如果是那么
怎么样?我似乎没有找到合适的 Net::SSLeay::X509_Store<somthing>
电话。
到时候我可以进行阻塞OCSP吗?
如果没有,那么
- 如何调用
ocsp_resolver
?
我需要这个来检查非装订 Web 服务器的证书状态,以及链证书(通常不装订)的证书状态。
我认为(目前,截至 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
中添加这种功能,但现在这个 hack 应该可以工作了。
另请注意,resolve_blocking
没有使用 LWP::UserAgent
对象,而是依赖于 HTTP::Tiny
。因此,任何特定于 LWP::UserAgent
的设置(如代理)都将无效。如果这是一个问题,您可以手动执行请求并将其提供给 OCSP 解析器对象,使用 $ocsp->requests
获取请求并使用 $ocsp->add_response
将响应提供给解析器对象。
最终,我通过修补 IO::Socket::SSL
解决了这个问题,以支持新的 SSL_ocsp_check_callback
论点。
我在 connect_SSL()
中评估它,紧接着所有其他 OCSP 尝试。
这是我使用的补丁(超过 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'};
这个问题是关于 Perl 用法的
IO::Socket::SSL
/
Net::SSLeay
/
LWP::UserAgent
.
要使用 OCSP 检查证书吊销状态,需要显式调用套接字的 ocsp_resolver
,例如resolve_blocking()
。
这是我通过连接时使用的策略
Net::LDAP
.
但在LWP::UserAgent
中,连接是对象的私有缓存属性。
我能否从验证回调中获取套接字引用,即回调的第二个参数?
如果是那么
怎么样?我似乎没有找到合适的
Net::SSLeay::X509_Store<somthing>
电话。到时候我可以进行阻塞OCSP吗?
如果没有,那么
- 如何调用
ocsp_resolver
?
我需要这个来检查非装订 Web 服务器的证书状态,以及链证书(通常不装订)的证书状态。
我认为(目前,截至 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
中添加这种功能,但现在这个 hack 应该可以工作了。
另请注意,resolve_blocking
没有使用 LWP::UserAgent
对象,而是依赖于 HTTP::Tiny
。因此,任何特定于 LWP::UserAgent
的设置(如代理)都将无效。如果这是一个问题,您可以手动执行请求并将其提供给 OCSP 解析器对象,使用 $ocsp->requests
获取请求并使用 $ocsp->add_response
将响应提供给解析器对象。
最终,我通过修补 IO::Socket::SSL
解决了这个问题,以支持新的 SSL_ocsp_check_callback
论点。
我在 connect_SSL()
中评估它,紧接着所有其他 OCSP 尝试。
这是我使用的补丁(超过 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'};