android: Add a script to build OpenSSL's libcrypto as needed by the app

The build script requires the paths to the NDK and OpenSSL sources.

It runs the build in a Docker container, by default. But if the required
tools are installed on the system (currently jq, make and perl) it can
also be run directly on the system by defining NO_DOCKER.

A relatively recent version of the NDK is required (the pre-built
toolchains are required).
This commit is contained in:
Tobias Brunner
2023-02-13 15:30:58 +01:00
parent 2fc8b14918
commit 7e5c4bbb32
3 changed files with 155 additions and 0 deletions
+26
View File
@@ -0,0 +1,26 @@
# Container for building OpenSSL's libcrypto for use in strongSwan's Android app
#
# Use the script to simplify the process of building the image and running
# the compilation in the container, e.g.:
#
# ANDROID_NDK_ROOT=~/android-ndk OPENSSL_SRC=~/openssl ./build.sh
FROM debian:bullseye
ARG packages="jq make perl"
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -qq -y \
--no-install-recommends \
$packages \
&& rm -rf /var/lib/apt/lists/*
COPY compile.sh /
RUN chmod +x /compile.sh
ENV ANDROID_NDK_ROOT /ndk
ENV OUT_DIR /out
WORKDIR /src
ENTRYPOINT ["/compile.sh"]
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash
#
# Build OpenSSL's libcrypto for use in strongSwan's Android app. Requires
# passing the path to the Android NDK as well as that to the OpenSSL sources,
# for instance:
#
# ANDROID_NDK_ROOT=~/android-ndk OPENSSL_SRC=~/openssl ./build.sh
#
# The files are written to the jni/openssl directory of the app, by default, but
# that can be changed via $OUT variable.
#
# Setting $NO_DOCKER disables the use of Docker (requires the necessary build
# tools on the system), otherwise, setting $TAG allows using a custom tag for
# the Docker image.
#
set -e
if [ -z "${ANDROID_NDK_ROOT}" ]; then
echo "ANDROID_NDK_ROOT is not set"
exit 1
elif [ ! -d "${ANDROID_NDK_ROOT}" ]; then
echo "ANDROID_NDK_ROOT=${ANDROID_NDK_ROOT} is not a directory"
exit 1
fi
if [ -z "${OPENSSL_SRC}" ]; then
echo "OPENSSL_SRC is not set"
exit 1
elif [ ! -d "${OPENSSL_SRC}" ]; then
echo "OPENSSL_SRC=${OPENSSL_SRC} is not a directory"
exit 1
fi
: ${TAG=strongswan-android-openssl-builder}
DIR=$(dirname `readlink -f $0`)
: ${OUT=$DIR/../app/src/main/jni/openssl}
mkdir -p $OUT
if [ -z "${NO_DOCKER}" ]; then
docker build -t ${TAG} ${DIR}
docker run --rm -ti \
-u $(id -u ${USER}):$(id -g ${USER}) \
-v ${ANDROID_NDK_ROOT}:/ndk \
-v ${OPENSSL_SRC}:/src \
-v ${OUT}:/out \
${TAG}
else
pushd $OPENSSL_SRC
OUT_DIR=${OUT} $DIR/compile.sh
popd
fi
if [ ! -f "${OUT}/Android.mk" ]; then
echo "## Creating Android.mk for OpenSSL's libcrypto"
cat << EOF > ${OUT}/Android.mk
LOCAL_PATH := \$(call my-dir)
include \$(CLEAR_VARS)
LOCAL_MODULE := libcrypto_static
LOCAL_SRC_FILES := \$(TARGET_ARCH_ABI)/libcrypto.a
LOCAL_EXPORT_C_INCLUDES := \$(LOCAL_PATH)/include
include \$(PREBUILT_STATIC_LIBRARY)
EOF
fi
+64
View File
@@ -0,0 +1,64 @@
#!/bin/bash
#
# Compile static versions of OpenSSL's libcrypto for use with strongSwan's
# Android app.
#
# Copies archives and header files to $OUT_DIR.
set -e
export PATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
# necessary for OpenSSL 1.1.1
export ANDROID_NDK_HOME=${ANDROID_NDK_ROOT}
# automatically determine the ABIs supported by the NDK
: ${ABIS=$(jq -r 'keys | join(" ")' ${ANDROID_NDK_ROOT}/meta/abis.json)}
# this should match APP_PLATFORM
: ${MIN_SDK=21}
for ABI in ${ABIS}
do
echo "## Building OpenSSL's libcrypto for ${ABI}"
case ${ABI} in
armeabi-v7a)
OPTIONS="android-arm"
;;
arm64-v8a)
OPTIONS="android-arm64"
;;
x86)
OPTIONS="android-x86"
;;
x86_64)
OPTIONS="android-x86_64"
;;
esac
OPTIONS="${OPTIONS} \
no-shared no-ct no-cast no-comp no-dgram no-dsa no-gost no-idea \
no-rmd160 no-seed no-sm2 no-sm3 no-sm4 no-sock no-srp no-srtp \
no-asm no-err no-engine no-dso no-hw no-stdio no-ui-console \
-fPIC -DOPENSSL_PIC \
-ffast-math -O3 -funroll-loops -Wno-macro-redefined \
-D__ANDROID_API__=${MIN_SDK} \
"
make distclean >/dev/null || true
./Configure ${OPTIONS}
make -j $(nproc) build_generated >/dev/null
make -j $(nproc) libcrypto.a >/dev/null
mkdir -p ${OUT_DIR}/${ABI}
cp libcrypto.a ${OUT_DIR}/${ABI}
done
# The only difference between ABIs is the config header (e.g. configuration.h
# for OpenSSL 3.0), which does define the size of BN_ULONG in bn.h.
# However, the only function we use that depends on it is BN_set_word() when
# generating RSA private keys, which isn't used in the Android app.
cp -R include/ ${OUT_DIR}