Skip to content

Commit 95a73d4

Browse files
authored
[WIP] Updates to Digital Signature Verification for HDF5 Plugins (#6166)
* Add signature verification caching for HDF5 plugins Implements a signature verification cache to avoid redundant cryptographic operations when loading the same plugin multiple times. The cache stores verification results (success/failure) indexed by plugin path and file modification time, enabling instant verification on cache hits while maintaining security through mtime-based invalidation. Implementation Details: 1. Cache Structure (H5PLsig.c): - H5PL_signature_cache_entry_t: path, mtime, verified status - Dynamic array with doubling growth strategy (initial capacity: 8) - Stores both positive and negative verification results 2. Cache Operations: - H5PL__check_signature_cache(): Check cache, validate mtime - H5PL__update_signature_cache(): Add/update cache entries - Integrated into H5PL__verify_signature_appended() - Cache invalidation on file modification (mtime check) 3. Code Cleanup: - Removed commented GPG/GPGME configuration from H5pubconf.h.in - Eliminated dead code since the implementation uses OpenSSL 4. Test Infrastructure: - New test executable: h5signverifytest - 6 new test cases: * Verify signed plugin (positive test) * Verify unsigned plugin (negative test) * Verify tampered plugin (security test) * Cache basic functionality (performance test) * Cache invalidation on modification (security test) * Cache negative results (DoS prevention) - CMake integration with dependency management - CreateTamperedPlugin.cmake: Generate tampered plugins for testing Files Modified: - src/H5PLsig.c: Cache implementation and integration - src/H5pubconf.h.in: Removed GPG comments - tools/test/h5sign/CMakeLists.txt: Added h5signverifytest build - tools/test/h5sign/CMakeTests.cmake: Added verification tests Files Added: - tools/test/h5sign/h5signverifytest.c: Comprehensive test suite - tools/test/h5sign/CreateTamperedPlugin.cmake: Tamper test helper Performance: Eliminates cryptographic overhead on repeated plugin loads (cache hit returns instantly vs. full RSA signature verification). Security: mtime-based invalidation ensures modified plugins are re-verified, preventing cache from masking tampering. Negative result caching prevents retry attacks on invalid plugins. Backward Compatibility: Fully backward compatible, cache is transparent optimization with no API changes.
1 parent f75ccaf commit 95a73d4

30 files changed

+6822
-34
lines changed

.github/workflows/arm-main.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ jobs:
3838
runs-on: windows-11-arm
3939
if: ${{ inputs.build_mode != 'Debug' }}
4040
steps:
41+
- name: Check OpenSSL Version (Windows)
42+
run: openssl version
43+
4144
- name: Install Dependencies
4245
uses: ssciwr/doxygen-install@501e53b879da7648ab392ee226f5b90e42148449 # v1
4346
with:

.github/workflows/main-static.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,10 @@ jobs:
138138
run: brew install ninja curl
139139
if: ${{ matrix.ostype == 'macos' }}
140140

141+
- name: Check OpenSSL Version (Windows)
142+
run: openssl version
143+
if: matrix.ostype == 'windows'
144+
141145
- name: Install Dependencies
142146
uses: ssciwr/doxygen-install@501e53b879da7648ab392ee226f5b90e42148449 # v1
143147
with:

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ jobs:
155155
run: brew install ninja curl
156156
if: ${{ matrix.ostype == 'macos' }}
157157

158+
- name: Check OpenSSL Version (Windows)
159+
run: openssl version
160+
if: matrix.ostype == 'windows'
161+
158162
- name: Install Dependencies
159163
uses: ssciwr/doxygen-install@501e53b879da7648ab392ee226f5b90e42148449 # v1
160164
with:
Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
name: Test Signed Plugins
2+
3+
on:
4+
push:
5+
branches: [ develop, feature/dig_sig_ver, feature/* ]
6+
pull_request:
7+
branches: [ develop ]
8+
9+
permissions:
10+
contents: read
11+
12+
env:
13+
CTEST_OUTPUT_ON_FAILURE: 1
14+
15+
jobs:
16+
# Test signature verification in both serial and parallel configurations
17+
test-signed-plugins:
18+
name: "${{ matrix.config.name }}"
19+
runs-on: ubuntu-latest
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
config:
24+
# Serial configurations
25+
- name: "Serial (Debug + Shared)"
26+
build_type: Debug
27+
shared: ON
28+
parallel: OFF
29+
30+
- name: "Serial (Release + Static)"
31+
build_type: Release
32+
shared: OFF
33+
parallel: OFF
34+
35+
# Parallel configurations - test MPI collective verification
36+
- name: "Parallel (Debug + Shared)"
37+
build_type: Debug
38+
shared: ON
39+
parallel: ON
40+
41+
- name: "Parallel (Release + Shared)"
42+
build_type: Release
43+
shared: ON
44+
parallel: ON
45+
46+
steps:
47+
- name: Checkout code
48+
uses: actions/checkout@v4
49+
50+
- name: Install base dependencies
51+
run: |
52+
sudo apt-get update
53+
sudo apt-get install -y \
54+
libssl-dev \
55+
zlib1g-dev \
56+
libaec-dev
57+
58+
- name: Install MPI dependencies
59+
if: matrix.config.parallel == 'ON'
60+
run: |
61+
sudo apt-get install -y \
62+
libopenmpi-dev \
63+
openmpi-bin
64+
65+
- name: Generate test RSA key pair
66+
run: |
67+
echo "Generating test RSA key pair for CI testing..."
68+
openssl genrsa -out ci-test-private.pem 2048
69+
openssl rsa -in ci-test-private.pem -pubout -out ci-test-public.pem
70+
echo "Test keys generated successfully"
71+
ls -lh ci-test-*.pem
72+
73+
- name: Configure CMake
74+
run: |
75+
cmake -B build \
76+
-DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \
77+
-DHDF5_REQUIRE_SIGNED_PLUGINS:BOOL=ON \
78+
-DHDF5_PLUGIN_PUBLIC_KEY_FILE="${PWD}/ci-test-public.pem" \
79+
-DHDF5_ENABLE_PARALLEL:BOOL=${{ matrix.config.parallel }} \
80+
-DBUILD_SHARED_LIBS:BOOL=${{ matrix.config.shared }} \
81+
-DBUILD_STATIC_LIBS:BOOL=ON \
82+
-DBUILD_TESTING:BOOL=ON \
83+
-DHDF5_BUILD_TOOLS:BOOL=ON \
84+
-DHDF5_ENABLE_ZLIB_SUPPORT:BOOL=ON \
85+
-DHDF5_ENABLE_SZIP_SUPPORT:BOOL=ON
86+
87+
- name: Copy private key to build directory
88+
run: |
89+
echo "Copying private key to build directory for plugin signing..."
90+
cp ci-test-private.pem build/private.pem
91+
mkdir -p build/test
92+
cp ci-test-private.pem build/test/private.pem
93+
ls -lh build/private.pem build/test/private.pem
94+
95+
- name: Build
96+
run: cmake --build build --parallel 4
97+
98+
- name: Verify signature test binary exists
99+
run: |
100+
if [ -f "build/bin/test_plugin_signature" ] || [ -f "build/bin/test_plugin_signature.exe" ]; then
101+
echo "✓ Plugin signature verification test binary found"
102+
ls -lh build/bin/test_plugin_signature* || true
103+
else
104+
echo "WARNING: Plugin signature verification test binary not found"
105+
echo "This might be expected if HDF5_REQUIRE_SIGNED_PLUGINS is OFF"
106+
fi
107+
108+
- name: Run Tests (Serial)
109+
if: matrix.config.parallel == 'OFF'
110+
run: |
111+
cd build
112+
ctest --parallel 4 --output-on-failure
113+
114+
# Explicitly run plugin signature verification test
115+
echo ""
116+
echo "Running plugin signature verification test..."
117+
ctest --tests-regex "H5PLUGIN-signature-verification" --verbose
118+
119+
- name: Run Tests (Parallel)
120+
if: matrix.config.parallel == 'ON'
121+
run: |
122+
cd build
123+
# Run all tests including parallel tests
124+
ctest --parallel 4 --output-on-failure
125+
126+
# Specifically test MPI tests to ensure collective verification is exercised
127+
echo "Running MPI-specific tests..."
128+
ctest --tests-regex "MPI_TEST" --verbose || echo "MPI tests completed"
129+
130+
# Explicitly run plugin signature verification test
131+
echo ""
132+
echo "Running plugin signature verification test..."
133+
ctest --tests-regex "H5PLUGIN-signature-verification" --verbose
134+
135+
# Comprehensive test to verify signature verification logic paths
136+
verify-signature-paths:
137+
name: "Verify Signature Logic Paths"
138+
runs-on: ubuntu-latest
139+
140+
steps:
141+
- name: Checkout code
142+
uses: actions/checkout@v4
143+
144+
- name: Install dependencies
145+
run: |
146+
sudo apt-get update
147+
sudo apt-get install -y \
148+
libssl-dev \
149+
zlib1g-dev \
150+
libaec-dev \
151+
libopenmpi-dev \
152+
openmpi-bin
153+
154+
- name: Generate test RSA key pair
155+
run: |
156+
echo "Generating test RSA key pair for CI testing..."
157+
openssl genrsa -out ci-test-private.pem 2048
158+
openssl rsa -in ci-test-private.pem -pubout -out ci-test-public.pem
159+
echo "Test keys generated successfully"
160+
ls -lh ci-test-*.pem
161+
162+
- name: Configure CMake (Parallel with all features)
163+
run: |
164+
cmake -B build \
165+
-DCMAKE_BUILD_TYPE=Debug \
166+
-DHDF5_REQUIRE_SIGNED_PLUGINS:BOOL=ON \
167+
-DHDF5_PLUGIN_PUBLIC_KEY_FILE="${PWD}/ci-test-public.pem" \
168+
-DHDF5_ENABLE_PARALLEL:BOOL=ON \
169+
-DBUILD_SHARED_LIBS:BOOL=ON \
170+
-DBUILD_TESTING:BOOL=ON \
171+
-DHDF5_BUILD_TOOLS:BOOL=ON \
172+
-DHDF5_ENABLE_ZLIB_SUPPORT:BOOL=ON
173+
174+
- name: Copy private key to build directory
175+
run: |
176+
echo "Copying private key to build directory for plugin signing..."
177+
cp ci-test-private.pem build/private.pem
178+
mkdir -p build/test
179+
cp ci-test-private.pem build/test/private.pem
180+
ls -lh build/private.pem build/test/private.pem
181+
182+
- name: Build
183+
run: cmake --build build --parallel 4
184+
185+
- name: Verify H5PL__verify_plugin_signature is compiled
186+
run: |
187+
echo "Checking that signature verification function is present..."
188+
grep -r "H5PL__verify_plugin_signature" build/src/ || true
189+
190+
- name: Verify serial path compiled
191+
run: |
192+
echo "Checking serial signature verification path..."
193+
grep -A 5 "Serial mode: always verify" src/H5PLint.c
194+
195+
- name: Verify parallel path compiled
196+
run: |
197+
echo "Checking parallel signature verification path..."
198+
grep -A 10 "Collective: root verifies" src/H5PLint.c
199+
grep -A 5 "Independent: each rank verifies" src/H5PLint.c
200+
201+
- name: Run comprehensive tests
202+
run: |
203+
cd build
204+
# Run full test suite
205+
ctest --output-on-failure --verbose
206+
207+
- name: Verify plugin signature tests execute
208+
run: |
209+
cd build
210+
echo "========================================"
211+
echo "Running Plugin Signature Verification Tests"
212+
echo "========================================"
213+
214+
# Run signature verification tests explicitly and fail on any error
215+
ctest --tests-regex "H5PLUGIN-signature-verification" --verbose
216+
217+
echo ""
218+
echo "Plugin signature verification tests completed successfully!"

0 commit comments

Comments
 (0)