«Невозможно получить сертификат локального эмитента» и «неизвестное имя tlsv1»,

У меня возникла проблема с проверкой обратной связи IPN Paypal. Проблема возникла месяц назад, я считаю, что когда Paypal обновил свои стандарты безопасности и свои сертификаты.

На моем веб-сайте запущен Magento 1.8.1.0, который использует phpcurl под капотом. Он запускает openSUSE 12.3 и:

PHP 5.3.17 Apache 2.2.29 mysql Ver 14.14 Distrib 5.5.33 OpenSSL 1.0.1j 

Установленная версия завитка:

 curl -V curl 7.28.1 (x86_64-suse-linux-gnu) libcurl/7.28.1 OpenSSL/1.0.1j zlib/1.2.7 libidn/1.25 libssh2/1.4.3 Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP 

Я включил журналы завихрения, и кажется, что конечная точка IPN Paypal ( https://www.paypal.com/cgi-bin/webscr ) отвечает на меня с ошибкой HTTP 500:

 < HTTP/1.1 500 Internal Server Error < Date: Fri, 14 Oct 2016 09:44:18 GMT < Server: Apache/2.2.29 (Linux/SUSE) < Vary: accept-language,accept-charset < Accept-Ranges: bytes < Connection: close < Content-Type: text/html; charset=iso-8859-1 < Content-Language: en < X-Pad: avoid browser bug < * Closing connection #0 * About to connect() to www.paypal.com port 443 (#0) * Trying 23.223.77.167... * connected * Connected to www.paypal.com (23.223.77.167) port 443 (#0) * successfully set certificate verify locations: * CAfile: none CApath: /etc/ssl/certs/ * error:14077458:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 unrecognized name * Closing connection #0 

Я попытался проверить проблему из командной строки (я не знаю, имеет ли смысл этот вывод):

 openssl s_client -connect paypal.com:443 CONNECTED(00000003) depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA verify error:num=20:unable to get local issuer certificate verify return:0 --- Certificate chain 0 s:/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=paypal.com i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA --- Server certificate -----BEGIN CERTIFICATE----- MIIFYjCCBEqgAwIBAgIQDmVBkWzoz7Kbe1JxAQW6xDANBgkqhkiG9w0BAQsFADBw MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz dXJhbmNlIFNlcnZlciBDQTAeFw0xNDEyMTIwMDAwMDBaFw0xNjEyMTYxMjAwMDBa MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhT YW4gSm9zZTEVMBMGA1UEChMMUGF5UGFsLCBJbmMuMRowGAYDVQQLExFQYXlQYWwg UHJvZHVjdGlvbjETMBEGA1UEAxMKcGF5cGFsLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBANXIsmUH//txCs+od5f84aSHXXkpA+AaX8L4ccmsvNMW 4Jwuu9kcW8yQfeNUq1N5UDdjsctoVu5qW9IQOBo19zcSg9lyUZ63+ZwduKnm8ye7 W4u5vvo5GYPZzWZpHcyKy1m1Uz7KQfasiU1YBgSl4smUBSZsJKaBykoBEUyijYN6 mip9FpPKoN9ZuOE4GLK963drV/t/1nDhLXDdzK9D8N6g/C+OlHQ8T67K9vKrCX9j cbYneE344eCGOoGf1FVFJ/9NUy+ZQyit+sljb2QoNtfqwwBQiIaj0IOuvpkYJbJE BcboNkr7TavfbQ9QP4D8OLpMU8FtSCJoeu1uBeSdWO8CAwEAAaOCAekwggHlMB8G A1UdIwQYMBaAFFFo/5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBQfVMctDtNs xGP+ZhzqjFB1OgGP3jAlBgNVHREEHjAcggpwYXlwYWwuY29tgg53d3cucGF5cGFs LmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF BwMCMHUGA1UdHwRuMGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9z aGEyLWhhLXNlcnZlci1nMy5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 LmNvbS9zaGEyLWhhLXNlcnZlci1nMy5jcmwwQgYDVR0gBDswOTA3BglghkgBhv1s AQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCB gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E aWdpQ2VydFNIQTJIaWdoQXNzdXJhbmNlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQC MAAwDQYJKoZIhvcNAQELBQADggEBAD15aUhd9rxLX4Hzl51h5ZxGuXMAZgnxigaJ FKMl6rqiXax3Oo9qihGbwzVnmZ+dwsCsn+skWMhKvgcxMIxpB7z/wFrRF8YF93XK /s2YeENBrBR198kQ9Ac4WHNqhFgfqTF9KEdwmN4/1wCCplwuXTGWSgaCoqAClf1v 72ZKV1DDGoRIJkdzbsjXMPt1EdbuZ37UFbJEFe/uq7qBwvUFBNHzcLuWQQPr0eDk PVdBjT163/DBaG9DaOGNHhl+V6pJQygq8Yz3DaRqjBh1a6TMpy/lIdGBjNS89ABM 9jcDo2EzsuoVNEhTg0hXbDPyt/vz/OrfDdDiSQG0I8k9evRCT5g= -----END CERTIFICATE----- subject=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=paypal.com issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA --- No client certificate CA names sent --- SSL handshake has read 2791 bytes and written 663 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : AES256-SHA256 Session-ID: 53D6D36E366DBA89D458ABABFB9A08E5A6C470A61DFF00C908B3C8EAB320DB3F Session-ID-ctx: Master-Key: 782AB9DDB7319512EFAA3F1843D1E70013E3E8BD384C20584537878DA09B0D9F0E1D6CD39624DD0CDC2BC0DD96616469 Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1476950153 Timeout : 300 (sec) Verify return code: 20 (unable to get local issuer certificate) --- 

Это PHP-код, который использует php-curl:

  /** * Post back to PayPal to check whether this request is a valid one * * @param Zend_Http_Client_Adapter_Interface $httpAdapter */ protected function _postBack(Zend_Http_Client_Adapter_Interface $httpAdapter) { $sReq = ''; foreach ($this->_request as $k => $v) { $sReq .= '&'.$k.'='.urlencode($v); } $sReq .= "&cmd=_notify-validate"; $sReq = substr($sReq, 1); $this->_debugData['postback'] = $sReq; $this->_debugData['postback_to'] = $this->_config->getPaypalUrl(); $httpAdapter->setConfig(array('verifypeer' => $this->_config->verifyPeer)); $httpAdapter->addOption(CURLOPT_SSLVERSION,6);//CURL_SSLVERSION_TLSv1_2 $httpAdapter->write(Zend_Http_Client::POST, $this->_config->getPaypalUrl(), '1.1', array( 'Connection: close', 'User-Agent: XXXXXXXX' ), $sReq); try { $response = $httpAdapter->read(); } catch (Exception $e) { $this->_debugData['http_error'] = array('error' => $e->getMessage(), 'code' => $e->getCode()); throw $e; } $this->_debugData['postback_result'] = $response; $response = preg_split('/^\r?$/m', $response, 2); $response = trim($response[1]); if ($response != 'VERIFIED') { throw new Exception('PayPal IPN postback failure. See ' . self::DEFAULT_LOG_FILE . ' for details.'); } unset($this->_debugData['postback'], $this->_debugData['postback_result']); } 

А также:

 /** * Array of CURL options * * @var array */ protected $_options = array(); /** * Apply current configuration array to transport resource * * @return Varien_Http_Adapter_Curl */ protected function _applyConfig() { if (empty($this->_config)) { return $this; } // apply additional options to cURL foreach ($this->_options as $option => $value) { curl_setopt($this->_getResource(), $option, $value); } $verifyPeer = isset($this->_config['verifypeer']) ? $this->_config['verifypeer'] : 0; curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYPEER, $verifyPeer); $verifyHost = isset($this->_config['verifyhost']) ? $this->_config['verifyhost'] : 0; curl_setopt($this->_getResource(), CURLOPT_SSL_VERIFYHOST, $verifyHost); foreach ($this->_config as $param => $curlOption) { if (array_key_exists($param, $this->_allowedParams)) { curl_setopt($this->_getResource(), $this->_allowedParams[$param], $this->_config[$param]); } } return $this; } /** * Set array of additional cURL options * * @param array $options * @return Varien_Http_Adapter_Curl */ public function setOptions(array $options = array()) { $this->_options = $options; return $this; } /** * Add additional option to cURL * * @param int $option the CURLOPT_* constants * @param mixed $value * @return Varien_Http_Adapter_Curl */ public function addOption($option, $value) { $this->_options[$option] = $value; return $this; } /** * Set the configuration array for the adapter * * @param array $config * @return Varien_Http_Adapter_Curl */ public function setConfig($config = array()) { $this->_config = $config; return $this; } /** * Connect to the remote server * * @deprecated since 1.4.0.0-rc1 * @param string $host * @param int $port * @param boolean $secure * @return Varien_Http_Adapter_Curl */ public function connect($host, $port = 80, $secure = false) { return $this->_applyConfig(); } /** * Send request to the remote server * * @param string $method * @param Zend_Uri_Http $url * @param string $http_ver * @param array $headers * @param string $body * @return string Request as text */ public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '') { if ($url instanceof Zend_Uri_Http) { $url = $url->getUri(); } $this->_applyConfig(); curl_setopt($this->_getResource(), CURLOPT_VERBOSE, true); $handle = fopen('/srv/www/htdocs/MascagniB2C/var/log/curl.log', 'a+'); curl_setopt($this->_getResource(), CURLOPT_STDERR, $handle); // set url to post to curl_setopt($this->_getResource(), CURLOPT_URL, $url); curl_setopt($this->_getResource(), CURLOPT_RETURNTRANSFER, true); if ($method == Zend_Http_Client::POST) { curl_setopt($this->_getResource(), CURLOPT_POST, true); curl_setopt($this->_getResource(), CURLOPT_POSTFIELDS, $body); } elseif ($method == Zend_Http_Client::GET) { curl_setopt($this->_getResource(), CURLOPT_HTTPGET, true); } if (is_array($headers)) { curl_setopt($this->_getResource(), CURLOPT_HTTPHEADER, $headers); } /** * @internal Curl options setter have to be re-factored */ $header = isset($this->_config['header']) ? $this->_config['header'] : true; curl_setopt($this->_getResource(), CURLOPT_HEADER, $header); return $body; } 

Можете ли вы мне посоветовать понять, где проблема в моей конфигурации openssl (или я смотрю в неправильном направлении)? Мне не хватает сертификата?


ОБНОВИТЬ

Я предложил попробовать:

 openssl s_client -CApath /etc/ssl/certs/ -connect paypal.com:443 CONNECTED(00000003) depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA verify return:1 depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA verify return:1 depth=0 C = US, ST = California, L = San Jose, O = "PayPal, Inc.", OU = PayPal Production, CN = paypal.com verify return:1 --- Certificate chain 0 s:/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=paypal.com i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA --- Server certificate -----BEGIN CERTIFICATE----- MIIFYjCCBEqgAwIBAgIQDmVBkWzoz7Kbe1JxAQW6xDANBgkqhkiG9w0BAQsFADBw MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz dXJhbmNlIFNlcnZlciBDQTAeFw0xNDEyMTIwMDAwMDBaFw0xNjEyMTYxMjAwMDBa MH0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMREwDwYDVQQHEwhT YW4gSm9zZTEVMBMGA1UEChMMUGF5UGFsLCBJbmMuMRowGAYDVQQLExFQYXlQYWwg UHJvZHVjdGlvbjETMBEGA1UEAxMKcGF5cGFsLmNvbTCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBANXIsmUH//txCs+od5f84aSHXXkpA+AaX8L4ccmsvNMW 4Jwuu9kcW8yQfeNUq1N5UDdjsctoVu5qW9IQOBo19zcSg9lyUZ63+ZwduKnm8ye7 W4u5vvo5GYPZzWZpHcyKy1m1Uz7KQfasiU1YBgSl4smUBSZsJKaBykoBEUyijYN6 mip9FpPKoN9ZuOE4GLK963drV/t/1nDhLXDdzK9D8N6g/C+OlHQ8T67K9vKrCX9j cbYneE344eCGOoGf1FVFJ/9NUy+ZQyit+sljb2QoNtfqwwBQiIaj0IOuvpkYJbJE BcboNkr7TavfbQ9QP4D8OLpMU8FtSCJoeu1uBeSdWO8CAwEAAaOCAekwggHlMB8G A1UdIwQYMBaAFFFo/5CvAgd1PMzZZWRiohK4WXI7MB0GA1UdDgQWBBQfVMctDtNs xGP+ZhzqjFB1OgGP3jAlBgNVHREEHjAcggpwYXlwYWwuY29tgg53d3cucGF5cGFs LmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF BwMCMHUGA1UdHwRuMGwwNKAyoDCGLmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9z aGEyLWhhLXNlcnZlci1nMy5jcmwwNKAyoDCGLmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 LmNvbS9zaGEyLWhhLXNlcnZlci1nMy5jcmwwQgYDVR0gBDswOTA3BglghkgBhv1s AQEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCB gwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy dC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E aWdpQ2VydFNIQTJIaWdoQXNzdXJhbmNlU2VydmVyQ0EuY3J0MAwGA1UdEwEB/wQC MAAwDQYJKoZIhvcNAQELBQADggEBAD15aUhd9rxLX4Hzl51h5ZxGuXMAZgnxigaJ FKMl6rqiXax3Oo9qihGbwzVnmZ+dwsCsn+skWMhKvgcxMIxpB7z/wFrRF8YF93XK /s2YeENBrBR198kQ9Ac4WHNqhFgfqTF9KEdwmN4/1wCCplwuXTGWSgaCoqAClf1v 72ZKV1DDGoRIJkdzbsjXMPt1EdbuZ37UFbJEFe/uq7qBwvUFBNHzcLuWQQPr0eDk PVdBjT163/DBaG9DaOGNHhl+V6pJQygq8Yz3DaRqjBh1a6TMpy/lIdGBjNS89ABM 9jcDo2EzsuoVNEhTg0hXbDPyt/vz/OrfDdDiSQG0I8k9evRCT5g= -----END CERTIFICATE----- subject=/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=PayPal Production/CN=paypal.com issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA --- No client certificate CA names sent --- SSL handshake has read 2791 bytes and written 663 bytes --- New, TLSv1/SSLv3, Cipher is AES256-SHA256 Server public key is 2048 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1.2 Cipher : AES256-SHA256 Session-ID: 78A62BA404C7656931D4FA5658820B4000CD69DBB82BAEB8E725ADBBE2B3E9C0 Session-ID-ctx: Master-Key: 725C7887E3F5BABC6BF878DDD4C2F9A246A08382BB259C700E8D74C95FF75D6E98FF2979BBB8661C7525D36956397179 Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1476950900 Timeout : 300 (sec) Verify return code: 0 (ok) --- 

Я думаю, вам нужно обновить версию curl, так как ваша версия curl не поддерживает TLSv1.2 для php ( source ). И PayPal обеспечивает использование TLSv1.2 ( source )

openssl s_client -connect paypal.com:443

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

Вы хотите использовать TLS 1.0 или выше, и вы хотите использовать Server Name Indicication (SNI). Таким образом, команда должна использовать -servername для привлечения SNI и -tls1 для использования TLS 1.0. Вы можете даже использовать -tls1_2 если хотите:

 $ openssl s_client -connect paypal.com:443 -servername paypal.com -tls1 CONNECTED(00000005) depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA verify error:num=20:unable to get local issuer certificate Server did acknowledge servername extension. ... New, SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: 78A62BA404C4AA8731D4FA5658820840A014955818597872E725ADBBE29AB06B Session-ID-ctx: Master-Key: DCE1A463B22DEB10AEA4CECD6C89560502F1F67583C0DDDDF81B0FD99D31C83AE81AA484C32ADC6E312AEC8AB5FE86D1 PSK identity: None PSK identity hint: None SRP username: None Start Time: 1478608307 Timeout : 7200 (sec) Verify return code: 20 (unable to get local issuer certificate) Extended master secret: no 

Вы можете очистить Verify return code: 20 (unable to get local issuer certificate) , используя -CAfile с DigiCert High Assurance EV Root CA. Вы можете получить его из сертификатов доверенных корневых сертификатов DigiCert . Как только вы его получите, вам необходимо преобразовать его из DER в PEM.

 $ wget https://www.digicert.com/CACerts/DigiCertHighAssuranceEVRootCA.crt ... $ file DigiCertHighAssuranceEVRootCA.crt DigiCertHighAssuranceEVRootCA.crt: data $ openssl x509 -in DigiCertHighAssuranceEVRootCA.crt -inform DER \ -out DigiCertHighAssuranceEVRootCA.pem -outform PEM $ file DigiCertHighAssuranceEVRootCA.pem DigiCertHighAssuranceEVRootCA.pem: ASCII text 

Затем выполните следующее. Обратите внимание, что он заканчивается Verify return code: 0 (ok) .

 $ openssl s_client -connect paypal.com:443 -servername paypal.com -tls1 -CAfile DigiCertHighAssuranceEVRootCA.pem CONNECTED(00000005) depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA verify return:1 depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA verify return:1 depth=0 C = US, ST = California, L = San Jose, O = "PayPal, Inc.", OU = PayPal Production, CN = paypal.com verify return:1 Server did acknowledge servername extension. ... New, SSLv3, Cipher is AES256-SHA Server public key is 2048 bit Secure Renegotiation IS supported No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : AES256-SHA Session-ID: 53D6D36E366E7A68D458ABABFB9A08E5F1EC49287E6265D008B3C8EAB3098951 Session-ID-ctx: Master-Key: 13C070B784545ED1F11608E4871936CABF9BFC8A4320C025003ABE05320C3598342500BB12C90F89270B19D26D793A96 PSK identity: None PSK identity hint: None SRP username: None Start Time: 1478608643 Timeout : 7200 (sec) Verify return code: 0 (ok) Extended master secret: no 

Наконец, все, что вам нужно сделать, это указать PHP и cURL использовать DigiCertHighAssuranceEVRootCA.pem . Ваша команда cURL, вероятно, будет выглядеть примерно так:

 curl www.paypal.com:443 --tlsv1.0 --cacert DigiCertHighAssuranceEVRootCA.pem 

Я не знаю, что делать в PHP.