diff options
author | jsing <> | 2022-10-17 18:44:36 +0000 |
---|---|---|
committer | jsing <> | 2022-10-17 18:44:36 +0000 |
commit | 88e2e531dd14bb11c24ba57cd3d8d2affeb7ec31 (patch) | |
tree | 1f1fe5d71021b2e62eda8325c2d15c35af427753 /src | |
parent | b490988617e6c314a3df0d6a5bbbc3f60b36c053 (diff) | |
download | openbsd-88e2e531dd14bb11c24ba57cd3d8d2affeb7ec31.tar.gz openbsd-88e2e531dd14bb11c24ba57cd3d8d2affeb7ec31.tar.bz2 openbsd-88e2e531dd14bb11c24ba57cd3d8d2affeb7ec31.zip |
Revise expire callback regress to use chains with expired certificates.
Rather than using X509_STORE_CTX_set_time() (which is resulting all
certificates in the chain being treated as expired), use chains that have
an expired leaf or expired intermediate. This triggers a different code
path, which is currently mishandled (and hence failing).
Also ensure that the resulting error and error depth match what we expect
them to be.
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libcrypto/x509/expirecallback.c | 91 |
1 files changed, 66 insertions, 25 deletions
diff --git a/src/regress/lib/libcrypto/x509/expirecallback.c b/src/regress/lib/libcrypto/x509/expirecallback.c index 3da49708ff..f7dcff8e94 100644 --- a/src/regress/lib/libcrypto/x509/expirecallback.c +++ b/src/regress/lib/libcrypto/x509/expirecallback.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: expirecallback.c,v 1.1 2022/06/25 20:01:43 beck Exp $ */ | 1 | /* $OpenBSD: expirecallback.c,v 1.2 2022/10/17 18:44:36 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2020 Joel Sing <jsing@openbsd.org> |
4 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
@@ -112,16 +112,20 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) | |||
112 | 112 | ||
113 | static void | 113 | static void |
114 | verify_cert(const char *roots_dir, const char *roots_file, | 114 | verify_cert(const char *roots_dir, const char *roots_file, |
115 | const char *bundle_file, int *chains, int mode) | 115 | const char *bundle_file, int *chains, int *error, int *error_depth, |
116 | int mode) | ||
116 | { | 117 | { |
117 | STACK_OF(X509) *roots = NULL, *bundle = NULL; | 118 | STACK_OF(X509) *roots = NULL, *bundle = NULL; |
118 | time_t future = 2000000000; /* May 17 2033 */ | ||
119 | X509_STORE_CTX *xsc = NULL; | 119 | X509_STORE_CTX *xsc = NULL; |
120 | X509_STORE *store = NULL; | 120 | X509_STORE *store = NULL; |
121 | int verify_err, use_dir; | ||
122 | X509 *leaf = NULL; | 121 | X509 *leaf = NULL; |
122 | int use_dir; | ||
123 | int ret; | ||
123 | 124 | ||
124 | *chains = 0; | 125 | *chains = 0; |
126 | *error = 0; | ||
127 | *error_depth = 0; | ||
128 | |||
125 | use_dir = (mode == MODE_MODERN_VFY_DIR); | 129 | use_dir = (mode == MODE_MODERN_VFY_DIR); |
126 | 130 | ||
127 | if (!use_dir && !certs_from_file(roots_file, &roots)) | 131 | if (!use_dir && !certs_from_file(roots_file, &roots)) |
@@ -141,12 +145,6 @@ verify_cert(const char *roots_dir, const char *roots_file, | |||
141 | errx(1, "failed to init store context"); | 145 | errx(1, "failed to init store context"); |
142 | } | 146 | } |
143 | 147 | ||
144 | /* | ||
145 | * Set the time int the future to exercise the expired cert | ||
146 | * callback | ||
147 | */ | ||
148 | X509_STORE_CTX_set_time(xsc, 0, future); | ||
149 | |||
150 | if (use_dir) { | 148 | if (use_dir) { |
151 | if (!X509_STORE_load_locations(store, NULL, roots_dir)) | 149 | if (!X509_STORE_load_locations(store, NULL, roots_dir)) |
152 | errx(1, "failed to set by_dir directory of %s", roots_dir); | 150 | errx(1, "failed to set by_dir directory of %s", roots_dir); |
@@ -161,18 +159,22 @@ verify_cert(const char *roots_dir, const char *roots_file, | |||
161 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); | 159 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); |
162 | if (!use_dir) | 160 | if (!use_dir) |
163 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); | 161 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); |
164 | if (X509_verify_cert(xsc) == 1) { | 162 | |
163 | ret = X509_verify_cert(xsc); | ||
164 | |||
165 | *error = X509_STORE_CTX_get_error(xsc); | ||
166 | *error_depth = X509_STORE_CTX_get_error_depth(xsc); | ||
167 | |||
168 | if (ret == 1) { | ||
165 | *chains = 1; /* XXX */ | 169 | *chains = 1; /* XXX */ |
166 | goto done; | 170 | goto done; |
167 | } | 171 | } |
168 | 172 | ||
169 | verify_err = X509_STORE_CTX_get_error(xsc); | 173 | if (*error == 0) |
170 | if (verify_err == 0) | ||
171 | errx(1, "Error unset on failure!\n"); | 174 | errx(1, "Error unset on failure!\n"); |
172 | 175 | ||
173 | fprintf(stderr, "failed to verify at %d: %s\n", | 176 | fprintf(stderr, "failed to verify at %d: %s\n", |
174 | X509_STORE_CTX_get_error_depth(xsc), | 177 | *error_depth, X509_verify_cert_error_string(*error)); |
175 | X509_verify_cert_error_string(verify_err)); | ||
176 | 178 | ||
177 | done: | 179 | done: |
178 | sk_X509_pop_free(roots, X509_free); | 180 | sk_X509_pop_free(roots, X509_free); |
@@ -185,26 +187,37 @@ verify_cert(const char *roots_dir, const char *roots_file, | |||
185 | struct verify_cert_test { | 187 | struct verify_cert_test { |
186 | const char *id; | 188 | const char *id; |
187 | int want_chains; | 189 | int want_chains; |
190 | int want_error; | ||
191 | int want_error_depth; | ||
192 | int want_legacy_error; | ||
193 | int want_legacy_error_depth; | ||
188 | int failing; | 194 | int failing; |
189 | }; | 195 | }; |
190 | 196 | ||
191 | struct verify_cert_test verify_cert_tests[] = { | 197 | struct verify_cert_test verify_cert_tests[] = { |
192 | { | 198 | { |
193 | .id = "1a", | ||
194 | .want_chains = 1, | ||
195 | }, | ||
196 | { | ||
197 | .id = "2a", | 199 | .id = "2a", |
198 | .want_chains = 1, | 200 | .want_chains = 1, |
199 | .failing = 1, | 201 | .want_error = 0, |
202 | .want_error_depth = 0, | ||
203 | .want_legacy_error = 0, | ||
204 | .want_legacy_error_depth = 0, | ||
200 | }, | 205 | }, |
201 | { | 206 | { |
202 | .id = "2b", | 207 | .id = "8a", |
203 | .want_chains = 0, | 208 | .want_chains = 1, |
209 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
210 | .want_error_depth = 0, | ||
211 | .want_legacy_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
212 | .want_legacy_error_depth = 0, | ||
204 | }, | 213 | }, |
205 | { | 214 | { |
206 | .id = "2c", | 215 | .id = "9a", |
207 | .want_chains = 1, | 216 | .want_chains = 1, |
217 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
218 | .want_error_depth = 0, | ||
219 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
220 | .want_legacy_error_depth = 0, | ||
208 | .failing = 1, | 221 | .failing = 1, |
209 | }, | 222 | }, |
210 | }; | 223 | }; |
@@ -217,8 +230,8 @@ verify_cert_test(const char *certs_path, int mode) | |||
217 | { | 230 | { |
218 | char *roots_file, *bundle_file, *roots_dir; | 231 | char *roots_file, *bundle_file, *roots_dir; |
219 | struct verify_cert_test *vct; | 232 | struct verify_cert_test *vct; |
233 | int chains, error, error_depth; | ||
220 | int failed = 0; | 234 | int failed = 0; |
221 | int chains; | ||
222 | size_t i; | 235 | size_t i; |
223 | 236 | ||
224 | for (i = 0; i < N_VERIFY_CERT_TESTS; i++) { | 237 | for (i = 0; i < N_VERIFY_CERT_TESTS; i++) { |
@@ -234,7 +247,9 @@ verify_cert_test(const char *certs_path, int mode) | |||
234 | errx(1, "asprintf"); | 247 | errx(1, "asprintf"); |
235 | 248 | ||
236 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); | 249 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); |
237 | verify_cert(roots_dir, roots_file, bundle_file, &chains, mode); | 250 | verify_cert(roots_dir, roots_file, bundle_file, &chains, &error, |
251 | &error_depth, mode); | ||
252 | |||
238 | if ((mode == MODE_VERIFY && chains == vct->want_chains) || | 253 | if ((mode == MODE_VERIFY && chains == vct->want_chains) || |
239 | (chains == 0 && vct->want_chains == 0) || | 254 | (chains == 0 && vct->want_chains == 0) || |
240 | (chains == 1 && vct->want_chains > 0)) { | 255 | (chains == 1 && vct->want_chains > 0)) { |
@@ -248,6 +263,32 @@ verify_cert_test(const char *certs_path, int mode) | |||
248 | if (!vct->failing) | 263 | if (!vct->failing) |
249 | failed |= 1; | 264 | failed |= 1; |
250 | } | 265 | } |
266 | |||
267 | if (mode == MODE_LEGACY_VFY) { | ||
268 | if (error != vct->want_legacy_error) { | ||
269 | fprintf(stderr, "FAIL: Got legacy error %d, " | ||
270 | "want %d\n", error, vct->want_legacy_error); | ||
271 | failed |= 1; | ||
272 | } | ||
273 | if (error_depth != vct->want_legacy_error_depth) { | ||
274 | fprintf(stderr, "FAIL: Got legacy error depth " | ||
275 | "%d, want %d\n", error_depth, | ||
276 | vct->want_legacy_error_depth); | ||
277 | failed |= 1; | ||
278 | } | ||
279 | } else if (mode == MODE_MODERN_VFY || mode == MODE_MODERN_VFY_DIR) { | ||
280 | if (error != vct->want_error) { | ||
281 | fprintf(stderr, "FAIL: Got error %d, want %d\n", | ||
282 | error, vct->want_error); | ||
283 | failed |= 1; | ||
284 | } | ||
285 | if (error_depth != vct->want_error_depth) { | ||
286 | fprintf(stderr, "FAIL: Got error depth %d, want" | ||
287 | " %d\n", error_depth, vct->want_error_depth); | ||
288 | failed |= 1; | ||
289 | } | ||
290 | } | ||
291 | |||
251 | fprintf(stderr, "\n"); | 292 | fprintf(stderr, "\n"); |
252 | 293 | ||
253 | free(roots_file); | 294 | free(roots_file); |