-
- if (vpm)
- X509_STORE_set1_param(cert_ctx, vpm);
-
- lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_file());
- if (lookup == NULL) abort();
- if (CAfile) {
- i=X509_LOOKUP_load_file(lookup,CAfile,X509_FILETYPE_PEM);
- if(!i) {
- BIO_printf(bio_err, "Error loading file %s\n", CAfile);
- ERR_print_errors(bio_err);
- goto end;
- }
- } else X509_LOOKUP_load_file(lookup,NULL,X509_FILETYPE_DEFAULT);
-
- lookup=X509_STORE_add_lookup(cert_ctx,X509_LOOKUP_hash_dir());
- if (lookup == NULL) abort();
- if (CApath) {
- i=X509_LOOKUP_add_dir(lookup,CApath,X509_FILETYPE_PEM);
- if(!i) {
- BIO_printf(bio_err, "Error loading directory %s\n", CApath);
- ERR_print_errors(bio_err);
- goto end;
- }
- } else X509_LOOKUP_add_dir(lookup,NULL,X509_FILETYPE_DEFAULT);
-
- ERR_clear_error();
-
- if(untfile)
- {
- untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
- NULL, e, "untrusted certificates");
- if(!untrusted)
- goto end;
- }
-
- if(trustfile)
- {
- trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
- NULL, e, "trusted certificates");
- if(!trusted)
- goto end;
- }
-
- if(crlfile)
- {
- crls = load_crls(bio_err, crlfile, FORMAT_PEM,
- NULL, e, "other CRLs");
- if(!crls)
- goto end;
- }
-
- if (argc < 1) check(cert_ctx, NULL, untrusted, trusted, crls, e);
- else
- for (i=0; i<argc; i++)
- check(cert_ctx,argv[i], untrusted, trusted, crls, e);
- ret=0;
-end:
- if (ret == 1) {
- BIO_printf(bio_err,"usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
-#ifndef OPENSSL_NO_ENGINE
- BIO_printf(bio_err," [-engine e]");
-#endif
- BIO_printf(bio_err," cert1 cert2 ...\n");
-
- BIO_printf(bio_err,"recognized usages:\n");
- for(i = 0; i < X509_PURPOSE_get_count(); i++)
- {
- X509_PURPOSE *ptmp;
- ptmp = X509_PURPOSE_get0(i);
- BIO_printf(bio_err, "\t%-10s\t%s\n",
- X509_PURPOSE_get0_sname(ptmp),
- X509_PURPOSE_get0_name(ptmp));
- }
-
- BIO_printf(bio_err,"recognized verify names:\n");
- for(i = 0; i < X509_VERIFY_PARAM_get_count(); i++)
- {
- const X509_VERIFY_PARAM *vptmp;
- vptmp = X509_VERIFY_PARAM_get0(i);
- BIO_printf(bio_err, "\t%-10s\n",
- X509_VERIFY_PARAM_get0_name(vptmp));
- }
-
- }
- if (vpm) X509_VERIFY_PARAM_free(vpm);
- if (cert_ctx != NULL) X509_STORE_free(cert_ctx);
- sk_X509_pop_free(untrusted, X509_free);
- sk_X509_pop_free(trusted, X509_free);
- sk_X509_CRL_pop_free(crls, X509_CRL_free);
- apps_shutdown();
- OPENSSL_EXIT(ret);
- }
-
-static int check(X509_STORE *ctx, char *file,
- STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
- STACK_OF(X509_CRL) *crls, ENGINE *e)
- {
- X509 *x=NULL;
- int i=0,ret=0;
- X509_STORE_CTX *csc;
-
- x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file");
- if (x == NULL)
- goto end;
- fprintf(stdout,"%s: ",(file == NULL)?"stdin":file);
-
- csc = X509_STORE_CTX_new();
- if (csc == NULL)
- {
- ERR_print_errors(bio_err);
- goto end;
- }
- X509_STORE_set_flags(ctx, vflags);
- if(!X509_STORE_CTX_init(csc,ctx,x,uchain))
- {
- ERR_print_errors(bio_err);
- goto end;
- }
- if(tchain) X509_STORE_CTX_trusted_stack(csc, tchain);
- if (crls)
- X509_STORE_CTX_set0_crls(csc, crls);
- i=X509_verify_cert(csc);
- X509_STORE_CTX_free(csc);
-
- ret=0;
-end:
- if (i > 0)
- {
- fprintf(stdout,"OK\n");
- ret=1;
- }
- else
- ERR_print_errors(bio_err);
- if (x != NULL) X509_free(x);
-
- return(ret);
- }
-
-static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx)
- {
- int cert_error = X509_STORE_CTX_get_error(ctx);
- X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
-
- if (!ok)
- {
- if (current_cert)
- {
- X509_NAME_print_ex_fp(stdout,
- X509_get_subject_name(current_cert),
- 0, XN_FLAG_ONELINE);
- printf("\n");
- }
- printf("%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(NULL, 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_INVALID_NON_CA:
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
- case X509_V_ERR_INVALID_PURPOSE:
- case X509_V_ERR_CRL_HAS_EXPIRED:
- case X509_V_ERR_CRL_NOT_YET_VALID:
- case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
- ok = 1;
-
- case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
- ok = 1;
-
- }
-
- return ok;
-
- }
- if (cert_error == X509_V_OK && ok == 2)
- policies_print(NULL, ctx);
- if (!v_verbose)
- ERR_clear_error();
- return(ok);
- }
+ }
+
+ csc = X509_STORE_CTX_new();
+ if (csc == NULL) {
+ printf("error %s: X.509 store context allocation failed\n",
+ (file == NULL) ? "stdin" : file);
+ goto end;
+ }
+
+ X509_STORE_set_flags(ctx, vflags);
+ if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
+ X509_STORE_CTX_free(csc);
+ printf("error %s: X.509 store context initialization failed\n",
+ (file == NULL) ? "stdin" : file);
+ goto end;
+ }
+ if (tchain != NULL)
+ X509_STORE_CTX_set0_trusted_stack(csc, tchain);
+ if (crls != NULL)
+ X509_STORE_CTX_set0_crls(csc, crls);
+ i = X509_verify_cert(csc);
+ if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
+ printf("%s: OK\n", (file == NULL) ? "stdin" : file);
+ ret = 1;
+ 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, get_nameopt());
+ if (j < num_untrusted)
+ printf(" (untrusted)");
+ printf("\n");
+ }
+ sk_X509_pop_free(chain, X509_free);
+ }
+ } else {
+ printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file);
+ }
+ X509_STORE_CTX_free(csc);
+
+ end:
+ if (i <= 0)
+ ERR_print_errors(bio_err);
+ X509_free(x);
+
+ return ret;
+}
+
+static int cb(int ok, X509_STORE_CTX *ctx)
+{
+ int cert_error = X509_STORE_CTX_get_error(ctx);
+ X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
+
+ if (!ok) {
+ if (current_cert != NULL) {
+ X509_NAME_print_ex(bio_err,
+ X509_get_subject_name(current_cert),
+ 0, get_nameopt());
+ BIO_printf(bio_err, "\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));
+
+ /*
+ * Pretend that some errors are ok, so they don't stop further
+ * processing of the certificate chain. Setting ok = 1 does this.
+ * After X509_verify_cert() is done, we verify that there were
+ * no actual errors, even if the returned value was positive.
+ */
+ switch (cert_error) {
+ case X509_V_ERR_NO_EXPLICIT_POLICY:
+ policies_print(ctx);
+ /* fall thru */
+ case X509_V_ERR_CERT_HAS_EXPIRED:
+ /* Continue even if the leaf is a self signed cert */
+ case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
+ /* Continue after extension errors too */
+ case X509_V_ERR_INVALID_CA:
+ case X509_V_ERR_INVALID_NON_CA:
+ case X509_V_ERR_PATH_LENGTH_EXCEEDED:
+ case X509_V_ERR_INVALID_PURPOSE:
+ case X509_V_ERR_CRL_HAS_EXPIRED:
+ 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(ctx);
+ if (!v_verbose)
+ ERR_clear_error();
+ return ok;
+}