diff options
-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); |