diff options
author | Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> | 2022-11-03 10:43:47 +0530 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2022-11-25 10:35:23 -0500 |
commit | b2c7d54b40620211c4b95b58b8bb20649c3b6bac (patch) | |
tree | aaf3c88ebb5ce33fd02c1ae1fa482ded55819f23 | |
parent | 7203130ed8b58c0df75cb72222ac2bcf546bce44 (diff) | |
download | meta-openembedded-b2c7d54b40620211c4b95b58b8bb20649c3b6bac.tar.gz |
strongswan: Fix CVE-2022-40617
Add a patch to fix CVE-2022-40617 issue which allows remote attackers to
cause a denial of service in the revocation plugin by sending a crafted
end-entity (and intermediate CA) certificate that contains a CRL/OCSP
URL that points to a server (under the attacker's control) that doesn't
properly respond but (for example) just does nothing after the initial
TCP handshake, or sends an excessive amount of application data.
Link: https://nvd.nist.gov/vuln/detail/CVE-2022-40617
Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch | 210 | ||||
-rw-r--r-- | meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb | 1 |
2 files changed, 211 insertions, 0 deletions
diff --git a/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch new file mode 100644 index 0000000000..66e5047125 --- /dev/null +++ b/meta-networking/recipes-support/strongswan/files/CVE-2022-40617.patch | |||
@@ -0,0 +1,210 @@ | |||
1 | From 66d3b2e0e596a6eac1ebcd15c83a8d9368fe7b34 Mon Sep 17 00:00:00 2001 | ||
2 | From: Tobias Brunner <tobias@strongswan.org> | ||
3 | Date: Fri, 22 Jul 2022 15:37:43 +0200 | ||
4 | Subject: [PATCH] credential-manager: Do online revocation checks only after | ||
5 | basic trust chain validation | ||
6 | |||
7 | This avoids querying URLs of potentially untrusted certificates, e.g. if | ||
8 | an attacker sends a specially crafted end-entity and intermediate CA | ||
9 | certificate with a CDP that points to a server that completes the | ||
10 | TCP handshake but then does not send any further data, which will block | ||
11 | the fetcher thread (depending on the plugin) for as long as the default | ||
12 | timeout for TCP. Doing that multiple times will block all worker threads, | ||
13 | leading to a DoS attack. | ||
14 | |||
15 | The logging during the certificate verification obviously changes. The | ||
16 | following example shows the output of `pki --verify` for the current | ||
17 | strongswan.org certificate: | ||
18 | |||
19 | new: | ||
20 | |||
21 | using certificate "CN=www.strongswan.org" | ||
22 | using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3" | ||
23 | using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
24 | reached self-signed root ca with a path length of 1 | ||
25 | checking certificate status of "CN=www.strongswan.org" | ||
26 | requesting ocsp status from 'http://r3.o.lencr.org' ... | ||
27 | ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3" | ||
28 | ocsp response is valid: until Jul 27 12:59:58 2022 | ||
29 | certificate status is good | ||
30 | checking certificate status of "C=US, O=Let's Encrypt, CN=R3" | ||
31 | ocsp response verification failed, no signer certificate 'C=US, O=Let's Encrypt, CN=R3' found | ||
32 | fetching crl from 'http://x1.c.lencr.org/' ... | ||
33 | using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
34 | crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
35 | crl is valid: until Apr 18 01:59:59 2023 | ||
36 | certificate status is good | ||
37 | certificate trusted, lifetimes valid, certificate not revoked | ||
38 | |||
39 | old: | ||
40 | |||
41 | using certificate "CN=www.strongswan.org" | ||
42 | using trusted intermediate ca certificate "C=US, O=Let's Encrypt, CN=R3" | ||
43 | checking certificate status of "CN=www.strongswan.org" | ||
44 | requesting ocsp status from 'http://r3.o.lencr.org' ... | ||
45 | ocsp response correctly signed by "C=US, O=Let's Encrypt, CN=R3" | ||
46 | ocsp response is valid: until Jul 27 12:59:58 2022 | ||
47 | certificate status is good | ||
48 | using trusted ca certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
49 | checking certificate status of "C=US, O=Let's Encrypt, CN=R3" | ||
50 | ocsp response verification failed, no signer certificate 'C=US, O=Let's Encrypt, CN=R3' found | ||
51 | fetching crl from 'http://x1.c.lencr.org/' ... | ||
52 | using trusted certificate "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
53 | crl correctly signed by "C=US, O=Internet Security Research Group, CN=ISRG Root X1" | ||
54 | crl is valid: until Apr 18 01:59:59 2023 | ||
55 | certificate status is good | ||
56 | reached self-signed root ca with a path length of 1 | ||
57 | certificate trusted, lifetimes valid, certificate not revoked | ||
58 | |||
59 | Note that this also fixes an issue with the previous dual-use of the | ||
60 | `trusted` flag. It not only indicated whether the chain is trusted but | ||
61 | also whether the current issuer is the root anchor (the corresponding | ||
62 | flag in the `cert_validator_t` interface is called `anchor`). This was | ||
63 | a problem when building multi-level trust chains for pre-trusted | ||
64 | end-entity certificates (i.e. where `trusted` is TRUE from the start). | ||
65 | This caused the main loop to get aborted after the first intermediate CA | ||
66 | certificate and the mentioned `anchor` flag wasn't correct in any calls | ||
67 | to `cert_validator_t` implementations. | ||
68 | |||
69 | Fixes: CVE-2022-40617 | ||
70 | |||
71 | CVE: CVE-2022-40617 | ||
72 | Upstream-Status: Backport [https://download.strongswan.org/security/CVE-2022-40617/strongswan-5.1.0-5.9.7_cert_online_validate.patch] | ||
73 | Signed-off-by: Ranjitsinh Rathod <ranjitsinh.rathod@kpit.com> | ||
74 | |||
75 | --- | ||
76 | .../credentials/credential_manager.c | 54 +++++++++++++++---- | ||
77 | 1 file changed, 45 insertions(+), 9 deletions(-) | ||
78 | |||
79 | diff --git a/src/libstrongswan/credentials/credential_manager.c b/src/libstrongswan/credentials/credential_manager.c | ||
80 | index e93b5943a3a7..798785544e41 100644 | ||
81 | --- a/src/libstrongswan/credentials/credential_manager.c | ||
82 | +++ b/src/libstrongswan/credentials/credential_manager.c | ||
83 | @@ -556,7 +556,7 @@ static void cache_queue(private_credential_manager_t *this) | ||
84 | */ | ||
85 | static bool check_lifetime(private_credential_manager_t *this, | ||
86 | certificate_t *cert, char *label, | ||
87 | - int pathlen, bool trusted, auth_cfg_t *auth) | ||
88 | + int pathlen, bool anchor, auth_cfg_t *auth) | ||
89 | { | ||
90 | time_t not_before, not_after; | ||
91 | cert_validator_t *validator; | ||
92 | @@ -571,7 +571,7 @@ static bool check_lifetime(private_credential_manager_t *this, | ||
93 | continue; | ||
94 | } | ||
95 | status = validator->check_lifetime(validator, cert, | ||
96 | - pathlen, trusted, auth); | ||
97 | + pathlen, anchor, auth); | ||
98 | if (status != NEED_MORE) | ||
99 | { | ||
100 | break; | ||
101 | @@ -604,13 +604,13 @@ static bool check_lifetime(private_credential_manager_t *this, | ||
102 | */ | ||
103 | static bool check_certificate(private_credential_manager_t *this, | ||
104 | certificate_t *subject, certificate_t *issuer, bool online, | ||
105 | - int pathlen, bool trusted, auth_cfg_t *auth) | ||
106 | + int pathlen, bool anchor, auth_cfg_t *auth) | ||
107 | { | ||
108 | cert_validator_t *validator; | ||
109 | enumerator_t *enumerator; | ||
110 | |||
111 | if (!check_lifetime(this, subject, "subject", pathlen, FALSE, auth) || | ||
112 | - !check_lifetime(this, issuer, "issuer", pathlen + 1, trusted, auth)) | ||
113 | + !check_lifetime(this, issuer, "issuer", pathlen + 1, anchor, auth)) | ||
114 | { | ||
115 | return FALSE; | ||
116 | } | ||
117 | @@ -623,7 +623,7 @@ static bool check_certificate(private_credential_manager_t *this, | ||
118 | continue; | ||
119 | } | ||
120 | if (!validator->validate(validator, subject, issuer, | ||
121 | - online, pathlen, trusted, auth)) | ||
122 | + online, pathlen, anchor, auth)) | ||
123 | { | ||
124 | enumerator->destroy(enumerator); | ||
125 | return FALSE; | ||
126 | @@ -726,6 +726,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, | ||
127 | auth_cfg_t *auth; | ||
128 | signature_params_t *scheme; | ||
129 | int pathlen; | ||
130 | + bool is_anchor = FALSE; | ||
131 | |||
132 | auth = auth_cfg_create(); | ||
133 | get_key_strength(subject, auth); | ||
134 | @@ -743,7 +744,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, | ||
135 | auth->add(auth, AUTH_RULE_CA_CERT, issuer->get_ref(issuer)); | ||
136 | DBG1(DBG_CFG, " using trusted ca certificate \"%Y\"", | ||
137 | issuer->get_subject(issuer)); | ||
138 | - trusted = TRUE; | ||
139 | + trusted = is_anchor = TRUE; | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | @@ -778,11 +779,18 @@ static bool verify_trust_chain(private_credential_manager_t *this, | ||
144 | DBG1(DBG_CFG, " issuer is \"%Y\"", | ||
145 | current->get_issuer(current)); | ||
146 | call_hook(this, CRED_HOOK_NO_ISSUER, current); | ||
147 | + if (trusted) | ||
148 | + { | ||
149 | + DBG1(DBG_CFG, " reached end of incomplete trust chain for " | ||
150 | + "trusted certificate \"%Y\"", | ||
151 | + subject->get_subject(subject)); | ||
152 | + } | ||
153 | break; | ||
154 | } | ||
155 | } | ||
156 | - if (!check_certificate(this, current, issuer, online, | ||
157 | - pathlen, trusted, auth)) | ||
158 | + /* don't do online verification here */ | ||
159 | + if (!check_certificate(this, current, issuer, FALSE, | ||
160 | + pathlen, is_anchor, auth)) | ||
161 | { | ||
162 | trusted = FALSE; | ||
163 | issuer->destroy(issuer); | ||
164 | @@ -794,7 +802,7 @@ static bool verify_trust_chain(private_credential_manager_t *this, | ||
165 | } | ||
166 | current->destroy(current); | ||
167 | current = issuer; | ||
168 | - if (trusted) | ||
169 | + if (is_anchor) | ||
170 | { | ||
171 | DBG1(DBG_CFG, " reached self-signed root ca with a " | ||
172 | "path length of %d", pathlen); | ||
173 | @@ -807,6 +815,34 @@ static bool verify_trust_chain(private_credential_manager_t *this, | ||
174 | DBG1(DBG_CFG, "maximum path length of %d exceeded", MAX_TRUST_PATH_LEN); | ||
175 | call_hook(this, CRED_HOOK_EXCEEDED_PATH_LEN, subject); | ||
176 | } | ||
177 | + else if (trusted && online) | ||
178 | + { | ||
179 | + enumerator_t *enumerator; | ||
180 | + auth_rule_t rule; | ||
181 | + | ||
182 | + /* do online revocation checks after basic validation of the chain */ | ||
183 | + pathlen = 0; | ||
184 | + current = subject; | ||
185 | + enumerator = auth->create_enumerator(auth); | ||
186 | + while (enumerator->enumerate(enumerator, &rule, &issuer)) | ||
187 | + { | ||
188 | + if (rule == AUTH_RULE_CA_CERT || rule == AUTH_RULE_IM_CERT) | ||
189 | + { | ||
190 | + if (!check_certificate(this, current, issuer, TRUE, pathlen++, | ||
191 | + rule == AUTH_RULE_CA_CERT, auth)) | ||
192 | + { | ||
193 | + trusted = FALSE; | ||
194 | + break; | ||
195 | + } | ||
196 | + else if (rule == AUTH_RULE_CA_CERT) | ||
197 | + { | ||
198 | + break; | ||
199 | + } | ||
200 | + current = issuer; | ||
201 | + } | ||
202 | + } | ||
203 | + enumerator->destroy(enumerator); | ||
204 | + } | ||
205 | if (trusted) | ||
206 | { | ||
207 | result->merge(result, auth, FALSE); | ||
208 | -- | ||
209 | 2.25.1 | ||
210 | |||
diff --git a/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb b/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb index 8a5855fb87..c11748645c 100644 --- a/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb +++ b/meta-networking/recipes-support/strongswan/strongswan_5.8.4.bb | |||
@@ -14,6 +14,7 @@ SRC_URI = "http://download.strongswan.org/strongswan-${PV}.tar.bz2 \ | |||
14 | file://CVE-2021-41990.patch \ | 14 | file://CVE-2021-41990.patch \ |
15 | file://CVE-2021-41991.patch \ | 15 | file://CVE-2021-41991.patch \ |
16 | file://CVE-2021-45079.patch \ | 16 | file://CVE-2021-45079.patch \ |
17 | file://CVE-2022-40617.patch \ | ||
17 | " | 18 | " |
18 | 19 | ||
19 | SRC_URI[md5sum] = "0634e7f40591bd3f6770e583c3f27d29" | 20 | SRC_URI[md5sum] = "0634e7f40591bd3f6770e583c3f27d29" |