2016-09-09 67 views
1

我想創建一個基本的服務器和客戶端使用OpenSSL及其BIO但BIO_do_connect返回-1。之後ERR_get_error返回0。 我試着通過編寫// check [condition]來最小化下面的代碼。在我的真實代碼中,我使用if檢查做了同樣的事情,然後打印出由ERR_get_error返回的錯誤。 (所以,如果條件爲真我打印錯誤MSG)客戶端返回-1在BIO_do_connect

這是我的服務器代碼:

// init OpenSSL 
SSL_load_error_strings(); 
ERR_load_BIO_strings(); 
SSL_library_init(); 
OpenSSL_add_all_algorithms(); 

SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); 
SSL_CTX_set_default_passwd_cb(ctx, &myPasswordCallback); 

int certState = SSL_CTX_use_certificate_file(ctx, "../certs/cert.pem", SSL_FILETYPE_PEM); 
// check certState < 0 

int keyState = SSL_CTX_use_PrivateKey_file(ctx, "../certs/key.pem", SSL_FILETYPE_PEM); 
// check keyState < 0 

BIO *serverBio = BIO_new_ssl(ctx, 0); 
// check serverBio == nullptr 

SSL *serverSsl = nullptr; 
BIO_get_ssl(serverBio, &serverSsl); 
// check serverSsl == nullptr 

SSL_set_mode(serverSsl, SSL_MODE_AUTO_RETRY); 

BIO *acceptBio = BIO_new_accept("6672"); 
// check acceptBio == nullptr 

int setupAcceptResult = BIO_do_accept(acceptBio); 
// check setupAcceptResult <= 0 

int acceptResult = BIO_do_accept(acceptBio); 
// check acceptResult <= 0 

BIO *clientBio = BIO_pop(acceptBio); 
// check clientBio == nullptr 

BIO_free_all(clientBio); 

BIO_free_all(acceptBio); 
BIO_free_all(serverBio); 

// cleanup OpenSSL 
SSL_CTX_free(ctx); 
EVP_cleanup(); 
ERR_free_strings(); 

該服務器運行正常,但我的客戶端無法連接到它:

// init OpenSSL 
SSL_load_error_strings(); 
ERR_load_BIO_strings(); 
SSL_library_init(); 
OpenSSL_add_all_algorithms(); 

SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method()); 
SSL_CTX_set_default_passwd_cb(ctx, &myPasswordCallback); 

int certState = SSL_CTX_use_certificate_file(ctx, "../certs/cert.pem", SSL_FILETYPE_PEM); 
// check certState < 0 

int keyState = SSL_CTX_use_PrivateKey_file(ctx, "../certs/key.pem", SSL_FILETYPE_PEM); 
// check keyState < 0 

BIO *clientBio = BIO_new_ssl_connect(ctx); 
SSL *clientSsl = nullptr; 
BIO_get_ssl(clientBio, &clientSsl); 
// check clientSsl == nullptr 

SSL_set_mode(clientSsl, SSL_MODE_AUTO_RETRY); 

BIO_set_conn_hostname(clientBio, "localhost:6672"); 

long connectionState = BIO_do_connect(clientBio); 
// check connectionState <= 0 
// here it fails; connectionState is -1 

long sslState = SSL_get_verify_result(clientSsl); 
// check sslState != X509_V_OK 

BIO_free_all(clientBio); 

SSL_CTX_free(ctx); 

EVP_cleanup(); 
ERR_free_strings(); 

對不起,張貼這麼多的代碼。我沒有真正找到使用BIO的OpenSSL服務器/客戶端的完整示例。

+0

['ERR_get_error'](http://www.openssl.org/docs/manmaster/crypto/ERR_get_error.html)返回的錯誤是什麼? [BIO_do_connect總是返回-1](http://stackoverflow.com/q/18450867),[bio_do_connect()返回-1](http://stackoverflow.com/q/38301089),[BIO_do_connect失敗,返回負值](http://stackoverflow.com/q/22402771)等 – jww

+0

@jww ERR_get_error返回0.這些問題並沒有幫助我。 – torkleyy

回答

0

您的服務器代碼基本上是這樣的:

  1. 設置serverBio作爲SSL
  2. 創建一個新的BIO acceptBio沒有SSL
  3. 接受連接連接 - > clientBio
  4. 免費一切

由於serverBio未被用於新創建的TCP con服務器在這裏沒有進行任何SSL握手nection clientBio。

除此之外,我建議您首先對已知良好的客戶端和服務器測試您的服務器和客戶端,以便您可以更快地找出問題所在。 openssl s_clientopenssl s_server提供這樣的測試客戶端和服務器。還有數據包捕獲(wireshark)有助於瞭解服務器和客戶端之間發生了什麼。

+0

感謝您的回答!所以我必須第三次做BIO_do_handshake?因爲我已經調用過兩次了(BIO_do_accept被定義爲BIO_do_handshake)。 – torkleyy

+0

我已經嘗試過,但它沒有完成,s_client只是連接,但它沒有從我的服務器獲得任何證書。 – torkleyy

+0

@ User9182736455:BIO_do_accept未定義爲BIO_do_handshake。您在服務器中僅使用TCP BIO。沒有任何關聯使用BIO_set_ssl或基於BIO_s_accept或類似方法創建BIO。 –