diff options
author | jsing <> | 2022-10-17 18:36:52 +0000 |
---|---|---|
committer | jsing <> | 2022-10-17 18:36:52 +0000 |
commit | b490988617e6c314a3df0d6a5bbbc3f60b36c053 (patch) | |
tree | e6b2aa8a730a8b912fd3117b949546d34fb22a7d /src | |
parent | 12051870b7613e05090211a9b7c5ff1483462bee (diff) | |
download | openbsd-b490988617e6c314a3df0d6a5bbbc3f60b36c053.tar.gz openbsd-b490988617e6c314a3df0d6a5bbbc3f60b36c053.tar.bz2 openbsd-b490988617e6c314a3df0d6a5bbbc3f60b36c053.zip |
Ensure that verification results in the expected error and error depth.
Improve verification regress and ensure that the legacy or modern
verification completes with the expected error and error depth.
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libcrypto/x509/verify.c | 129 |
1 files changed, 113 insertions, 16 deletions
diff --git a/src/regress/lib/libcrypto/x509/verify.c b/src/regress/lib/libcrypto/x509/verify.c index 3b85280359..93a6e43c51 100644 --- a/src/regress/lib/libcrypto/x509/verify.c +++ b/src/regress/lib/libcrypto/x509/verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: verify.c,v 1.9 2021/10/31 08:27:15 tb Exp $ */ | 1 | /* $OpenBSD: verify.c,v 1.10 2022/10/17 18:36:52 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> |
@@ -20,6 +20,7 @@ | |||
20 | #include <string.h> | 20 | #include <string.h> |
21 | 21 | ||
22 | #include <openssl/bio.h> | 22 | #include <openssl/bio.h> |
23 | #include <openssl/crypto.h> | ||
23 | #include <openssl/err.h> | 24 | #include <openssl/err.h> |
24 | #include <openssl/pem.h> | 25 | #include <openssl/pem.h> |
25 | #include <openssl/x509.h> | 26 | #include <openssl/x509.h> |
@@ -102,15 +103,20 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) | |||
102 | 103 | ||
103 | static void | 104 | static void |
104 | verify_cert(const char *roots_dir, const char *roots_file, | 105 | verify_cert(const char *roots_dir, const char *roots_file, |
105 | const char *bundle_file, int *chains, int mode) | 106 | const char *bundle_file, int *chains, int *error, int *error_depth, |
107 | int mode) | ||
106 | { | 108 | { |
107 | STACK_OF(X509) *roots = NULL, *bundle = NULL; | 109 | STACK_OF(X509) *roots = NULL, *bundle = NULL; |
108 | X509_STORE_CTX *xsc = NULL; | 110 | X509_STORE_CTX *xsc = NULL; |
109 | X509_STORE *store = NULL; | 111 | X509_STORE *store = NULL; |
110 | int verify_err, use_dir; | ||
111 | X509 *leaf = NULL; | 112 | X509 *leaf = NULL; |
113 | int use_dir; | ||
114 | int ret; | ||
112 | 115 | ||
113 | *chains = 0; | 116 | *chains = 0; |
117 | *error = 0; | ||
118 | *error_depth = 0; | ||
119 | |||
114 | use_dir = (mode == MODE_MODERN_VFY_DIR); | 120 | use_dir = (mode == MODE_MODERN_VFY_DIR); |
115 | 121 | ||
116 | if (!use_dir && !certs_from_file(roots_file, &roots)) | 122 | if (!use_dir && !certs_from_file(roots_file, &roots)) |
@@ -143,18 +149,22 @@ verify_cert(const char *roots_dir, const char *roots_file, | |||
143 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); | 149 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); |
144 | if (!use_dir) | 150 | if (!use_dir) |
145 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); | 151 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); |
146 | if (X509_verify_cert(xsc) == 1) { | 152 | |
153 | ret = X509_verify_cert(xsc); | ||
154 | |||
155 | *error = X509_STORE_CTX_get_error(xsc); | ||
156 | *error_depth = X509_STORE_CTX_get_error_depth(xsc); | ||
157 | |||
158 | if (ret == 1) { | ||
147 | *chains = 1; /* XXX */ | 159 | *chains = 1; /* XXX */ |
148 | goto done; | 160 | goto done; |
149 | } | 161 | } |
150 | 162 | ||
151 | verify_err = X509_STORE_CTX_get_error(xsc); | 163 | if (*error == 0) |
152 | if (verify_err == 0) | ||
153 | errx(1, "Error unset on failure!\n"); | 164 | errx(1, "Error unset on failure!\n"); |
154 | 165 | ||
155 | fprintf(stderr, "failed to verify at %d: %s\n", | 166 | fprintf(stderr, "failed to verify at %d: %s\n", |
156 | X509_STORE_CTX_get_error_depth(xsc), | 167 | *error_depth, X509_verify_cert_error_string(*error)); |
157 | X509_verify_cert_error_string(verify_err)); | ||
158 | 168 | ||
159 | done: | 169 | done: |
160 | sk_X509_pop_free(roots, X509_free); | 170 | sk_X509_pop_free(roots, X509_free); |
@@ -164,12 +174,6 @@ verify_cert(const char *roots_dir, const char *roots_file, | |||
164 | X509_free(leaf); | 174 | X509_free(leaf); |
165 | } | 175 | } |
166 | 176 | ||
167 | struct verify_cert_test { | ||
168 | const char *id; | ||
169 | int want_chains; | ||
170 | int failing; | ||
171 | }; | ||
172 | |||
173 | static void | 177 | static void |
174 | verify_cert_new(const char *roots_file, const char *bundle_file, int *chains) | 178 | verify_cert_new(const char *roots_file, const char *bundle_file, int *chains) |
175 | { | 179 | { |
@@ -231,6 +235,16 @@ verify_cert_new(const char *roots_file, const char *bundle_file, int *chains) | |||
231 | x509_verify_ctx_free(ctx); | 235 | x509_verify_ctx_free(ctx); |
232 | } | 236 | } |
233 | 237 | ||
238 | struct verify_cert_test { | ||
239 | const char *id; | ||
240 | int want_chains; | ||
241 | int want_error; | ||
242 | int want_error_depth; | ||
243 | int want_legacy_error; | ||
244 | int want_legacy_error_depth; | ||
245 | int failing; | ||
246 | }; | ||
247 | |||
234 | struct verify_cert_test verify_cert_tests[] = { | 248 | struct verify_cert_test verify_cert_tests[] = { |
235 | { | 249 | { |
236 | .id = "1a", | 250 | .id = "1a", |
@@ -243,6 +257,10 @@ struct verify_cert_test verify_cert_tests[] = { | |||
243 | { | 257 | { |
244 | .id = "2b", | 258 | .id = "2b", |
245 | .want_chains = 0, | 259 | .want_chains = 0, |
260 | .want_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
261 | .want_error_depth = 0, | ||
262 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
263 | .want_legacy_error_depth = 0, | ||
246 | }, | 264 | }, |
247 | { | 265 | { |
248 | .id = "2c", | 266 | .id = "2c", |
@@ -255,14 +273,26 @@ struct verify_cert_test verify_cert_tests[] = { | |||
255 | { | 273 | { |
256 | .id = "3b", | 274 | .id = "3b", |
257 | .want_chains = 0, | 275 | .want_chains = 0, |
276 | .want_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
277 | .want_error_depth = 2, | ||
278 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
279 | .want_legacy_error_depth = 2, | ||
258 | }, | 280 | }, |
259 | { | 281 | { |
260 | .id = "3c", | 282 | .id = "3c", |
261 | .want_chains = 0, | 283 | .want_chains = 0, |
284 | .want_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
285 | .want_error_depth = 1, | ||
286 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
287 | .want_legacy_error_depth = 1, | ||
262 | }, | 288 | }, |
263 | { | 289 | { |
264 | .id = "3d", | 290 | .id = "3d", |
265 | .want_chains = 0, | 291 | .want_chains = 0, |
292 | .want_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
293 | .want_error_depth = 0, | ||
294 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
295 | .want_legacy_error_depth = 0, | ||
266 | }, | 296 | }, |
267 | { | 297 | { |
268 | .id = "3e", | 298 | .id = "3e", |
@@ -279,6 +309,8 @@ struct verify_cert_test verify_cert_tests[] = { | |||
279 | { | 309 | { |
280 | .id = "4c", | 310 | .id = "4c", |
281 | .want_chains = 1, | 311 | .want_chains = 1, |
312 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
313 | .want_legacy_error_depth = 1, | ||
282 | .failing = 1, | 314 | .failing = 1, |
283 | }, | 315 | }, |
284 | { | 316 | { |
@@ -296,6 +328,8 @@ struct verify_cert_test verify_cert_tests[] = { | |||
296 | { | 328 | { |
297 | .id = "4g", | 329 | .id = "4g", |
298 | .want_chains = 1, | 330 | .want_chains = 1, |
331 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
332 | .want_legacy_error_depth = 1, | ||
299 | .failing = 1, | 333 | .failing = 1, |
300 | }, | 334 | }, |
301 | { | 335 | { |
@@ -309,6 +343,8 @@ struct verify_cert_test verify_cert_tests[] = { | |||
309 | { | 343 | { |
310 | .id = "5b", | 344 | .id = "5b", |
311 | .want_chains = 1, | 345 | .want_chains = 1, |
346 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
347 | .want_legacy_error_depth = 2, | ||
312 | .failing = 1, | 348 | .failing = 1, |
313 | }, | 349 | }, |
314 | { | 350 | { |
@@ -322,6 +358,8 @@ struct verify_cert_test verify_cert_tests[] = { | |||
322 | { | 358 | { |
323 | .id = "5e", | 359 | .id = "5e", |
324 | .want_chains = 1, | 360 | .want_chains = 1, |
361 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
362 | .want_legacy_error_depth = 1, | ||
325 | .failing = 1, | 363 | .failing = 1, |
326 | }, | 364 | }, |
327 | { | 365 | { |
@@ -339,6 +377,8 @@ struct verify_cert_test verify_cert_tests[] = { | |||
339 | { | 377 | { |
340 | .id = "5i", | 378 | .id = "5i", |
341 | .want_chains = 1, | 379 | .want_chains = 1, |
380 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
381 | .want_legacy_error_depth = 1, | ||
342 | .failing = 1, | 382 | .failing = 1, |
343 | }, | 383 | }, |
344 | { | 384 | { |
@@ -348,11 +388,19 @@ struct verify_cert_test verify_cert_tests[] = { | |||
348 | { | 388 | { |
349 | .id = "6b", | 389 | .id = "6b", |
350 | .want_chains = 1, | 390 | .want_chains = 1, |
391 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
392 | .want_error_depth = 0, | ||
393 | .want_legacy_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
394 | .want_legacy_error_depth = 2, | ||
351 | .failing = 1, | 395 | .failing = 1, |
352 | }, | 396 | }, |
353 | { | 397 | { |
354 | .id = "7a", | 398 | .id = "7a", |
355 | .want_chains = 1, | 399 | .want_chains = 1, |
400 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
401 | .want_error_depth = 0, | ||
402 | .want_legacy_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
403 | .want_legacy_error_depth = 3, | ||
356 | .failing = 1, | 404 | .failing = 1, |
357 | }, | 405 | }, |
358 | { | 406 | { |
@@ -362,14 +410,24 @@ struct verify_cert_test verify_cert_tests[] = { | |||
362 | { | 410 | { |
363 | .id = "8a", | 411 | .id = "8a", |
364 | .want_chains = 0, | 412 | .want_chains = 0, |
413 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
414 | .want_error_depth = 0, | ||
415 | .want_legacy_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
416 | .want_legacy_error_depth = 0, | ||
365 | }, | 417 | }, |
366 | { | 418 | { |
367 | .id = "9a", | 419 | .id = "9a", |
368 | .want_chains = 0, | 420 | .want_chains = 0, |
421 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
422 | .want_error_depth = 1, | ||
423 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
424 | .want_legacy_error_depth = 0, | ||
369 | }, | 425 | }, |
370 | { | 426 | { |
371 | .id = "10a", | 427 | .id = "10a", |
372 | .want_chains = 1, | 428 | .want_chains = 1, |
429 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
430 | .want_error_depth = 0, | ||
373 | }, | 431 | }, |
374 | { | 432 | { |
375 | .id = "10b", | 433 | .id = "10b", |
@@ -378,6 +436,10 @@ struct verify_cert_test verify_cert_tests[] = { | |||
378 | { | 436 | { |
379 | .id = "11a", | 437 | .id = "11a", |
380 | .want_chains = 1, | 438 | .want_chains = 1, |
439 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
440 | .want_error_depth = 0, | ||
441 | .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, | ||
442 | .want_legacy_error_depth = 1, | ||
381 | .failing = 1, | 443 | .failing = 1, |
382 | }, | 444 | }, |
383 | { | 445 | { |
@@ -391,6 +453,10 @@ struct verify_cert_test verify_cert_tests[] = { | |||
391 | { | 453 | { |
392 | .id = "13a", | 454 | .id = "13a", |
393 | .want_chains = 1, | 455 | .want_chains = 1, |
456 | .want_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
457 | .want_error_depth = 0, | ||
458 | .want_legacy_error = X509_V_ERR_CERT_HAS_EXPIRED, | ||
459 | .want_legacy_error_depth = 2, | ||
394 | .failing = 1, | 460 | .failing = 1, |
395 | }, | 461 | }, |
396 | }; | 462 | }; |
@@ -403,8 +469,8 @@ verify_cert_test(const char *certs_path, int mode) | |||
403 | { | 469 | { |
404 | char *roots_file, *bundle_file, *roots_dir; | 470 | char *roots_file, *bundle_file, *roots_dir; |
405 | struct verify_cert_test *vct; | 471 | struct verify_cert_test *vct; |
472 | int chains, error, error_depth; | ||
406 | int failed = 0; | 473 | int failed = 0; |
407 | int chains; | ||
408 | size_t i; | 474 | size_t i; |
409 | 475 | ||
410 | for (i = 0; i < N_VERIFY_CERT_TESTS; i++) { | 476 | for (i = 0; i < N_VERIFY_CERT_TESTS; i++) { |
@@ -419,11 +485,16 @@ verify_cert_test(const char *certs_path, int mode) | |||
419 | if (asprintf(&roots_dir, "./%s/roots", vct->id) == -1) | 485 | if (asprintf(&roots_dir, "./%s/roots", vct->id) == -1) |
420 | errx(1, "asprintf"); | 486 | errx(1, "asprintf"); |
421 | 487 | ||
488 | error = 0; | ||
489 | error_depth = 0; | ||
490 | |||
422 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); | 491 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); |
423 | if (mode == MODE_VERIFY) | 492 | if (mode == MODE_VERIFY) |
424 | verify_cert_new(roots_file, bundle_file, &chains); | 493 | verify_cert_new(roots_file, bundle_file, &chains); |
425 | else | 494 | else |
426 | verify_cert(roots_dir, roots_file, bundle_file, &chains, mode); | 495 | verify_cert(roots_dir, roots_file, bundle_file, &chains, |
496 | &error, &error_depth, mode); | ||
497 | |||
427 | if ((mode == MODE_VERIFY && chains == vct->want_chains) || | 498 | if ((mode == MODE_VERIFY && chains == vct->want_chains) || |
428 | (chains == 0 && vct->want_chains == 0) || | 499 | (chains == 0 && vct->want_chains == 0) || |
429 | (chains == 1 && vct->want_chains > 0)) { | 500 | (chains == 1 && vct->want_chains > 0)) { |
@@ -437,6 +508,32 @@ verify_cert_test(const char *certs_path, int mode) | |||
437 | if (!vct->failing) | 508 | if (!vct->failing) |
438 | failed |= 1; | 509 | failed |= 1; |
439 | } | 510 | } |
511 | |||
512 | if (mode == MODE_LEGACY_VFY) { | ||
513 | if (error != vct->want_legacy_error) { | ||
514 | fprintf(stderr, "FAIL: Got legacy error %d, " | ||
515 | "want %d\n", error, vct->want_legacy_error); | ||
516 | failed |= 1; | ||
517 | } | ||
518 | if (error_depth != vct->want_legacy_error_depth) { | ||
519 | fprintf(stderr, "FAIL: Got legacy error depth " | ||
520 | "%d, want %d\n", error_depth, | ||
521 | vct->want_legacy_error_depth); | ||
522 | failed |= 1; | ||
523 | } | ||
524 | } else if (mode == MODE_MODERN_VFY || mode == MODE_MODERN_VFY_DIR) { | ||
525 | if (error != vct->want_error) { | ||
526 | fprintf(stderr, "FAIL: Got error %d, want %d\n", | ||
527 | error, vct->want_error); | ||
528 | failed |= 1; | ||
529 | } | ||
530 | if (error_depth != vct->want_error_depth) { | ||
531 | fprintf(stderr, "FAIL: Got error depth %d, want" | ||
532 | " %d\n", error_depth, vct->want_error_depth); | ||
533 | failed |= 1; | ||
534 | } | ||
535 | } | ||
536 | |||
440 | fprintf(stderr, "\n"); | 537 | fprintf(stderr, "\n"); |
441 | 538 | ||
442 | free(roots_file); | 539 | free(roots_file); |