diff options
Diffstat (limited to 'src')
| -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 | } |
