Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined reference to libssl function with Android NDK

I am very new to Android, compiling, and linking in general. I do not know which details are important with my problem, so I will just tell you everything. If you see anything strange or incorrect, please let me know.

I built the libcrypto.so and libssl.so libraries in the Android-NDK. I wrote native code which uses a function in openssl.so (and openssl.so uses functions in libssl.so). The code compiles, however I receive an "undefined reference" error when linking:

./obj/local/armeabi/objs/pki_send/pki_send.o: In function `main':
/home/android/nativeserver/jni/pki_send.c:27: undefined reference to `RSA_generate_key'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/pki_send] Error 1

I searched on Google and found a person with the same problem as me, she is even calling the same function (except this person is not building for Android): http://ubuntuforums.org/showthread.php?t=1081028. I'll quote the part of her post here that is relevant to my problem:

When I remove an argument [to the function which causes the "undefined reference"] the compiler says that there's too few arguments and when I add an argument the compiler says there's too many arguments, so it seems like there is "some" kind of reference to the correct function. There's some linking going on wrongly perhaps?

I noticed this same behaviour. She solved her problem by compiling with the -lssl setting, which tells the compiler to use the openssl library. For me to do this, I changed the module in the Android.mk file from this:

LOCAL_LDLIBS += -ldl

to this:

LOCAL_LDLIBS += -lssl -lcrypto -ldl 

I included -lcrypto just to be safe, since libssl depends on libcrypto. Now when I run ndk-build, I receive the following error:

/home/android/android-ndk-r8/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: cannot find -lssl
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/pki_send] Error 1

This error shows that "ld" cannot find libssl.so. I have both libcrypto.so and libssl.so in my jni directory. I ideally wanted to find a way to add the jni directory to the search path of "ld", but I could not figure this out. I attempted to solve this problem by adding libssl.so and libcrypto.so to the following directory: /android-ndk-r8/platforms/android-8/arch-arm/usr/lib (I believe that "ld" searches here for libraries). Once I did this, I ran ndk-build again and received an "undefined reference" error:

./obj/local/armeabi/objs/pki_send/pki_send.o: In function `main':
/home/android/nativeserver/jni/pki_send.c:27: undefined reference to `RSA_generate_key'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/pki_send] Error 1

From here, I am clueless as to how to proceed.

Just in case it is important, here is the code in my Android.mk file:

LOCAL_PATH := $(call my-dir)
APP_PLATFORM := android-8

include $(CLEAR_VARS)

LOCAL_MODULE    := crypto 
LOCAL_SRC_FILES := libcrypto.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE    := ssl 
LOCAL_SRC_FILES := libssl.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../include/

include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)

LOCAL_SRC_FILES := pki_send.c 
LOCAL_MODULE    := pki_send 
LOCAL_SHARED_LIBRARIES := ssl crypto 
LOCAL_LDLIBS += -lssl -lcrypto -ldl

LOCAL_MODULE_TAGS := optional

include $(BUILD_EXECUTABLE)

EDIT: Something I forgot to add: when I use functions in my native code in libcrypto.so, the code compiles and links fine. It seems that I can use any function in libcrypto.so. However, the function which gives me problems is in libssl.so. This may or may not be important.

like image 968
Rob Avatar asked Feb 19 '23 17:02

Rob


1 Answers

I solved the problem. The function I was calling, "RSA_generate_key", only exists in the deprecated version of libcrypto.so. I was using the newer version that uses "RSA_generate_key_ex". I found this out by doing a readelf on libcrypto.so:

$ ./arm-linux-androideabi-readelf -all ~/nativeserver/jni/libcrypto.so |grep RSA_generate
   679: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex
 10334: 00089239   992 FUNC    GLOBAL DEFAULT    7 RSA_generate_key_ex

The reason why the program still compiled is because RSA_generate_key is in the header file of openssl/rsa.h even though the library does not have it.

like image 198
Rob Avatar answered Mar 05 '23 16:03

Rob