[openssl-users] Loading engines recursively and crypto engine lock

Jakob Bohm jb-openssl at wisemo.com
Wed Aug 10 13:31:50 UTC 2016

On 08/08/2016 13:39, Krzysztof Konopko wrote:
> Hi,
> TL;DR;
> Is it allowed to initialise engines recursively, ie. call 
> `engine2->init` from `engine1->init`?
> --
> I have a solution in a consumer product based on OpenSSL 1.0.2 series 
> that uses two engines: one (engine1) for selecting client certificate 
> chain (TLS client auth) and another one (engine2) for RPC operations 
> on associated private keys stored in H/W.  This works only if supplied 
> (installed) locks are recursive as for each engine initialisation 
> `CRYPTO_LOCK_ENGINE` is taken.
> From what I see, OpenSSL 1.1.x onward, provides locking internally and 
> it's non-recursive.  Also `lock_dbg_cb()` implementation in OpenSSL 
> before 1.1.x suggests locks are not expected to be recursive.
> Here's some more context of my use case.​
> OpenSSL loads `engine1` for me automatically (`
> ​​
>> OPENSSL_SSL_CLIENT_ENGINE_AUTO` variable) which is convenient as I 
> don't have control over application's `main()` function.  In my case 
> it's proprietary code but equally it could be Python script (I do not 
> fancy patching Python interpreter to get to its `main()` function and 
> load/initialise engines explicitly).
> So my _only_ entry point is `engine1->init`.  In that entry point I 
> initialise engine2 which is a fairly slow operation (need to load 
> certs from permanent storage) so definitely want to do this only once. 
> Oh, and the app is heavily multi-threaded so I'm glad OpenSSL 
> carefully takes crypto engine lock where needed.
> But because engines are initialised recursively, the locking 
> implementation I supply uses recursive mutex which works very well and 
> makes perfect sense to me in this case (I know that the same thread 
> calls locked functions recursively for a reason).  This works only 
> before 1.1.x.
> Alternatively I could lazy-initialise engine2 in certificate callback 
> function but any initialisation failure here would be less meaningful 
> and it would require another lock to protect engine2 handle.  In 
> `engine1->init` I know a lock is already held so I thought it's safer 
> to do more initialisation here.  Besides `engine2->init` is not called 
> directly but through a layer of application logic so conceptually 
> these two engines are orthogonal and know nothing about each other.
> I guess initialising engines recursively does not work in OpenSSL 
> 1.1.x (it'd be a dead-lock) and I need to seek for a different place 
> to initialise engine2, for example in certificate cb?  This would mean 
> I "leak" some knowledge of engine2 existence into engine1, have 
> guarantee that crypto engine lock is not held in certificate callabck 
> function and need another lock to protect access to engine2 handle.
> Please let me know what your views are and if the above makes sense.
I am not part of the OpenSSL team and have no idea what their
thinking or suggestions are.

However the following should be a generic workaround:

1. Create a third engine3 which loads both engine1 and engine2
   internally (without going through OpenSSL and its locks).
   So for example engine3->init calls both engine2->init and

2. engine3 would export/provide all the methods from engine1
   and engine2 by forwarding or reexporting the calls.

3. OpenSSL itself is instructed to use only your engine3

4. As a more ambitious project, someone could write a generic
   "engine3" which loads a list of actual engines from a config

At the OpenSSL design level, the OpenSSL team might extend the
colon-separatedlist of engines rather than just a single engine.


Jakob Bohm, CIO, Partner, WiseMo A/S.  https://www.wisemo.com
Transformervej 29, 2860 Søborg, Denmark.  Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded

More information about the openssl-users mailing list