Проверка хоста с использованием сертификатов SSL Wildcard

Мой HTTPS-клиент использует Poco C++ для соединения с нашим сервером, который использует подстановочный сертификат (*.example.com). Сбой соединения с CertificateValidationException и сообщение об ошибке "Недопустимый сертификат от xyzw: сбой проверки приложения".

Странная вещь, это не всегда терпит неудачу, просто большую часть времени. После большой отладки я догадываюсь, что это связано с топологией (например, через подсети) или с тем, как / когда имя хоста преобразуется в IP-адрес.

Я думаю, что это потому, что в тех случаях, когда все работает, как ожидалось, локальный DNS маршрутизирует имя хоста. Но в тех случаях, когда это не работает (выше сообщения об ошибке), перевод имени хоста находится на локальном компьютере, как мой компьютер.

Есть ли способ сузить то, что здесь происходит? Это общая или известная проблема?

Благодарю.

1 ответ

Я просто столкнулся с этим же симптомом сам. Используя Poco::Net::HTTPSClientSession, я мог просто отлично подключиться к сайтам без подстановочных знаков, но произошел сбой с исключением и сообщением, упомянутым выше, при подключении к подстановочным сайтам *.example.com. Отметьте, однако, что поведение, которое я наблюдал, было на 100% последовательным, никогда не прерывистым

После отладки исходного кода Poco я обнаружил проблему в том, как класс HTTPSClientConnection настраивается для проверки сертификата. Я подал проблему Poco № 1303 на pocoproject.org, но, что не совсем понятно, если вы создадите HTTPSClientSession с помощью конструктора без аргументов, вы всегда получите это исключение при подключении к серверу с подстановочным сертификатом. Например:

Poco::URI uri("http://blah.example.com");   // SSL cert is for *.example.com
Poco::Net::HTTPSClientSession session;      // Note no-arg constructor
session.setHost(uri.getHost());
session.setPort(uri.getPort());

Poco::Net::HTTPRequest req;
// Populate req...

session.sendRequest(req);      // Throws CertificateValidationException:
                               // "Unacceptable certificate from x.x.x.x,
                               // application verification failure"

Проблема заключается в том, что при проверке сертификата различные классы Poco:: Net ищут имя партнера в качестве IP-адреса, если имя хоста еще не было задано, а затем впоследствии пытаются сопоставить этот IP-адрес с сертификатом подстановочного знака CN (очевидно, xyzw не сможет сравниться с *.example.com).

Хорошей новостью является то, что есть несколько простых решений. Самый простой - просто использовать конструктор HTTPSClientSession(хост, порт), который установит правильное имя хоста в базовом SecureStreamSocket, чтобы последующая проверка сертификата соответствовала реальному имени хоста (blah.example.com) с сертификатом (CN=*.example.com) вместо IP-адреса:

Poco::URI uri("http://blah.example.com");
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());      // Calls SecureStreamSocket::setPeerHostName() internally

Также есть и другие обходные пути: сначала создайте свой собственный SecureStreamSocket, вызовите для него функцию setPeerHostName(), а затем передайте его в соответствующий конструктор HTTPSClientSession и т. Д. Если необходимо, см. Ссылку на средство отслеживания проблем, приведенную выше.

Другие вопросы по тегам