2

尝试使用 cacertinpem.c curl c 代码使用 ca 证书加载 https 页面时出现 NSS -12286 错误。我在带有路径的代码中使用 cacert.pem 文件。但是当我尝试使用 curl -v“ https://sampleserve.com:443 ”时,同样的事情也在起作用,在这种情况下,ssl 将默认 ca 路径作为“/etc/tls/certs/ca.budle.crt”

但是此 c 代码不适用于默认 ca 位置和 ca 的外部路径选择。

这个错误的原因是什么(NSS -12286)。

Error:
* About to connect() to fiservices.sterlingbankng.com port 443 (#0)
*   Trying 1.1.1.1... * Connection timed out
*   Trying 1.1.1.2... * connected
* Connected to fiservices.sterlingbankng.com (1.1.1.2) port 443 (#0)
* Initializing NSS with certpath: /etc/pki/nssdb
*   CAfile: ./cacert.pem   CApath: ./cacert.pem
* NSS error -12286
* Error in TLS handshake, trying SSLv3...

GET /CanFI/ HTTP/1.1
Host: sampleserver.com
Accept: */*

* Connection died, retrying a fresh connect
* Closing connection #0
* Issue another request to this URL: 'https://sampleserver.com'
* About to connect() to sampleserver.com port 443 (#0)
*   Trying 1.1.1.1... * Connection timed out
*   Trying 1.1.1.2... * connected
* Connected to sampleserver.com (1.1.1.2) port 443 (#0)
* TLS disabled due to previous handshake failure
*   CAfile: ./cacert.pem
  CApath: ./cacert.pem
* NSS error -12286
* Closing connection #0
* SSL connect error

示例代码:

size_t writefunction( void *ptr, size_t size, size_t nmemb, void *stream)
{
  fwrite(ptr,size,nmemb,stream);              

  return(nmemb*size);                   
}

static CURLcode sslctx_function(CURL * curl, void * sslctx, void * parm)
{

  X509_STORE * store;

  X509 * cert=NULL;   

  BIO * bio;                             

  char * mypem = "-----BEGIN CERTIFICATE-----\n"\     "-----END CERTIFICATE-----\n";  //public certificate    

}     

int main(void)    
{

  CURL * ch;

  CURLcode rv;

  rv=curl_global_init(CURL_GLOBAL_ALL);

  ch=curl_easy_init();

  rv=curl_easy_setopt(ch,CURLOPT_VERBOSE, 1L);

  rv=curl_easy_setopt(ch,CURLOPT_HEADER, 0L);

  rv=curl_easy_setopt(ch,CURLOPT_NOPROGRESS, 1L);

  rv=curl_easy_setopt(ch,CURLOPT_NOSIGNAL, 1L);

  rv=curl_easy_setopt(ch,CURLOPT_WRITEFUNCTION, *writefunction);

  rv=curl_easy_setopt(ch,CURLOPT_WRITEDATA, stdout);

  rv=curl_easy_setopt(ch,CURLOPT_HEADERFUNCTION, *writefunction);

  rv=curl_easy_setopt(ch,CURLOPT_WRITEHEADER, stderr);

  rv=curl_easy_setopt(ch,CURLOPT_SSLCERTTYPE,"PEM");  

  rv=curl_easy_setopt (ch, CURLOPT_CAPATH, "./cacert.pem" );  

  rv=curl_easy_setopt (ch, CURLOPT_CAINFO, "./cacert.pem" ); 

  rv=curl_easy_setopt(ch,CURLOPT_SSL_VERIFYPEER,1L); 

  rv=curl_easy_setopt(ch, CURLOPT_URL, "https://");   

  rv=curl_easy_perform(ch);           

  if (rv==CURLE_OK)             

    printf("*** transfer succeeded ***\n"); 

  else                   

    printf("*** transfer failed ***\n"); 

  rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function); 

  rv=curl_easy_perform(ch);              

  if (rv==CURLE_OK)             

    printf("*** transfer succeeded ***\n");               
  else             

    printf("*** transfer failed ***\n");               

  curl_easy_cleanup(ch);  

  curl_global_cleanup();  

  return rv;               
}

谢谢

4

3 回答 3

1

在 PHP 中遇到了这个问题。我在命令行上使用 -v 运行 curl 并发现 NSS -12286 错误。

事实证明,远程服务器和 curl 没有共同的密码(nss 错误代码)。我们向 curl 对象添加了一个密码,如下所示:

curl_setopt($oCurl, CURLOPT_SSL_CIPHER_LIST, 'rsa_rc4_128_sha');
于 2013-08-13T19:28:44.040 回答
1

我注意到的第一件事,你正在做:

rv=curl_easy_setopt (ch, CURLOPT_CAPATH, "./cacert.pem" );

需要指定一个“字符串命名包含多个 CA 证书以验证对等方的目录”。从手册页。你可能想要"/etc/tls/certs/"

此外,它会出现以下行:

rv=curl_easy_setopt(ch,CURLOPT_SSL_CTX_FUNCTION, *sslctx_function); 

什么都不做。我这样说是因为再次从手册页中,“此选项仅适用于由 OpenSSL 提供支持的 libcurl”。我这样说是因为,您的错误日志有“NSS 错误”

我使用 ssl 的经验仅限于使用 openssl。我发现命令行功能openssl s_client很有帮助。话虽如此,很容易错过配置您的设置。许多函数和命令行选项甚至会尝试使用最疯狂的输入,从而导致红鲱鱼错误。

编辑: 我对您的程序的尝试成功完成。

#include <stdio.h>
#include <curl/curl.h>

int main(void)
{
    CURL * ch;
    CURLcode rv;
    rv=curl_global_init(CURL_GLOBAL_ALL);
    ch=curl_easy_init();
    rv=curl_easy_setopt(ch, CURLOPT_VERBOSE, 1L);
    rv=curl_easy_setopt(ch, CURLOPT_CAPATH, "/etc/ssl/certs");
    rv=curl_easy_setopt(ch, CURLOPT_URL, "https://");
    rv=curl_easy_perform(ch);
    if (rv==CURLE_OK) {
        printf("*** transfer succeeded ***\n");
    }
    else {
        printf("*** transfer failed ***\n");
    }
    curl_easy_cleanup(ch);
    curl_global_cleanup();
    return rv;
}
于 2013-05-22T07:27:18.463 回答
0

我们在连接配置为仅接受 PCI DSS 兼容密码的 Plesk Centos 服务器和开箱即用没有重叠密码的 Binami/DigitalOcean Debian 堆栈之间遇到了这个问题(如 12286 所示)。答案是更新 DigitalOcean Debian 以使用与其他服务器相同的密码套件并重新启动 apache。

您显然可以更改任一机器上的密码套件,或同时更改两者 - 但我们选择全面保留 PCI DSS 密码套件。

于 2016-03-28T14:55:28.380 回答