diff options
author | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
---|---|---|
committer | cvs2svn <admin@example.com> | 2025-04-14 17:32:06 +0000 |
commit | eb8dd9dca1228af0cd132f515509051ecfabf6f6 (patch) | |
tree | edb6da6af7e865d488dc1a29309f1e1ec226e603 /src/usr.bin/openssl/verify.c | |
parent | 247f0352e0ed72a4f476db9dc91f4d982bc83eb2 (diff) | |
download | openbsd-tb_20250414.tar.gz openbsd-tb_20250414.tar.bz2 openbsd-tb_20250414.zip |
This commit was manufactured by cvs2git to create tag 'tb_20250414'.tb_20250414
Diffstat (limited to 'src/usr.bin/openssl/verify.c')
-rw-r--r-- | src/usr.bin/openssl/verify.c | 457 |
1 files changed, 0 insertions, 457 deletions
diff --git a/src/usr.bin/openssl/verify.c b/src/usr.bin/openssl/verify.c deleted file mode 100644 index a87d5d47df..0000000000 --- a/src/usr.bin/openssl/verify.c +++ /dev/null | |||
@@ -1,457 +0,0 @@ | |||
1 | /* $OpenBSD: verify.c,v 1.18 2023/11/21 17:56:19 tb Exp $ */ | ||
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * This package is an SSL implementation written | ||
6 | * by Eric Young (eay@cryptsoft.com). | ||
7 | * The implementation was written so as to conform with Netscapes SSL. | ||
8 | * | ||
9 | * This library is free for commercial and non-commercial use as long as | ||
10 | * the following conditions are aheared to. The following conditions | ||
11 | * apply to all code found in this distribution, be it the RC4, RSA, | ||
12 | * lhash, DES, etc., code; not just the SSL code. The SSL documentation | ||
13 | * included with this distribution is covered by the same copyright terms | ||
14 | * except that the holder is Tim Hudson (tjh@cryptsoft.com). | ||
15 | * | ||
16 | * Copyright remains Eric Young's, and as such any Copyright notices in | ||
17 | * the code are not to be removed. | ||
18 | * If this package is used in a product, Eric Young should be given attribution | ||
19 | * as the author of the parts of the library used. | ||
20 | * This can be in the form of a textual message at program startup or | ||
21 | * in documentation (online or textual) provided with the package. | ||
22 | * | ||
23 | * Redistribution and use in source and binary forms, with or without | ||
24 | * modification, are permitted provided that the following conditions | ||
25 | * are met: | ||
26 | * 1. Redistributions of source code must retain the copyright | ||
27 | * notice, this list of conditions and the following disclaimer. | ||
28 | * 2. Redistributions in binary form must reproduce the above copyright | ||
29 | * notice, this list of conditions and the following disclaimer in the | ||
30 | * documentation and/or other materials provided with the distribution. | ||
31 | * 3. All advertising materials mentioning features or use of this software | ||
32 | * must display the following acknowledgement: | ||
33 | * "This product includes cryptographic software written by | ||
34 | * Eric Young (eay@cryptsoft.com)" | ||
35 | * The word 'cryptographic' can be left out if the rouines from the library | ||
36 | * being used are not cryptographic related :-). | ||
37 | * 4. If you include any Windows specific code (or a derivative thereof) from | ||
38 | * the apps directory (application code) you must include an acknowledgement: | ||
39 | * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | ||
40 | * | ||
41 | * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | ||
42 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
43 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
44 | * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | ||
45 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
46 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
47 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
48 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
49 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
50 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
51 | * SUCH DAMAGE. | ||
52 | * | ||
53 | * The licence and distribution terms for any publically available version or | ||
54 | * derivative of this code cannot be changed. i.e. this code cannot simply be | ||
55 | * copied and put under another distribution licence | ||
56 | * [including the GNU Public Licence.] | ||
57 | */ | ||
58 | |||
59 | #include <stdio.h> | ||
60 | #include <stdlib.h> | ||
61 | #include <string.h> | ||
62 | |||
63 | #include "apps.h" | ||
64 | |||
65 | #include <openssl/bio.h> | ||
66 | #include <openssl/err.h> | ||
67 | #include <openssl/pem.h> | ||
68 | #include <openssl/x509.h> | ||
69 | #include <openssl/x509v3.h> | ||
70 | |||
71 | static int cb(int ok, X509_STORE_CTX *ctx); | ||
72 | static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, | ||
73 | STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls); | ||
74 | static int vflags = 0; | ||
75 | |||
76 | static struct { | ||
77 | char *CAfile; | ||
78 | char *CApath; | ||
79 | char *crlfile; | ||
80 | char *trustfile; | ||
81 | char *untfile; | ||
82 | int verbose; | ||
83 | X509_VERIFY_PARAM *vpm; | ||
84 | } cfg; | ||
85 | |||
86 | static int | ||
87 | verify_opt_args(int argc, char **argv, int *argsused) | ||
88 | { | ||
89 | int oargc = argc; | ||
90 | int badarg = 0; | ||
91 | |||
92 | if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm)) | ||
93 | return (1); | ||
94 | if (badarg) | ||
95 | return (1); | ||
96 | |||
97 | *argsused = oargc - argc; | ||
98 | |||
99 | return (0); | ||
100 | } | ||
101 | |||
102 | static const struct option verify_options[] = { | ||
103 | { | ||
104 | .name = "CAfile", | ||
105 | .argname = "file", | ||
106 | .desc = "Certificate Authority file", | ||
107 | .type = OPTION_ARG, | ||
108 | .opt.arg = &cfg.CAfile, | ||
109 | }, | ||
110 | { | ||
111 | .name = "CApath", | ||
112 | .argname = "path", | ||
113 | .desc = "Certificate Authority path", | ||
114 | .type = OPTION_ARG, | ||
115 | .opt.arg = &cfg.CApath, | ||
116 | }, | ||
117 | { | ||
118 | .name = "CRLfile", | ||
119 | .argname = "file", | ||
120 | .desc = "Certificate Revocation List file", | ||
121 | .type = OPTION_ARG, | ||
122 | .opt.arg = &cfg.crlfile, | ||
123 | }, | ||
124 | { | ||
125 | .name = "trusted", | ||
126 | .argname = "file", | ||
127 | .desc = "Trusted certificates file", | ||
128 | .type = OPTION_ARG, | ||
129 | .opt.arg = &cfg.trustfile, | ||
130 | }, | ||
131 | { | ||
132 | .name = "untrusted", | ||
133 | .argname = "file", | ||
134 | .desc = "Untrusted certificates file", | ||
135 | .type = OPTION_ARG, | ||
136 | .opt.arg = &cfg.untfile, | ||
137 | }, | ||
138 | { | ||
139 | .name = "verbose", | ||
140 | .desc = "Verbose", | ||
141 | .type = OPTION_FLAG, | ||
142 | .opt.flag = &cfg.verbose, | ||
143 | }, | ||
144 | { | ||
145 | .name = NULL, | ||
146 | .desc = "", | ||
147 | .type = OPTION_ARGV_FUNC, | ||
148 | .opt.argvfunc = verify_opt_args, | ||
149 | }, | ||
150 | { NULL }, | ||
151 | }; | ||
152 | |||
153 | static const struct option verify_shared_options[] = { | ||
154 | { | ||
155 | .name = "attime", | ||
156 | .argname = "epoch", | ||
157 | .desc = "Use epoch as the verification time", | ||
158 | }, | ||
159 | { | ||
160 | .name = "check_ss_sig", | ||
161 | .desc = "Check the root CA self-signed certificate signature", | ||
162 | }, | ||
163 | { | ||
164 | .name = "crl_check", | ||
165 | .desc = "Enable CRL checking for the leaf certificate", | ||
166 | }, | ||
167 | { | ||
168 | .name = "crl_check_all", | ||
169 | .desc = "Enable CRL checking for the entire certificate chain", | ||
170 | }, | ||
171 | { | ||
172 | .name = "explicit_policy", | ||
173 | .desc = "Require explicit policy (per RFC 3280)", | ||
174 | }, | ||
175 | { | ||
176 | .name = "extended_crl", | ||
177 | .desc = "Enable extended CRL support", | ||
178 | }, | ||
179 | { | ||
180 | .name = "ignore_critical", | ||
181 | .desc = "Disable critical extension checking", | ||
182 | }, | ||
183 | { | ||
184 | .name = "inhibit_any", | ||
185 | .desc = "Inhibit any policy (per RFC 3280)", | ||
186 | }, | ||
187 | { | ||
188 | .name = "inhibit_map", | ||
189 | .desc = "Inhibit policy mapping (per RFC 3280)", | ||
190 | }, | ||
191 | { | ||
192 | .name = "issuer_checks", | ||
193 | .desc = "Enable debugging of certificate issuer checks", | ||
194 | }, | ||
195 | { | ||
196 | .name = "legacy_verify", | ||
197 | .desc = "Use legacy certificate chain verification", | ||
198 | }, | ||
199 | { | ||
200 | .name = "policy", | ||
201 | .argname = "name", | ||
202 | .desc = "Add given policy to the acceptable set", | ||
203 | }, | ||
204 | { | ||
205 | .name = "policy_check", | ||
206 | .desc = "Enable certificate policy checking", | ||
207 | }, | ||
208 | { | ||
209 | .name = "policy_print", | ||
210 | .desc = "Print policy", | ||
211 | }, | ||
212 | { | ||
213 | .name = "purpose", | ||
214 | .argname = "name", | ||
215 | .desc = "Verify for the given purpose", | ||
216 | }, | ||
217 | { | ||
218 | .name = "use_deltas", | ||
219 | .desc = "Use delta CRLS (if present)", | ||
220 | }, | ||
221 | { | ||
222 | .name = "verify_depth", | ||
223 | .argname = "num", | ||
224 | .desc = "Limit verification to the given depth", | ||
225 | }, | ||
226 | { | ||
227 | .name = "x509_strict", | ||
228 | .desc = "Use strict X.509 rules (disables workarounds)", | ||
229 | }, | ||
230 | { NULL }, | ||
231 | }; | ||
232 | |||
233 | static void | ||
234 | verify_usage(void) | ||
235 | { | ||
236 | int i; | ||
237 | |||
238 | fprintf(stderr, | ||
239 | "usage: verify [-CAfile file] [-CApath directory] [-check_ss_sig]\n" | ||
240 | " [-CRLfile file] [-crl_check] [-crl_check_all]\n" | ||
241 | " [-explicit_policy] [-extended_crl]\n" | ||
242 | " [-ignore_critical] [-inhibit_any] [-inhibit_map]\n" | ||
243 | " [-issuer_checks] [-policy_check] [-purpose purpose]\n" | ||
244 | " [-trusted file] [-untrusted file] [-verbose]\n" | ||
245 | " [-x509_strict] [certificates]\n\n"); | ||
246 | |||
247 | options_usage(verify_options); | ||
248 | |||
249 | fprintf(stderr, "\nVerification options:\n\n"); | ||
250 | options_usage(verify_shared_options); | ||
251 | |||
252 | fprintf(stderr, "\nValid purposes:\n\n"); | ||
253 | for (i = 0; i < X509_PURPOSE_get_count(); i++) { | ||
254 | const X509_PURPOSE *ptmp = X509_PURPOSE_get0(i); | ||
255 | fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp), | ||
256 | X509_PURPOSE_get0_name(ptmp)); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | int | ||
261 | verify_main(int argc, char **argv) | ||
262 | { | ||
263 | STACK_OF(X509) *untrusted = NULL, *trusted = NULL; | ||
264 | STACK_OF(X509_CRL) *crls = NULL; | ||
265 | X509_STORE *cert_ctx = NULL; | ||
266 | X509_LOOKUP *lookup = NULL; | ||
267 | char **cert_files = NULL; | ||
268 | int argsused; | ||
269 | int ret = 1; | ||
270 | |||
271 | if (pledge("stdio rpath", NULL) == -1) { | ||
272 | perror("pledge"); | ||
273 | exit(1); | ||
274 | } | ||
275 | |||
276 | memset(&cfg, 0, sizeof(cfg)); | ||
277 | |||
278 | if (options_parse(argc, argv, verify_options, NULL, &argsused) != 0) { | ||
279 | verify_usage(); | ||
280 | goto end; | ||
281 | } | ||
282 | |||
283 | if (argsused < argc) | ||
284 | cert_files = &argv[argsused]; | ||
285 | |||
286 | cert_ctx = X509_STORE_new(); | ||
287 | if (cert_ctx == NULL) | ||
288 | goto end; | ||
289 | X509_STORE_set_verify_cb(cert_ctx, cb); | ||
290 | |||
291 | if (cfg.vpm) | ||
292 | X509_STORE_set1_param(cert_ctx, cfg.vpm); | ||
293 | |||
294 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); | ||
295 | if (lookup == NULL) | ||
296 | abort(); /* XXX */ | ||
297 | if (cfg.CAfile) { | ||
298 | if (!X509_LOOKUP_load_file(lookup, cfg.CAfile, | ||
299 | X509_FILETYPE_PEM)) { | ||
300 | BIO_printf(bio_err, "Error loading file %s\n", | ||
301 | cfg.CAfile); | ||
302 | ERR_print_errors(bio_err); | ||
303 | goto end; | ||
304 | } | ||
305 | } else | ||
306 | X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); | ||
307 | |||
308 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); | ||
309 | if (lookup == NULL) | ||
310 | abort(); /* XXX */ | ||
311 | if (cfg.CApath) { | ||
312 | if (!X509_LOOKUP_add_dir(lookup, cfg.CApath, | ||
313 | X509_FILETYPE_PEM)) { | ||
314 | BIO_printf(bio_err, "Error loading directory %s\n", | ||
315 | cfg.CApath); | ||
316 | ERR_print_errors(bio_err); | ||
317 | goto end; | ||
318 | } | ||
319 | } else | ||
320 | X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); | ||
321 | |||
322 | ERR_clear_error(); | ||
323 | |||
324 | if (cfg.untfile) { | ||
325 | untrusted = load_certs(bio_err, cfg.untfile, | ||
326 | FORMAT_PEM, NULL, "untrusted certificates"); | ||
327 | if (!untrusted) | ||
328 | goto end; | ||
329 | } | ||
330 | if (cfg.trustfile) { | ||
331 | trusted = load_certs(bio_err, cfg.trustfile, | ||
332 | FORMAT_PEM, NULL, "trusted certificates"); | ||
333 | if (!trusted) | ||
334 | goto end; | ||
335 | } | ||
336 | if (cfg.crlfile) { | ||
337 | crls = load_crls(bio_err, cfg.crlfile, FORMAT_PEM, | ||
338 | NULL, "other CRLs"); | ||
339 | if (!crls) | ||
340 | goto end; | ||
341 | } | ||
342 | ret = 0; | ||
343 | if (cert_files == NULL) { | ||
344 | if (1 != check(cert_ctx, NULL, untrusted, trusted, crls)) | ||
345 | ret = -1; | ||
346 | } else { | ||
347 | do { | ||
348 | if (1 != check(cert_ctx, *cert_files++, untrusted, | ||
349 | trusted, crls)) | ||
350 | ret = -1; | ||
351 | } while (*cert_files != NULL); | ||
352 | } | ||
353 | |||
354 | end: | ||
355 | if (cfg.vpm) | ||
356 | X509_VERIFY_PARAM_free(cfg.vpm); | ||
357 | if (cert_ctx != NULL) | ||
358 | X509_STORE_free(cert_ctx); | ||
359 | sk_X509_pop_free(untrusted, X509_free); | ||
360 | sk_X509_pop_free(trusted, X509_free); | ||
361 | sk_X509_CRL_pop_free(crls, X509_CRL_free); | ||
362 | |||
363 | return (ret < 0 ? 2 : ret); | ||
364 | } | ||
365 | |||
366 | static int | ||
367 | check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain, | ||
368 | STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls) | ||
369 | { | ||
370 | X509 *x = NULL; | ||
371 | X509_STORE_CTX *csc = NULL; | ||
372 | const char *certfile = (file == NULL) ? "stdin" : file; | ||
373 | int verify_err; | ||
374 | int i = 0, ret = 0; | ||
375 | |||
376 | x = load_cert(bio_err, file, FORMAT_PEM, NULL, "certificate file"); | ||
377 | if (x == NULL) | ||
378 | goto end; | ||
379 | |||
380 | if ((csc = X509_STORE_CTX_new()) == NULL) | ||
381 | goto end; | ||
382 | X509_STORE_set_flags(ctx, vflags); | ||
383 | if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) | ||
384 | goto end; | ||
385 | if (tchain) | ||
386 | X509_STORE_CTX_trusted_stack(csc, tchain); | ||
387 | if (crls) | ||
388 | X509_STORE_CTX_set0_crls(csc, crls); | ||
389 | |||
390 | i = X509_verify_cert(csc); | ||
391 | verify_err = X509_STORE_CTX_get_error(csc); | ||
392 | |||
393 | if (i > 0 && verify_err == X509_V_OK) { | ||
394 | fprintf(stdout, "%s: OK\n", certfile); | ||
395 | ret = 1; | ||
396 | } else { | ||
397 | fprintf(stdout, "%s: verification failed: %d (%s)\n", certfile, | ||
398 | verify_err, X509_verify_cert_error_string(verify_err)); | ||
399 | } | ||
400 | |||
401 | end: | ||
402 | if (i <= 0) | ||
403 | ERR_print_errors(bio_err); | ||
404 | X509_free(x); | ||
405 | X509_STORE_CTX_free(csc); | ||
406 | |||
407 | return (ret); | ||
408 | } | ||
409 | |||
410 | static int | ||
411 | cb(int ok, X509_STORE_CTX *ctx) | ||
412 | { | ||
413 | int cert_error = X509_STORE_CTX_get_error(ctx); | ||
414 | X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx); | ||
415 | |||
416 | if (!ok) { | ||
417 | if (current_cert) { | ||
418 | X509_NAME_print_ex_fp(stdout, | ||
419 | X509_get_subject_name(current_cert), | ||
420 | 0, XN_FLAG_ONELINE); | ||
421 | printf("\n"); | ||
422 | } | ||
423 | printf("%serror %d at %d depth lookup:%s\n", | ||
424 | X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "", | ||
425 | cert_error, | ||
426 | X509_STORE_CTX_get_error_depth(ctx), | ||
427 | X509_verify_cert_error_string(cert_error)); | ||
428 | switch (cert_error) { | ||
429 | case X509_V_ERR_NO_EXPLICIT_POLICY: | ||
430 | case X509_V_ERR_CERT_HAS_EXPIRED: | ||
431 | |||
432 | /* | ||
433 | * since we are just checking the certificates, it is | ||
434 | * ok if they are self signed. But we should still | ||
435 | * warn the user. | ||
436 | */ | ||
437 | |||
438 | case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: | ||
439 | /* Continue after extension errors too */ | ||
440 | case X509_V_ERR_INVALID_CA: | ||
441 | case X509_V_ERR_INVALID_NON_CA: | ||
442 | case X509_V_ERR_PATH_LENGTH_EXCEEDED: | ||
443 | case X509_V_ERR_INVALID_PURPOSE: | ||
444 | case X509_V_ERR_CRL_HAS_EXPIRED: | ||
445 | case X509_V_ERR_CRL_NOT_YET_VALID: | ||
446 | case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: | ||
447 | ok = 1; | ||
448 | |||
449 | } | ||
450 | |||
451 | return ok; | ||
452 | |||
453 | } | ||
454 | if (!cfg.verbose) | ||
455 | ERR_clear_error(); | ||
456 | return (ok); | ||
457 | } | ||