使用libcurl从c++ /Windows发布到需要客户端证书进行身份验证的API ?CURLE_SSL_CERTPR



我已经搜索了这里,但没有找到任何匹配的。我用curl.exe测试了一下,效果很好。然后我尝试了一个小的测试程序。在VS2017中创建了一个命令行Win32项目,并从simplessl.c中复制了代码。问题是,无论我尝试什么证书,我总是得到CURLE_SSL_CERTPROBLEM。这表明客户端证书是错误的。我甚至尝试了2048位证书和密钥从这里:https://fm4dd.com/openssl/certexamples.shtm不知道如何排除故障。

我使用的测试程序:

#include "pch.h"
#include <iostream>
#include <curl/curl.h>
int main()
{
std::cout << "Hello World!n"; 
CURL *curl;
CURLcode res;
FILE *headerfile;
const char *pPassphrase = NULL;
static const char *pCertFile = "C:\Prog\TestCurl\2048b-rsa-example-cert.pem";
static const char *pCACertFile = "cacert.pem";
static const char *pHeaderFile = "C:\Prog\TestCurl\requestWith.txt";
const char *pKeyName;
const char *pKeyType;
const char *pEngine;
#ifdef USE_ENGINE
pKeyName = "rsa_test";
pKeyType = "ENG";
pEngine = "chil";            /* for nChiper HSM... */
#else
pKeyName = "C:\Prog\TestCurl\2048b-rsa-example-keypair.pem";
pKeyType = "PEM";
pEngine = NULL;
#endif
headerfile = fopen(pHeaderFile, "wb");
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
/* what call to write: */
//curl_easy_setopt(curl, CURLOPT_URL, "https://pintatesti.vero.fi/FIS/Return/IIT/Test/GetWithholdingPercentage/v1");
curl_easy_setopt(curl, CURLOPT_URL, "https://www.pedago.fi");
curl_easy_setopt(curl, CURLOPT_HEADERDATA, headerfile);
do { /* dummy loop, just to break out from */
if (pEngine) {
/* use crypto engine */
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE, pEngine) != CURLE_OK) {
/* load the crypto engine */
fprintf(stderr, "can't set crypto enginen");
break;
}
if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != CURLE_OK) {
/* set the crypto engine as default */
/* only needed for the first time you load
a engine in a curl object... */
fprintf(stderr, "can't set crypto engine as defaultn");
break;
}
}
/* cert is stored PEM coded in file... */
/* since PEM is default, we needn't set it for PEM */
curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
/* set the cert for client authentication */
curl_easy_setopt(curl, CURLOPT_SSLCERT, pCertFile);
/* sorry, for engine we must set the passphrase
(if the key has one...) */
if (pPassphrase)
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, pPassphrase);
/* if we use a key stored in a crypto engine,
we must set the key type to "ENG" */
curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, pKeyType);
/* set the private key (file or ID in engine) */
curl_easy_setopt(curl, CURLOPT_SSLKEY, pKeyName);
/* set the file with the certs vaildating the server */
//curl_easy_setopt(curl, CURLOPT_CAINFO, pCACertFile);
/* disconnect if we can't validate server's cert */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
/* Perform the request, res will get the return code */
res = curl_easy_perform(curl);
/* Check for errors */
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %sn",
curl_easy_strerror(res));
/* we are done... */
} while (0);
/* always cleanup */
curl_easy_cleanup(curl);
}
curl_global_cleanup();
return 0;
}

编辑:我得到的潜在错误是"渠道:证书格式兼容性错误"我能找到的唯一事件是在通道。c中,它与P12类型比较,但我的证书是PEM?

Edit2:所以如果我将证书导入本地存储,它确实有效,这是我绝对想要避免的!还有curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);看起来是个好主意!

编辑3:搞定了。可能与:在libcurl ssl请求中发送客户端证书有问题,我错过了什么?这是从2019年开始的。不过,我更希望将证书保存在文件中。

Edit4: "libcurl/7.79.1 channel WinIDN">

我在朋友的帮助下解决了这个问题。Libcurl在Windows上作为默认编译时将默认为channel。要覆盖它,您需要构建OpenSSL,因此:nmake /f Makefile.vc mode=static DEBUG=yes WITH_SSL=static WITH_DEVEL=C:ProgOpenSSL-Win32_111L。重要的关键字是WITH_SSL=static或dynamic和WITH_DEVEL=您的OpenSSL文件所在的路径。当以这种方式构建时,您可以为证书和密钥提供文件路径,例如:curl_easy_setopt(curl, CURLOPT_SSLCERT, m_Certificate.GetString());

这让你从Windows中混乱的证书处理中解脱出来,并让你将证书保存在应用程序本身。

相关内容

  • 没有找到相关文章

最新更新