Unsolved QCA on Android
-
Hi
I need OpenPGP to encrypt password, so I've choosend QCA (Qt Cryptographic Architecture)
https://github.com/KDE/qca
On Linux there is no problem, for Android I did cross compiled it with command:cmake . -DCMAKE_SYSTEM_NAME=Android -DCMAKE_TOOLCHAIN_FILE=/opt/Android/Ndk/android-ndk-r20/build/cmake/android.toolchain.cmake -DQt5_DIR=/opt/Felgo/Felgo/android_armv7/lib/cmake/Qt5/ -DQt5Core_DIR=/opt/Felgo/Felgo/android_armv7/lib/cmake/Qt5Core/ -DQt5Test_DIR=/opt/Felgo/Felgo/android_armv7/lib/cmake/Qt5Test/ -DQt5Network_DIR=/opt/Felgo/Felgo/android_armv7/lib/cmake/Qt5Network/ -DANDROID_PLATFORM=android-29 -DCMAKE_INSTALL_PREFIX=/usr/local/android -DUSE_RELATIVE_PATHS=ON
Config says the package relocatable
-- Check for working C compiler: /opt/Android/Ndk/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -- Check for working C compiler: /opt/Android/Ndk/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /opt/Android/Ndk/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -- Check for working CXX compiler: /opt/Android/Ndk/android-ndk-r20/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Deprecation Warning at CMakeLists.txt:19 (cmake_policy): The OLD behavior for policy CMP0042 will be removed from a future version of CMake. The cmake-policies(7) manual explains that the OLD behaviors of all policies are deprecated and that a policy should be set to OLD only under specific short-term circumstances. Projects should be ported to the NEW behavior and not rely on setting a policy to OLD. -- Found Doxygen: /usr/bin/doxygen (found version "1.8.13") found components: doxygen dot -- Installed package is relocatable -- Checking for certstore.. -- Found system certstore -- certstore path: /etc/ssl/certs/ca-certificates.crt -- Looking for include file sys/filio.h -- Looking for include file sys/filio.h - not found -- Performing Test MLOCK_TAKES_VOID -- Performing Test MLOCK_TAKES_VOID - Success -- Found PkgConfig: /usr/bin/pkg-config (found version "0.29") -- Checking for module 'botan-2' -- No package 'botan-2' found -- Checking for module 'nss' -- No package 'nss' found -- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR) (Required is at least version "1.1.1") -- Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY OPENSSL_INCLUDE_DIR) -- Checking for one of the modules 'libpkcs11-helper-1' Plugins: qca-botan off qca-cyrus-sasl off qca-gcrypt off qca-gnupg on qca-logger on qca-nss off qca-ossl off qca-pkcs11 off qca-softstore on QCA prefix is /usr/local/android Plugins will be installed to /usr/local/android/lib/qca-qt5 Binary will be installed to /usr/local/android/bin Library will be installed to /usr/local/android/lib Public headers will be installed to /usr/local/android/include/Qca-qt5 Private headers will be installed to /usr/local/android/include/Qca-qt5 Feature file will be installed to /usr/local/android/mkspecs/features Documentation will be installed to /usr/local/android/share/doc/qca-qt5/html Man page will be installed to /usr/local/android/share/man Pkg-config file will be installed to /usr/local/android/lib/pkgconfig -- Configuring done -- Generating done
I have copied libraries into android/libs/armeabi-v7a/ linking and installing into Android device works fine, there are 3 plugins in crypto directory, visible in android-build directory:
libqca-gnupg.so libqca-logger.so libqca-softstore.so
But when app starts is does not support any of these plugins
QCA::Initializer init; if(QCA::isSupported("logger")) { qDebug()<<"BackEnd::encrypt logger supported"; } else { qDebug()<<"BackEnd::encrypt logger NOT supported"; } if(QCA::isSupported("softstore")) { qDebug()<<"BackEnd::encrypt softstore supported"; } else { qDebug()<<"BackEnd::encrypt softstore NOT supported"; } if(QCA::isSupported("openpgp")) { qDebug()<<"BackEnd::encrypt openpgp supported"; } else { qDebug()<<"BackEnd::encrypt openpgp NOT supported, return"; return; }
result is:
BackEnd::encrypt logger NOT supported BackEnd::encrypt softstore NOT supported BackEnd::encrypt openpgp NOT supported, return
Can someone give me some hint ? What is worying me is this sentence from QCA changes list
- qca-gnupg: try both gpg and gpg2 to find gnupg executable
if it is using command from OS then it will not work on Android ?
Best Regards
Marek -
When I unzip APK file I can see that in lib/armeabi-v7a/ there is file libqca-qt5.so
file lib/armeabi-v7a/libqca-qt5.so lib/armeabi-v7a/libqca-qt5.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, BuildID[sha1]=70b166ed2526bff0c5c8c365f2ef585ec73a6440, stripped
But there is no subdirectory "crypto" or any other that I have placed in android/libs/armeabi-v7a
How to tell QtCreator to include subdirectories from armeabi-v7a into APK ?Best Regards
Marek -
Hi,
The Androïd deployment process is described here.
-
@SGaist thanks, somehow I can't make it work
There is some issue with gradle here
"fileTree() does not import the subdirectory"
https://github.com/gradle/gradle/issues/2394
So maybe it is not possible to include subdirectories ?Best
Marek -
@Marek said in QCA on Android:
So maybe it is not possible to include subdirectories ?
That I do not know sorry.
It looks like it should be somehow possible. See this git gist.
-
@SGaist It looks like they are creating files instead of directories like this:
libplugins_crypto_libqca-ossl.so
So I created mine in the same manner
libplugins_crypto_libqca-gnupg.so
But QCA still says OpenPGP is not supported. Maybe it needs some underlying package like gnuPG to work. I have filed bug report to ask for this
https://bugs.kde.org/show_bug.cgi?id=432142Thanks for help
Marek -
Hi,
thanks a lot for asking this question and providing the cmake command.
For me, the cmake command had been the missing link while trying to resurrect one of my old applications.I realize the thread is a bit older but I hope my notes can still be helpful for some.
Regarding getting the QCA plug-in to work.
I am not sure if you looked at that already but just in case.For debugging QCA, e.g., seeing which plug-ins get loaded etc., I use the following code:
QCA::scanForPlugins(); qDebug("QCA Plugin Diagnostics Context: %s", QCA::pluginDiagnosticText().toUtf8().constData()); QStringList capabilities; capabilities = QCA::supportedFeatures(); qDebug("QCA supports: %s", capabilities.join(",").toUtf8().constData());
In my case, the output looks like this (this already uses the second "hack" solution below):
D MeePasswords: Preparing QCA plug-in... D MeePasswords: Initializing QCA... D MeePasswords: QCA initialized. W qtMainLoopThrea: type=1400 audit(0.0:40594): avc: granted { execute } for path="/data/data/com.ruedigergad.MeePasswords/crypto/libqca-ossl_armeabi-v7a.so" dev="mmcblk0p62" ino=661675 scontext=u:r:untrusted_app_27:s0:c231,c256,c512,c768 tcontext=u:object_r:app_data_file:s0:c231,c256,c512,c768 tclass=file D MeePasswords: QCA Plugin Diagnostics Context: Checking Qt static plugins: D MeePasswords: (none) D MeePasswords: Checking Qt Library Path: /data/data/com.ruedigergad.MeePasswords D MeePasswords: libqca-ossl_armeabi-v7a.so: (class: opensslPlugin) loaded as qca-ossl D MeePasswords: Checking Qt Library Path: /data/app/com.ruedigergad.MeePasswords-e3TV3HWpyXAxUPgO-5Zp7Q==/lib/arm D MeePasswords: (No 'crypto' subdirectory) 05-09 10:38:51.644 13166 13263 D MeePasswords: D MeePasswords: QCA supports: random,md5,sha1,keystorelist,ripemd160,md4,sha224,sha256,sha384,sha512,whirlpool,hmac(md5),hmac(sha1),hmac(sha224),hmac(sha256),hmac(sha384),hmac(sha512),hmac(ripemd160),aes128-ecb,aes128-cfb,aes128-cbc,aes128-cbc-pkcs7,aes128-ofb,aes192-ecb,aes192-cfb,aes192-cbc,aes192-cbc-pkcs7,aes192-ofb,aes256-ecb,aes256-cbc,aes256-cbc-pkcs7,aes256-cfb,aes256-ofb,blowfish-ecb,blowfish-cbc-pkcs7,blowfish-cbc,blowfish-cfb,blowfish-ofb,tripledes-ecb,tripledes-cbc,des-ecb,des-ecb-pkcs7,des-cbc,des-cbc-pkcs7,des-cfb,des-ofb,cast5-ecb,cast5-cbc,cast5-cbc-pkcs7,cast5-cfb,cast5-ofb,pbkdf1(sha1),pbkdf2(sha1),hkdf(sha256),pkey,dlgroup,rsa,dsa,dh,cert,csr,crl,certcollection,pkcs12,tls,cms,ca
At least in my case, getting QCA to load the plug-in I needed, took a bit of effort.
From what I can tell, the background is as follows:- QCA searches dynamically loaded plug-ins as follows:
- Go through the paths defined in the environment variable QCA_PLUGIN_PATH and QCoreApplication::libraryPaths().
- For each directory, check if there is a "crypto" sub-directory. The "crypto" name is hard-coded.
- For all *.so files in */crypto, try to load them as plug-in. (It does some further checks regarding versions etc. but I'll leave that out here.)
- As you already observed, Qt Android packaging is a bit odd regarding including sub-directories and removing files it does not consider "valid" or so.
- There is a related post: https://forum.qt.io/topic/108470/installs-ignores-res-folder/6
I ended up with two hacks as solution:
- Include the QCA plug-in as static plug-in.
- Package the QCA plug-in along with the Android libraries and at application startup, create the "crypto" sub-directory, copy the QCA plug-in there, and add the parent directory of "crypto" to the QCoreApplication library path.
The first hack, statically linked plug-in, worked roughly as follows:
// Include plug-in statically in main.cpp #ifdef ANDROID #include <QtPlugin> Q_IMPORT_PLUGIN(opensslPlugin) #endif
# Add dynamic & static linking in project file LIBS += \ -L$$PWD/lib/qt5/build/android/android-24/qca \ -l:libqca-qt5_armeabi-v7a.so \ -L$$PWD/lib/qt5/build/android/android-24/qca/qca-qt5/crypto \ -l:libqca-ossl.a \ -L$$PWD/lib/qt5/build/android/android-24/openssl \ -l:libcrypto.so \ -l:libssl.so
As you see my quick hack uses a mix of dynamic linking (for QCA and OpenSSL libs) and static linking (for the ossl QCA plug-in).
The alternative hack, copying the file etc., looks as follows:
qDebug("Preparing QCA plug-in..."); QDir dir("../"); dir.mkdir("crypto"); QFile::copy("../lib/libqca-ossl_armeabi-v7a.so", "../crypto/libqca-ossl_armeabi-v7a.so"); QCoreApplication::addLibraryPath("../");
Overall, both approaches are somewhat "hackish" but I couldn't spend more time on this and at least it got me unblocked.
Just in case, the project, for which I use this is: https://github.com/ruedigergad/meepasswords
There I also have some more notes and pre-compiled builds of OpenSSL and QCA.Cheers,
Ruediger
- QCA searches dynamically loaded plug-ins as follows:
-
@Ruediger thanks for extensive info
For reasons not related to Qt my customer changed encyption from OpenPGP to symmetric AES and I ended up compiling in OpenSSL on Android and iOS platform. But will git it a try next time.Best
Marek