Skip to content

Commit ff493c2

Browse files
authored
Merge pull request #9834 from padelsbach/padelsbach/finding-23
Fix OCSP->CRL fallback
2 parents 58f48a9 + ebda79f commit ff493c2

File tree

12 files changed

+923
-261
lines changed

12 files changed

+923
-261
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,3 +488,6 @@ AGENTS.md
488488

489489
# Code navigation files
490490
compile_commands.json
491+
492+
# Python cache
493+
__pycache__/

certs/crl/gencrls.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,4 +241,17 @@ openssl crl -in extra-crls/large_crlnum2.pem -text > tmp
241241
check_result $?
242242
mv tmp extra-crls/large_crlnum2.pem
243243

244+
# OCSP root-ca CRL (empty, no revocations)
245+
cp blank.index.txt demoCA/index.txt
246+
247+
echo "Step 31"
248+
openssl ca -config ../renewcerts/wolfssl.cnf -gencrl -crldays 1000 -out ../ocsp/root-ca-crl.pem -keyfile ../ocsp/root-ca-key.pem -cert ../ocsp/root-ca-cert.pem
249+
check_result $?
250+
251+
# metadata
252+
echo "Step 32"
253+
openssl crl -in ../ocsp/root-ca-crl.pem -text > tmp
254+
check_result $?
255+
mv tmp ../ocsp/root-ca-crl.pem
256+
244257
exit 0

certs/ocsp/include.am

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ EXTRA_DIST += \
2323
certs/ocsp/ocsp-responder-cert.pem \
2424
certs/ocsp/server1-key.pem \
2525
certs/ocsp/server1-cert.pem \
26+
certs/ocsp/server1-chain-noroot.pem \
2627
certs/ocsp/server2-key.pem \
2728
certs/ocsp/server2-cert.pem \
2829
certs/ocsp/server3-key.pem \
@@ -33,6 +34,7 @@ EXTRA_DIST += \
3334
certs/ocsp/server5-cert.pem \
3435
certs/ocsp/root-ca-key.pem \
3536
certs/ocsp/root-ca-cert.pem \
37+
certs/ocsp/root-ca-crl.pem \
3638
certs/ocsp/test-response.der \
3739
certs/ocsp/test-response-rsapss.der \
3840
certs/ocsp/test-response-nointern.der \

certs/ocsp/renewcerts.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ update_cert server3 "www3.wolfssl.com" intermediate2-ca
8989
update_cert server4 "www4.wolfssl.com" intermediate2-ca v3_req2 08 # REVOKED
9090
update_cert server5 "www5.wolfssl.com" intermediate3-ca v3_req3 09
9191

92+
# server1-chain-noroot.pem: server1 + intermediate1 without root-ca
93+
# (used by tests that need a chain where the root is not sent by the server)
94+
head -n "$(grep -n 'END CERTIFICATE' server1-cert.pem | head -2 | tail -1 | cut -d: -f1)" server1-cert.pem > server1-chain-noroot.pem
95+
check_result $? ""
96+
9297
# Create response DER buffer for test
9398
openssl ocsp -port 22221 -ndays 1000 -index index-ca-and-intermediate-cas.txt -rsigner ocsp-responder-cert.pem -rkey ocsp-responder-key.pem -CA root-ca-cert.pem -partial_chain &
9499
PID=$!

certs/ocsp/root-ca-crl.pem

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
-----BEGIN X509 CRL-----
2+
MIIB8TCB2gIBATANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMxEzARBgNV
3+
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT
4+
U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NMIHJvb3Qg
5+
Q0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20XDTI2MDIyNTE5NTQx
6+
MloXDTM2MDIyMzE5NTQxMlqgDjAMMAoGA1UdFAQDAgEBMA0GCSqGSIb3DQEBCwUA
7+
A4IBAQB25t9Aca9CcNe95wh1Wnbh5iy/bia5+uRgZjc1aj/fylr8hRyWtOJZlG+S
8+
zfNBgqIAvwRVi/Tc8YPhW9Lae5q8Fm3yxoNPLXtjLr+zaDdyvmLxktL+KxlipV94
9+
UkJfriy3AwsyGtPAL59ziBnJss8MtymrNWO8tRklWQTj10esMZioiJ1DjaiujV3Q
10+
oivVpWT7CiyzL8/mcBDcLhoFwJzgJS8Wz1gWXW91LSKIZdC9QLs7dAml7lHj8P6r
11+
5t/0KDjcitESALpgvrOYTbloUr9vQbklWuiQtmV4m0mqjrdci0DJdi9+00AHI0Cx
12+
Khl2ffvl7QFIATotVj6EKb3FgKhd
13+
-----END X509 CRL-----
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIE7jCCA9agAwIBAgIBBTANBgkqhkiG9w0BAQsFADCBoTELMAkGA1UEBhMCVVMx
3+
EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM
4+
B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NM
5+
IGludGVybWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wu
6+
Y29tMB4XDTI1MTExMzIwNDEzNloXDTI4MDgwOTIwNDEzNlowgZgxCzAJBgNVBAYT
7+
AlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxlMRAwDgYD
8+
VQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmluZzEZMBcGA1UEAwwQd3d3
9+
MS53b2xmc3NsLmNvbTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTCC
10+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOaWVXXPipdojLY49noFvjO2
11+
UUc3ivfbkb6Sa7cAjPLFJG4Y6ZIAgQHcs0woqbeA8ZbPI3ovrvjjDy3TXiPn20yy
12+
XYkWF76+gdv7Em0oSxCgEgQnwcnQeZXv6I2MWZtOcn28SSsiTvhP4gzx6emX+d+M
13+
WgqqOB1DBKOniaHig6RLtU5FiKYiXaypWGeIwdVh770RBSeUR7szpYrK7h+NwG4k
14+
r83Kv4BHcZWsqfFdI2z1S7Sp4cRm++XEoZ+nUdF4zS60Py7igvN/xKf0Mc92Jz/b
15+
LtJuw0cjgqNIQIynwRPwY1BUQ/ZxEuFvpXpYJvf9iztwGKBDugFrs/jVvgUTZDEC
16+
AwEAAaOCATYwggEyMAkGA1UdEwQCMAAwHQYDVR0OBBYEFMxVFQDiRImSY20QXbme
17+
c7ZdOhnKMIHEBgNVHSMEgbwwgbmAFIPGOoksgfQC151M4irAcYJkRNoOoYGdpIGa
18+
MIGXMQswCQYDVQQGEwJVUzETMBEGA1UECAwKV2FzaGluZ3RvbjEQMA4GA1UEBwwH
19+
U2VhdHRsZTEQMA4GA1UECgwHd29sZlNTTDEUMBIGA1UECwwLRW5naW5lZXJpbmcx
20+
GDAWBgNVBAMMD3dvbGZTU0wgcm9vdCBDQTEfMB0GCSqGSIb3DQEJARYQaW5mb0B3
21+
b2xmc3NsLmNvbYIBATALBgNVHQ8EBAMCBeAwMgYIKwYBBQUHAQEEJjAkMCIGCCsG
22+
AQUFBzABhhZodHRwOi8vMTI3LjAuMC4xOjIyMjIxMA0GCSqGSIb3DQEBCwUAA4IB
23+
AQBZVHFAYgrl8GELqy6w3SNRK3u/VHEpTeKUEuzEOhgA2GZTvPk5DroQWfWMWE3d
24+
NVX6fUEtehkfqMQRz6eOQ9KYm8DbeSAj9SiVLgartP6pDJHGMh01LouFr6ghQBTn
25+
gnHcB6O7hFwfHGpHSgEnBdReToInidg2iv4P2absHzgKJk+/WBJmcTNjxKEjA1je
26+
bUymC8YqiV7CjFYvxAFe7wjJfjWfI/3+85YzS1kEO4AGGY5KHCSnpBcSMriG63Kc
27+
2Ni6GQ6chwdBEoYo8CWFU1H02RvKUmeYTLOMsm/Hxx24S4Brhhdu5/opwqCPtsOy
28+
p/wK7eMUb4BBVJMV2Y8KTB4V
29+
-----END CERTIFICATE-----
30+
-----BEGIN CERTIFICATE-----
31+
MIIE8DCCA9igAwIBAgIBATANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UEBhMCVVMx
32+
EzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoM
33+
B3dvbGZTU0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMRgwFgYDVQQDDA93b2xmU1NM
34+
IHJvb3QgQ0ExHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjUx
35+
MTEzMjA0MTM0WhcNMjgwODA5MjA0MTM0WjCBoTELMAkGA1UEBhMCVVMxEzARBgNV
36+
BAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dvbGZT
37+
U0wxFDASBgNVBAsMC0VuZ2luZWVyaW5nMSIwIAYDVQQDDBl3b2xmU1NMIGludGVy
38+
bWVkaWF0ZSBDQSAxMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMIIB
39+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3rTIXHfgLbH1ua0WRzWgNWVl
40+
xuFAqx60uRO3y4y7d6V22m2Hh/ZKTRPkJj4nh+5bx2o/RTBhVVz2NdFl+pgRo6dV
41+
1b6Rgkv8vpDWUFNjmiwi4TUR3HgCl4rkRpKcUwh23h9TtrjKdz55brzQ4w0wW0z2
42+
lA0wKWSfBOXb+4lgZ7uvJoNRdyQvKwuhlIEQmOjrJqgefOTEbGcGlVVK3VL08mBt
43+
ASsZkTVtpAhHBnEkANnexlbzi1Ms4pqWpfNi5cTjI/LS/CHqD2J2jdWZSM7cWMS7
44+
f9qULIB0g8XgsBV+Qf0O8vTweHZ7rSYNqkiWFy8h45UrJjf5qoAv/t72XryXfwID
45+
AQABo4IBOTCCATUwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUg8Y6iSyB9ALXnUzi
46+
KsBxgmRE2g4wgcQGA1UdIwSBvDCBuYAUc7AcpC+Cy89HpTjXsASCOn5yFSGhgZ2k
47+
gZowgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQH
48+
DAdTZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtFbmdpbmVlcmlu
49+
ZzEYMBYGA1UEAwwPd29sZlNTTCByb290IENBMR8wHQYJKoZIhvcNAQkBFhBpbmZv
50+
QHdvbGZzc2wuY29tggFjMAsGA1UdDwQEAwIBBjAyBggrBgEFBQcBAQQmMCQwIgYI
51+
KwYBBQUHMAGGFmh0dHA6Ly8xMjcuMC4wLjE6MjIyMjAwDQYJKoZIhvcNAQELBQAD
52+
ggEBAHfsiTfUNS4k/dLe2ZiHvlKutdT2EzQSLPB4mAef9+R2327rl8cDo+YVbuKU
53+
FmvtWalKEKDMwmF4x/scBEogwfyUxpmwOowvK30VMFPHm3NUb00WpqstilFwHxuO
54+
YAtWi/KUAf2BX3PL7V7MSnHBqRrXxytaZgJ32hDoRUKgfO94/90I9oQvQfUYyaJI
55+
0V22pE0yr4NduWTsQOliOO8b0Y7J6P2z6OGh2hYeJjyCNsuNgGczyjC/kwPInL6i
56+
b6p8diQ9Bpmrp/4S89v9oIq1DcGckLfKfm37/yrD/nyfQejCf0/6S0nEoNC8/Tg0
57+
Iv/Vg3lwf2wwja2T+7h3ATSvzA4=
58+
-----END CERTIFICATE-----

src/internal.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15954,7 +15954,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1595415954
if (ret == WC_NO_ERR_TRACE(WC_PENDING_E))
1595515955
goto exit_ppc;
1595615956
#endif
15957-
if (ret == 0) {
15957+
if (ret == 0 || ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN)) {
1595815958
ret = ProcessPeerCertCheckKey(ssl, args);
1595915959
}
1596015960
else if (ret == WC_NO_ERR_TRACE(ASN_PARSE_E) ||
@@ -16052,7 +16052,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1605216052
}
1605316053
#endif /* HAVE_OCSP */
1605416054

16055-
if (ret == 0) {
16055+
if (ret == 0 || ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN)) {
1605616056
#ifdef HAVE_CRL
1605716057
if (SSL_CM(ssl)->crlEnabled &&
1605816058
SSL_CM(ssl)->crlCheckAll) {
@@ -16593,7 +16593,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1659316593
#endif /* HAVE_OCSP */
1659416594

1659516595
#ifdef HAVE_CRL
16596-
if (ret == 0 && doLookup && SSL_CM(ssl)->crlEnabled) {
16596+
if ((ret == 0 || ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN))
16597+
&& doLookup && SSL_CM(ssl)->crlEnabled) {
1659716598
WOLFSSL_MSG("Doing Leaf CRL check");
1659816599
ret = CheckCertCRL(SSL_CM(ssl)->crl, args->dCert);
1659916600
#ifdef WOLFSSL_NONBLOCK_OCSP
@@ -16621,7 +16622,8 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx,
1662116622
#endif
1662216623
}
1662316624
}
16624-
if (ret == 0 && doLookup && SSL_CM(ssl)->crlEnabled &&
16625+
if ((ret == 0 || ret == WC_NO_ERR_TRACE(OCSP_CERT_UNKNOWN))
16626+
&& doLookup && SSL_CM(ssl)->crlEnabled &&
1662516627
SSL_CM(ssl)->crlCheckAll && args->totalCerts == 1) {
1662616628
/* Check the entire cert chain */
1662716629
if (args->dCert->ca != NULL) {

tests/api.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33409,6 +33409,8 @@ TEST_CASE testCases[] = {
3340933409
TEST_DECL(test_ocsp_response_parsing),
3341033410
TEST_DECL(test_ocsp_certid_enc_dec),
3341133411
TEST_DECL(test_ocsp_tls_cert_cb),
33412+
TEST_DECL(test_ocsp_cert_unknown_crl_fallback),
33413+
TEST_DECL(test_ocsp_cert_unknown_crl_fallback_nonleaf),
3341233414
TEST_TLS_DECLS,
3341333415
TEST_DECL(test_wc_DhSetNamedKey),
3341433416
/* This test needs to stay at the end to clean up any caches allocated. */

tests/api/create_ocsp_test_blobs.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,10 @@ def cert_status(value: int) -> rfc6960.CertStatus:
126126
revoked['revocationTime'] = useful.GeneralizedTime().fromDateTime(
127127
datetime.now() - timedelta(days=1))
128128
cs['revoked'] = revoked
129+
elif value == CERT_UNKNOWN:
130+
unknown = rfc6960.UnknownInfo('').subtype(implicitTag=tag.Tag(
131+
tag.tagClassContext, tag.tagFormatSimple, 2))
132+
cs['unknown'] = unknown
129133

130134
return cs
131135

@@ -444,6 +448,38 @@ def create_bad_response(rd: dict) -> bytes:
444448
'responder_key': WOLFSSL_OCSP_CERT_PATH + 'ocsp-responder-key.pem',
445449
'name': 'resp_root_ca_cert'
446450
},
451+
{
452+
'response_status': 0,
453+
'signature_algorithm': signature_algorithm(),
454+
'certs_path': [WOLFSSL_OCSP_CERT_PATH + 'root-ca-cert.pem'],
455+
'responder_by_name': True,
456+
'responder_cert': WOLFSSL_OCSP_CERT_PATH + 'root-ca-cert.pem',
457+
'responses': [
458+
{
459+
'issuer_cert': WOLFSSL_OCSP_CERT_PATH + 'root-ca-cert.pem',
460+
'serial': 0x01,
461+
'status': CERT_UNKNOWN
462+
}
463+
],
464+
'responder_key': WOLFSSL_OCSP_CERT_PATH + 'root-ca-key.pem',
465+
'name': 'resp_cert_unknown'
466+
},
467+
{
468+
'response_status': 0,
469+
'signature_algorithm': signature_algorithm(),
470+
'certs_path': [WOLFSSL_OCSP_CERT_PATH + '../ca-cert.pem'],
471+
'responder_by_name': True,
472+
'responder_cert': WOLFSSL_OCSP_CERT_PATH + '../ca-cert.pem',
473+
'responses': [
474+
{
475+
'issuer_cert': WOLFSSL_OCSP_CERT_PATH + '../ca-cert.pem',
476+
'serial': 0x01,
477+
'status': CERT_UNKNOWN
478+
}
479+
],
480+
'responder_key': WOLFSSL_OCSP_CERT_PATH + '../ca-key.pem',
481+
'name': 'resp_server_cert_unknown'
482+
},
447483
]
448484

449485
with open('./tests/api/test_ocsp_test_blobs.h', 'w') as f:

0 commit comments

Comments
 (0)