typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
- OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_UNTRUSTED, OPT_TRUSTED,
- OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
+ OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
+ OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
OPT_V_ENUM,
OPT_VERBOSE
} OPTION_CHOICE;
{OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
{OPT_HELP_STR, 1, '-', "Valid options are:\n"},
{"help", OPT_HELP, '-', "Display this summary"},
- {"verbose", OPT_VERBOSE, '-'},
- {"CApath", OPT_CAPATH, '/'},
- {"CAfile", OPT_CAFILE, '<'},
- {"untrusted", OPT_UNTRUSTED, '<'},
- {"trusted", OPT_TRUSTED, '<'},
- {"CRLfile", OPT_CRLFILE, '<'},
- {"crl_download", OPT_CRL_DOWNLOAD, '-'},
- {"show_chain", OPT_SHOW_CHAIN, '-'},
+ {"verbose", OPT_VERBOSE, '-',
+ "Print extra information about the operations being performed."},
+ {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"},
+ {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"},
+ {"no-CAfile", OPT_NOCAFILE, '-',
+ "Do not load the default certificates file"},
+ {"no-CApath", OPT_NOCAPATH, '-',
+ "Do not load certificates from the default certificates directory"},
+ {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"},
+ {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"},
+ {"CRLfile", OPT_CRLFILE, '<',
+ "File containing one or more CRL's (in PEM format) to load"},
+ {"crl_download", OPT_CRL_DOWNLOAD, '-',
+ "Attempt to download CRL information for this certificate"},
+ {"show_chain", OPT_SHOW_CHAIN, '-',
+ "Display information about the certificate chain"},
+ OPT_V_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
#endif
- OPT_V_OPTIONS,
{NULL}
};
X509_STORE *store = NULL;
X509_VERIFY_PARAM *vpm = NULL;
char *prog, *CApath = NULL, *CAfile = NULL;
+ int noCApath = 0, noCAfile = 0;
char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
OPTION_CHOICE o;
case OPT_CAFILE:
CAfile = opt_arg();
break;
+ case OPT_NOCAPATH:
+ noCApath = 1;
+ break;
+ case OPT_NOCAFILE:
+ noCAfile = 1;
+ break;
case OPT_UNTRUSTED:
untfile = opt_arg();
break;
}
argc = opt_num_rest();
argv = opt_rest();
+ if (trustfile && (CAfile || CApath)) {
+ BIO_printf(bio_err,
+ "%s: Cannot use -trusted with -CAfile or -CApath\n",
+ prog);
+ goto end;
+ }
- if (!(store = setup_verify(CAfile, CApath)))
+ if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
goto end;
X509_STORE_set_verify_cb(store, cb);
}
end:
- if (vpm)
- X509_VERIFY_PARAM_free(vpm);
- if (store != NULL)
- X509_STORE_free(store);
+ X509_VERIFY_PARAM_free(vpm);
+ X509_STORE_free(store);
sk_X509_pop_free(untrusted, X509_free);
sk_X509_pop_free(trusted, X509_free);
sk_X509_CRL_pop_free(crls, X509_CRL_free);
int i = 0, ret = 0;
X509_STORE_CTX *csc;
STACK_OF(X509) *chain = NULL;
+ int num_untrusted;
x = load_cert(file, FORMAT_PEM, NULL, e, "certificate file");
if (x == NULL)
if (crls)
X509_STORE_CTX_set0_crls(csc, crls);
i = X509_verify_cert(csc);
- if (i > 0 && show_chain)
- chain = X509_STORE_CTX_get1_chain(csc);
- X509_STORE_CTX_free(csc);
-
- ret = 0;
- end:
if (i > 0) {
printf("OK\n");
ret = 1;
- } else
- ERR_print_errors(bio_err);
- if (chain) {
- printf("Chain:\n");
- for (i = 0; i < sk_X509_num(chain); i++) {
- X509 *cert = sk_X509_value(chain, i);
- printf("depth=%d: ", i);
- X509_NAME_print_ex_fp(stdout,
- X509_get_subject_name(cert),
- 0, XN_FLAG_ONELINE);
- printf("\n");
- }
- sk_X509_pop_free(chain, X509_free);
+ if (show_chain) {
+ int j;
+
+ chain = X509_STORE_CTX_get1_chain(csc);
+ num_untrusted = X509_STORE_CTX_get_num_untrusted(csc);
+ printf("Chain:\n");
+ for (j = 0; j < sk_X509_num(chain); j++) {
+ X509 *cert = sk_X509_value(chain, j);
+ printf("depth=%d: ", j);
+ X509_NAME_print_ex_fp(stdout,
+ X509_get_subject_name(cert),
+ 0, XN_FLAG_ONELINE);
+ if (j < num_untrusted)
+ printf(" (untrusted)");
+ printf("\n");
+ }
+ sk_X509_pop_free(chain, X509_free);
+ }
}
- if (x != NULL)
- X509_free(x);
+ X509_STORE_CTX_free(csc);
- return (ret);
+ end:
+ if (i <= 0)
+ ERR_print_errors(bio_err);
+ X509_free(x);
+
+ return ret;
}
static int cb(int ok, X509_STORE_CTX *ctx)
if (!ok) {
if (current_cert) {
- X509_NAME_print_ex_fp(stdout,
- X509_get_subject_name(current_cert),
- 0, XN_FLAG_ONELINE);
- printf("\n");
+ X509_NAME_print_ex(bio_err,
+ X509_get_subject_name(current_cert),
+ 0, XN_FLAG_ONELINE);
+ BIO_printf(bio_err, "\n");
}
- printf("%serror %d at %d depth lookup:%s\n",
+ BIO_printf(bio_err, "%serror %d at %d depth lookup:%s\n",
X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
cert_error,
X509_STORE_CTX_get_error_depth(ctx),
X509_verify_cert_error_string(cert_error));
switch (cert_error) {
case X509_V_ERR_NO_EXPLICIT_POLICY:
- policies_print(bio_err, ctx);
+ policies_print(ctx);
case X509_V_ERR_CERT_HAS_EXPIRED:
/*
* since we are just checking the certificates, it is ok if they
* are self signed. But we should still warn the user.
*/
-
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
/* Continue after extension errors too */
case X509_V_ERR_INVALID_CA:
case X509_V_ERR_CRL_NOT_YET_VALID:
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
ok = 1;
-
}
return ok;
}
if (cert_error == X509_V_OK && ok == 2)
- policies_print(bio_out, ctx);
+ policies_print(ctx);
if (!v_verbose)
ERR_clear_error();
return (ok);