Skip to content

Commit ccd3562

Browse files
committed
Add CRL generation code
1 parent 2d39410 commit ccd3562

File tree

11 files changed

+1880
-8
lines changed

11 files changed

+1880
-8
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ ecc-key.der
104104
ecc-key.pem
105105
certreq.der
106106
certreq.pem
107+
crlRsaOut.pem
108+
crlRsaOut.der
109+
crlEccOut.pem
110+
crlEccOut.der
107111
pkcs7cert.der
108112
pkcs7authEnvelopedDataAES128GCM.der
109113
pkcs7authEnvelopedDataAES128GCM_ECDH_SHA1KDF.der
@@ -470,3 +474,6 @@ wolfssl/debug-trace-error-codes.h
470474
wolfssl/debug-untrace-error-codes.h
471475

472476
AGENTS.md
477+
478+
# Code navigation files
479+
compile_commands.json

scripts/crl-openssl-verify.test

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
#!/usr/bin/env bash
2+
3+
# crl-openssl-verify.test
4+
# Verifies CRL files generated by test_sk_X509_CRL_encode using OpenSSL
5+
6+
# Exit on first error
7+
set -e
8+
9+
# CRL files generated by test_sk_X509_CRL_encode
10+
CRL_RSA_PEM="./certs/crl/crlRsaOut.pem"
11+
CRL_RSA_DER="./certs/crl/crlRsaOut.der"
12+
CRL_ECC_PEM="./certs/crl/crlEccOut.pem"
13+
CRL_ECC_DER="./certs/crl/crlEccOut.der"
14+
15+
# Issuer certificates used to sign the CRLs (must match the signing keys)
16+
# RSA CRL is signed with ca-key.pem, issuer is ca-cert.pem subject
17+
RSA_ISSUER_CERT="./certs/ca-cert.pem"
18+
# ECC CRL is signed with ecc-key.pem, issuer is server-ecc.pem subject
19+
ECC_ISSUER_CERT="./certs/server-ecc.pem"
20+
21+
# Expected number of revoked certificates in each CRL
22+
EXPECTED_REVOKED_COUNT=4
23+
24+
exit_code=0
25+
26+
check_openssl() {
27+
if ! command -v openssl &> /dev/null; then
28+
echo "OpenSSL not found, skipping test"
29+
exit 0
30+
fi
31+
}
32+
33+
print_openssl_info() {
34+
echo "OpenSSL version: $(openssl version)"
35+
echo "OpenSSL binary: $(command -v openssl)"
36+
}
37+
38+
print_debug_info() {
39+
local crl_file="$1"
40+
local crl_text="$2"
41+
42+
echo " === DEBUG INFO ==="
43+
echo " OpenSSL version: $(openssl version)"
44+
echo " CRL file: $crl_file"
45+
echo " CRL file size: $(wc -c < "$crl_file" 2>/dev/null || echo "N/A") bytes"
46+
echo " --- CRL Text Output (first 100 lines) ---"
47+
echo "$crl_text" | head -100 | sed 's/^/ /'
48+
echo " --- End CRL Text ---"
49+
}
50+
51+
# Check if a serial number is present in CRL text
52+
# Handles various OpenSSL output formats:
53+
# "Serial Number: 02"
54+
# "Serial Number: 2"
55+
# "Serial Number: 0x02"
56+
# Multi-line format with serial on next line
57+
check_serial_in_crl() {
58+
local crl_text="$1"
59+
local serial="$2"
60+
61+
# Try exact match first (e.g., "Serial Number: 02")
62+
if echo "$crl_text" | grep -qi "Serial Number:.*[^0-9a-f]0*$serial[^0-9a-f]"; then
63+
return 0
64+
fi
65+
66+
# Try without leading zeros (e.g., "Serial Number: 2" for serial "02")
67+
local serial_no_leading_zero=$(echo "$serial" | sed 's/^0*//')
68+
if [ -n "$serial_no_leading_zero" ]; then
69+
if echo "$crl_text" | grep -qi "Serial Number:.*[^0-9a-f]$serial_no_leading_zero[^0-9a-f]"; then
70+
return 0
71+
fi
72+
# End of line match
73+
if echo "$crl_text" | grep -qi "Serial Number:.*[^0-9a-f]$serial_no_leading_zero$"; then
74+
return 0
75+
fi
76+
fi
77+
78+
# Try hex format (e.g., "Serial Number: 0x02")
79+
if echo "$crl_text" | grep -qi "Serial Number:.*0x0*$serial"; then
80+
return 0
81+
fi
82+
83+
# Try exact match at end of line
84+
if echo "$crl_text" | grep -qi "Serial Number: 0*$serial$"; then
85+
return 0
86+
fi
87+
88+
# Try case-insensitive match for the serial anywhere after "Serial Number"
89+
if echo "$crl_text" | grep -i "Serial Number" | grep -qi "[^0-9a-f]0*$serial[^0-9a-f]\|[^0-9a-f]0*$serial$"; then
90+
return 0
91+
fi
92+
93+
return 1
94+
}
95+
96+
verify_crl_pem() {
97+
local crl_file="$1"
98+
local issuer_cert="$2"
99+
local crl_type="$3"
100+
101+
if [ ! -f "$crl_file" ]; then
102+
echo "SKIP: $crl_type CRL PEM file not found: $crl_file"
103+
echo " (test_sk_X509_CRL_encode may not have run or feature disabled)"
104+
return 0
105+
fi
106+
107+
echo "Verifying $crl_type CRL (PEM): $crl_file"
108+
109+
# Parse and display CRL info
110+
if ! openssl crl -in "$crl_file" -inform PEM -noout -text > /dev/null 2>&1; then
111+
echo "FAIL: OpenSSL failed to parse $crl_type CRL PEM"
112+
echo " OpenSSL error output:"
113+
openssl crl -in "$crl_file" -inform PEM -noout -text 2>&1 | sed 's/^/ /' || true
114+
exit_code=1
115+
return 1
116+
fi
117+
echo " - OpenSSL can parse CRL: OK"
118+
119+
# Get the CRL text for further checks
120+
crl_text=$(openssl crl -in "$crl_file" -inform PEM -noout -text 2>/dev/null)
121+
122+
# Verify CRL signature against issuer certificate
123+
# This is the critical cryptographic verification using -CAfile and -verify
124+
if [ -f "$issuer_cert" ]; then
125+
verify_output=$(openssl crl -in "$crl_file" -inform PEM -noout -CAfile "$issuer_cert" -verify 2>&1)
126+
if echo "$verify_output" | grep -q "verify OK"; then
127+
echo " - CRL signature verification (-CAfile -verify): OK"
128+
else
129+
echo " - CRL signature verification (-CAfile -verify): FAIL"
130+
echo " Verification output: $verify_output"
131+
echo " Issuer cert: $issuer_cert"
132+
print_debug_info "$crl_file" "$crl_text"
133+
exit_code=1
134+
return 1
135+
fi
136+
else
137+
echo " - CRL signature verification: SKIPPED (issuer cert not found: $issuer_cert)"
138+
fi
139+
140+
# Count revoked certificates
141+
revoked_count=$(echo "$crl_text" | grep -c "Serial Number:" || true)
142+
143+
if [ "$revoked_count" -eq "$EXPECTED_REVOKED_COUNT" ]; then
144+
echo " - Revoked certificate count: $revoked_count (expected $EXPECTED_REVOKED_COUNT) OK"
145+
else
146+
echo " - Revoked certificate count: $revoked_count (expected $EXPECTED_REVOKED_COUNT) FAIL"
147+
print_debug_info "$crl_file" "$crl_text"
148+
exit_code=1
149+
return 1
150+
fi
151+
152+
# Check for required CRL fields
153+
if echo "$crl_text" | grep -q "Issuer:"; then
154+
echo " - Issuer field: OK"
155+
else
156+
echo " - Issuer field: MISSING"
157+
print_debug_info "$crl_file" "$crl_text"
158+
exit_code=1
159+
fi
160+
161+
if echo "$crl_text" | grep -q "Last Update:"; then
162+
echo " - Last Update field: OK"
163+
else
164+
echo " - Last Update field: MISSING"
165+
print_debug_info "$crl_file" "$crl_text"
166+
exit_code=1
167+
fi
168+
169+
if echo "$crl_text" | grep -q "Next Update:"; then
170+
echo " - Next Update field: OK"
171+
else
172+
echo " - Next Update field: MISSING"
173+
print_debug_info "$crl_file" "$crl_text"
174+
exit_code=1
175+
fi
176+
177+
# Check signature algorithm is present
178+
if echo "$crl_text" | grep -q "Signature Algorithm:"; then
179+
sig_alg=$(echo "$crl_text" | grep "Signature Algorithm:" | head -1 | awk '{print $3}')
180+
echo " - Signature Algorithm: $sig_alg OK"
181+
else
182+
echo " - Signature Algorithm: MISSING"
183+
print_debug_info "$crl_file" "$crl_text"
184+
exit_code=1
185+
fi
186+
187+
# Check for signature value
188+
# OpenSSL 3.x uses "Signature Value:" label
189+
# OpenSSL 1.1.x just shows hex bytes after "Signature Algorithm:" without a label
190+
if echo "$crl_text" | grep -q "Signature Value:"; then
191+
echo " - Signature Value: present OK"
192+
elif echo "$crl_text" | grep -Eq "^\s+[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}"; then
193+
# Found hex signature bytes (OpenSSL 1.1.x format)
194+
echo " - Signature Value: present OK (hex bytes format)"
195+
else
196+
echo " - Signature Value: MISSING"
197+
print_debug_info "$crl_file" "$crl_text"
198+
exit_code=1
199+
fi
200+
201+
# Verify expected serial numbers are present (using flexible matching)
202+
for serial in "02" "03" "04"; do
203+
if check_serial_in_crl "$crl_text" "$serial"; then
204+
echo " - Serial $serial revoked: OK"
205+
else
206+
echo " - Serial $serial revoked: MISSING"
207+
echo " Looking for serial: $serial"
208+
echo " Serial lines found in CRL:"
209+
echo "$crl_text" | grep -i "Serial" | sed 's/^/ /'
210+
print_debug_info "$crl_file" "$crl_text"
211+
exit_code=1
212+
fi
213+
done
214+
215+
if [ $exit_code -eq 0 ]; then
216+
echo "PASS: $crl_type CRL PEM structure verified"
217+
else
218+
echo "FAIL: $crl_type CRL PEM had errors (see above)"
219+
fi
220+
echo ""
221+
return 0
222+
}
223+
224+
verify_crl_der() {
225+
local crl_file="$1"
226+
local crl_type="$2"
227+
228+
if [ ! -f "$crl_file" ]; then
229+
echo "SKIP: $crl_type CRL DER file not found: $crl_file"
230+
return 0
231+
fi
232+
233+
echo "Verifying $crl_type CRL (DER): $crl_file"
234+
235+
# Parse DER format
236+
if ! openssl crl -in "$crl_file" -inform DER -noout -text > /dev/null 2>&1; then
237+
echo "FAIL: OpenSSL failed to parse $crl_type CRL DER"
238+
echo " OpenSSL error output:"
239+
openssl crl -in "$crl_file" -inform DER -noout -text 2>&1 | sed 's/^/ /' || true
240+
exit_code=1
241+
return 1
242+
fi
243+
244+
# Count revoked certificates
245+
revoked_count=$(openssl crl -in "$crl_file" -inform DER -noout -text 2>/dev/null | \
246+
grep -c "Serial Number:" || true)
247+
248+
if [ "$revoked_count" -eq "$EXPECTED_REVOKED_COUNT" ]; then
249+
echo "PASS: $crl_type CRL DER has $revoked_count revoked certificates (expected $EXPECTED_REVOKED_COUNT)"
250+
else
251+
echo "FAIL: $crl_type CRL DER has $revoked_count revoked certificates (expected $EXPECTED_REVOKED_COUNT)"
252+
echo " DER CRL content:"
253+
openssl crl -in "$crl_file" -inform DER -noout -text 2>/dev/null | head -50 | sed 's/^/ /'
254+
exit_code=1
255+
return 1
256+
fi
257+
258+
echo ""
259+
return 0
260+
}
261+
262+
compare_pem_der() {
263+
local pem_file="$1"
264+
local der_file="$2"
265+
local crl_type="$3"
266+
267+
if [ ! -f "$pem_file" ] || [ ! -f "$der_file" ]; then
268+
return 0
269+
fi
270+
271+
echo "Comparing $crl_type CRL PEM vs DER..."
272+
273+
# Convert PEM to DER and compare
274+
converted_der=$(mktemp)
275+
trap "rm -f $converted_der" EXIT
276+
277+
openssl crl -in "$pem_file" -inform PEM -outform DER -out "$converted_der" 2>/dev/null
278+
279+
if cmp -s "$converted_der" "$der_file"; then
280+
echo "PASS: $crl_type CRL PEM and DER are equivalent"
281+
else
282+
echo "FAIL: $crl_type CRL PEM and DER do not match after conversion"
283+
echo " PEM file size: $(wc -c < "$pem_file") bytes"
284+
echo " DER file size: $(wc -c < "$der_file") bytes"
285+
echo " Converted DER size: $(wc -c < "$converted_der") bytes"
286+
exit_code=1
287+
fi
288+
289+
rm -f "$converted_der"
290+
trap - EXIT
291+
292+
echo ""
293+
}
294+
295+
######### begin program #########
296+
297+
echo "============================================"
298+
echo "CRL OpenSSL Verification Test"
299+
echo "============================================"
300+
echo ""
301+
302+
check_openssl
303+
print_openssl_info
304+
echo ""
305+
306+
# Check if CRL files exist at all
307+
echo "Checking for CRL files..."
308+
for f in "$CRL_RSA_PEM" "$CRL_RSA_DER" "$CRL_ECC_PEM" "$CRL_ECC_DER"; do
309+
if [ -f "$f" ]; then
310+
echo " Found: $f ($(wc -c < "$f") bytes)"
311+
else
312+
echo " Missing: $f"
313+
fi
314+
done
315+
echo ""
316+
317+
# Test RSA-signed CRL
318+
verify_crl_pem "$CRL_RSA_PEM" "$RSA_ISSUER_CERT" "RSA"
319+
verify_crl_der "$CRL_RSA_DER" "RSA"
320+
compare_pem_der "$CRL_RSA_PEM" "$CRL_RSA_DER" "RSA"
321+
322+
# Test ECC-signed CRL
323+
verify_crl_pem "$CRL_ECC_PEM" "$ECC_ISSUER_CERT" "ECC"
324+
verify_crl_der "$CRL_ECC_DER" "ECC"
325+
compare_pem_der "$CRL_ECC_PEM" "$CRL_ECC_DER" "ECC"
326+
327+
# Summary
328+
echo "============================================"
329+
if [ $exit_code -eq 0 ]; then
330+
echo "All CRL verification tests PASSED"
331+
else
332+
echo "Some CRL verification tests FAILED"
333+
echo "(See detailed output above for failure reasons)"
334+
fi
335+
echo "============================================"
336+
337+
exit $exit_code
338+
339+
########## end program ##########

scripts/include.am

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ if BUILD_CRL
1919
# make revoked test rely on completion of resume test
2020
dist_noinst_SCRIPTS+= scripts/crl-revoked.test
2121
scripts/crl-revoked.log: scripts/resume.log
22+
23+
# CRL OpenSSL verification test - verifies CRLs created by test_sk_X509_CRL_encode
24+
# depends on unit tests completing first (which creates the CRL files)
25+
# also depends on resume.log to ensure DTLS resume tests complete first
26+
dist_noinst_SCRIPTS+= scripts/crl-openssl-verify.test
27+
scripts/crl-openssl-verify.log: tests/unit.log
28+
scripts/crl-openssl-verify.log: scripts/resume.log
2229
endif
2330

2431
# arrange to serialize ocsp.test, ocsp-stapling.test, ocsp-stapling-with-ca-as-responder.test, ocsp-stapling2.test, and testsuite,

0 commit comments

Comments
 (0)