2014-12-25 75 views
3

我有一個Linux進程需要充當SSL服務器(接受來自其他客戶端的服務連接),但也需要在同一進程中啓動與其他SSL服務器的客戶端會話。OpenSSL是否允許每個進程有多個SSL_CTX,一個SSL_CTX用於服務器會話,另一個SSL_CTX用於客戶端會話?

我打算使用兩個SSL_CTX_new()函數調用創建兩個單獨的SSL_CTX句柄,一個調用服務器方法,另一個調用客戶端方法。是否支持在單個進程中雙重使用OpenSSL?我希望OpenSSL使用SSL_CTX句柄 - 並且不依賴於全局或靜態局部變量 - 它可能需要創建和服務新會話的所有上下文信息。這是一個好的假設嗎?

回答

1

根據我的經驗:只要您正確初始化了OpenSSL庫,就可以自由創建幾個上下文。在OpenSSL手冊頁中描述的設置線程鎖之後,我在同一個應用程序中使用了兩個不同的上下文,而沒有任何問題:http://www.openssl.org/docs/crypto/threads.html。如果您的應用程序不使用線程,則根本不需要此類設置。

6

的OpenSSL是否允許每個進程多個SSL_CTX,用於服務器會話一個SSL_CTX ...

是的,這是很常見的。它在使用服務器名稱指示時很常見。在SNI的情況下,每個服務器的默認值爲SSL_CTX,然後爲SSL_CTX。如果客戶端在其ClientHello中包含服務器名稱擴展名,則您將返回默認SSL_CTX或SNI回調中的專用SSL_CTX

SSL_CTX被庫引用計數,所以在調用SSL_CTX_free之一引用計數下降到0之前,它們不會真正釋放。

這裏是SNI一些相關的問題,如果有興趣:

第一偶數爲您提供的回調代碼。 GetServerContext返回基於服務器名稱的新(或現有的)背景:

/* Need a new certificate for this domain */ 
SSL_CTX* ctx = GetServerContext(servername); 
if(ctx == NULL) handleFailure(); 
... 

/* Set new context */ 
SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx); 

的OpenSSL是否允許每個進程多個SSL_CTX,...等SSL_CTX客戶端會話?

是的,但你通常不使用它。客戶端不是通常像服務器那樣更改它的SSL_CTX

在客戶端連接到多個服務器的情況下,通常您將通道參數設置爲SSL_CTX_set_options,並將其用於每個服務器(甚至不同的服務器)的每個連接。參數可以是協議(TLS 1.1,TLS 1.2),密碼套件(刪除匿名密碼套件)和壓縮。有關更多詳細信息,請參閱下面關於SSL/TLS Client的討論。

客戶端確實需要設置服務器的主機名,但這是在SSL*上使用SSL_set_tlsext_host_name完成的,而不是SSL_CTX*。或者,如果您正在使用BIO's,它看起來會是這樣的。注意BIO有效地包裝了SSL*,這樣你就不會修改SSL_CTX*

BIO* web = BIO_new_ssl_connect(ctx); 
if(web == NULL) handleFailure(); 

res = BIO_set_conn_hostname(web, HOST_NAME ":" HOST_PORT); 
if(res != 1) handleFailure(); 

...一個與服務器的方法調用和其他與客戶端的方法

不需要。它們之間的唯一區別(如SSLv23_client_methodSSLv23_server_method)是幾個功能指針,用於看不到結構中的功能connectaccept。客戶請致電connect,服務器致電accept

相反,只是使用通用SSLv23_method,一切都會好起來的。您仍然需要調整SSL_CTX_set_options的上下文,因爲SSL_CTX_new提供的默認上下文包含弱/受傷/斷開的協議和密碼。

OpenSSL的維基頁面SSL/TLS Client顯示如何調整SSL_CTX對象。它會執行以下,並且其可以通過客戶端和服務器中使用:

  • 禁用的SSLv2
  • 禁用SSLv3的
  • 禁用壓縮
  • 禁用匿名協議
  • 使用「強」密碼

使用像"HIGH: ... : !SRP:!PSK"這樣的自定義密碼列表消除了許多弱/受傷的密碼,並刪除了一串密碼sui可能在服務器上不支持這些測試(因此客戶沒有理由對其進行廣告)。 SRP是Thomas Wu的安全遠程密碼,PSK是預先共享密鑰。​​基於它們,所以它在ClientHello中節省了近180個字節。


是支持一個單一的過程中這種兩用的OpenSSL?

是的。


我的希望是,OpenSSL的使用SSL_CTX手柄 - 並且不依賴於全局或靜態局部變量

嗯,你的運氣那裏。有很多全局變量,其中一些是動態分配的,其中一些沒有被釋放。

如果您使用Java或C#,則每次共享對象被加載/卸載時都會泄漏它們。所以你的Java或C#程序會隨着時間的推移積累越來越多的內存。 OpenSSL開發者覺得不值得他們的時間。例如,請參閱OpenSSL郵件列表上的Small memory leak on multithreaded server

+0

綜合答案。謝謝!我不得不在SNI上稍微閱讀一下。聽起來像一個SSL_CTX_new(SSL_v23_method)是我需要用作客戶端(使用connect()調用)和服務器(使用accept())調用所需要的。正確? – perplexed

+0

在OpenSSL中使用全局變量和靜態變量實際上是一個我不應該擔心的實現細節。我之所以提到它們只是因爲我擔心全局變量可能帶有特定於上下文的信息,這些信息會阻止使用多個SSL_CTX。 – perplexed

+0

我很好奇,從多個線程作爲客戶端使用單個SSL_CTX到多個主機的情況如何?告訴我是否太離題,但這個線程似乎是最接近我的問題/問題。假如我在反向代理的情況下使用openSSL,那麼使用配置了多個線程/主機之間共享的必要驗證證書/路徑的單個CTX是否安全?我試圖確定我的新發現的「解密失敗或壞記錄mac」是否與此有關。 –

相關問題