From b68b63e374015cf0aafaaec62a065293b1be59e3 Mon Sep 17 00:00:00 2001 From: beck Date: Sat, 28 Aug 2021 15:13:50 +0000 Subject: [PATCH] Add a pass using the modern vfy with by_dir roots, code by me, script to generate certdirs by jsing, and make chicken sacrifies by tb. ok tb@ jsing@ --- regress/lib/libcrypto/x509/Makefile | 8 ++- regress/lib/libcrypto/x509/make-dir-roots.pl | 69 ++++++++++++++++++++ regress/lib/libcrypto/x509/verify.c | 44 +++++++++---- 3 files changed, 106 insertions(+), 15 deletions(-) create mode 100644 regress/lib/libcrypto/x509/make-dir-roots.pl diff --git a/regress/lib/libcrypto/x509/Makefile b/regress/lib/libcrypto/x509/Makefile index 37da3fb9339..6b4256bfad1 100644 --- a/regress/lib/libcrypto/x509/Makefile +++ b/regress/lib/libcrypto/x509/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.4 2020/09/11 18:34:29 beck Exp $ +# $OpenBSD: Makefile,v 1.5 2021/08/28 15:13:50 beck Exp $ PROGS = constraints verify x509attribute x509name LDADD= -Wl,-Bstatic -lcrypto -Wl,-Bdynamic @@ -11,7 +11,13 @@ SUBDIR += bettertls REGRESS_TARGETS=regress-constraints regress-verify regress-x509attribute regress-x509name CLEANFILES+= x509name.result +.if make(clean) || make(cleandir) +.BEGIN: + rm -rf ${.OBJDIR}/[0-9]* +.endif + regress-verify: verify + perl ${.CURDIR}/make-dir-roots.pl ${.CURDIR}/../certs . ./verify ${.CURDIR}/../certs regress-constraints: constraints diff --git a/regress/lib/libcrypto/x509/make-dir-roots.pl b/regress/lib/libcrypto/x509/make-dir-roots.pl new file mode 100644 index 00000000000..54d05e0519a --- /dev/null +++ b/regress/lib/libcrypto/x509/make-dir-roots.pl @@ -0,0 +1,69 @@ +#!/usr/bin/perl + +# +# Copyright (c) 2021 Joel Sing +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +sub root_pem_to_dir() { + $certs = 0; + $in_cert = 0; + + ($roots_file, $certs_dir) = @_; + + open ROOTS, "<$roots_file" or + die "failed to open roots file '$roots_file'"; + while () { + if ($_ eq "-----BEGIN CERTIFICATE-----\n") { + $in_cert = 1; + $cert_path = "$certs_dir/ca-$certs.pem"; + open CERT, ">$cert_path" or + die "failed to open '$cert_path'"; + $certs++; + } + if ($in_cert) { + print CERT $_; + } + if ($_ eq "-----END CERTIFICATE-----\n") { + $in_cert = 0; + } + } + close ROOTS; + + my @args = ("openssl", "certhash", $certs_dir); + system(@args) == 0 or die "certhash failed"; +} + +if (scalar @ARGV != 2) { + print("$0 \n"); + exit(1); +} +$certs_path = shift @ARGV; +$output_dir = shift @ARGV; + +opendir CERTS, $certs_path or + die "failed to open certs directory '$certs_path'"; +while (readdir CERTS) { + next if ($_ !~ '^[0-9]+[a-z]?$'); + + $roots_file = join("/", $certs_path, $_, "roots.pem"); + $roots_dir = join("/", $output_dir, $_, "roots"); + + mkdir "$output_dir"; + mkdir "$output_dir/$_"; + mkdir "$output_dir/$_/roots"; + + &root_pem_to_dir($roots_file, $roots_dir); +} +closedir CERTS; diff --git a/regress/lib/libcrypto/x509/verify.c b/regress/lib/libcrypto/x509/verify.c index 259854ef12f..74ba603a227 100644 --- a/regress/lib/libcrypto/x509/verify.c +++ b/regress/lib/libcrypto/x509/verify.c @@ -1,7 +1,7 @@ -/* $OpenBSD: verify.c,v 1.6 2021/08/27 16:15:42 beck Exp $ */ +/* $OpenBSD: verify.c,v 1.7 2021/08/28 15:13:50 beck Exp $ */ /* * Copyright (c) 2020 Joel Sing - * Copyright (c) 2020 Bob Beck + * Copyright (c) 2020-2021 Bob Beck * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -26,9 +26,10 @@ #include #include -#define MODE_MODERN_VFY 0 -#define MODE_LEGACY_VFY 1 -#define MODE_VERIFY 2 +#define MODE_MODERN_VFY 0 +#define MODE_MODERN_VFY_DIR 1 +#define MODE_LEGACY_VFY 2 +#define MODE_VERIFY 3 static int verbose = 1; @@ -100,18 +101,20 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) } static void -verify_cert(const char *roots_file, const char *bundle_file, int *chains, - int mode) +verify_cert(const char *roots_dir, const char *roots_file, + const char *bundle_file, int *chains, int mode) { STACK_OF(X509) *roots = NULL, *bundle = NULL; X509_STORE_CTX *xsc = NULL; + X509_STORE *store = NULL; + int verify_err, use_dir; unsigned long flags; X509 *leaf = NULL; - int verify_err; *chains = 0; + use_dir = (mode == MODE_MODERN_VFY_DIR); - if (!certs_from_file(roots_file, &roots)) + if (!use_dir && !certs_from_file(roots_file, &roots)) errx(1, "failed to load roots from '%s'", roots_file); if (!certs_from_file(bundle_file, &bundle)) 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, if ((xsc = X509_STORE_CTX_new()) == NULL) errx(1, "X509_STORE_CTX"); - if (!X509_STORE_CTX_init(xsc, NULL, leaf, bundle)) { + if (use_dir && (store = X509_STORE_new()) == NULL) + errx(1, "X509_STORE"); + if (!X509_STORE_CTX_init(xsc, store, leaf, bundle)) { ERR_print_errors_fp(stderr); errx(1, "failed to init store context"); } + if (use_dir) { + if (!X509_STORE_load_locations(store, NULL, roots_dir)) + errx(1, "failed to set by_dir directory of %s", roots_dir); + } if (mode == MODE_LEGACY_VFY) { flags = X509_VERIFY_PARAM_get_flags(xsc->param); flags |= X509_V_FLAG_LEGACY_VERIFY; @@ -137,7 +146,8 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains, if (verbose) X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); - X509_STORE_CTX_set0_trusted_stack(xsc, roots); + if (!use_dir) + X509_STORE_CTX_set0_trusted_stack(xsc, roots); if (X509_verify_cert(xsc) == 1) { *chains = 1; /* XXX */ goto done; @@ -154,6 +164,7 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains, done: sk_X509_pop_free(roots, X509_free); sk_X509_pop_free(bundle, X509_free); + X509_STORE_free(store); X509_STORE_CTX_free(xsc); X509_free(leaf); } @@ -394,7 +405,7 @@ struct verify_cert_test verify_cert_tests[] = { static int verify_cert_test(const char *certs_path, int mode) { - char *roots_file, *bundle_file; + char *roots_file, *bundle_file, *roots_dir; struct verify_cert_test *vct; int failed = 0; int chains; @@ -409,13 +420,15 @@ verify_cert_test(const char *certs_path, int mode) if (asprintf(&bundle_file, "%s/%s/bundle.pem", certs_path, vct->id) == -1) errx(1, "asprintf"); + if (asprintf(&roots_dir, "./%s/roots", vct->id) == -1) + errx(1, "asprintf"); fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); if (mode == MODE_VERIFY) verify_cert_new(roots_file, bundle_file, &chains); else - verify_cert(roots_file, bundle_file, &chains, mode); - if ((mode == 2 && chains == vct->want_chains) || + verify_cert(roots_dir, roots_file, bundle_file, &chains, mode); + if ((mode == MODE_VERIFY && chains == vct->want_chains) || (chains == 0 && vct->want_chains == 0) || (chains == 1 && vct->want_chains > 0)) { fprintf(stderr, "INFO: Succeeded with %d chains%s\n", @@ -432,6 +445,7 @@ verify_cert_test(const char *certs_path, int mode) free(roots_file); free(bundle_file); + free(roots_dir); } return failed; @@ -451,6 +465,8 @@ main(int argc, char **argv) failed |= verify_cert_test(argv[1], MODE_LEGACY_VFY); fprintf(stderr, "\n\nTesting modern x509_vfy\n"); failed |= verify_cert_test(argv[1], MODE_MODERN_VFY); + fprintf(stderr, "\n\nTesting modern x509_vfy by_dir\n"); + failed |= verify_cert_test(argv[1], MODE_MODERN_VFY_DIR); fprintf(stderr, "\n\nTesting x509_verify\n"); failed |= verify_cert_test(argv[1], MODE_VERIFY); -- 2.20.1