diff options
Diffstat (limited to '')
| -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); |
