2013-05-22 926 views
1

在使用cacertinpem.c curl c代碼嘗試使用ca證書加載https頁面時,出現NSS -12286錯誤。 我正在使用路徑代碼alog中使用cacert.pem文件。但同樣的事情工作時,我嘗試使用curl -v「https://sampleserve.com:443」,在這種情況下ssl採取默認ca路徑爲「/etc/tls/certs/ca.budle.crt」curl在TLS握手中NSS -12286錯誤

但是,這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;    
} 

感謝

回答

0

我注意到的第一件事情,你這樣做:

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; 
} 
+0

謝謝..正如你上面提到的,我已經嘗試給CA證書的完整路徑和刪除ctx選項aswell.But仍然錯誤保持不變。我也嘗試使用「openssl s_client -verify 0 -connect ip:port」使用命令,我可以獲得服務器公共證書,下面是輸出的一部分log.openssl s_client -verify 0 -connect ip:port 驗證深度爲0 連接(00000003) 深度= 3 C = US,O =「VeriSign,Inc.」,OU = 3級公共主要認證機構 驗證返回:1 3 s:/ C = US/O = VeriSign,Inc./OU=Class 3公共小學C – user1495372

1

在PHP中運行此操作。我用-v在命令行上運行curl,發現NSS -12286錯誤。

原來,遠程服務器和捲曲沒有共同的密碼(nss error codes)。 我們增加了一個暗號,以捲曲的對象,像這樣:

curl_setopt($oCurl, CURLOPT_SSL_CIPHER_LIST, 'rsa_rc4_128_sha');