我使用--openssldir=< path to ssl >/ssl(链接到/etc/ssl)构建了openssl 1.1.1,并使用--with-ssl=< path to openssl >构建了curl 7.76.1。 编译了以下代码:
#include <iostream>
#include <curl/curl.h>
int main()
{
CURL *curl = curl_easy_init();
if (curl)
{
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Accept: */*");
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_URL, "https://<address>");
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "<some data>");
curl_easy_perform(curl);
curl_slist_free_all(headers)
}
curl_easy_cleanup(curl);
}
当我运行此代码时,出现错误:
curl_easy_operation() failed : Problem with the SSL CA cert (path? access rights?)
我在 strace 中看到,它正在尝试打开“/etc/pki/tls/certs/ca-bundle.crt” 但在我的机器(Ubuntu 12 和 Ubuntu 14)中没有文件夹“/etc/pki”。 为什么curl使用“/etc/pki”而不是“/etc/ssl”?我怎样才能强制它使用“/etc/ssl”? 我尝试使用 --without-nss 构建curl,但没有成功。
编辑: 我的解决方案是添加以下代码:
ifstream caBundleFile("/etc/pki/tls/certs/ca-bundle.crt");
if (caBundleFile.good()) {
curl_easy_setopt(curl, CURLOPT_CAINFO, "/etc/pki/tls/certs/ca-bundle.crt");
caBundleFile.close();
} else {
curl_easy_setopt(curl, CURLOPT_CAPATH, "/etc/ssl/certs");
}
有两种流行的存储根证书的格式。第一个适用于 RHEL/Centos 等,第二个适用于 Ubuntu 等发行版。
对于未来的读者,答案是设置curl CA路径
#include <iostream>
#include <curl/curl.h>
const std::string curlCertPath = "./keys/curl-ca-bundle.crt";
int main()
{
CURL *curl;
CURLcode res;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
curl_easy_setopt(curl, CURLOPT_CAINFO, curlCertPath.c_str());
res = curl_easy_perform(curl);
if (res == CURLE_OK)
{
std::cout << "Curl worked" << std::endl;
}
else
{
std::cout << "Error: curl failed: " << curl_easy_strerror(res) << std::endl;
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}