Hi List,

The function ENGINE_by_id() becomes infinitely
recursive if passed the identifier for any library
which hasn't been loaded yet, with the precondition
that the 'dynamic' library hasn't been loaded yet
either.

This is due to the "experimental" changes added to the
0.9.8 version of the function where if an engine
wasn't found by iterating through the list then the
dynamic engine is attempted to be used:

..
..
iterator = ENGINE_by_id("dynamic");
if(!iterator || !ENGINE_ctrl_cmd_string ...
..
..

If the dynamic engine hasn't already been loaded this
call becomes infinitely recursive, and the 'if' line
can never be reached.

Ensuring that the dynamic library has been loaded
first obviously mitigates this problem, however
judging by functions such as this taken from
apps\app.c it looks to me like calling ENGINE_by_id()
without having loaded the dynamic library should be
allowed as a means of checking if a library is
available:

/* Try to load an engine in a shareable library */
static ENGINE *try_load_engine(BIO *err, const char
*engine, int debug)
{
ENGINE *e = ENGINE_by_id("dynamic");
if (e)
{
if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
{
ENGINE_free(e);
e = NULL;
}
}
return e;
}

Here's a quick fix which simply recognises the special
case where the identifier is "dynamic" and attempting
to use the dynamic engine is prevented.

diff -ru openssl-0.9.8_orig/crypto/engine/eng_list.c
openssl-0.9.8_fix/crypto/engine/eng_list.c
--- openssl-0.9.8_orig/crypto/engine/eng_list.c
2005-07-22 10:36:52.000000000 +1000
+++ openssl-0.9.8_fix/crypto/engine/eng_list.c
2005-08-02 13:38:58.000000000 +1000
@@ -394,19 +394,23 @@
#else
/* EEK! Experimental code starts */
if(iterator) return iterator;
+ /* Prevent infinite recusrion if we're looking for
the dynamic engine. */
+ if (strcmp(id,"dynamic"))
+ {
#ifdef OPENSSL_SYS_VMS
- if((load_dir = getenv("OPENSSL_ENGINES")) == 0)
load_dir = "SSLROOT:[ENGINES]";
+ if((load_dir = getenv("OPENSSL_ENGINES")) == 0)
load_dir = "SSLROOT:[ENGINES]";
#else
- if((load_dir = getenv("OPENSSL_ENGINES")) == 0)
load_dir = ENGINESDIR;
+ if((load_dir = getenv("OPENSSL_ENGINES")) == 0)
load_dir = ENGINESDIR;
#endif
- iterator = ENGINE_by_id("dynamic");
- if(!iterator || !ENGINE_ctrl_cmd_string(iterator,
"ID", id, 0) ||
+ iterator = ENGINE_by_id("dynamic");
+ if(!iterator || !ENGINE_ctrl_cmd_string(iterator,
"ID", id, 0) ||
!ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2",
0) ||
!ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
load_dir, 0) ||
!ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL,
0))
- goto notfound;
- return iterator;
+ goto notfound;
+ return iterator;
+ }
notfound:

ENGINEerr(ENGINE_F_ENGINE_BY_ID,ENGINE_R_NO_SUCH_E NGINE);
ERR_add_error_data(2, "id=", id);

(I've attached this patch also incase Yahoo! mangles!
the! patch!)

Thanks for your time,

Jon

Send instant messages to your online friends http://au.messenger.yahoo.com
__________________________________________________ ____________________
OpenSSL Project http://www.openssl.org
Development Mailing List openssl-dev@openssl.org
Automated List Manager majordomo@openssl.org