【发布时间】:2014-11-03 17:38:11
【问题描述】:
我正在使用 WebService,但我仍然无法验证对等证书。 我使用 libCurl 转 C 语言,这是输出:
无法执行发布,错误:无法使用给定的 CA 证书对对等证书进行身份验证
所以我尝试通过 openssl 命令测试连接:
openssl s_client -connect homnfce.sefaz.am.gov.br:443 -cert cert.pem -key nfcek.pem
然后:
Verify return code: 20 (unable to get local issuer certificate)
进一步,我查看了服务器证书,发现它们有一个证书链。 所以我下载了它们并使用 keytool 添加:
keytool -import -trustcacerts -file cert1.cer -alias mykey
keytool -import -trustcacerts -file cert2.cer -alias mykey2
keytool -import -trustcacerts -file cert3.cer -alias mykey3
即使进行了这些更改,我仍然无法验证对等证书。
我认为在设置 CURLOPTs 时可能表示错误,以下是代码摘录:
if (curl_easy_setopt(curl, CURLOPT_POST, 1) != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POST, 1) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_URL, "https://homnfce.sefaz.am.gov.br/nfce-services-nac/services/NfeStatusServico2?wsdl") != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_URL) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_PORT, 443) != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_PORT, 443) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_SSLCERT, "cert.pem") != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSLCERT) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_SSLKEY, "nfcek.pem") != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSLKEY) failed");
return -1;
}
sprintf(szCertPath, "%s","/home/CAcerts/");
if (curl_easy_setopt(curl, CURLOPT_CAPATH, szCertPath) != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, iLen) != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_SSLCERTPASSWD, szMyPw) != CURLE_OK ) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_TIMEOUT) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_READDATA, pfChk) != CURLE_OK ) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_WRITEDATA, pfAnswer) != CURLE_OK ) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_WRITEDATA) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_TIMEOUT, iOnlineServerTimeout) != CURLE_OK ) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_TIMEOUT) failed");
return -1;
}
if (curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) != CURLE_OK) {
if ( DEBUG_DETAILS ) vTrace("curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1) failed");
return __LINE__;
}
if ( (res = curl_easy_perform(curl)) != CURLE_OK ){
if ( DEBUG_DETAILS ) vTraceStr("iNFCE_CurlReq(): Cannot Perform Post, Err: %s\n", (char *)curl_easy_strerror(res));
return -1;
}
重要的是我不能使用不安全模式选项忽略对等身份验证 (CURLOPT_SSL_VERIFYPEER = 0)。
有什么想法吗?有什么问题?
提前致谢
【问题讨论】:
-
您能告诉我们您的 curl 使用的是什么 SSL 库吗?我以为
keytool是用于 Java 密钥存储的? -
如何发现 curl 使用的是哪个 SSL 库?我认为它使用 OpenSSL 默认值。
-
在您的
libcurl.so上尝试ldd。您是否尝试过将这三个证书添加到CURLOPT_CAPATH(在您的示例中为/home/CAcerts/)并按照此处指定的 curl.haxx.se/libcurl/c/CURLOPT_CAPATH.html 运行 OpenSSL c_rehash? -
我没有使用 libcurl 动态链接,我的意思是,我不使用 dlopen 来使用 libcurl.so 的功能,我添加了 curl.h 头文件。顺便说一句,我检查了我的 libcurl.so 的 ldd,它使用了 libssl.so 我正在处理 c_rehash 函数来 openssl
-
您的任何 .pem 文件是否是实际的自签名根证书(主题 == 颁发者)?默认情况下,OpenSSL 会尝试将信任链构建为自签名根证书。检查openssl.6102.n7.nabble.com/… 进行讨论。
标签: c linux ssl certificate libcurl