]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
android: Add a script to build OpenSSL's libcrypto as needed by the app
authorTobias Brunner <tobias@strongswan.org>
Thu, 9 Feb 2023 15:39:08 +0000 (16:39 +0100)
committerTobias Brunner <tobias@strongswan.org>
Mon, 13 Feb 2023 14:30:58 +0000 (15:30 +0100)
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).

src/frontends/android/openssl/Dockerfile [new file with mode: 0644]
src/frontends/android/openssl/build.sh [new file with mode: 0755]
src/frontends/android/openssl/compile.sh [new file with mode: 0755]

diff --git a/src/frontends/android/openssl/Dockerfile b/src/frontends/android/openssl/Dockerfile
new file mode 100644 (file)
index 0000000..4b88928
--- /dev/null
@@ -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"]
diff --git a/src/frontends/android/openssl/build.sh b/src/frontends/android/openssl/build.sh
new file mode 100755 (executable)
index 0000000..fc541ef
--- /dev/null
@@ -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
diff --git a/src/frontends/android/openssl/compile.sh b/src/frontends/android/openssl/compile.sh
new file mode 100755 (executable)
index 0000000..81463b9
--- /dev/null
@@ -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}