diff options
author | jsing <> | 2020-07-14 19:08:30 +0000 |
---|---|---|
committer | jsing <> | 2020-07-14 19:08:30 +0000 |
commit | 169f8c3b88d5219a4a6f00dd3335d337ce82c8bb (patch) | |
tree | 3c4bedc392c07c6bb915e1e35aec2e36b400cf6d /src/usr.bin/openssl/verify.c | |
parent | ef9e219c0f3e7bb1b407f5c40535bc494508797e (diff) | |
download | openbsd-169f8c3b88d5219a4a6f00dd3335d337ce82c8bb.tar.gz openbsd-169f8c3b88d5219a4a6f00dd3335d337ce82c8bb.tar.bz2 openbsd-169f8c3b88d5219a4a6f00dd3335d337ce82c8bb.zip |
Convert option handling for openssl(1) verify.
ok inoguchi@, tb@
Diffstat (limited to 'src/usr.bin/openssl/verify.c')
-rw-r--r-- | src/usr.bin/openssl/verify.c | 308 |
1 files changed, 220 insertions, 88 deletions
diff --git a/src/usr.bin/openssl/verify.c b/src/usr.bin/openssl/verify.c index f616e3c440..3da41b917a 100644 --- a/src/usr.bin/openssl/verify.c +++ b/src/usr.bin/openssl/verify.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: verify.c,v 1.7 2018/02/07 05:47:55 jsing Exp $ */ | 1 | /* $OpenBSD: verify.c,v 1.8 2020/07/14 19:08:30 jsing Exp $ */ |
2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
3 | * All rights reserved. | 3 | * All rights reserved. |
4 | * | 4 | * |
@@ -71,19 +71,198 @@ | |||
71 | static int cb(int ok, X509_STORE_CTX * ctx); | 71 | static int cb(int ok, X509_STORE_CTX * ctx); |
72 | static int check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain, | 72 | static int check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain, |
73 | STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls); | 73 | STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls); |
74 | static int v_verbose = 0, vflags = 0; | 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 | } verify_config; | ||
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, &verify_config.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 = &verify_config.CAfile, | ||
109 | }, | ||
110 | { | ||
111 | .name = "CApath", | ||
112 | .argname = "path", | ||
113 | .desc = "Certificate Authority path", | ||
114 | .type = OPTION_ARG, | ||
115 | .opt.arg = &verify_config.CApath, | ||
116 | }, | ||
117 | { | ||
118 | .name = "CRLfile", | ||
119 | .argname = "file", | ||
120 | .desc = "Certificate Revocation List file", | ||
121 | .type = OPTION_ARG, | ||
122 | .opt.arg = &verify_config.crlfile, | ||
123 | }, | ||
124 | { | ||
125 | .name = "trusted", | ||
126 | .argname = "file", | ||
127 | .desc = "Trusted certificates file", | ||
128 | .type = OPTION_ARG, | ||
129 | .opt.arg = &verify_config.trustfile, | ||
130 | }, | ||
131 | { | ||
132 | .name = "untrusted", | ||
133 | .argname = "file", | ||
134 | .desc = "Untrusted certificates file", | ||
135 | .type = OPTION_ARG, | ||
136 | .opt.arg = &verify_config.untfile, | ||
137 | }, | ||
138 | { | ||
139 | .name = "verbose", | ||
140 | .desc = "Verbose", | ||
141 | .type = OPTION_FLAG, | ||
142 | .opt.flag = &verify_config.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 = "policy", | ||
197 | .argname = "name", | ||
198 | .desc = "Add given policy to the acceptable set", | ||
199 | }, | ||
200 | { | ||
201 | .name = "policy_check", | ||
202 | .desc = "Enable certificate policy checking", | ||
203 | }, | ||
204 | { | ||
205 | .name = "policy_print", | ||
206 | .desc = "Print policy", | ||
207 | }, | ||
208 | { | ||
209 | .name = "purpose", | ||
210 | .argname = "name", | ||
211 | .desc = "Verify for the given purpose", | ||
212 | }, | ||
213 | { | ||
214 | .name = "use_deltas", | ||
215 | .desc = "Use delta CRLS (if present)", | ||
216 | }, | ||
217 | { | ||
218 | .name = "verify_depth", | ||
219 | .argname = "num", | ||
220 | .desc = "Limit verification to the given depth", | ||
221 | }, | ||
222 | { | ||
223 | .name = "x509_strict", | ||
224 | .desc = "Use strict X.509 rules (disables workarounds)", | ||
225 | }, | ||
226 | { NULL }, | ||
227 | }; | ||
228 | |||
229 | static void | ||
230 | verify_usage(void) | ||
231 | { | ||
232 | int i; | ||
233 | |||
234 | fprintf(stderr, | ||
235 | "usage: verify [-CAfile file] [-CApath directory] [-check_ss_sig]\n" | ||
236 | " [-CRLfile file] [-crl_check] [-crl_check_all]\n" | ||
237 | " [-explicit_policy] [-extended_crl]\n" | ||
238 | " [-ignore_critical] [-inhibit_any] [-inhibit_map]\n" | ||
239 | " [-issuer_checks] [-policy_check] [-purpose purpose]\n" | ||
240 | " [-trusted file] [-untrusted file] [-verbose]\n" | ||
241 | " [-x509_strict] [certificates]\n\n"); | ||
242 | |||
243 | options_usage(verify_options); | ||
244 | |||
245 | fprintf(stderr, "\nVerification options:\n\n"); | ||
246 | options_usage(verify_shared_options); | ||
247 | |||
248 | fprintf(stderr, "\nValid purposes:\n\n"); | ||
249 | for (i = 0; i < X509_PURPOSE_get_count(); i++) { | ||
250 | X509_PURPOSE *ptmp = X509_PURPOSE_get0(i); | ||
251 | fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp), | ||
252 | X509_PURPOSE_get0_name(ptmp)); | ||
253 | } | ||
254 | } | ||
75 | 255 | ||
76 | int | 256 | int |
77 | verify_main(int argc, char **argv) | 257 | verify_main(int argc, char **argv) |
78 | { | 258 | { |
79 | int i, ret = 1, badarg = 0; | 259 | int i, ret = 1; |
80 | char *CApath = NULL, *CAfile = NULL; | 260 | STACK_OF(X509) *untrusted = NULL, *trusted = NULL; |
81 | char *untfile = NULL, *trustfile = NULL, *crlfile = NULL; | 261 | STACK_OF(X509_CRL) *crls = NULL; |
82 | STACK_OF(X509) * untrusted = NULL, *trusted = NULL; | ||
83 | STACK_OF(X509_CRL) * crls = NULL; | ||
84 | X509_STORE *cert_ctx = NULL; | 262 | X509_STORE *cert_ctx = NULL; |
85 | X509_LOOKUP *lookup = NULL; | 263 | X509_LOOKUP *lookup = NULL; |
86 | X509_VERIFY_PARAM *vpm = NULL; | 264 | char **cert_files = NULL; |
265 | int argsused; | ||
87 | 266 | ||
88 | if (single_execution) { | 267 | if (single_execution) { |
89 | if (pledge("stdio rpath", NULL) == -1) { | 268 | if (pledge("stdio rpath", NULL) == -1) { |
@@ -92,65 +271,31 @@ verify_main(int argc, char **argv) | |||
92 | } | 271 | } |
93 | } | 272 | } |
94 | 273 | ||
274 | memset(&verify_config, 0, sizeof(verify_config)); | ||
275 | |||
276 | if (options_parse(argc, argv, verify_options, NULL, &argsused) != 0) { | ||
277 | verify_usage(); | ||
278 | goto end; | ||
279 | } | ||
280 | |||
281 | if (argsused < argc) | ||
282 | cert_files = &argv[argsused]; | ||
283 | |||
95 | cert_ctx = X509_STORE_new(); | 284 | cert_ctx = X509_STORE_new(); |
96 | if (cert_ctx == NULL) | 285 | if (cert_ctx == NULL) |
97 | goto end; | 286 | goto end; |
98 | X509_STORE_set_verify_cb(cert_ctx, cb); | 287 | X509_STORE_set_verify_cb(cert_ctx, cb); |
99 | 288 | ||
100 | argc--; | 289 | if (verify_config.vpm) |
101 | argv++; | 290 | X509_STORE_set1_param(cert_ctx, verify_config.vpm); |
102 | for (;;) { | ||
103 | if (argc >= 1) { | ||
104 | if (strcmp(*argv, "-CApath") == 0) { | ||
105 | if (argc-- < 1) | ||
106 | goto end; | ||
107 | CApath = *(++argv); | ||
108 | } else if (strcmp(*argv, "-CAfile") == 0) { | ||
109 | if (argc-- < 1) | ||
110 | goto end; | ||
111 | CAfile = *(++argv); | ||
112 | } else if (args_verify(&argv, &argc, &badarg, bio_err, | ||
113 | &vpm)) { | ||
114 | if (badarg) | ||
115 | goto end; | ||
116 | continue; | ||
117 | } else if (strcmp(*argv, "-untrusted") == 0) { | ||
118 | if (argc-- < 1) | ||
119 | goto end; | ||
120 | untfile = *(++argv); | ||
121 | } else if (strcmp(*argv, "-trusted") == 0) { | ||
122 | if (argc-- < 1) | ||
123 | goto end; | ||
124 | trustfile = *(++argv); | ||
125 | } else if (strcmp(*argv, "-CRLfile") == 0) { | ||
126 | if (argc-- < 1) | ||
127 | goto end; | ||
128 | crlfile = *(++argv); | ||
129 | } | ||
130 | else if (strcmp(*argv, "-help") == 0) | ||
131 | goto end; | ||
132 | else if (strcmp(*argv, "-verbose") == 0) | ||
133 | v_verbose = 1; | ||
134 | else if (argv[0][0] == '-') | ||
135 | goto end; | ||
136 | else | ||
137 | break; | ||
138 | argc--; | ||
139 | argv++; | ||
140 | } else | ||
141 | break; | ||
142 | } | ||
143 | |||
144 | if (vpm) | ||
145 | X509_STORE_set1_param(cert_ctx, vpm); | ||
146 | 291 | ||
147 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); | 292 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file()); |
148 | if (lookup == NULL) | 293 | if (lookup == NULL) |
149 | abort(); | 294 | abort(); /* XXX */ |
150 | if (CAfile) { | 295 | if (verify_config.CAfile) { |
151 | i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM); | 296 | i = X509_LOOKUP_load_file(lookup, verify_config.CAfile, X509_FILETYPE_PEM); |
152 | if (!i) { | 297 | if (!i) { |
153 | BIO_printf(bio_err, "Error loading file %s\n", CAfile); | 298 | BIO_printf(bio_err, "Error loading file %s\n", verify_config.CAfile); |
154 | ERR_print_errors(bio_err); | 299 | ERR_print_errors(bio_err); |
155 | goto end; | 300 | goto end; |
156 | } | 301 | } |
@@ -159,11 +304,11 @@ verify_main(int argc, char **argv) | |||
159 | 304 | ||
160 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); | 305 | lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir()); |
161 | if (lookup == NULL) | 306 | if (lookup == NULL) |
162 | abort(); | 307 | abort(); /* XXX */ |
163 | if (CApath) { | 308 | if (verify_config.CApath) { |
164 | i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM); | 309 | i = X509_LOOKUP_add_dir(lookup, verify_config.CApath, X509_FILETYPE_PEM); |
165 | if (!i) { | 310 | if (!i) { |
166 | BIO_printf(bio_err, "Error loading directory %s\n", CApath); | 311 | BIO_printf(bio_err, "Error loading directory %s\n", verify_config.CApath); |
167 | ERR_print_errors(bio_err); | 312 | ERR_print_errors(bio_err); |
168 | goto end; | 313 | goto end; |
169 | } | 314 | } |
@@ -172,52 +317,39 @@ verify_main(int argc, char **argv) | |||
172 | 317 | ||
173 | ERR_clear_error(); | 318 | ERR_clear_error(); |
174 | 319 | ||
175 | if (untfile) { | 320 | if (verify_config.untfile) { |
176 | untrusted = load_certs(bio_err, untfile, FORMAT_PEM, | 321 | untrusted = load_certs(bio_err, verify_config.untfile, FORMAT_PEM, |
177 | NULL, "untrusted certificates"); | 322 | NULL, "untrusted certificates"); |
178 | if (!untrusted) | 323 | if (!untrusted) |
179 | goto end; | 324 | goto end; |
180 | } | 325 | } |
181 | if (trustfile) { | 326 | if (verify_config.trustfile) { |
182 | trusted = load_certs(bio_err, trustfile, FORMAT_PEM, | 327 | trusted = load_certs(bio_err, verify_config.trustfile, FORMAT_PEM, |
183 | NULL, "trusted certificates"); | 328 | NULL, "trusted certificates"); |
184 | if (!trusted) | 329 | if (!trusted) |
185 | goto end; | 330 | goto end; |
186 | } | 331 | } |
187 | if (crlfile) { | 332 | if (verify_config.crlfile) { |
188 | crls = load_crls(bio_err, crlfile, FORMAT_PEM, | 333 | crls = load_crls(bio_err, verify_config.crlfile, FORMAT_PEM, |
189 | NULL, "other CRLs"); | 334 | NULL, "other CRLs"); |
190 | if (!crls) | 335 | if (!crls) |
191 | goto end; | 336 | goto end; |
192 | } | 337 | } |
193 | ret = 0; | 338 | ret = 0; |
194 | if (argc < 1) { | 339 | if (cert_files == NULL) { |
195 | if (1 != check(cert_ctx, NULL, untrusted, trusted, crls)) | 340 | if (1 != check(cert_ctx, NULL, untrusted, trusted, crls)) |
196 | ret = -1; | 341 | ret = -1; |
197 | } else { | 342 | } else { |
198 | for (i = 0; i < argc; i++) | 343 | do { |
199 | if (1 != check(cert_ctx, argv[i], untrusted, trusted, | 344 | if (1 != check(cert_ctx, *cert_files++, untrusted, trusted, |
200 | crls)) | 345 | crls)) |
201 | ret = -1; | 346 | ret = -1; |
347 | } while (*cert_files != NULL); | ||
202 | } | 348 | } |
203 | 349 | ||
204 | end: | 350 | end: |
205 | if (ret == 1) { | 351 | if (verify_config.vpm) |
206 | BIO_printf(bio_err, "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]"); | 352 | X509_VERIFY_PARAM_free(verify_config.vpm); |
207 | BIO_printf(bio_err, " [-attime timestamp]"); | ||
208 | BIO_printf(bio_err, " cert1 cert2 ...\n"); | ||
209 | |||
210 | BIO_printf(bio_err, "recognized usages:\n"); | ||
211 | for (i = 0; i < X509_PURPOSE_get_count(); i++) { | ||
212 | X509_PURPOSE *ptmp; | ||
213 | ptmp = X509_PURPOSE_get0(i); | ||
214 | BIO_printf(bio_err, "\t%-10s\t%s\n", | ||
215 | X509_PURPOSE_get0_sname(ptmp), | ||
216 | X509_PURPOSE_get0_name(ptmp)); | ||
217 | } | ||
218 | } | ||
219 | if (vpm) | ||
220 | X509_VERIFY_PARAM_free(vpm); | ||
221 | if (cert_ctx != NULL) | 353 | if (cert_ctx != NULL) |
222 | X509_STORE_free(cert_ctx); | 354 | X509_STORE_free(cert_ctx); |
223 | sk_X509_pop_free(untrusted, X509_free); | 355 | sk_X509_pop_free(untrusted, X509_free); |
@@ -318,7 +450,7 @@ cb(int ok, X509_STORE_CTX * ctx) | |||
318 | } | 450 | } |
319 | if (cert_error == X509_V_OK && ok == 2) | 451 | if (cert_error == X509_V_OK && ok == 2) |
320 | policies_print(NULL, ctx); | 452 | policies_print(NULL, ctx); |
321 | if (!v_verbose) | 453 | if (!verify_config.verbose) |
322 | ERR_clear_error(); | 454 | ERR_clear_error(); |
323 | return (ok); | 455 | return (ok); |
324 | } | 456 | } |