diff options
Diffstat (limited to 'src/regress')
-rw-r--r-- | src/regress/lib/libcrypto/x509/verify.c | 99 |
1 files changed, 90 insertions, 9 deletions
diff --git a/src/regress/lib/libcrypto/x509/verify.c b/src/regress/lib/libcrypto/x509/verify.c index 08ca0b24ff..1a11c2ffe5 100644 --- a/src/regress/lib/libcrypto/x509/verify.c +++ b/src/regress/lib/libcrypto/x509/verify.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* $OpenBSD: verify.c,v 1.1 2020/07/14 18:33:00 jsing Exp $ */ | 1 | /* $OpenBSD: verify.c,v 1.2 2020/09/13 15:06:17 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 | * | 5 | * |
5 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
6 | * 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 |
@@ -23,6 +24,11 @@ | |||
23 | #include <openssl/pem.h> | 24 | #include <openssl/pem.h> |
24 | #include <openssl/x509.h> | 25 | #include <openssl/x509.h> |
25 | #include <openssl/x509v3.h> | 26 | #include <openssl/x509v3.h> |
27 | #include <openssl/x509_verify.h> | ||
28 | |||
29 | #define MODE_MODERN_VFY 0 | ||
30 | #define MODE_LEGACY_VFY 1 | ||
31 | #define MODE_VERIFY 2 | ||
26 | 32 | ||
27 | static int verbose = 1; | 33 | static int verbose = 1; |
28 | 34 | ||
@@ -94,10 +100,12 @@ verify_cert_cb(int ok, X509_STORE_CTX *xsc) | |||
94 | } | 100 | } |
95 | 101 | ||
96 | static void | 102 | static void |
97 | verify_cert(const char *roots_file, const char *bundle_file, int *chains) | 103 | verify_cert(const char *roots_file, const char *bundle_file, int *chains, |
104 | int mode) | ||
98 | { | 105 | { |
99 | STACK_OF(X509) *roots = NULL, *bundle = NULL; | 106 | STACK_OF(X509) *roots = NULL, *bundle = NULL; |
100 | X509_STORE_CTX *xsc = NULL; | 107 | X509_STORE_CTX *xsc = NULL; |
108 | unsigned long flags; | ||
101 | X509 *leaf = NULL; | 109 | X509 *leaf = NULL; |
102 | int verify_err; | 110 | int verify_err; |
103 | 111 | ||
@@ -117,6 +125,16 @@ verify_cert(const char *roots_file, const char *bundle_file, int *chains) | |||
117 | ERR_print_errors_fp(stderr); | 125 | ERR_print_errors_fp(stderr); |
118 | errx(1, "failed to init store context"); | 126 | errx(1, "failed to init store context"); |
119 | } | 127 | } |
128 | if (mode == MODE_LEGACY_VFY) { | ||
129 | flags = X509_VERIFY_PARAM_get_flags(xsc->param); | ||
130 | flags |= X509_V_FLAG_LEGACY_VERIFY; | ||
131 | X509_VERIFY_PARAM_set_flags(xsc->param, flags); | ||
132 | } else { | ||
133 | flags = X509_VERIFY_PARAM_get_flags(xsc->param); | ||
134 | flags &= ~X509_V_FLAG_LEGACY_VERIFY; | ||
135 | X509_VERIFY_PARAM_set_flags(xsc->param, flags); | ||
136 | } | ||
137 | |||
120 | if (verbose) | 138 | if (verbose) |
121 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); | 139 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); |
122 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); | 140 | X509_STORE_CTX_set0_trusted_stack(xsc, roots); |
@@ -143,6 +161,60 @@ struct verify_cert_test { | |||
143 | int failing; | 161 | int failing; |
144 | }; | 162 | }; |
145 | 163 | ||
164 | static void | ||
165 | verify_cert_new(const char *roots_file, const char *bundle_file, int *chains) | ||
166 | { | ||
167 | STACK_OF(X509) *roots = NULL, *bundle = NULL; | ||
168 | X509_STORE_CTX *xsc = NULL; | ||
169 | X509 *leaf = NULL; | ||
170 | struct x509_verify_ctx *ctx; | ||
171 | |||
172 | *chains = 0; | ||
173 | |||
174 | if (!certs_from_file(roots_file, &roots)) | ||
175 | errx(1, "failed to load roots from '%s'", roots_file); | ||
176 | if (!certs_from_file(bundle_file, &bundle)) | ||
177 | errx(1, "failed to load bundle from '%s'", bundle_file); | ||
178 | if (sk_X509_num(bundle) < 1) | ||
179 | errx(1, "not enough certs in bundle"); | ||
180 | leaf = sk_X509_shift(bundle); | ||
181 | |||
182 | if ((xsc = X509_STORE_CTX_new()) == NULL) | ||
183 | errx(1, "X509_STORE_CTX"); | ||
184 | if (!X509_STORE_CTX_init(xsc, NULL, leaf, bundle)) { | ||
185 | ERR_print_errors_fp(stderr); | ||
186 | errx(1, "failed to init store context"); | ||
187 | } | ||
188 | if (verbose) | ||
189 | X509_STORE_CTX_set_verify_cb(xsc, verify_cert_cb); | ||
190 | |||
191 | if ((ctx = x509_verify_ctx_new(roots)) == NULL) | ||
192 | errx(1, "failed to create ctx"); | ||
193 | if (!x509_verify_ctx_set_intermediates(ctx, bundle)) | ||
194 | errx(1, "failed to set intermediates"); | ||
195 | |||
196 | if ((*chains = x509_verify(ctx, leaf, NULL)) == 0) { | ||
197 | fprintf(stderr, "failed to verify at %lu: %s\n", | ||
198 | x509_verify_ctx_error_depth(ctx), | ||
199 | x509_verify_ctx_error_string(ctx)); | ||
200 | } else { | ||
201 | for (int c = 0; verbose && c < *chains; c++) { | ||
202 | fprintf(stderr, "Chain %d\n--------\n", c); | ||
203 | STACK_OF(X509) * chain = x509_verify_ctx_chain(ctx, c); | ||
204 | for (int i = 0; i < sk_X509_num(chain); i++) { | ||
205 | X509 *cert = sk_X509_value(chain, i); | ||
206 | X509_NAME_print_ex_fp(stderr, | ||
207 | X509_get_subject_name(cert), 0, | ||
208 | XN_FLAG_ONELINE); | ||
209 | fprintf(stderr, "\n"); | ||
210 | } | ||
211 | } | ||
212 | } | ||
213 | sk_X509_pop_free(roots, X509_free); | ||
214 | sk_X509_pop_free(bundle, X509_free); | ||
215 | X509_free(leaf); | ||
216 | } | ||
217 | |||
146 | struct verify_cert_test verify_cert_tests[] = { | 218 | struct verify_cert_test verify_cert_tests[] = { |
147 | { | 219 | { |
148 | .id = "1a", | 220 | .id = "1a", |
@@ -306,7 +378,7 @@ struct verify_cert_test verify_cert_tests[] = { | |||
306 | (sizeof(verify_cert_tests) / sizeof(*verify_cert_tests)) | 378 | (sizeof(verify_cert_tests) / sizeof(*verify_cert_tests)) |
307 | 379 | ||
308 | static int | 380 | static int |
309 | verify_cert_test(const char *certs_path) | 381 | verify_cert_test(const char *certs_path, int mode) |
310 | { | 382 | { |
311 | char *roots_file, *bundle_file; | 383 | char *roots_file, *bundle_file; |
312 | struct verify_cert_test *vct; | 384 | struct verify_cert_test *vct; |
@@ -325,16 +397,20 @@ verify_cert_test(const char *certs_path) | |||
325 | errx(1, "asprintf"); | 397 | errx(1, "asprintf"); |
326 | 398 | ||
327 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); | 399 | fprintf(stderr, "== Test %zu (%s)\n", i, vct->id); |
328 | verify_cert(roots_file, bundle_file, &chains); | 400 | if (mode == MODE_VERIFY) |
329 | if ((chains == 0 && vct->want_chains == 0) || | 401 | verify_cert_new(roots_file, bundle_file, &chains); |
402 | else | ||
403 | verify_cert(roots_file, bundle_file, &chains, mode); | ||
404 | if ((mode == 2 && chains == vct->want_chains) || | ||
405 | (chains == 0 && vct->want_chains == 0) || | ||
330 | (chains == 1 && vct->want_chains > 0)) { | 406 | (chains == 1 && vct->want_chains > 0)) { |
331 | fprintf(stderr, "INFO: Succeeded with %d chains%s\n", | 407 | fprintf(stderr, "INFO: Succeeded with %d chains%s\n", |
332 | chains, vct->failing ? " (known failure)" : ""); | 408 | chains, vct->failing ? " (legacy failure)" : ""); |
333 | if (vct->failing) | 409 | if (mode == MODE_LEGACY_VFY && vct->failing) |
334 | failed |= 1; | 410 | failed |= 1; |
335 | } else { | 411 | } else { |
336 | fprintf(stderr, "FAIL: Failed with %d chains%s\n", | 412 | fprintf(stderr, "FAIL: Failed with %d chains%s\n", |
337 | chains, vct->failing ? " (known failure)" : ""); | 413 | chains, vct->failing ? " (legacy failure)" : ""); |
338 | if (!vct->failing) | 414 | if (!vct->failing) |
339 | failed |= 1; | 415 | failed |= 1; |
340 | } | 416 | } |
@@ -357,7 +433,12 @@ main(int argc, char **argv) | |||
357 | exit(1); | 433 | exit(1); |
358 | } | 434 | } |
359 | 435 | ||
360 | failed |= verify_cert_test(argv[1]); | 436 | fprintf(stderr, "\n\nTesting legacy x509_vfy\n"); |
437 | failed |= verify_cert_test(argv[1], MODE_LEGACY_VFY); | ||
438 | fprintf(stderr, "\n\nTesting modern x509_vfy\n"); | ||
439 | failed |= verify_cert_test(argv[1], MODE_MODERN_VFY); | ||
440 | fprintf(stderr, "\n\nTesting x509_verify\n"); | ||
441 | failed |= verify_cert_test(argv[1], MODE_VERIFY); | ||
361 | 442 | ||
362 | return (failed); | 443 | return (failed); |
363 | } | 444 | } |