Ошибка сертификата PHP cURL

Я пытаюсь добавить кастом cer-сертификат моего запроса PHP cURL, но я продолжаю получать эту ошибку:

error setting certificate verify locations:
CAfile: /path/to/my/cert.cer
CApath: none

Все, что я нашел об этой ошибке, это то, что:

  1. Путь относительный.
    Как видите, я указал абсолютный путь.

  2. Путь ошибочный.
    Я пытался var_dump(file_exists($certLocation));, который дает мне true, так что это не тот случай.

  3. Права доступа к файлу неверны.
    Я установил разрешения для 777 в целях отладки. Ошибка остается.

  4. Путь к файлу не имеет +xРазрешения где-то в цепочке.
    Я также установил это, гарантируя, что весь путь от root +xРазрешения, и до сих пор не повезло.

Я в недоумении, перепробовав все, что могу найти, и факт в том, Я даже не понимаю, что на самом деле означает ошибка. Что такое verify location? Все, что я могу понять, это ошибка загрузки файла.

Любой свет, проливаемый на это, очень ценится. Смотрите пример кода ниже.

Благодарю.

Код, который я использую:

<?php

$oCurl = curl_init($this->baseUrl);
curl_setopt($oCurl, CURLOPT_FAILONERROR, 1);
curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($oCurl, CURLOPT_POST, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($oCurl, CURLOPT_CAINFO, "/tmp/cert.cer");

Ошибка:

error setting certificate verify locations:
CAfile: /tmp/cert.cer
CApath: none

1

Решение

CURLOPT_CAINFO используется в сочетании с CURLOPT_SSL_VERIFYPEER

CURLOPT_CAINFO должен быть установлен на CA или CA-bundle в формате PEM. Мне удалось отследить код curl, который вызывает эту ошибку, и вот что я нашел:

в локон / openssl.c:

if(!SSL_CTX_load_verify_locations(connssl->ctx,
data->set.str[STRING_SSL_CAFILE],
data->set.str[STRING_SSL_CAPATH])) {
if(data->set.ssl.verifypeer) {
/* Fail if we insist on successfully verifying the server. */
failf(data, "error setting certificate verify locations:\n""  CAfile: %s\n  CApath: %s",
data->set.str[STRING_SSL_CAFILE]?
data->set.str[STRING_SSL_CAFILE]: "none",
data->set.str[STRING_SSL_CAPATH]?
data->set.str[STRING_SSL_CAPATH] : "none");
return CURLE_SSL_CACERT_BADFILE;
}
...

Видимо, вызов на SSL_CTX_load_verify_locations возвращается 0 и в сочетании с фактом наличия CURLOPT_SSL_VERIFYPEER установлен в 1 это вызывает ошибку.

SSL_CTX_load_verify_locations это функция из библиотеки openssl, и согласно документации (Документация SSL_CTX_load_verify_locations), следующие утверждения должны быть приняты во внимание:

«Если CAfile не равен NULL, он указывает на файл сертификатов CA в PEM формат.»

«CA-файл обрабатывается при выполнении функции SSL_CTX_load_verify_locations ()».

«0 — Операция завершилась неудачно, поскольку CAfile и CApath имеют значение NULL или обработка в одном из указанных местоположений завершилась неудачно». под ВОЗВРАЩАЕМЫЕ ЦЕННОСТИ раздел


Вы можете попытаться конвертировать ваши cer к pem используя следующую команду:

openssl x509 -in /tmp/cert.cer -inform der -outform pem -out /tmp/cert.pem

но я не могу гарантировать, что это будет работать, потому что я не уверен, есть ли у вас правильный CA или файл CA-комплекта.

2

Другие решения

Если в вашей установке PHP нет обновленного корневого сертификата CA, загрузите его на веб-сайте curl и сохраните на своем сервере:

http://curl.haxx.se/docs/caextract.html

Затем установите path к этому в вашем php.ini файл, например в Windows:

curl.cainfo=c:\php\cacert.pem

НОТА:
Выключение CURLOPT_SSL_VERIFYPEER позволяет атаковать человека посередине (MITM), чего вы не хотите!


SRC1 — https://stackoverflow.com/a/14064903/797495
SRC2 — http://php.net/manual/en/function.curl-setopt.php#110457

1