2012-09-06 74 views
0

我用openssl編寫代碼來連接tls下的服務器。如果我從pem文件加載證書,它可以正常工作。但是,如果我從pfx文件加載證書,則會在調用SSL_connect時發生SSL_ERROR_SSL。我不知道加載pfx文件的過程是否錯誤。過程如下。SSL_ERROR__SSL在調用SSL_connect時發生

FILE* fp = fopen("cert.pfx", "rb"); 
PKCS12* p12 = d2i_PKCS12_fp(fp, NULL); 
PKCS12_parse(p12, NULL, &private_key, &certificate, &ca_certificates); 
SSL_CTX_use_certificate(ctx, certificate); 
SSL_CTX_use_PrivateKey(ctx, private_key); 
SSL_CTX_check_private_key(ctx); 
SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(ca_certificates, i); 
SSL_CTX_add_client_CA(ctx, sk_X509_value(ca_certificates, i); 
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); 
SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); 
... 
SSL* ssl = SSL_new(ssl_context); 
SSL_set_fd(ssl, sockfd); 
SSL_connect(ssl); 
... 

我已經用其他客戶端測試了pfx文件。它運作良好。所以問題不在於pfx文件。有沒有openssl的選項會失敗的連接?或者我沒有正確設置CA證書? pfx文件包含我自己簽名的CA。但它適用於其他客戶端。

在SSL_connect()失敗後,我調用了ERR_get_error()。並且獲得證書驗證失敗。所以我認爲在上面加載pfx文件的過程中出現了一些問題。也許我不會正確添加CA證書。任何人都可以告訴我加載pfx的正確流程。

請幫忙!

回答

0

是你的i變量計數器的大小爲sk_num(ca_certificates)?如果是,請嘗試刪除我認爲不適合客戶的線路SSL_CTX_add_client_CA(不確定,難以理解)。

而且,在你的錯誤處理,把下面的行,找出了原因:

SSL_load_error_strings(); // just once 
char msg[1024]; 
ERR_error_string_n(ERR_get_error(), err_msg, sizeof(err_msg)); 
printf("%s\n", msg);` 

或者,也可以嘗試直接獲得SSL錯誤:

int ssl_error = SSL_get_verify_result(ssl); 

產生的int可以在這裏檢查page

+0

我找到了解決方案。此代碼適用於客戶端使用。我研究了SSL_CTX_load_verify_locations()函數的來源。它通過X509_STORE_add_cert()函數將ca證書添加到SSL上下文的cert_store中。我做了同樣的工作。所以感謝您的幫助。 – geeker

1

我發現,使用SSL_CTX_add_extra_chain_cert添加證書的順序很重要。證書由PKCS12_parse添加的oder必須已從libssl 0.9.8更改爲libssl1.0。 這就是爲什麼我使用下面的代碼切換到將它們添加到證書商店的原因。

X509_STORE * certStore = SSL_CTX_get_cert_store(ctx); 
for(int i = 0; i < sk_X509_num(ca) ; i++) 
{ 
    if (X509_STORE_add_cert(certStore, sk_X509_value(ca_certificates, i))==0) 
    { 
     ERR_print_errors_fp (stderr); 
    } 
} 
相關問題