Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QT + OpenSSL + Android

I would like to setup the OpenSSL lib. for my Qt project. Under Linux it is working fine with the built-in OpenSSL. I added this to my .pro file:

LIBS+=-lcrypto
PKGCONFIG += openssl

But if I use it in Android, it gives error. I followed this instructions:

$ . ./setenv-android.sh
$ cd openssl-1.0.1h/
$ perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org
$ ./config shared -no-ssl2 -no-ssl3 -no-comp -no-hw -no-engine --openssldir=/usr/local/ssl/$ANDROID_API
$ make depend
$ ./Configure shared android-armv7
$ make build_libs
$ export CC=/home/laci/android-ndk-r10/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
$ export AR=/home/laci/android-ndk-r10/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar
$ export ANDROID_DEV=/home/laci/android-ndk-r10/platforms/android-14/arch-arm/usr/
$ make all
$ sudo -E make install CC=$ANDROID_TOOLCHAIN/arm-linux-androideabi-gcc RANLIB=$ANDROID_TOOLCHAIN/arm-linux-androideabi-ranlib

These websites were my sources:

  • OpenSSL wiki
  • QtDoc - Adding OpenSSL support

What am I doing wrong?

Thanks in advance for your answers

like image 620
bastlaca Avatar asked Aug 05 '14 20:08

bastlaca


People also ask

Can QT be used for Android?

Qt for Android enables you to run Qt 5 applications on Android devices. All Qt modules (essentials and add-ons) are supported except the following: Qt WebEngine. Qt Serial Port.

Does Android use OpenSSL?

OpenSSL is also used in some Android applications that require cryptography functions. Usually, Android developers use the Native Development Kit (NDK) to compile the source code into a native library and package it into your APK.


1 Answers

The solution is:

1a) proper way: compile openssl libraries for android (use 1.0.2+, don't use 1.1.* - at least for Qt 5.9.2)

or

1b) quick and dirty way: GET THEM FROM any existing application APK (warning: outdated libs ==> security threat) if you need quick and dirty solution. Look for libssl.so and libcrypto.so inside APK arm directory.

THEN

2a) open Qt Creator, Projects -> [project] -> Build & Run -> Android for armeabi->v7a -> Build -> Build Android APK -> Android -> Additional Libraries -> Add.. (add libssl.so, libcrypto.so there)

or

2b) in your .pro makefile, add the following:

ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
contains(ANDROID_TARGET_ARCH,armeabi-v7a) {
     ANDROID_EXTRA_LIBS = \
        $$PWD/android/libs/arm/libcrypto.so \
        $$PWD/android/libs/arm/libssl.so
}

($$PWD/android/.. is your path inside your project where you put these libs). ANDROID_PACKAGE_SOURCE_DIR looks like optional for this case.

THEN

3) Add them for loading into AndroidManifest (valid at least for Qt 5.9.2): carefully add them here in your existing meta-data of main activity and out-of-process services if any.

        <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --:lib/libssl.so:lib/libcrypto.so"/>

"lib" MUST be "lib" here, it refers on-device directory layout, not your project structure.

THEN

4) build your apk. Verify your libs are in proper place:

$ jar tvf ./android-build/build/outputs/apk/android-build-debug.apk| grep libssl
344388 Tue Apr 11 12:35:36 EEST 2017 lib/armeabi-v7a/libssl.so

I put this instruction here, because I spent too much time looking for answer and anything without ANDROID_EXTRA_LIBS did not work for me.

NB

Why it's so problematic? Because androids up to 6.0 may contain their own libssl/libcrypto and linking via "-l" will add auto-load entry in your main binary (not Qt-managed), and system libs may be of wrong version, or load SILENTLY INSTEAD OF YOUR shipped binaries thus masking bug with Android 7. Android 7 definitely does not contain libssl and "-l" will fail and symbols will not be resolved at runtime.

By not using "-l" and by using Qt's "android.app.load_local_libs" instead, you force QtLoader to use your version of libs. Remember, openssl 1.0.2 is working with default android Qt build, and 1.1.* will NOT work because of different symbols. (SSL_init_library is 1.0.2, OPENSSL_init_library is 1.1.*)

Interesting that because of these complexities, method "1b)" may not work. APK you chose may contain libssl.so, but its author built it incorrectly and loads it incorrectly, so his libssl.so may be incorrect versioned shared library which are generally no-go on android, but author used -l and never loaded own lib (used system instead) and never knew his library will not load on android.

like image 128
Sanny Avatar answered Oct 10 '22 23:10

Sanny