Question

I have an application that uses the JNI to call a C file that reads some system information. I have this running fine on Linux, but on Solaris 10 (SPARC, 32-bit) I am having trouble when the library is used. I compiled the C file on the same machine that I am testing it on with the command:

gcc -O2 -fPIC -shared -static-libgcc -I/usr/local/ssl/include \
    -I$JAVA_HOME/include -I$JAVA_HOME/include/solaris -lcrypto \
    -lm -std=c99 -o libosaccess.so osaccess.c

This compiles fine, but unlike on Linux, I had to include the path to the system OpenSSL, -I/usr/local/ssl/include. This is obviously the problem, as when the library is used, I get the following fatal error due to an OpenSSL type:

ld.so.1: java: fatal: relocation error: file /workspace/solaris_sparc/libosaccess.so: symbol EVP_aes_256_cbc: referenced symbol not found
Killed

I have tried adding the location of the system OpenSSL to the PATH and also my LD_LIBRARY_PATH, but continue to get the error. I have read that I can see the paths that my application is looking using ldd -d but can't quite seem to get this working as of yet.

Can anyone tell me if there is a way I can set where the OpenSSL files are so that all applications can find them? On my Linux machine, there are no environment variables that include the path to the OpenSSL on that. There is, however, a binary called openssl under /usr/bin, which is included in the PATH variable. I have found a binary on Solaris, but adding this to the PATH doesn't help.

EDIT

@ nudzo and Kenster

Ok so rather than try to squeeze this into the comments box for your answers, I thought I'd post it in addition to my question to improve the readability.

So I have checked my system and there is only the two copies of OpenSSL that I can find.

  • Doing a pkginfo | grep 'SUNWcry*' shows that I have the two additional packages installed.
  • Only the /usr/sfw location has the two 'extra' libraries you mentioned
  • Both locations have the evp.h header file that includes the EVP_aes_256_cbc symbol.

The locations are:

/usr/sfw

xxx-1035> find /usr/sfw -type f -name 'openssl'
 /usr/sfw/bin/openssl
xxx-1036> find /usr/sfw -type f -name 'evp.h'
 /usr/sfw/include/openssl/evp.h
xxx-1037> find /usr/sfw -type f -name 'libcrypto*'
 /usr/sfw/lib/sparcv9/libcrypto.so.0.9.7
 /usr/sfw/lib/sparcv9/libcrypto_extra.so.0.9.7
 /usr/sfw/lib/libcrypto.so.0.9.7
 /usr/sfw/lib/libcrypto_extra.so.0.9.7
xxx-1038> find /usr/sfw -type f -name 'libssl*'
 /usr/sfw/lib/sparcv9/libssl.so.0.9.7
 /usr/sfw/lib/sparcv9/libssl_extra.so.0.9.7
 /usr/sfw/lib/libssl.so.0.9.7
 /usr/sfw/lib/libssl_extra.so.0.9.7

/usr/local/ssl

xxx-1040> find /usr/local/ssl -type f -name 'openssl'
 /usr/local/ssl/bin/openssl
xxx-1041> find /usr/local/ssl -type f -name 'evp.h'
 /usr/local/ssl/include/openssl/evp.h
xxx-1042> find /usr/local/ssl -type f -name 'libcrypto*'
 /usr/local/ssl/lib/libcrypto.a
 /usr/local/ssl/lib/libcrypto.so.0.9.7
 /usr/local/ssl/lib/libcrypto.so.0.9.8
 /usr/local/ssl/lib/pkgconfig/libcrypto.pc
xxx-1043> find /usr/local/ssl -type f -name 'libssl*'
 /usr/local/ssl/lib/libssl.a
 /usr/local/ssl/lib/libssl.so.0.9.7
 /usr/local/ssl/lib/libssl.so.0.9.8
 /usr/local/ssl/lib/pkgconfig/libssl.pc

I recompiled my C file using:

gcc -O2 -fPIC -shared -static-libgcc \
    -I$JAVA_HOME/include -I$JAVA_HOME/include/solaris \
    -I/usr/sfw/include -L/usr/sfw/lib -R/usr/sfw/lib \
    -lcrypto -lm -std=c99 -o libosaccess.so osaccess.c

Again, omission of the path to the headers throws implicit declaration of function errors of the EVP types when compiling. This, however, still causes the same error as originally posted.

So if there are only these two copies on the system, that would indicate that instead of using the version shipped with Solaris (/usr/sfw), the system default is using the /usr/local copy that doesn't have the additional 'extra' shared objects. Would that be a fair assumption to make? How would I conclusively check this? I don't have permissions to remove either copy.

Also, running cryptoadm list -mv output a lot of information I didn't quite understand. However I found these entries in a couple of the slot tables:

CKM_AES_CBC                  16   32   .  X  X  .  .  .  .  .  .  .  X  X  .  .

and also:

Kernel software providers:
==========================
aes256: CKM_AES_ECB,CKM_AES_CBC,CKM_AES_CTR

Kernel hardware providers:
==========================
n2cp/0: CKM_DES_CBC,...,CKM_AES_CBC,...

I apologise for the huge amount of extra information.

Was it helpful?

Solution

If the linker were failing to find a shared library, it would give you a different error. Your problem is that the linker is finding all of the libraries that it thinks it should, but it's not finding a symbol for EVP_aes_256_cbc.

It seems that there is an issue with this symbol on Solaris 10. See some of these links:

The solution seems to be to make sure you have both SUNWcry and SUNWcryr installed, if you're using those packages for crypto. And look for a library named libcrypto_extra.so or libssl_extra.so, and include that when linking.

OTHER TIPS

I think your link time and run time OpenSSL are different. Solaris have OpenSSL in /usr/sfw and I recommend you to use rather that one. Especially when you use Solaris bundled gcc. Another good reason is, that this OpenSSL has PKCS11 crypto engine, which you can bind to Solaris PKCS11 token and then you can use full power of hardware crypto accelerators. Run cryptoadm list -mv to get your hardware capabilities.

To link it properly add -L/usr/sfw/lib -R/usr/sfw/lib and as mentioned above also add libcrypto_extra.so, libssl_extra.so cause those holds strong crypto ciphers... you know, those comic export laws.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top