簡體   English   中英

OpenSSL PKCS#11簽名多進程

[英]OpenSSL PKCS#11 signing multi process

我正在調試某人為應用程序編寫的php模塊中的分段錯誤(因此,更改工作流和其他耗時的操作是不可能的)。

我有以下代碼:...

...some code... int marker=0; ENGINE_load_dynamic(); ENGINE *e=ENGINE_by_id("dynamic"); if (e==NULL) return NULL; ...some more code to set some parameters using ENGINE_ctrl_cmd_string(...)

marker++; // gets about 10 or something e=ENGINE_by_id("pkcs11"); if (e==NULL) return NULL;

這是有趣的部分-SIGSEGV:

marker++; //11 if (!ENGINE_init(e)){ std::cout<<"..error.."; ENGINE_finish(e); ENGINE_free(e); ENGINE_cleanup(); return null; }

...code using pkcs#11 token that does work....

該問題以某種隨機的方式出現。 該代碼段是php模塊的一部分。 該腳本是從PostgreSQL腳本調用的,而PostgreSQL腳本又由位於另一台服務器上的另一個php應用程序調用(不要怪我是這種設計,我在這里進行調試)。 當我快速刷新主要的php應用程序頁面時,會出現SIGSEGV,我認為它會同時多次調用上述腳本,因此嘗試同時使用來自不同進程的令牌。

我的假設正確嗎? 使用相同令牌從不同進程調用ENGINE_init / finish / free會發生沖突並導致分段錯誤嗎?

使用我的處理程序捕獲分段錯誤,該處理程序拾取標記值並在退出之前將其打印出來,這是我進行sigsegv調試時可以想到的最簡單的方法。 如果此方法可能會產生錯誤的結果,我們將不勝感激。

有什么想法嗎?

有一個README.ENGINE提供了有關引擎的討論。 我不確定它會有多大用處,因為它提出了很高的要求。 例如,“ ...源代碼可以很好地自我記錄,但是需要一些摘要和使用說明”。

但這是dynamic

新的“動態” ENGINE提供了一種低開銷的方式來支持未預先編譯並鏈接到基於OpenSSL的應用程序中的ENGINE實現。 這可能是因為現有的嵌入式實現存在已知問題,並且您希望對現有應用程序使用較新的版本。 同樣可能是因為您正在使用的應用程序(或OpenSSL庫)根本不支持您要使用的ENGINE,而ENGINE提供程序(例如,硬件供應商)正在為您提供一個獨立的實現。共享庫的形式。 “動態”的另一個用例是與希望
保持最小的占用空間,因此不要在OpenSSL的各種ENGINE實現中進行鏈接,而是讓您以“動態”可加載共享庫的形式提供它們(如果需要)。 硬件供應商應有可能提供自己的共享庫,以支持任意硬件,以與基於OpenSSL 0.9.7或更高版本的應用程序一起使用。 如果您使用的是基於0.9.7(或更高版本)的應用程序,並且僅在所需版本之后才宣布所需的支持,請要求供應商將其ENGINE反向移植到所需的版本。

“動態”如何工作?

 The dynamic ENGINE has a special flag in its implementation such that every time application code asks for the 'dynamic' ENGINE, it in fact gets its own copy of it. As such, multi-threaded code (or code that multiplexes multiple uses of 'dynamic' in a single application in any way at all) does not get confused by 'dynamic' being used to do many independent things. Other ENGINEs typically don't do this so there is only ever 1 ENGINE structure of its type (and reference counts are used to keep order). The dynamic ENGINE itself provides absolutely no cryptographic functionality, and any attempt to "initialise" the ENGINE automatically fails. All it does provide are a few "control commands" that can be used to control how it will load an external ENGINE implementation from a shared-library. To see these control commands, use the command-line; openssl engine -vvvv dynamic The "SO_PATH" control command should be used to identify the shared-library that contains the ENGINE implementation, and "NO_VCHECK" might possibly be useful if there is a minor version conflict and you (or a vendor helpdesk) is convinced you can safely ignore it. "ID" is probably only needed if a shared-library implements multiple ENGINEs, but if you know the engine id you expect to be using, it doesn't hurt to specify it (and this provides a sanity check if nothing else). "LIST_ADD" is only required if you actually wish the loaded ENGINE to be discoverable by application code later on using the ENGINE's "id". For most applications, this isn't necessary - but some application authors may have nifty reasons for using it. The "LOAD" command is the only one that takes no parameters and is the command that uses the settings from any previous commands to actually *load* the shared-library ENGINE implementation. If this command succeeds, the (copy of the) 'dynamic' ENGINE will magically morph into the ENGINE that has been loaded from the shared-library. As such, any control commands supported by the loaded ENGINE could then be executed as per normal. Eg. if ENGINE "foo" is implemented in the shared-library "libfoo.so" and it supports some special control command "CMD_FOO", the following code would load and use it (NB: obviously this code has no error checking); ENGINE *e = ENGINE_by_id("dynamic"); ENGINE_ctrl_cmd_string(e, "SO_PATH", "/lib/libfoo.so", 0); ENGINE_ctrl_cmd_string(e, "ID", "foo", 0); ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0); ENGINE_ctrl_cmd_string(e, "CMD_FOO", "some input data", 0); For testing, the "openssl engine" utility can be useful for this sort of thing. For example the above code excerpt would achieve much the same result as; openssl engine dynamic \\ -pre SO_PATH:/lib/libfoo.so \\ -pre ID:foo \\ -pre LOAD \\ -pre "CMD_FOO:some input data" Or to simply see the list of commands supported by the "foo" ENGINE; openssl engine -vvvv dynamic \\ -pre SO_PATH:/lib/libfoo.so \\ -pre ID:foo \\ -pre LOAD Applications that support the ENGINE API and more specifically, the "control commands" mechanism, will provide some way for you to pass such commands through to ENGINEs. As such, you would select "dynamic" as the ENGINE to use, and the parameters/commands you pass would control the *actual* ENGINE used. Each command is actually a name-value pair and the value can sometimes be omitted (eg. the "LOAD" command). Whilst the syntax demonstrated in "openssl engine" uses a colon to separate the command name from the value, applications may provide their own syntax for making that separation (eg. a win32 registry key-value pair may be used by some applications). The reason for the "-pre" syntax in the "openssl engine" utility is that some commands might be issued to an ENGINE *after* it has been initialised for use. Eg. if an ENGINE implementation requires a smart-card to be inserted during initialisation (or a PIN to be typed, or whatever), there may be a control command you can issue afterwards to "forget" the smart-card so that additional initialisation is no longer possible. In applications such as web-servers, where potentially volatile code may run on the same host system, this may provide some arguable security value. In such a case, the command would be passed to the ENGINE after it has been initialised for use, and so the "-post" switch would be used instead. Applications may provide a different syntax for supporting this distinction, and some may simply not provide it at all ("-pre" is almost always what you're after, in reality). 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM