2014-02-19 53 views
1

我在Linux中編寫了一個C庫(比方說,libA),它利用Openssl來執行base64編解碼器,哈希等。一些其他項目例如projB)利用libA做些事情,而這些項目本身也會調用Openssl API。所以,projB調用Openssl的API的方式有兩種:Openssl線程安全回調函數註冊既有直接調用也有間接調用

  1. 呼叫Openssl的的API直接:projB - > Openssl的
  2. 呼叫Openssl的API的間接:projB - >力霸 - > Openssl的

同時,這是officially announced,Openssl不是線程安全的,除非至少有兩個回調函數註冊到Openssl中:

  • 空隙ssl_locking_function(INT模式,INT N,常量字符*文件,INT線)
  • 無符號長ssl_threadid_function()

LIBA暴露下面的API來projB:

  • int InitA(void)
  • int ActionStuff()
  • 無效DestroyA()

爲了確保的OpenSSL線程安全,是有兩種解決方案:

#1。 libA在InitA中將回調函數註冊到Openssl中()
#2。 projB註冊回調函數到Openssl的初始化時,調用的API力霸面前,力霸沒有做回調註冊

有了解決方案#1,力霸本身是線程安全的,對於調用的API Openssl的。但是,projB還必須確保其線程安全性,並且它將採取類似的將回調函數註冊到Openssl的操作。

假設LIBA註冊以下回調函數

  • 空隙ssl_locking_function_A(INT模式,詮釋N,常量字符*文件,INT線)
  • 無符號長ssl_threadid_function_A()

和projB寄存器這些

  • 無效ssl_locking_function_B(INT模式,詮釋N,爲const char *文件,INT線)
  • 無符號長ssl_threadid_function_B()

據我瞭解,力霸的回調函數後projB的註冊,

  1. projB初始化
  2. :最終,projB的回調函數是由力霸的陰影
  3. projB註冊ssl_locking_function_B()和ssl_threadid_function_B()到Openssl的
  4. projB調用INITA()
  5. 力霸註冊ssl_locking_function_A()和ssl_threadid_function_A()到Openssl的
  6. projB調用ActionStuff()
  7. ...
  8. projB調用DestroyA()
  9. projB反初始化

我的問題是,哪種解決方案更好,#1或#2?有沒有更好的解決方案?

+0

你是說'projB'意識到'libA'正在使用OpenSSL,但也想直接使用OpenSSL本身? – jxh

回答

2

它正式宣佈,OpenSSL是不是線程安全的,除非至少兩個回調函數被註冊到OpenSSL:已

叉安全和信號安全性更差。參見例如,Random Fork SafetyLibcrypto Fork Safety


爲了確保的OpenSSL線程安全,是有兩種解決方案:

我相信這是第三.... OpenSSL提供了一個定義一個名爲OPENSSL_THREADS。如果定義了OPENSSL_THREADS,則OpenSSL由線程支持構建。請務必包含<openssl/opensslconf.h>以獲得準確的結果。

LibALibB的初始化期間,如果需要,任一庫都應安裝鎖。我相信你可以檢查CRYPTO_THREADID_get_callback,如果它爲null,那麼你應該初始化鎖。您還應該包含一個狀態變量,以便在關閉時清理資源。

在現實中,你真的想知道lock_cs<openssl source>/crypto/th-lock.c的地位。這就是鎖陣列的地方。但它的靜態,所以你不能去它。


我的問題是,該解決方案是更好的,1號或2?有沒有更好的解決方案?

實際上,您可能會發現這些庫不會執行任何操作,並將它留給使用該庫的開發人員(儘管有可能的競賽)。最好的RTFM。最安全的解決方案可能是:(1)如果OpenSSL支持線程,(2)您的庫需要線程和(3)線程鎖未安裝,則在初始化期間安裝鎖。

+0

https://www.openssl.org/support/faq.html#PROG1宣佈「OpenSSL自動使用標準庫的多線程版本。多線程應用程序必須通過調用CRYPTO_set_locking_callback()爲OpenSSL提供兩個回調函數和CRYPTO_set_id_callback()「。據我所知,即使「./config threads」在構建Openssl之前完成,如果兩個回調函數沒有註冊,它仍然不是線程安全的。真的嗎? – yasi

相關問題