Folks:

I'm having this problem that was earlier described by Eric Hughes on  
this list:

http://thread.gmane.org/gmane.comp.encryption.cryptopp/2305

Here is the buildbot (automated unit tester) which shows how the  
problem manifests when I run my unit tests:

http://allmydata.org/buildbot-pycryptopp/builders/gutsy-syslib/builds/ 
20/steps/test/logs/stdio

I've built a dynamic library named 'ecdsa.so' which depends on  
libcryptopp.so.  When I try to use it I get this error:

terminate called after throwing an instance of  
'CryptoPP::NameValuePairs::ValueTypeMismatch'
   what():  NameValuePairs: type mismatch for 'InputBuffer', stored  
'N8CryptoPP23ConstByteArrayParameterE', trying to retrieve  
'N8CryptoPP23ConstByteArrayParameterE'

The problem as I currently understand it is that the  
ConstByteArrayParameter class is defined in algparam.h, which is  
(transitively) #include'd by my code, and so when I build my  
ecdsa.so, any RTTI code in ecdsa.so (for example the typeid operator)  
will identify the copy of ConstByteArrayParameter that was built into  
ecdsa.so.  If at run-time I want to compare type information, such as  
for the named-argument features which Crypto++ uses, then if one of  
the arguments came from libcryptopp.so and the other came from  
ecdsa.so, or equivalently if libcryptopp.so is throwing an exception  
of a given type and ecdsa.so is catching exceptions of that type,  
then the types will not compare equal and the program will fail.

I've spent about a day learning about dynamic linking and visibility  
and so forth, and I don't see a clean way to fix this without  
changing the Crypto++ source code.  There is an unclean way to fix  
it, which is to set the RTLD_GLOBAL flag before dlopening ecdsa.so.   
This was offered as a solution by Geoff Beier:

http://allmydata.org/pipermail/tahoe-dev/2009-February/001153.html
http://www.opengroup.org/onlinepubs/009695399/functions/dlopen.html

I think what this does is makes it so that symbols defined in  
ecdsa.so when it is loaded are used to resolve libcryptopp.so's needs  
for symbols.  This happens to fix the two known problems that my  
project currently encounters, but it seems fragile.  For example, if  
ecdsa.so is the one raising the exception and libcryptopp.so is the  
one trying to catch it, this won't work, will it?  Also if some  
program has unluckily loaded libcryptopp.so before it loads my  
ecdsa.so, then it will be too late for my RTLD_GLOBAL to take effect.

The only clean, long-term solution I can think of for the long term  
is to change Crypto++ to remove definitions from header files so that  
code like mine will get only undefined symbols by #include'ing Crypto+ 
+ header files.  For example, if ConstByteArrayParameter were  
declared as "class ConstByteArrayParameter;" in algparam.h and  
defined only in some implementation file such as "algparam.cpp", then  
the compiler and linked when building my ecdsa.so would know that it  
didn't know the actual type of ConstByteArrayParameter and any RTTI  
code would be compiled to use an indirect symbol that would not be  
resolved until load time.  Is that right?

Is there any easier solution for me?  I'd like to build ecdsa.so that  
it requires libcryptopp.so at load-time, and that ecdsa.so gets all  
Crypto++ symbols resolved at load-time from libcryptopp.so's  
definitions of those symbols.

Thanks!

Regards,

Zooko

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the "Crypto++ Users" 
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at 
http://www.cryptopp.com.
-~----------~----~----~----~------~----~------~--~---

Reply via email to