Files
Christopher Fahlin 01e26dd717 feat(openssl): upgrade from 3.0.8 to 3.1.2 (FIPS 140-3 Cert #4985)
- 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)
2026-05-09 12:38:27 -07:00

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