diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/regress/lib/libcrypto/x509/Makefile | 8 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/x509/make-dir-roots.pl | 69 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/x509/verify.c | 44 |
3 files changed, 106 insertions, 15 deletions
diff --git a/src/regress/lib/libcrypto/x509/Makefile b/src/regress/lib/libcrypto/x509/Makefile index 37da3fb933..6b4256bfad 100644 --- a/src/regress/lib/libcrypto/x509/Makefile +++ b/src/regress/lib/libcrypto/x509/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.4 2020/09/11 18:34:29 beck Exp $ | 1 | # $OpenBSD: Makefile,v 1.5 2021/08/28 15:13:50 beck Exp $ |
| 2 | 2 | ||
| 3 | PROGS = constraints verify x509attribute x509name | 3 | PROGS = constraints verify x509attribute x509name |
| 4 | LDADD= -Wl,-Bstatic -lcrypto -Wl,-Bdynamic | 4 | LDADD= -Wl,-Bstatic -lcrypto -Wl,-Bdynamic |
| @@ -11,7 +11,13 @@ SUBDIR += bettertls | |||
| 11 | REGRESS_TARGETS=regress-constraints regress-verify regress-x509attribute regress-x509name | 11 | REGRESS_TARGETS=regress-constraints regress-verify regress-x509attribute regress-x509name |
| 12 | CLEANFILES+= x509name.result | 12 | CLEANFILES+= x509name.result |
| 13 | 13 | ||
| 14 | .if make(clean) || make(cleandir) | ||
| 15 | .BEGIN: | ||
| 16 | rm -rf ${.OBJDIR}/[0-9]* | ||
| 17 | .endif | ||
| 18 | |||
| 14 | regress-verify: verify | 19 | regress-verify: verify |
| 20 | perl ${.CURDIR}/make-dir-roots.pl ${.CURDIR}/../certs . | ||
| 15 | ./verify ${.CURDIR}/../certs | 21 | ./verify ${.CURDIR}/../certs |
| 16 | 22 | ||
| 17 | regress-constraints: constraints | 23 | regress-constraints: constraints |
diff --git a/src/regress/lib/libcrypto/x509/make-dir-roots.pl b/src/regress/lib/libcrypto/x509/make-dir-roots.pl new file mode 100644 index 0000000000..54d05e0519 --- /dev/null +++ b/src/regress/lib/libcrypto/x509/make-dir-roots.pl | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | #!/usr/bin/perl | ||
| 2 | |||
| 3 | # | ||
| 4 | # Copyright (c) 2021 Joel Sing <jsing@openbsd.org> | ||
| 5 | # | ||
| 6 | # Permission to use, copy, modify, and distribute this software for any | ||
| 7 | # purpose with or without fee is hereby granted, provided that the above | ||
| 8 | # copyright notice and this permission notice appear in all copies. | ||
| 9 | # | ||
| 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | # | ||
| 18 | |||
| 19 | sub root_pem_to_dir() { | ||
| 20 | $certs = 0; | ||
| 21 | $in_cert = 0; | ||
| 22 | |||
| 23 | ($roots_file, $certs_dir) = @_; | ||
| 24 | |||
| 25 | open ROOTS, "<$roots_file" or | ||
| 26 | die "failed to open roots file '$roots_file'"; | ||
| 27 | while (<ROOTS>) { | ||
| 28 | if ($_ eq "-----BEGIN CERTIFICATE-----\n") { | ||
| 29 | $in_cert = 1; | ||
| 30 | $cert_path = "$certs_dir/ca-$certs.pem"; | ||
| 31 | open CERT, ">$cert_path" or | ||
| 32 | die "failed to open '$cert_path'"; | ||
| 33 | $certs++; | ||
| 34 | } | ||
| 35 | if ($in_cert) { | ||
| 36 | print CERT $_; | ||
| 37 | } | ||
| 38 | if ($_ eq "-----END CERTIFICATE-----\n") { | ||
| 39 | $in_cert = 0; | ||
| 40 | } | ||
| 41 | } | ||
| 42 | close ROOTS; | ||
| 43 | |||
| 44 | my @args = ("openssl", "certhash", $certs_dir); | ||
| 45 | system(@args) == 0 or die "certhash failed"; | ||
| 46 | } | ||
| 47 | |||
| 48 | if (scalar @ARGV != 2) { | ||
| 49 | print("$0 <certs-path> <output-dir>\n"); | ||
| 50 | exit(1); | ||
| 51 | } | ||
| 52 | $certs_path = shift @ARGV; | ||
| 53 | $output_dir = shift @ARGV; | ||
| 54 | |||
| 55 | opendir CERTS, $certs_path or | ||
| 56 | die "failed to open certs directory '$certs_path'"; | ||
| 57 | while (readdir CERTS) { | ||
| 58 | next if ($_ !~ '^[0-9]+[a-z]?$'); | ||
| 59 | |||
| 60 | $roots_file = join("/", $certs_path, $_, "roots.pem"); | ||
| 61 | $roots_dir = join("/", $output_dir, $_, "roots"); | ||
| 62 | |||
| 63 | mkdir "$output_dir"; | ||
| 64 | mkdir "$output_dir/$_"; | ||
| 65 | mkdir "$output_dir/$_/roots"; | ||
| 66 | |||
| 67 | &root_pem_to_dir($roots_file, $roots_dir); | ||
| 68 | } | ||
| 69 | closedir CERTS; | ||
diff --git a/src/regress/lib/libcrypto/x509/verify.c b/src/regress/lib/libcrypto/x509/verify.c index 259854ef12..74ba603a22 100644 --- a/src/regress/lib/libcrypto/x509/verify.c +++ b/src/regress/lib/libcrypto/x509/verify.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* $OpenBSD: verify.c,v 1.6 2021/08/27 16:15:42 beck Exp $ */ | 1 | /* $OpenBSD: verify.c,v 1.7 2021/08/28 15:13:50 beck 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 Bob Beck <beck@openbsd.org> | 4 | * Copyright (c) 2020-2021 Bob Beck <beck@openbsd.org> |
| 5 | * | 5 | * |
| 6 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
| 7 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
| @@ -26,9 +26,10 @@ | |||
| 26 | #include <openssl/x509v3.h> | 26 | #include <openssl/x509v3.h> |
| 27 | #include <openssl/x509_verify.h> | 27 | #include <openssl/x509_verify.h> |
| 28 | 28 | ||
| 29 | #define MODE_MODERN_VFY 0 | 29 | #define MODE_MODERN_VFY 0 |
| 30 | #define MODE_LEGACY_VFY 1 | 30 | #define MODE_MODERN_VFY_DIR 1 |
| 31 | #define MODE_VERIFY 2 | 31 | #define MODE_LEGACY_VFY 2 |
| 32 | #define MODE_VERIFY 3 | ||
| 32 | 33 | ||
| 33 | static int verbose = 1; | 34 | static int verbose = 1; |
| 34 | 35 | ||
| @@ -100,18 +101,20 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) | |||
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | static void | 103 | static void |
| 103 | verify_cert(const char *roots_file, const char *bundle_file, int *chains, | 104 | verify_cert(const char *roots_dir, const char *roots_file, |
| 104 | int mode) | 105 | const char *bundle_file, int *chains, int mode) |
| 105 | { | 106 | { |
| 106 | STACK_OF(X509) *roots = NULL, *bundle = NULL; | 107 | STACK_OF(X509) *roots = NULL, *bundle = NULL; |
| 107 | X509_STORE_CTX *xsc = NULL; | 108 | X509_STORE_CTX *xsc = NULL; |
| 109 | X509_STORE *store = NULL; | ||
| 110 | int verify_err, use_dir; | ||
| 108 | unsigned long flags; | 111 | unsigned long flags; |
| 109 | X509 *leaf = NULL; | 112 | X509 *leaf = NULL; |
| 110 | int verify_err; | ||
| 111 | 113 | ||
| 112 | *chains = 0; | 114 | *chains = 0; |
| 115 | use_dir = (mode == MODE_MODERN_VFY_DIR); | ||
| 113 | 116 | ||
| 114 | if (!certs_from_file(roots_file, &roots)) | 117 | if (!use_dir && !certs_from_file(roots_file, &roots)) |
| 115 | errx(1, "failed to load roots from '%s'", roots_file); | 118 | errx(1, "failed to load roots from '%s'", roots_file); |
| 116 | if (!certs_from_file(bundle_file, &bundle)) | 119 | if (!certs_from_file(bundle_file, &bundle)) |
| 117 | errx(1, "failed to load bundle from '%s'", bundle_file); | 120 | errx(1, "failed to load bundle from '%s'", bundle_file); |
| @@ -121,10 +124,16 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains, | |||
| 121 | 124 | ||
| 122 | if ((xsc = X509_STORE_CTX_new()) == NULL) | 125 | if ((xsc = X509_STORE_CTX_new()) == NULL) |
| 123 | errx(1, "X509_STORE_CTX"); | 126 | errx(1, "X509_STORE_CTX"); |
| 124 | if (!X509_STORE_CTX_init(xsc, NULL, leaf, bundle)) { | 127 | if (use_dir && (store = X509_STORE_new()) == NULL) |
| 128 | errx(1, "X509_STORE"); | ||
| 129 | if (!X509_STORE_CTX_init(xsc, store, leaf, bundle)) { | ||
| 125 | ERR_print_errors_fp(stderr); | 130 | ERR_print_errors_fp(stderr); |
| 126 | errx(1, "failed to init store context"); | 131 | errx(1, "failed to init store context"); |
| 127 | } | 132 | } |
| 133 | if (use_dir) { | ||
| 134 | if (!X509_STORE_load_locations(store, NULL, roots_dir)) | ||
| 135 | errx(1, "failed to set by_dir directory of %s", roots_dir); | ||
| 136 | } | ||
| 128 | if (mode == MODE_LEGACY_VFY) { | 137 | if (mode == MODE_LEGACY_VFY) { |
| 129 | flags = X509_VERIFY_PARAM_get_flags(xsc->param); | 138 | flags = X509_VERIFY_PARAM_get_flags(xsc->param); |
| 130 | flags |= X509_V_FLAG_LEGACY_VERIFY; | 139 | flags |= X509_V_FLAG_LEGACY_VERIFY; |
| @@ -137,7 +146,8 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains, | |||
| 137 | 146 | ||
| 138 | if (verbose) | 147 | if (verbose) |
| 139 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); | 148 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); |
| 140 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); | 149 | if (!use_dir) |
| 150 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); | ||
| 141 | if (X509_verify_cert(xsc) == 1) { | 151 | if (X509_verify_cert(xsc) == 1) { |
| 142 | *chains = 1; /* XXX */ | 152 | *chains = 1; /* XXX */ |
| 143 | goto done; | 153 | goto done; |
| @@ -154,6 +164,7 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains, | |||
| 154 | done: | 164 | done: |
| 155 | sk_X509_pop_free(roots, X509_free); | 165 | sk_X509_pop_free(roots, X509_free); |
| 156 | sk_X509_pop_free(bundle, X509_free); | 166 | sk_X509_pop_free(bundle, X509_free); |
| 167 | X509_STORE_free(store); | ||
| 157 | X509_STORE_CTX_free(xsc); | 168 | X509_STORE_CTX_free(xsc); |
| 158 | X509_free(leaf); | 169 | X509_free(leaf); |
| 159 | } | 170 | } |
| @@ -394,7 +405,7 @@ struct verify_cert_test verify_cert_tests[] = { | |||
| 394 | static int | 405 | static int |
| 395 | verify_cert_test(const char *certs_path, int mode) | 406 | verify_cert_test(const char *certs_path, int mode) |
| 396 | { | 407 | { |
| 397 | char *roots_file, *bundle_file; | 408 | char *roots_file, *bundle_file, *roots_dir; |
| 398 | struct verify_cert_test *vct; | 409 | struct verify_cert_test *vct; |
| 399 | int failed = 0; | 410 | int failed = 0; |
| 400 | int chains; | 411 | int chains; |
| @@ -409,13 +420,15 @@ verify_cert_test(const char *certs_path, int mode) | |||
| 409 | if (asprintf(&bundle_file, "%s/%s/bundle.pem", certs_path, | 420 | if (asprintf(&bundle_file, "%s/%s/bundle.pem", certs_path, |
| 410 | vct->id) == -1) | 421 | vct->id) == -1) |
| 411 | errx(1, "asprintf"); | 422 | errx(1, "asprintf"); |
| 423 | if (asprintf(&roots_dir, "./%s/roots", vct->id) == -1) | ||
| 424 | errx(1, "asprintf"); | ||
| 412 | 425 | ||
| 413 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); | 426 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); |
| 414 | if (mode == MODE_VERIFY) | 427 | if (mode == MODE_VERIFY) |
| 415 | verify_cert_new(roots_file, bundle_file, &chains); | 428 | verify_cert_new(roots_file, bundle_file, &chains); |
| 416 | else | 429 | else |
| 417 | verify_cert(roots_file, bundle_file, &chains, mode); | 430 | verify_cert(roots_dir, roots_file, bundle_file, &chains, mode); |
| 418 | if ((mode == 2 && chains == vct->want_chains) || | 431 | if ((mode == MODE_VERIFY && chains == vct->want_chains) || |
| 419 | (chains == 0 && vct->want_chains == 0) || | 432 | (chains == 0 && vct->want_chains == 0) || |
| 420 | (chains == 1 && vct->want_chains > 0)) { | 433 | (chains == 1 && vct->want_chains > 0)) { |
| 421 | fprintf(stderr, "INFO: Succeeded with %d chains%s\n", | 434 | fprintf(stderr, "INFO: Succeeded with %d chains%s\n", |
| @@ -432,6 +445,7 @@ verify_cert_test(const char *certs_path, int mode) | |||
| 432 | 445 | ||
| 433 | free(roots_file); | 446 | free(roots_file); |
| 434 | free(bundle_file); | 447 | free(bundle_file); |
| 448 | free(roots_dir); | ||
| 435 | } | 449 | } |
| 436 | 450 | ||
| 437 | return failed; | 451 | return failed; |
| @@ -451,6 +465,8 @@ main(int argc, char **argv) | |||
| 451 | failed |= verify_cert_test(argv[1], MODE_LEGACY_VFY); | 465 | failed |= verify_cert_test(argv[1], MODE_LEGACY_VFY); |
| 452 | fprintf(stderr, "\n\nTesting modern x509_vfy\n"); | 466 | fprintf(stderr, "\n\nTesting modern x509_vfy\n"); |
| 453 | failed |= verify_cert_test(argv[1], MODE_MODERN_VFY); | 467 | failed |= verify_cert_test(argv[1], MODE_MODERN_VFY); |
| 468 | fprintf(stderr, "\n\nTesting modern x509_vfy by_dir\n"); | ||
| 469 | failed |= verify_cert_test(argv[1], MODE_MODERN_VFY_DIR); | ||
| 454 | fprintf(stderr, "\n\nTesting x509_verify\n"); | 470 | fprintf(stderr, "\n\nTesting x509_verify\n"); |
| 455 | failed |= verify_cert_test(argv[1], MODE_VERIFY); | 471 | failed |= verify_cert_test(argv[1], MODE_VERIFY); |
| 456 | 472 | ||
