OpenSSL

密碼學和 SSL/TLS 工具包

openssl-threads

名稱

openssl-threads - OpenSSL 中執行緒安全性的概觀

說明

在此手冊頁中,我們使用術語執行緒安全性來表示物件或函式可以同時由多個執行緒使用。

OpenSSL 可以建置為支援或不支援執行緒。此支援最重要的用途是讓 OpenSSL 本身可以使用單一一致的 API,如 CRYPTO_THREAD_run_once(3) 中的「範例」 所示。多平台應用程式也可以使用此 API。

特別是,設定為支援執行緒並不表示所有 OpenSSL 物件都是執行緒安全的。請特別注意:大多數物件不適合同時使用。此處提供一些一般性的高階指導原則,而例外狀況應記載在特定手冊頁中。

OpenSSL 執行緒 API 的一個主要用途是實作參考計數。OpenSSL 中的許多物件都是參考計數的,因此資源不會在移除最後一個參考之前釋放。參考通常會自動增加(例如將X509 憑證物件新增到X509_STORE 信任儲存區時)。通常會有object_up_ref() 函式可用於增加參考計數。當程式結束時,如果沒有將object_up_ref() 呼叫與正確數量的object_free() 呼叫配對,就會導致記憶體外洩。

許多物件都設定並取得 API 以設定物件中的屬性。set0 會將擁有權從呼叫者傳遞給物件,而 get0 會傳回指標,但屬性擁有權仍屬於物件,並傳回其參考。set1get1 函式不會變更擁有權,而是更新屬性的參考計數,讓物件在呼叫者和物件之間共用;呼叫者必須在完成後釋放傳回的屬性。涉及屬性本身具有參考計數,但僅以 setget 命名的函式是歷史遺留的;文件必須說明如何處理參考。只要符合擁有權需求,且不修改共用物件,取得方法通常是執行緒安全的。設定方法或修改共用物件通常不是執行緒安全的,如下所述。

只要呼叫的 API 沒有修改物件,物件就是執行緒安全的;在此情況下,參數通常會在 API 中標記為 const。並非所有參數都以這種方式標記。請注意,const 宣告並不表示不可變;例如 X509_cmp(3) 會取得指標指向 const 物件,但實作會使用 C 轉型來移除此指標,以便鎖定物件、產生並快取 DER 編碼,等等。

執行緒安全的另一個範例是當物件的內部狀態更新,例如快取值,會使用鎖定來執行。上述參考計數 API 就是一個範例。

然而,在所有情況下,通常不建議一個執行緒變更物件,例如設定私鑰或公鑰的元素,而另一個執行緒正在使用該物件,例如驗證簽章。

相同的 API 通常可以在不同的物件上同時使用,而不會產生干擾。例如,兩個執行緒可以使用兩個不同的 EVP_PKEY_CTX 物件計算簽章。

對於隱含的全球狀態或單例,執行緒安全性取決於該設施。CRYPTO_secure_malloc(3) 及相關 API 有自己的鎖定,而 CRYPTO_malloc(3) 假設底層平台配置會執行必要的鎖定。有些 API,例如 NCONF_load(3) 及相關 API,完全不會執行鎖定;這可以視為一個錯誤。

一個獨立但相關的問題是在其他物件從「工廠」物件建立後修改「工廠」物件。例如,SSL_CTX_new(3) 建立的 SSL_CTX 物件用於透過呼叫 SSL_new(3) 建立每個連線的 SSL 物件。在這個特定情況下,而且可能也適用於一般工廠方法,在用於建立其他物件後修改工廠物件是不安全的。

另請參閱

CRYPTO_THREAD_run_once(3),本機系統執行緒文件。

錯誤

必須承認這個頁面非常不完整。

版權所有 2021 The OpenSSL Project Authors。保留所有權利。

根據 Apache License 2.0(「授權」)授權。您只能在遵守授權的情況下使用此檔案。您可以在原始程式碼散佈中的 LICENSE 檔案或 https://www.openssl.org/source/license.html 取得副本。