Как установить флажок «verify_peer_name = false» параметр контекста SSL через php.ini в PHP 5.6

Случай. Я хотел бы открыть SSL-соединение с localhost а SSL-сертификат – это проблемы для полного доменного имени.

Проблема: без специальной обработки в строке (*) программа ниже не работает со следующим сообщением:

PHP Warning: stream_socket_enable_crypto(): Peer certificate CN='myhost.com' did not match expected CN='localhost' in test.php

Тест-программа PHP:

 $fp = stream_socket_client("tcp://localhost:993", $errno, $errstr, 30); // (*) if commented, the program fails //stream_context_set_option($fp, 'ssl', 'verify_peer_name', false); if (!$fp) { die("Unable to connect: $errstr ($errno)"); } if (!stream_socket_enable_crypto($fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { die("Failed to start SSL"); } fwrite($fp, "USER god\r\n"); fwrite($fp, "PASS secret\r\n"); while ($motd = fgets($fp)) { echo $motd; } fclose($fp); 

Поскольку у меня много устаревшего кода, я хотел бы иметь решение, применяя только изменения в php.ini (или CLI), но, к сожалению, ни один из ниже не работает:

php -d verify_peer_name=false test.php

php -d ssl.verify_peer_name=false test.php

Идеи?

Рекомендации:

  • Не удалось выполнить операцию SSL с кодом 1
  • Как проверить сертификат SMTP TLS?
  • Потоки SSL и PHP
  • Решение SSL для PHP 5.6
  • Изменения OpenSSL в PHP 5.6.x
  • Параметры контекста SSL

TL; DR

Когда cafile и capath являются одновременно конфигурацией среды выполнения и параметрами контекста SSL , verify_peer_name и verify_peer являются только параметрами контекста SSL .

Таким образом, эти более поздние два не могут быть изменены с помощью директив конфигурации времени исполнения.


Я могу понять путаницу из документации, воспроизведенной здесь, но эти два абзаца на самом деле относятся к двум различным понятиям в PHP.

Пакет CA по умолчанию может быть переопределен на глобальной основе , установив либо параметр конфигурации openssl.cafile, либо openssl.capath, либо на основе запроса , используя параметры контекста cafile или capath.

Хотя это и не рекомендуется в целом, можно отключить проверку сертификатов одноранговой сети для запроса , установив параметр контекста verify_peer в FALSE и отключить проверку имени пэра, установив параметр контекста verify_peer_name в FALSE.

Ссылка на исходный источник PHP

Прежде всего обратите внимание, что сама документация имеет четкое различие между openssl.cafile и openssl.capath на глобальной основе или на основе запроса в сравнении с verify_peer и verify_peer_name для запроса .

Это означает, что, когда openssl.cafile и openssl.capath могут быть адаптированы как через php.ini и через stream_context_set_option , с другой стороны verify_peer и verify_peer_name доступны только через stream_context_set_option .

Это также подтверждается самим исходным кодом PHP, вот некоторые строки, показывающие, что PHP php_stream_context_get_option основе языка C получает значение только из php_stream_context_get_option .

 must_verify_peer_name = GET_VER_OPT("verify_peer_name") ? zend_is_true(val) : sslsock->is_client; 

Ссылка на исходный код PHP github

Для ясности, вот объявление макроса GET_VER_OPT

 #define GET_VER_OPT(name) (PHP_STREAM_CONTEXT(stream) && (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", name)) != NULL) 

Ссылка на исходный код PHP github

Когда cafile и capath на самом деле сначала сопоставляются с значением php_stream_context_get_option , но тогда, если они имеют NULL в контексте, они затем выбираются в конфигурации ini.

 GET_VER_OPT_STRING("cafile", cafile); GET_VER_OPT_STRING("capath", capath); if (cafile == NULL) { cafile = zend_ini_string("openssl.cafile", sizeof("openssl.cafile")-1, 0); cafile = strlen(cafile) ? cafile : NULL; } 

Ссылка на исходный код PHP github

Тогда немного ниже в той же самой функции:

 if (capath == NULL) { capath = zend_ini_string("openssl.capath", sizeof("openssl.capath")-1, 0); capath = strlen(capath) ? capath : NULL; } 

Ссылка на исходный код PHP github

Для ясности, вот объявление макроса GET_VER_OPT_STRING

 #define GET_VER_OPT_STRING(name, str) if (GET_VER_OPT(name)) { convert_to_string_ex(val); str = Z_STRVAL_P(val); } 

Ссылка на исходный код PHP github

Вы также можете видеть, что, когда эти два значения openssl.capth и openssl.cafile определяются как существующая ini конфигурация, более поздние verify_peer и verify_peer_name нигде не найдены.

К сожалению, единственный способ пойти, как подсказывает его документация, – настроить его для запроса через stream_context_set_option ( $stream_or_context , 'ssl' , 'verify_peer_name' , false )

Также обратите внимание : значение по умолчанию для этих двух параметров контекста SSL изменилось в PHP версии 5.6.0, как это было предложено в документации:

5.6.0 Добавлено peer_fingerprint и verify_peer_name. Значение параметра verify_peer по умолчанию изменено на TRUE.

Ссылка на документацию PHP

Это означает, что такая проблема может возникнуть после обновления PHP с PHP < 5.6.0 поэтому, даже если я этого не рекомендую, поскольку PHP 5.5 подходит к концу, это жизненный цикл поддержки , значение по умолчанию этих двух параметров может сохраняться в false, придерживаясь версии PHP ниже 5.6.0 .