【问题标题】:SSL CA Certificates - LibCurl C Language (Linux)SSL CA 证书 - LibCurl C 语言 (Linux)
【发布时间】: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


【解决方案1】:

我已经做到了。 实际上这是服务器 CA 的问题。 我从主机下载了证书链,然后我使用 openssl 命令进行转换:

  openssl x509 -in raiz_v2.cer -out raiz_v2.pem
  openssl x509 -in ac_certsign_g6.cer -out ac_certsign_g6.pem
  openssl x509 -in ac_certsign_mult_g5.cer -out ac_certsign_mult_g5.pem

所以我统一他们使用:

 cat raiz_v2.pem > cacert.pem
 cat ac_certsign_g6.pem >> cacert.pem
 cat ac_certsign_mult_g5.pem >> cacert.pem

然后我使用 CURLOPT_CAINFO 选项指向 cacert.pem。

【讨论】:

    猜你喜欢
    • 2012-03-24
    • 1970-01-01
    • 1970-01-01
    • 2021-01-17
    • 2022-08-17
    • 2011-02-15
    • 2019-12-17
    • 2021-12-18
    • 2021-04-29
    相关资源
    最近更新 更多