diff --git a/apps/verify.c b/apps/verify.c index f6cea31f40..a823d58a75 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -244,6 +244,7 @@ static int check(X509_STORE *ctx, char *file, 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) @@ -265,8 +266,10 @@ static int check(X509_STORE *ctx, char *file, if (crls) X509_STORE_CTX_set0_crls(csc, crls); i = X509_verify_cert(csc); - if (i > 0 && show_chain) + if (i > 0 && show_chain) { chain = X509_STORE_CTX_get1_chain(csc); + num_untrusted = X509_STORE_CTX_get_num_untrusted(csc); + } X509_STORE_CTX_free(csc); ret = 0; @@ -284,6 +287,9 @@ static int check(X509_STORE *ctx, char *file, X509_NAME_print_ex_fp(stdout, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE); + if (i < num_untrusted) { + printf(" (untrusted)"); + } printf("\n"); } sk_X509_pop_free(chain, X509_free); diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 7222113c68..df012ddeb0 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -2452,6 +2452,11 @@ int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) return ctx->explicit_policy; } +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->last_untrusted; +} + int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) { const X509_VERIFY_PARAM *param; diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod index 242b9ee9fa..9cc7fcb817 100644 --- a/doc/apps/verify.pod +++ b/doc/apps/verify.pod @@ -42,6 +42,7 @@ B B [B<-verify_ip ip>] [B<-verify_name name>] [B<-x509_strict>] +[B<-show_chain>] [B<->] [certificates] @@ -227,6 +228,12 @@ Supported usages include: default, pkcs7, smime_sign, ssl_client, ssl_server. For strict X.509 compliance, disable non-compliant workarounds for broken certificates. +=item B<-show_chain> + +Display information about the certificate chain that has been built (if +successful). Certificates in the chain that came from the untrusted list will be +flagged as "untrusted". + =item B<-> Indicates the last option. All arguments following this are assumed to be @@ -491,6 +498,6 @@ L =head1 HISTORY -The -no_alt_chains options was first added to OpenSSL 1.1.0. +The -show_chain option was first added to OpenSSL 1.1.0. =cut diff --git a/doc/crypto/X509_STORE_CTX_new.pod b/doc/crypto/X509_STORE_CTX_new.pod index 7c154572ec..f8907d7ebb 100644 --- a/doc/crypto/X509_STORE_CTX_new.pod +++ b/doc/crypto/X509_STORE_CTX_new.pod @@ -25,6 +25,8 @@ X509_STORE_CTX_new, X509_STORE_CTX_cleanup, X509_STORE_CTX_free, X509_STORE_CTX_ void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); + =head1 DESCRIPTION These functions initialise an B structure for subsequent use @@ -76,6 +78,9 @@ X509_STORE_CTX_set_default() looks up and sets the default verification method to B. This uses the function X509_VERIFY_PARAM_lookup() to find an appropriate set of parameters from B. +X509_STORE_CTX_get_num_untrusted() returns the number of untrusted certificates +that were used in building the chain following a call to X509_verify_cert(). + =head1 NOTES The certificates and CRLs in a store are used internally and should B @@ -116,6 +121,9 @@ values. X509_STORE_CTX_set_default() returns 1 for success or 0 if an error occurred. +X509_STORE_CTX_get_num_untrusted() returns the number of untrusted certificates +used. + =head1 SEE ALSO L @@ -124,5 +132,6 @@ L =head1 HISTORY X509_STORE_CTX_set0_crls() was first added to OpenSSL 1.0.0 +X509_STORE_CTX_get_num_untrusted() was first added to OpenSSL 1.1.0 =cut diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h index 4ad20296f8..8e0a225400 100644 --- a/include/openssl/x509_vfy.h +++ b/include/openssl/x509_vfy.h @@ -528,6 +528,7 @@ void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_num_untrusted(X509_STORE_CTX *ctx); X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);