Skip to content

Commit 05a95fd

Browse files
authored
Merge pull request #355 from cconlon/v1.17-android
Android: Update FIPS Ready defines, add FIPS Ready GitHub Action
2 parents c9faa52 + 99a1c29 commit 05a95fd

6 files changed

Lines changed: 360 additions & 42 deletions

File tree

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
name: Android FIPS Ready Gradle Build and Test
2+
3+
on:
4+
push:
5+
branches: [ 'master', 'main', 'release/**' ]
6+
pull_request:
7+
branches: [ 'master' ]
8+
9+
concurrency:
10+
group: android-fips-${{ github.head_ref || github.ref }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
build_wolfssljni_fipsready:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Clone wolfssljni
18+
uses: actions/checkout@v4
19+
20+
# Free up disk space to prevent emulator from failing
21+
- name: Free up disk space
22+
run: |
23+
sudo rm -rf /usr/share/dotnet
24+
sudo rm -rf /usr/local/lib/android/sdk/ndk
25+
sudo rm -rf /opt/ghc
26+
sudo rm -rf /opt/hostedtoolcache/CodeQL
27+
sudo docker image prune --all --force
28+
df -h
29+
30+
# Get latest stable wolfSSL version for FIPS Ready download
31+
- name: Get latest wolfSSL stable version
32+
id: wolfssl-version
33+
run: |
34+
LATEST=$(curl -s -H "Authorization: token ${{ github.token }}" \
35+
"https://api.github.com/repos/wolfSSL/wolfssl/tags?per_page=100" | \
36+
jq -r '.[].name | select(endswith("-stable"))' | \
37+
sort -V | tail -1 | sed 's/^v//;s/-stable$//')
38+
if [ -z "$LATEST" ]; then
39+
echo "Failed to determine latest wolfSSL stable version" >&2
40+
exit 1
41+
fi
42+
echo "version=$LATEST" >> $GITHUB_OUTPUT
43+
echo "wolfSSL stable version: $LATEST"
44+
45+
# Cache wolfSSL FIPS Ready archive
46+
- name: Cache wolfSSL FIPS Ready archive
47+
uses: actions/cache@v4
48+
id: fips-cache
49+
with:
50+
path: wolfssl-fips-ready.zip
51+
key: wolfssl-fips-ready-${{ steps.wolfssl-version.outputs.version }}
52+
53+
# Download wolfSSL FIPS Ready if not cached
54+
- name: Download wolfSSL FIPS Ready
55+
if: steps.fips-cache.outputs.cache-hit != 'true'
56+
run: |
57+
VERSION="${{ steps.wolfssl-version.outputs.version }}"
58+
URL="https://www.wolfssl.com/wolfssl-${VERSION}-gplv3-fips-ready.zip"
59+
echo "Downloading: $URL"
60+
wget -q "$URL" -O wolfssl-fips-ready.zip
61+
62+
# Extract wolfSSL FIPS Ready to expected location
63+
- name: Extract wolfSSL FIPS Ready
64+
run: |
65+
unzip -q wolfssl-fips-ready.zip -d /tmp/wolfssl-fips-extract
66+
EXTRACTED_DIR=$(find /tmp/wolfssl-fips-extract -mindepth 1 -maxdepth 1 -type d | head -1)
67+
echo "Extracted directory: $EXTRACTED_DIR"
68+
ls "$EXTRACTED_DIR/wolfcrypt/src/" | head -5
69+
mv "$EXTRACTED_DIR" IDE/Android/app/src/main/cpp/wolfssl
70+
71+
# Configure CMakeLists.txt for FIPS Ready build
72+
- name: Configure for FIPS Ready
73+
run: |
74+
sed -i 's/set(WOLFSSL_PKG_TYPE "normal")/set(WOLFSSL_PKG_TYPE "fipsready")/' \
75+
IDE/Android/app/src/main/cpp/CMakeLists.txt
76+
grep 'WOLFSSL_PKG_TYPE' IDE/Android/app/src/main/cpp/CMakeLists.txt
77+
78+
# Patch MainActivity to auto-trigger WolfSSLProvider on launch,
79+
# so FIPS error callback fires and prints the expected hash to logcat
80+
# without needing a button press.
81+
- name: Patch MainActivity for auto FIPS hash detection
82+
run: |
83+
sed -i 's/button.setOnClickListener(buttonListener);/button.setOnClickListener(buttonListener);\n\n try { System.setProperty("wolfjsse.debug", "true"); Security.insertProviderAt(new WolfSSLProvider(), 1); } catch (Exception e) { e.printStackTrace(); }/' \
84+
IDE/Android/app/src/main/java/com/example/wolfssl/MainActivity.java
85+
86+
# Setup Java with Gradle caching
87+
- name: Setup java
88+
uses: actions/setup-java@v4
89+
with:
90+
distribution: 'zulu'
91+
java-version: '21'
92+
cache: 'gradle'
93+
94+
# Build all targets
95+
- name: Gradle Build (pass 1 - placeholder hash)
96+
run: cd IDE/Android && ./gradlew --build-cache assembleDebug assembleDebugUnitTest assembleDebugAndroidTest
97+
98+
# Enable KVM for hardware acceleration
99+
- name: Enable KVM
100+
run: |
101+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
102+
sudo udevadm control --reload-rules
103+
sudo udevadm trigger --name-match=kvm
104+
105+
# Cache AVD snapshot for faster emulator boot
106+
- name: AVD cache
107+
uses: actions/cache@v4
108+
id: avd-cache
109+
with:
110+
path: |
111+
~/.android/avd/*
112+
~/.android/adb*
113+
key: avd-wolfssljni-fips-30-x86_64-google_apis-v1
114+
115+
# Create AVD and generate snapshot for caching
116+
- name: Create AVD and generate snapshot
117+
if: steps.avd-cache.outputs.cache-hit != 'true'
118+
uses: reactivecircus/android-emulator-runner@v2.37.0
119+
with:
120+
api-level: 30
121+
arch: x86_64
122+
target: google_apis
123+
force-avd-creation: false
124+
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
125+
disable-animations: true
126+
script: echo "Generated AVD snapshot for caching"
127+
128+
# Launch app briefly to capture FIPS in-core hash from logcat.
129+
# The FIPS error callback prints the expected verifyCore hash on
130+
# startup if there is a mismatch.
131+
- name: Capture FIPS in-core hash
132+
id: fips-hash
133+
uses: reactivecircus/android-emulator-runner@v2.37.0
134+
timeout-minutes: 5
135+
with:
136+
api-level: 30
137+
arch: x86_64
138+
target: google_apis
139+
force-avd-creation: false
140+
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
141+
disable-animations: true
142+
script: |
143+
adb wait-for-device
144+
adb logcat -c
145+
cd IDE/Android && ./gradlew installDebug --no-daemon --no-watch-fs
146+
adb shell am start -W -n com.example.wolfssl/.MainActivity
147+
for i in 1 2 3 4 5 6; do sleep 5; adb logcat -d | grep -q 'hash = [A-Fa-f0-9]\{64\}' && break; echo "Waiting for FIPS hash ($i/6)..."; done
148+
adb logcat -d > /tmp/logcat_hash.txt 2>&1
149+
HASH=$(grep -o 'hash = [A-Fa-f0-9]\{64\}' /tmp/logcat_hash.txt | head -1 | sed 's/hash = //'); if [ -n "$HASH" ]; then echo "Captured FIPS hash: $HASH"; echo "hash=$HASH" >> $GITHUB_OUTPUT; else echo "No FIPS hash found in logcat, assuming existing hash is correct"; echo "hash=" >> $GITHUB_OUTPUT; fi
150+
151+
# Update FIPS hash in CMakeLists.txt and rebuild if needed
152+
- name: Rebuild with correct FIPS hash
153+
if: steps.fips-hash.outputs.hash != ''
154+
run: |
155+
HASH="${{ steps.fips-hash.outputs.hash }}"
156+
echo "Updating FIPS hash to: $HASH"
157+
sed -i "s/WOLFCRYPT_FIPS_CORE_HASH_VALUE=[A-Fa-f0-9]*/WOLFCRYPT_FIPS_CORE_HASH_VALUE=$HASH/g" \
158+
IDE/Android/app/src/main/cpp/CMakeLists.txt
159+
cd IDE/Android && ./gradlew --build-cache assembleDebug assembleDebugUnitTest assembleDebugAndroidTest
160+
161+
# Download Bouncy Castle provider for BKS conversion
162+
- name: Download Bouncy Castle Provider
163+
run: |
164+
BCPROV_JAR="bcprov-jdk18on-1.78.1.jar"
165+
BCPROV_URL="https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk18on/1.78.1/${BCPROV_JAR}"
166+
wget -q "$BCPROV_URL" -O "/tmp/${BCPROV_JAR}"
167+
wget -q "${BCPROV_URL}.sha256" -O "/tmp/${BCPROV_JAR}.sha256"
168+
(cd /tmp && echo "$(cat ${BCPROV_JAR}.sha256) ${BCPROV_JAR}" | sha256sum -c -)
169+
170+
# Convert JKS keystores to BKS format for Android
171+
- name: Convert JKS to BKS
172+
run: |
173+
cd examples/provider
174+
./convert-to-bks.sh /tmp/bcprov-jdk18on-1.78.1.jar
175+
176+
# Run instrumented tests on Android emulator
177+
- name: Run Android Instrumented Tests
178+
uses: reactivecircus/android-emulator-runner@v2.37.0
179+
timeout-minutes: 15
180+
with:
181+
api-level: 30
182+
arch: x86_64
183+
target: google_apis
184+
force-avd-creation: false
185+
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
186+
disable-animations: true
187+
script: |
188+
adb wait-for-device
189+
adb shell mkdir -p /data/local/tmp/examples/provider
190+
adb shell mkdir -p /data/local/tmp/examples/certs/intermediate
191+
adb push ./examples/provider/*.bks /data/local/tmp/examples/provider/
192+
adb push ./examples/certs/ /data/local/tmp/examples/
193+
adb logcat -c
194+
cd IDE/Android && ./gradlew connectedDebugAndroidTest --no-daemon --no-watch-fs || { adb logcat -d > /tmp/logcat.txt 2>&1; echo "=== LOGCAT (errors) ==="; grep -i "exception\|error\|fatal" /tmp/logcat.txt || true; exit 1; }
195+
adb logcat -d > /tmp/logcat.txt 2>&1 || true
196+
pgrep -f '[q]emu-system' | xargs -r kill -9 2>/dev/null || true
197+
pgrep -f '[c]rashpad' | xargs -r kill -9 2>/dev/null || true
198+
sleep 2
199+
200+
# Upload test reports even on failure
201+
- name: Upload Test Reports
202+
uses: actions/upload-artifact@v4
203+
if: always()
204+
timeout-minutes: 5
205+
with:
206+
name: android-fips-ready-test-reports
207+
path: |
208+
IDE/Android/app/build/reports/androidTests/
209+
/tmp/logcat.txt
210+
/tmp/logcat_hash.txt
211+
retention-days: 14

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib/
1717
docs/
1818
report/
1919
IDE/Android/.idea/deploymentTargetDropDown.xml
20+
IDE/Android/.idea/vcs.xml
2021
IDE/Android/app/.cxx/
2122
IDE/Android/app/src/main/cpp/wolfssl/
2223
IDE/WIN/.vs

IDE/Android/.idea/vcs.xml

Lines changed: 0 additions & 7 deletions
This file was deleted.

IDE/Android/app/src/main/cpp/CMakeLists.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,16 @@ elseif("${WOLFSSL_PKG_TYPE}" MATCHES "fipsready")
120120

121121
if("${ANDROID_ABI}" MATCHES "arm64-v8a")
122122
# https://developer.android.com/ndk/guides/abis#arm64-v8a
123-
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=DF2FF40654C405467072356FBA6C02A88F17E79B08A1A8F3A887C0F6AB4E4650)
123+
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=0C1CB1086D64FCD5AB5F7A0A8127244CE8D891CA5542B02FA4B9D81FD35C5C8A)
124124
elseif("${ANDROID_ABI}" MATCHES "armeabi-v7a")
125125
# https://developer.android.com/ndk/guides/abis#v7a
126-
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=DF2FF40654C405467072356FBA6C02A88F17E79B08A1A8F3A887C0F6AB4E4650)
126+
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=0C1CB1086D64FCD5AB5F7A0A8127244CE8D891CA5542B02FA4B9D81FD35C5C8A)
127127
elseif("${ANDROID_ABI}" MATCHES "x86_64")
128128
# https://developer.android.com/ndk/guides/abis#86-64
129-
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=DF2FF40654C405467072356FBA6C02A88F17E79B08A1A8F3A887C0F6AB4E4650)
129+
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=0C1CB1086D64FCD5AB5F7A0A8127244CE8D891CA5542B02FA4B9D81FD35C5C8A)
130130
elseif("${ANDROID_ABI}" MATCHES "x86")
131131
# https://developer.android.com/ndk/guides/abis#x86
132-
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=DF2FF40654C405467072356FBA6C02A88F17E79B08A1A8F3A887C0F6AB4E4650)
132+
add_definitions(-DWOLFCRYPT_FIPS_CORE_HASH_VALUE=0C1CB1086D64FCD5AB5F7A0A8127244CE8D891CA5542B02FA4B9D81FD35C5C8A)
133133
endif()
134134

135135
# Add preprocessor defines to CFLAGS, these match those placed into
@@ -156,8 +156,8 @@ elseif("${WOLFSSL_PKG_TYPE}" MATCHES "fipsready")
156156
-DHAVE_OCSP -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER
157157
-DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN -DWOLFSSL_CERT_REQ -DWOLFSSL_KEY_GEN
158158
-DHAVE_ALPN -DWOLFSSL_ALT_CERT_CHAINS -DSESSION_CERTS -DWOLFSSL_ENCRYPTED_KEYS
159-
-DWOLFSSL_SYS_CA_CERTS -DWOLFSSL_ALT_NAMES -DWOLFSSL_EITHER_SIDE
160-
-DWOLFSSL_TICKET_HAVE_ID -DWOLFSSL_CERT_NAME_ALL
159+
-DWOLFSSL_SYS_CA_CERTS -DWOLFSSL_ALT_NAMES -DWOLFSSL_ALWAYS_KEEP_SNI
160+
-DWOLFSSL_EITHER_SIDE -DWOLFSSL_TICKET_HAVE_ID -DWOLFSSL_CERT_NAME_ALL
161161
-DHAVE_SERVER_RENEGOTIATION_INFO -DWOLFSSL_ASN_TEMPLATE -DWOLFSSL_ASN_PRINT
162162
-DWOLFSSL_BASE64_ENCODE -DERROR_QUEUE_PER_THREAD -DNO_ERROR_QUEUE
163163
-DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWOLFSSL_USE_ALIGN

0 commit comments

Comments
 (0)