首页 > 解决方案 > OCSP resolve_blocking() 和 LWP::UserAgent

问题描述

这个问题是关于 IO::Socket::SSL / Net::SSLeay / 的 Perl 用法LWP::UserAgent

要使用 OCSP 检查证书吊销状态,需要显式调用ocsp_resolver套接字,例如resolve_blocking(). 这就是我通过连接时使用的策略 Net::LDAP

但在 中LWP::UserAgent,连接是对象的私有缓存属性。

我可以从验证回调中获取套接字引用,即回调的第二个参数吗?

如果是的话

如果没有,那么

我需要这个来检查非装订 Web 服务器的证书状态,以及链证书(通常不装订)的证书状态。

标签: perlssluser-agentlwpocsp

解决方案


我认为(目前,截至IO::Socket::SSL2.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响应提供给解析器对象。


推荐阅读