From a17f0caa37cf3ea77cf7f5ba99bc04613c18666f Mon Sep 17 00:00:00 2001 From: tb <> Date: Mon, 4 May 2026 13:52:39 +0000 Subject: libcrypto: extend verify and callback regress Add three more test variants for scenario 2a: 1) verify that a chain of length 3 validates with depth 2. 2) verify that a chain of length 3 fails to validate with depth 1. 3) verify that a chain of length 3 validates with depth 1 if we allow the callback to override the depth. Variant 3) fails in -current and reproduces a scenario reported by kirill. Also add two test variants for the scenarios in 14: 4): run the chain of length 32 with a yolo callback returning 1 5): run the chain of length 33 with a yolo callback returning 1 Test 5) fails because we currently bail out at the wrong depth. The verify callback should allow overriding the failure and will then hit the bounds check added in x509_verify.c r1.74 to avoid an overwrite. Reuse the existing test cases 2a and 14a/14b for this and add an optional vct->desc that uniquely identifies the test case. incorporates various feedback from jsing --- src/regress/lib/libcrypto/x509/callback.c | 24 ++++++++- src/regress/lib/libcrypto/x509/verify.c | 85 ++++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/regress/lib/libcrypto/x509/callback.c b/src/regress/lib/libcrypto/x509/callback.c index 24339e7613..a021115531 100644 --- a/src/regress/lib/libcrypto/x509/callback.c +++ b/src/regress/lib/libcrypto/x509/callback.c @@ -1,4 +1,4 @@ -/* $OpenBSD: callback.c,v 1.7 2026/05/04 13:49:07 tb Exp $ */ +/* $OpenBSD: callback.c,v 1.8 2026/05/04 13:52:39 tb Exp $ */ /* * Copyright (c) 2020 Joel Sing * Copyright (c) 2020-2021 Bob Beck @@ -177,6 +177,7 @@ verify_cert(const char *roots_dir, const char *roots_file, } struct verify_cert_test { + const char *desc; const char *id; int set_depth; int want_chains; @@ -192,6 +193,24 @@ struct verify_cert_test verify_cert_tests[] = { .id = "2a", .want_chains = 1, }, + { + .desc = "2a with depth 2", + .id = "2a", + .set_depth = 2, + .want_chains = 1, + }, + { + .desc = "2a with depth 1", + .id = "2a", + .set_depth = 1, + .want_chains = 0, + }, + { + .desc = "2a with depth 1", + .id = "2a", + .set_depth = 1, + .want_chains = 0, + }, { .id = "2b", .want_chains = 0, @@ -380,7 +399,8 @@ verify_cert_test(const char *certs_path, int mode) if (asprintf(&roots_dir, "./%s/roots", vct->id) == -1) errx(1, "asprintf"); - fprintf(output, "== Test %zu (%s)\n", i, vct->id); + fprintf(output, "== Test %zu (%s)\n", i, + vct->desc != NULL ? vct->desc : vct->id); fprintf(output, "== Legacy:\n"); mode = MODE_LEGACY_VFY; verify_cert(roots_dir, roots_file, bundle_file, &chains, diff --git a/src/regress/lib/libcrypto/x509/verify.c b/src/regress/lib/libcrypto/x509/verify.c index c65c988948..8696209922 100644 --- a/src/regress/lib/libcrypto/x509/verify.c +++ b/src/regress/lib/libcrypto/x509/verify.c @@ -1,4 +1,4 @@ -/* $OpenBSD: verify.c,v 1.15 2026/05/04 13:49:07 tb Exp $ */ +/* $OpenBSD: verify.c,v 1.16 2026/05/04 13:52:39 tb Exp $ */ /* * Copyright (c) 2020 Joel Sing * Copyright (c) 2020-2021 Bob Beck @@ -102,6 +102,41 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) return ok; } +static int +verify_cert_depth_cb(int ok, X509_STORE_CTX *xsc) +{ + int verify_err; + + ok = verify_cert_cb(ok, xsc); + + verify_err = X509_STORE_CTX_get_error(xsc); + if (verify_err == X509_V_ERR_CERT_CHAIN_TOO_LONG) { + fprintf(stderr, "overriding verify error at depth %d: %s\n", + X509_STORE_CTX_get_error_depth(xsc), + X509_verify_cert_error_string(verify_err)); + ok = 1; + } + + return ok; +} + +static int +verify_cert_yolo_cb(int ok, X509_STORE_CTX *xsc) +{ + int verify_err; + + verify_cert_cb(ok, xsc); + + verify_err = X509_STORE_CTX_get_error(xsc); + if (verify_err != X509_V_OK) { + fprintf(stderr, "overriding verify error at depth %d: %s\n", + X509_STORE_CTX_get_error_depth(xsc), + X509_verify_cert_error_string(verify_err)); + } + + return 1; +} + static void verify_cert(const char *roots_dir, const char *roots_file, const char *bundle_file, int *chains, int *error, int *error_depth, @@ -251,6 +286,7 @@ verify_cert_new(const char *roots_file, const char *bundle_file, int *chains, } struct verify_cert_test { + const char *desc; const char *id; int (*verify_cb)(int, X509_STORE_CTX *); int want_chains; @@ -271,6 +307,32 @@ struct verify_cert_test verify_cert_tests[] = { .id = "2a", .want_chains = 1, }, + { + .desc = "2a with depth 2", + .id = "2a", + .set_depth = 2, + .want_chains = 1, + }, + { + .desc = "2a with depth 1", + .id = "2a", + .set_depth = 1, + .want_chains = 0, + .want_error = X509_V_ERR_CERT_CHAIN_TOO_LONG, + .want_error_depth = 1, + .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + .want_legacy_error_depth = 1, + }, + { + .desc = "2a with depth 1 and depth callback", + .id = "2a", + .verify_cb = verify_cert_depth_cb, + .set_depth = 1, + .want_chains = 1, + .want_legacy_error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY, + .want_legacy_error_depth = 1, + .failing = 1, + }, { .id = "2b", .want_chains = 0, @@ -481,6 +543,13 @@ struct verify_cert_test verify_cert_tests[] = { .want_chains = 1, .want_error_depth = 0, }, + { + .desc = "14a with yolo callback", + .id = "14a", + .verify_cb = verify_cert_yolo_cb, + .want_chains = 1, + .want_error_depth = 0, + }, { .id = "14b", .want_chains = 0, @@ -490,6 +559,17 @@ struct verify_cert_test verify_cert_tests[] = { .want_legacy_error_depth = 0, .failing = 1, }, + { + .desc = "14b with yolo callback", + .id = "14b", + .verify_cb = verify_cert_yolo_cb, + .want_chains = 0, + .want_error = X509_V_ERR_CERT_CHAIN_TOO_LONG, + .want_error_depth = 32, + .want_legacy_error = 0, + .want_legacy_error_depth = 0, + .failing = 1, + }, }; #define N_VERIFY_CERT_TESTS \ @@ -519,7 +599,8 @@ verify_cert_test(const char *certs_path, int mode) error = 0; error_depth = 0; - fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); + fprintf(stderr, "== Test %zu (%s)\n", i, + vct->desc != NULL ? vct->desc : vct->id); if (mode == MODE_VERIFY) verify_cert_new(roots_file, bundle_file, &chains, vct->set_depth, vct->verify_cb); -- cgit v1.2.3-55-g6feb