01e26dd717
- Bump OPENSSL_VERSION default from 3.0.8 to 3.1.2 - Update SHA256 hash for openssl-3.1.2.tar.gz - Update all compliance checks to validate OpenSSL 3.1.x series - Update docs: README, install.md, CLAUDE.md, test READMEs - Previous 3.0.8 had only FIPS 140-2 (Cert #4282); 3.1.2 is the first OpenSSL with full FIPS 140-3 validation (Cert #4985, valid through March 2030)
324 lines
10 KiB
Bash
Executable File
324 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ---------------------------------------------------------------------------
|
|
# build.sh -- FIPS SQLCipher cross-compile orchestrator
|
|
#
|
|
# Supports Android (NDK) and iOS (Xcode) targets, plus packaging into
|
|
# AAR (Android) and XCFramework (iOS).
|
|
#
|
|
# Subcommands:
|
|
# ./build.sh # Android arm64-v8a (default)
|
|
# ./build.sh android # Android (respects ANDROID_ABI env)
|
|
# ./build.sh ios # iOS device arm64
|
|
# ./build.sh ios-simulator # iOS simulator arm64 + x86_64
|
|
# ./build.sh ios-all # Device + both simulator arches
|
|
# ./build.sh all # Android arm64+x86_64 + iOS all
|
|
# ./build.sh package-aar # Package Android artifacts into AAR
|
|
# ./build.sh package-xcframework # Package iOS artifacts into XCFramework
|
|
# ./build.sh package # Both AAR + XCFramework
|
|
#
|
|
# Required (Android):
|
|
# ANDROID_NDK_ROOT Path to NDK r26+ (sets ANDROID_NDK for CMake)
|
|
#
|
|
# Required (iOS):
|
|
# Xcode + Command Line Tools (xcrun must resolve)
|
|
#
|
|
# Optional (with defaults):
|
|
# ANDROID_ABI arm64-v8a
|
|
# ANDROID_PLATFORM android-24
|
|
# OPENSSL_VERSION 3.1.2
|
|
# SQLCIPHER_VERSION v4.6.1
|
|
# IOS_DEPLOYMENT_TARGET 15.0
|
|
# CMAKE_TOOLCHAIN_FILE $ANDROID_NDK_ROOT/build/cmake/android.toolchain.cmake
|
|
# OPENSSL_HOST_BIN Host openssl binary (enables in-tree fipsinstall
|
|
# when host arch == target arch)
|
|
# BUILD_TYPE Release
|
|
# JOBS auto-detected
|
|
#
|
|
# Usage:
|
|
# ANDROID_NDK_ROOT=$HOME/Library/Android/sdk/ndk/26.3.11579264 ./build.sh
|
|
# ANDROID_ABI=x86_64 ./build.sh android
|
|
# ./build.sh ios-all
|
|
# ./build.sh all
|
|
# ./build.sh package
|
|
# ---------------------------------------------------------------------------
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
SUBCOMMAND="${1:-android}"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Pre-flight: required host tooling
|
|
# ---------------------------------------------------------------------------
|
|
doctor() {
|
|
local missing=()
|
|
local tool
|
|
local tools=(cmake perl make git)
|
|
case "${SUBCOMMAND}" in
|
|
ios*) tools+=(xcrun xcodebuild) ;;
|
|
esac
|
|
for tool in "${tools[@]}"; do
|
|
if ! command -v "${tool}" >/dev/null 2>&1; then
|
|
missing+=("${tool}")
|
|
fi
|
|
done
|
|
if [ "${#missing[@]}" -gt 0 ]; then
|
|
echo "FATAL: missing required host tools: ${missing[*]}" >&2
|
|
if [ -f "${SCRIPT_DIR}/mise.toml" ] || [ -f "${SCRIPT_DIR}/.mise.toml" ]; then
|
|
echo "Hint: this repo ships a mise.toml. Run:" >&2
|
|
echo " mise trust && mise install" >&2
|
|
echo " then re-run ./build.sh." >&2
|
|
fi
|
|
exit 127
|
|
fi
|
|
}
|
|
doctor
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Shared inputs
|
|
# ---------------------------------------------------------------------------
|
|
: "${OPENSSL_VERSION:=3.1.2}"
|
|
: "${SQLCIPHER_VERSION:=v4.6.1}"
|
|
: "${OPENSSL_HOST_BIN:=}"
|
|
: "${BUILD_TYPE:=Release}"
|
|
: "${IOS_DEPLOYMENT_TARGET:=17.0}"
|
|
|
|
if command -v nproc >/dev/null 2>&1; then
|
|
JOBS="${JOBS:-$(nproc)}"
|
|
elif command -v sysctl >/dev/null 2>&1; then
|
|
JOBS="${JOBS:-$(sysctl -n hw.ncpu)}"
|
|
else
|
|
JOBS="${JOBS:-4}"
|
|
fi
|
|
|
|
_uname_s=$(uname -s)
|
|
_uname_m=$(uname -m)
|
|
|
|
# ===========================================================================
|
|
# ANDROID BUILD
|
|
# ===========================================================================
|
|
build_android() {
|
|
local abi="${1:-${ANDROID_ABI:-arm64-v8a}}"
|
|
: "${ANDROID_NDK_ROOT:?FATAL: export ANDROID_NDK_ROOT=<path/to/ndk>}"
|
|
local platform="${ANDROID_PLATFORM:-android-24}"
|
|
local toolchain_file="${CMAKE_TOOLCHAIN_FILE:-${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake}"
|
|
|
|
if [ ! -f "${toolchain_file}" ]; then
|
|
echo "FATAL: CMAKE_TOOLCHAIN_FILE not found: ${toolchain_file}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# NDK host tag
|
|
local ndk_host_tag
|
|
case "${_uname_s}" in
|
|
Darwin)
|
|
if [ -d "${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/darwin-arm64" ]; then
|
|
ndk_host_tag="darwin-arm64"
|
|
else
|
|
ndk_host_tag="darwin-x86_64"
|
|
fi
|
|
;;
|
|
Linux) ndk_host_tag="linux-x86_64" ;;
|
|
*) echo "FATAL: Unsupported host OS: ${_uname_s}" >&2; exit 1 ;;
|
|
esac
|
|
|
|
local ndk_toolchain="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/${ndk_host_tag}"
|
|
if [ ! -x "${ndk_toolchain}/bin/clang" ]; then
|
|
echo "FATAL: NDK clang not found at ${ndk_toolchain}/bin/clang" >&2
|
|
exit 1
|
|
fi
|
|
|
|
export PATH="${ndk_toolchain}/bin:${PATH}"
|
|
export ANDROID_NDK="${ANDROID_NDK_ROOT}"
|
|
export OPENSSL_HOST_BIN
|
|
|
|
local build_dir="${SCRIPT_DIR}/build/${abi}"
|
|
local dist_dir="${SCRIPT_DIR}/dist/${abi}"
|
|
|
|
cat <<EOF
|
|
================================================================
|
|
FIPS SQLCipher build [Android]
|
|
----------------------------------------------------------------
|
|
Host: ${_uname_s}/${_uname_m} (ndk: ${ndk_host_tag})
|
|
ABI: ${abi}
|
|
API: ${platform}
|
|
NDK: ${ANDROID_NDK_ROOT}
|
|
OpenSSL: ${OPENSSL_VERSION}
|
|
SQLCipher: ${SQLCIPHER_VERSION}
|
|
Jobs: ${JOBS}
|
|
================================================================
|
|
EOF
|
|
|
|
mkdir -p "${build_dir}" "${dist_dir}"
|
|
|
|
cmake -S "${SCRIPT_DIR}" -B "${build_dir}" -G "Unix Makefiles" \
|
|
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
|
-DCMAKE_TOOLCHAIN_FILE="${toolchain_file}" \
|
|
-DANDROID_NDK="${ANDROID_NDK_ROOT}" \
|
|
-DANDROID_ABI="${abi}" \
|
|
-DANDROID_PLATFORM="${platform}" \
|
|
-DOPENSSL_VERSION="${OPENSSL_VERSION}" \
|
|
-DSQLCIPHER_VERSION="${SQLCIPHER_VERSION}"
|
|
|
|
cmake --build "${build_dir}" --parallel "${JOBS}"
|
|
|
|
# Post-build integrity audit
|
|
echo ""
|
|
echo "--- Artifact listing: ${dist_dir} ---"
|
|
find "${dist_dir}" -maxdepth 3 -type f \
|
|
\( -name '*.so' -o -name '*.a' -o -name '*.cnf' -o -name '*.sh' \
|
|
-o -name '*.gradle' -o -name '*.xcconfig' -o -name '*.sha256' \) \
|
|
-print
|
|
|
|
if [ -x "${dist_dir}/fips/verify_integrity.sh" ] && \
|
|
[ -f "${dist_dir}/fips/libfips.so" ]; then
|
|
echo ""
|
|
"${dist_dir}/fips/verify_integrity.sh" "${dist_dir}/fips/libfips.so"
|
|
fi
|
|
|
|
if [ -f "${dist_dir}/lib/libsqlcipher.so" ] && \
|
|
command -v "${ndk_toolchain}/bin/llvm-readelf" >/dev/null 2>&1; then
|
|
echo ""
|
|
echo "--- libsqlcipher.so dependency audit ---"
|
|
"${ndk_toolchain}/bin/llvm-readelf" -d "${dist_dir}/lib/libsqlcipher.so" \
|
|
| grep -E '(NEEDED|SONAME|RUNPATH|RPATH)' || true
|
|
fi
|
|
}
|
|
|
|
# ===========================================================================
|
|
# iOS BUILD (single slice)
|
|
# ===========================================================================
|
|
build_ios_slice() {
|
|
local arch="$1" # arm64 | x86_64
|
|
local platform="$2" # OS | SIMULATOR
|
|
|
|
if [ "${platform}" = "OS" ]; then
|
|
local slice_name="ios-${arch}"
|
|
else
|
|
local slice_name="ios-simulator-${arch}"
|
|
fi
|
|
|
|
local build_dir="${SCRIPT_DIR}/build/${slice_name}"
|
|
local dist_dir="${SCRIPT_DIR}/dist/${slice_name}"
|
|
|
|
cat <<EOF
|
|
================================================================
|
|
FIPS SQLCipher build [iOS]
|
|
----------------------------------------------------------------
|
|
Arch: ${arch}
|
|
Platform: ${platform}
|
|
Min iOS: ${IOS_DEPLOYMENT_TARGET}
|
|
OpenSSL: ${OPENSSL_VERSION}
|
|
SQLCipher: ${SQLCIPHER_VERSION}
|
|
Jobs: ${JOBS}
|
|
================================================================
|
|
EOF
|
|
|
|
mkdir -p "${build_dir}" "${dist_dir}"
|
|
|
|
cmake -S "${SCRIPT_DIR}" -B "${build_dir}" -G "Ninja" \
|
|
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
|
-DTARGET_PLATFORM=iOS \
|
|
-DIOS_ARCH="${arch}" \
|
|
-DIOS_PLATFORM="${platform}" \
|
|
-DIOS_DEPLOYMENT_TARGET="${IOS_DEPLOYMENT_TARGET}" \
|
|
-DOPENSSL_VERSION="${OPENSSL_VERSION}" \
|
|
-DSQLCIPHER_VERSION="${SQLCIPHER_VERSION}"
|
|
|
|
cmake --build "${build_dir}" --parallel "${JOBS}"
|
|
|
|
echo ""
|
|
echo "--- Artifact listing: ${dist_dir} ---"
|
|
find "${dist_dir}" -maxdepth 3 -type f \
|
|
\( -name '*.a' -o -name '*.dylib' -o -name '*.cnf' -o -name '*.sha256' \) \
|
|
-print
|
|
|
|
if [ -f "${dist_dir}/fips/fips.dylib.sha256" ]; then
|
|
echo ""
|
|
echo "--- FIPS provider module baseline ---"
|
|
cat "${dist_dir}/fips/fips.dylib.sha256"
|
|
fi
|
|
}
|
|
|
|
# ===========================================================================
|
|
# DISPATCH
|
|
# ===========================================================================
|
|
case "${SUBCOMMAND}" in
|
|
android|"")
|
|
build_android "${ANDROID_ABI:-arm64-v8a}"
|
|
;;
|
|
|
|
ios)
|
|
build_ios_slice arm64 OS
|
|
;;
|
|
|
|
ios-simulator)
|
|
build_ios_slice arm64 SIMULATOR
|
|
build_ios_slice x86_64 SIMULATOR
|
|
;;
|
|
|
|
ios-all)
|
|
build_ios_slice arm64 OS
|
|
build_ios_slice arm64 SIMULATOR
|
|
build_ios_slice x86_64 SIMULATOR
|
|
;;
|
|
|
|
all)
|
|
build_android arm64-v8a
|
|
build_android x86_64
|
|
build_ios_slice arm64 OS
|
|
build_ios_slice arm64 SIMULATOR
|
|
build_ios_slice x86_64 SIMULATOR
|
|
;;
|
|
|
|
package-aar)
|
|
exec "${SCRIPT_DIR}/packaging/package_aar.sh"
|
|
;;
|
|
|
|
package-xcframework)
|
|
exec "${SCRIPT_DIR}/packaging/package_xcframework.sh"
|
|
;;
|
|
|
|
package)
|
|
"${SCRIPT_DIR}/packaging/package_aar.sh"
|
|
"${SCRIPT_DIR}/packaging/package_xcframework.sh"
|
|
|
|
# Stage final distributable artifacts into out/
|
|
out_dir="${SCRIPT_DIR}/out"
|
|
rm -rf "${out_dir}"
|
|
mkdir -p "${out_dir}/android" "${out_dir}/ios" "${out_dir}/include" "${out_dir}/src"
|
|
|
|
cp "${SCRIPT_DIR}/dist/fips-sqlcipher.aar" "${out_dir}/android/"
|
|
cp -R "${SCRIPT_DIR}/dist/FIPSSQLCipher.xcframework" "${out_dir}/ios/"
|
|
cp "${SCRIPT_DIR}/include/fips_init.h" "${out_dir}/include/"
|
|
cp "${SCRIPT_DIR}/include/fips_sqlcipher.h" "${out_dir}/include/"
|
|
cp "${SCRIPT_DIR}/include/fips_verify.hpp" "${out_dir}/include/"
|
|
cp "${SCRIPT_DIR}/src/fips_init.c" "${out_dir}/src/"
|
|
cp "${SCRIPT_DIR}/src/fips_init_android.c" "${out_dir}/src/"
|
|
cp "${SCRIPT_DIR}/src/fips_init_ios.c" "${out_dir}/src/"
|
|
cp "${SCRIPT_DIR}/install.md" "${out_dir}/"
|
|
|
|
echo ""
|
|
echo "Final artifacts staged in: ${out_dir}/"
|
|
;;
|
|
|
|
*)
|
|
echo "Unknown subcommand: ${SUBCOMMAND}" >&2
|
|
echo "Usage: ./build.sh [android|ios|ios-simulator|ios-all|all|package-aar|package-xcframework|package]" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
cat <<EOF
|
|
|
|
================================================================
|
|
BUILD COMPLETE
|
|
================================================================
|
|
Subcommand: ${SUBCOMMAND}
|
|
Dist root: ${SCRIPT_DIR}/dist/
|
|
|
|
Packaging:
|
|
./build.sh package-aar # -> dist/fips-sqlcipher.aar
|
|
./build.sh package-xcframework # -> dist/FIPSSQLCipher.xcframework
|
|
./build.sh package # Both
|
|
EOF
|