Как я могу заставить LWP проверять сертификаты сервера SSL?

Как будто вы пытаетесь получить доступ к объекту, который является null. Рассмотрим ниже пример:

TypeA objA;

. В это время вы только что объявили этот объект, но не инициализировали или не инициализировали. И всякий раз, когда вы пытаетесь получить доступ к каким-либо свойствам или методам в нем, он будет генерировать NullPointerException, что имеет смысл.

См. Также этот пример:

String a = null;
System.out.println(a.toString()); // NullPointerException will be thrown
44
задан Community 23 May 2017 в 10:29
поделиться

4 ответа

Существует два средства выполнения этого, в зависимости от которого модуля SSL Вы установили. документы LWP рекомендуют установить Склеп:: SSLeay. Если это - то, что Вы сделали, установив HTTPS_CA_FILE, переменная среды для указания ca-bundle.crt должна добиться цели. ( Склеп:: документы SSLeay упоминания это, но немного легки на деталях). Кроме того, в зависимости от Вашей установки Вы, возможно, должны установить HTTPS_CA_DIR переменная среды вместо этого.

Пример для Склепа:: SSLeay:


use LWP::Simple qw(get);
$ENV{HTTPS_CA_FILE} = "/path/to/your/ca/file/ca-bundle";
$ENV{HTTPS_DEBUG} = 1;

print get("https://some-server-with-bad-certificate.com");

__END__
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:unknown CA
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv3 write client hello A
SSL_connect:SSLv3 read server hello A
SSL3 alert write:fatal:bad certificate
SSL_connect:error in SSLv3 read server certificate B
SSL_connect:before/connect initialization
SSL_connect:SSLv2 write client hello A
SSL_connect:error in SSLv2 read server hello B

Примечание, которые добираются, не делает die, но оно действительно возвращается undef.

, С другой стороны, можно использовать IO::Socket::SSL модуль (также доступный от CPAN). Чтобы заставить это проверить сертификат сервера, необходимо изменить значения по умолчанию контекста SSL:


use IO::Socket::SSL qw(debug3);
use Net::SSLeay;
BEGIN {
    IO::Socket::SSL::set_ctx_defaults(
        verify_mode => Net::SSLeay->VERIFY_PEER(),
        ca_file => "/path/to/ca-bundle.crt",
      # ca_path => "/alternate/path/to/cert/authority/directory"
    );
}
use LWP::Simple qw(get);

warn get("https:://some-server-with-bad-certificate.com");

Эта версия также заставляет get() возвращать undef, но печатает предупреждение STDERR при выполнении его (а также набор отладки при импорте отладки* символы от IO:: Сокет:: SSL):


% perl ssl_test.pl
DEBUG: .../IO/Socket/SSL.pm:1387: new ctx 139403496
DEBUG: .../IO/Socket/SSL.pm:269: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:271: socket connected
DEBUG: .../IO/Socket/SSL.pm:284: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:327: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1135: SSL connect attempt failed with unknown errorerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed

DEBUG: .../IO/Socket/SSL.pm:333: fatal SSL error: SSL connect attempt failed with unknown errorerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
DEBUG: .../IO/Socket/SSL.pm:1422: free ctx 139403496 open=139403496
DEBUG: .../IO/Socket/SSL.pm:1425: OK free ctx 139403496
DEBUG: .../IO/Socket/SSL.pm:1135: IO::Socket::INET configuration failederror:00000000:lib(0):func(0):reason(0)
500 Can't connect to some-server-with-bad-certificate.com:443 (SSL connect attempt failed with unknown errorerror:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed) 

9
ответ дан Ether 26 November 2019 в 22:15
поделиться

Если Вы используете LWP:: UserAgent непосредственно (не через LWP:: Простой), можно проверить имя узла в сертификате путем добавления "If-SSL-Cert-Subject" заголовка к объекту HTTP::Request. Значение заголовка рассматривают как регулярное выражение, которое будет применено на предмет сертификата, и если это не соответствует, сбои запроса. Например:

#!/usr/bin/perl 
use LWP::UserAgent;
my $ua = LWP::UserAgent->new();
my $req = HTTP::Request->new(GET => 'https://yourdomain.tld/whatever');
$req->header('If-SSL-Cert-Subject' => '/CN=make-it-fail.tld');

my $res = $ua->request( $req );

print "Status: " . $res->status_line . "\n"

распечатает

Status: 500 Bad SSL certificate subject: '/C=CA/ST=Ontario/L=Ottawa/O=Your Org/CN=yourdomain.tld' !~ //CN=make-it-fail.tld/
2
ответ дан dave0 26 November 2019 в 22:15
поделиться

Вы также можете рассмотреть Net::SSLGlue ( http://search.cpan.org/dist/Net-SSLGlue/lib/Net/SSLGlue.pm ) Но, будьте осторожны, он зависит от последних версий IO::Socket::SSL и Net::SSLeay.

1
ответ дан 26 November 2019 в 22:15
поделиться

Вы правы, что беспокоитесь об этом. К сожалению, я не думаю, что это возможно на 100% безопасно с помощью каких-либо низкоуровневых привязок SSL / TLS, которые я искал для Perl.

По сути, вам нужно передать имя хоста сервера, который вы хотите подключить к библиотеке SSL, до того, как начнется квитирование. В качестве альтернативы вы можете организовать обратный вызов в нужный момент и прервать рукопожатие изнутри обратного вызова, если он не завершится. Люди, пишущие привязки Perl к OpenSSL, по-видимому, испытывали проблемы с согласованием интерфейса обратного вызова.

Метод проверки имени хоста по сертификату сервера также зависит от протокола. Так что это должен быть параметр любой идеальной функции.

Возможно, вы захотите узнать, есть ли какие-либо привязки к библиотеке Netscape / Mozilla NSS. Когда я посмотрел, мне показалось, что это неплохо.

1
ответ дан 26 November 2019 в 22:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: