繁体   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