OpenSC 0.13 memory corruption (was: opensc 0.11.13 and openssl 1.0 oddity)

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

OpenSC 0.13 memory corruption (was: opensc 0.11.13 and openssl 1.0 oddity)

Markus Kötter
Hello list,

basically I refer to the thread
"opensc 0.11.13 and openssl 1.0 oddity" 2010-04-15
http://thread.gmane.org/gmane.comp.encryption.opensc.devel/10038
which ended in these changes
https://github.com/OpenSC/OpenSC/commit/46def8b86cae98791049fd648128ad091ffec172
https://github.com/OpenSC/OpenSC/commit/7f3f6dec6b3b092214813ff1a1da86bb26cbda49

having current code look like this:
https://github.com/OpenSC/OpenSC/blob/master/src/pkcs11/openssl.c#L154

The problem with this approach is as simple as this:
        ENGINE_set_default(e, ENGINE_METHOD_ALL);
        ENGINE_free(e);
The gost engine is set as default, and free'd.

Not really valid, breaks OpenSSL hard.
ENGINE references are slightly more complicated:
http://www.openssl.org/docs/crypto/engine.html#Reference_counting_and_handles

I had it segfault in/beyond SSL_CTX_new.

To reproduce, ...
My setup is simple, I got two readers, two cards.
One card is used to authenticate to the SOAP API of a CA, thats the RA
card, second card is written to, the user card.

To issue a certificate, I need to
  * create a key on the USER card
  * sign a CSR with the key on the USER card (using engine_pkcs11)
  * submit the request to the SOAP API
  * approve the request
    * authenticate to the SOAP api using the RA cards cert/key pair
(engine_pkcs11)
    * sign the approval with the RA cards cert/key pair (engine_pkcs11)


As both cards are interfaced with opensc, loading an engine for both did
not work for me as I rely on the PIN parameter for the engine_pkcs11.
So I had to serialize access to the openssl engine, which allows
reproducing the problems with a single reader/card.
Have a single ENGINE running, finish it when not required, init a new
engine when required.

After loading the Engine to sign the CSR, the engine gets finished, and
removed, including all ENGINE_unregister_*.
When connecting to the SOAP service, OpenSSL would segfault ~12 frames
beyond SSL_CTX_new() as internal data structure was corrupted by the
ENGINE_free() introduced in OpenSC in the cited gost patchset.
It even segfaults when calling SSL_CTX_new while the pkcs11 engine is
loaded, the data corruption takes its toll.


My fix is simple, do not load gost. [no_free.diff]
It's radical, but I do not have access to gost enabled cards, and
therefore can't verify this ever worked correctly, in case it is not,
keeping a global reference to the engine and finishing it when done
might be better.


libp11 had similar problems, it is used in engine_pkcs11, and registers
it's ERR strings, but does not provide API to unregister them as well.
Unloading the engine resulted in the ERR strings getting unmapped as
well, loading the engine again crashed OpenSSL due to access to unmapped
memory.
Extending libp11 to allow unregistering the ERR strings
[add_ERR_unload_PKCS11_strings.diff] and making use of it in
engine_pkcs11 [unload_errstrings.diff] was required therefore.

Also attached is a testcase [testcase.py], written in python using M2Crypto.
run as
testcase.py <slot> <pin> <objid>
e.g.
gdb -ex r --args python /tmp/testcase.py 1 123456
46a808cfd5beafa5e60aefee867bf92025dc2849

You may have to adjust _PATH in the script accordingly to match your
settings.

This testcase segfaults in SSL_CTX_new due to the gost engine ENGINE_free.

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff7259f56 in look_str_cb (arg=<optimized out>,
sk=<optimized out>, nid=<optimized out>,
     def=<optimized out>) at tb_asnmth.c:216
#2  look_str_cb (nid=815, sk=0xbb0790, def=<optimized out>,
arg=0x7fffffffcf90) at tb_asnmth.c:206
#3  0x00007ffff7266ddf in doall_util_fn (arg=0x7fffffffcf70,
     func_arg=0x7ffff7258220 <int_cb_LHASH_DOALL_ARG>, func=0,
use_arg=1, lh=0xbb0490) at lhash.c:292
#4  lh_doall_arg (lh=0xbb0490, func=0x7ffff7258220
<int_cb_LHASH_DOALL_ARG>, arg=0x7fffffffcf70)
     at lhash.c:307
#5  0x00007ffff725871c in engine_table_doall (table=<optimized out>,
cb=<optimized out>,
     arg=<optimized out>) at eng_table.c:349
#6  0x00007ffff725a313 in ENGINE_pkey_asn1_find_str (pe=0x7fffffffcfc8,
str=<optimized out>,
     len=<optimized out>) at tb_asnmth.c:236
#7  0x00007ffff728c7c5 in EVP_PKEY_asn1_find_str (pe=0x7fffffffd010,
str=0x7ffff75a0377 "gost94", len=6)
     at ameth_lib.c:213
#8  0x00007ffff75952e4 in get_optional_pkey_id (pkey_name=<optimized
out>) at ssl_ciph.c:356
#9  0x00007ffff759641f in ssl_cipher_get_disabled (ssl=<synthetic
pointer>, mac=<synthetic pointer>,
     enc=<synthetic pointer>, auth=<synthetic pointer>, mkey=<synthetic
pointer>) at ssl_ciph.c:733
#10 ssl_create_cipher_list (ssl_method=0x7ffff77ade80,
cipher_list=0xbadbb8, cipher_list_by_id=
     0xbadbc0, rule_str=0x7ffff759ffac "ALL:!aNULL:!eNULL:!SSLv2") at
ssl_ciph.c:1371
#11 0x00007ffff758fd30 in SSL_CTX_new (meth=0x7ffff77ade80) at
ssl_lib.c:1762


Re-setting the PIN parameter for the engine, depending on the card to
use is possible, and allows using multiple cards without ENGINE_finish,
avoiding the libp11 ERR strings issue, but the corruption caused by the
gost engine free persists, and faults.



MfG
Markus Kötter

------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
Opensc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/opensc-devel

add_ERR_unload_PKCS11_strings.diff (970 bytes) Download Attachment
no_free.diff (1K) Download Attachment
unload_errstrings.diff (406 bytes) Download Attachment
testcase.py (2K) Download Attachment