From c431798e82c38855ac033e16b17d79ae18eaadaf Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Tue, 7 Sep 2004 18:38:46 +0000 Subject: [PATCH] Reformat smime utility. Add support for policy checking in verify utility. --- apps/apps.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-- apps/apps.h | 4 ++- apps/smime.c | 41 ++------------------------ apps/verify.c | 43 ++++++++++++++-------------- 4 files changed, 103 insertions(+), 64 deletions(-) diff --git a/apps/apps.c b/apps/apps.c index 6bc3562cdb..4121e47e9d 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -2141,10 +2141,14 @@ int WIN32_rename(char *from, char *to) } #endif -int args_verify(char ***pargs, int *badarg, BIO *err, X509_VERIFY_PARAM **pm) +int args_verify(char ***pargs, int *pargc, + int *badarg, BIO *err, X509_VERIFY_PARAM **pm) { ASN1_OBJECT *otmp = NULL; unsigned long flags = 0; + int i; + int purpose = 0; + char **oldargs = *pargs; char *arg = **pargs, *argn = (*pargs)[1]; if (!strcmp(arg, "-policy")) { @@ -2162,6 +2166,27 @@ int args_verify(char ***pargs, int *badarg, BIO *err, X509_VERIFY_PARAM **pm) } (*pargs)++; } + else if (strcmp(arg,"-purpose") == 0) + { + X509_PURPOSE *xptmp; + if (!argn) + *badarg = 1; + else + { + i = X509_PURPOSE_get_by_sname(argn); + if(i < 0) + { + BIO_printf(err, "unrecognized purpose\n"); + *badarg = 1; + } + else + { + xptmp = X509_PURPOSE_get0(i); + purpose = X509_PURPOSE_get_id(xptmp); + } + } + (*pargs)++; + } else if (!strcmp(arg, "-ignore_critical")) flags |= X509_V_FLAG_IGNORE_CRITICAL; else if (!strcmp(arg, "-issuer_checks")) @@ -2186,13 +2211,13 @@ int args_verify(char ***pargs, int *badarg, BIO *err, X509_VERIFY_PARAM **pm) if (*pm) X509_VERIFY_PARAM_free(*pm); *pm = NULL; - return 1; + goto end; } if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) { *badarg = 1; - return 1; + goto end; } if (otmp) @@ -2200,8 +2225,56 @@ int args_verify(char ***pargs, int *badarg, BIO *err, X509_VERIFY_PARAM **pm) if (flags) X509_VERIFY_PARAM_set_flags(*pm, flags); + if (purpose) + X509_VERIFY_PARAM_set_purpose(*pm, purpose); + + end: + (*pargs)++; + if (pargc) + *pargc -= *pargs - oldargs; + return 1; } + +static void nodes_print(BIO *out, char *name, STACK_OF(X509_POLICY_NODE) *nodes) + { + X509_POLICY_NODE *node; + int i; + BIO_printf(out, "%s Policies:", name); + if (nodes) + { + BIO_puts(out, "\n"); + for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) + { + node = sk_X509_POLICY_NODE_value(nodes, i); + X509_POLICY_NODE_print(out, node, 2); + } + } + else + BIO_puts(out, " \n"); + } + +void policies_print(BIO *out, X509_STORE_CTX *ctx) + { + X509_POLICY_TREE *tree; + int explicit_policy; + int free_out = 0; + if (out == NULL) + { + out = BIO_new_fp(stderr, BIO_NOCLOSE); + free_out = 1; + } + tree = X509_STORE_CTX_get0_policy_tree(ctx); + explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); + + BIO_printf(out, "Require explicit Policy: %s\n", + explicit_policy ? "True" : "False"); + + nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); + nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); + if (free_out) + BIO_free(out); + } diff --git a/apps/apps.h b/apps/apps.h index ede0c462fc..7d879637b7 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -317,7 +317,9 @@ int index_name_cmp(const char **a, const char **b); int parse_yesno(char *str, int def); X509_NAME *parse_name(char *str, long chtype, int multirdn); -int args_verify(char ***pargs, int *badarg, BIO *err, X509_VERIFY_PARAM **pm); +int args_verify(char ***pargs, int *pargc, + int *badarg, BIO *err, X509_VERIFY_PARAM **pm); +void policies_print(BIO *out, X509_STORE_CTX *ctx); #define FORMAT_UNDEF 0 #define FORMAT_ASN1 1 diff --git a/apps/smime.c b/apps/smime.c index 4e68643669..57ac6d8a26 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -365,7 +365,7 @@ int MAIN(int argc, char **argv) else badarg = 1; } - else if (args_verify(&args, &badarg, bio_err, &vpm)) + else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else badarg = 1; @@ -769,43 +769,10 @@ static int save_certs(char *signerfile, STACK_OF(X509) *signers) } -static void nodes_print(BIO *out, char *name, STACK_OF(X509_POLICY_NODE) *nodes) - { - X509_POLICY_NODE *node; - int i; - BIO_printf(out, "%s Policies:", name); - if (nodes) - { - BIO_puts(out, "\n"); - for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) - { - node = sk_X509_POLICY_NODE_value(nodes, i); - X509_POLICY_NODE_print(out, node, 2); - } - } - else - BIO_puts(out, " \n"); - } - -static void policies_print(BIO *out, X509_STORE_CTX *ctx) - { - X509_POLICY_TREE *tree; - int explicit_policy; - tree = X509_STORE_CTX_get0_policy_tree(ctx); - explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx); - - BIO_printf(out, "Require explicit Policy: %s\n", - explicit_policy ? "True" : "False"); - - nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree)); - nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree)); - } - /* Minimal callback just to output policy info (if any) */ static int smime_cb(int ok, X509_STORE_CTX *ctx) { - BIO *out; int error; error = X509_STORE_CTX_get_error(ctx); @@ -814,11 +781,7 @@ static int smime_cb(int ok, X509_STORE_CTX *ctx) && ((error != X509_V_OK) || (ok != 2))) return ok; - out = BIO_new_fp(stderr, BIO_NOCLOSE); - - policies_print(out, ctx); - - BIO_free(out); + policies_print(NULL, ctx); return ok; diff --git a/apps/verify.c b/apps/verify.c index 6a93c018b8..f7c85b8dd6 100644 --- a/apps/verify.c +++ b/apps/verify.c @@ -79,13 +79,14 @@ int MAIN(int, char **); int MAIN(int argc, char **argv) { ENGINE *e = NULL; - int i,ret=1; + int i,ret=1, badarg = 0; int purpose = -1; char *CApath=NULL,*CAfile=NULL; char *untfile = NULL, *trustfile = NULL; STACK_OF(X509) *untrusted = NULL, *trusted = NULL; X509_STORE *cert_ctx=NULL; X509_LOOKUP *lookup=NULL; + X509_VERIFY_PARAM *vpm = NULL; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif @@ -121,18 +122,12 @@ int MAIN(int argc, char **argv) if (argc-- < 1) goto end; CAfile= *(++argv); } - else if (strcmp(*argv,"-purpose") == 0) + else if (args_verify(&argv, &argc, &badarg, bio_err, + &vpm)) { - X509_PURPOSE *xptmp; - if (argc-- < 1) goto end; - i = X509_PURPOSE_get_by_sname(*(++argv)); - if(i < 0) - { - BIO_printf(bio_err, "unrecognized purpose\n"); + if (badarg) goto end; - } - xptmp = X509_PURPOSE_get0(i); - purpose = X509_PURPOSE_get_id(xptmp); + continue; } else if (strcmp(*argv,"-untrusted") == 0) { @@ -153,14 +148,6 @@ int MAIN(int argc, char **argv) #endif else if (strcmp(*argv,"-help") == 0) goto end; - else if (strcmp(*argv,"-ignore_critical") == 0) - vflags |= X509_V_FLAG_IGNORE_CRITICAL; - else if (strcmp(*argv,"-issuer_checks") == 0) - vflags |= X509_V_FLAG_CB_ISSUER_CHECK; - else if (strcmp(*argv,"-crl_check") == 0) - vflags |= X509_V_FLAG_CRL_CHECK; - else if (strcmp(*argv,"-crl_check_all") == 0) - vflags |= X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL; else if (strcmp(*argv,"-verbose") == 0) v_verbose=1; else if (argv[0][0] == '-') @@ -178,6 +165,9 @@ int MAIN(int argc, char **argv) e = setup_engine(bio_err, engine, 0); #endif + 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) { @@ -238,6 +228,7 @@ end: X509_PURPOSE_get0_name(ptmp)); } } + 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); @@ -339,10 +330,13 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) if (!ok) { - X509_NAME_oneline( + if (ctx->current_cert) + { + X509_NAME_oneline( X509_get_subject_name(ctx->current_cert),buf, sizeof buf); - printf("%s\n",buf); + printf("%s\n",buf); + } printf("error %d at %d depth lookup:%s\n",ctx->error, ctx->error_depth, X509_verify_cert_error_string(ctx->error)); @@ -360,7 +354,14 @@ static int MS_CALLBACK cb(int ok, X509_STORE_CTX *ctx) if (ctx->error == X509_V_ERR_CRL_HAS_EXPIRED) ok=1; if (ctx->error == X509_V_ERR_CRL_NOT_YET_VALID) ok=1; if (ctx->error == X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION) ok=1; + + if (ctx->error == X509_V_ERR_NO_EXPLICIT_POLICY) + policies_print(NULL, ctx); + return ok; + } + if ((ctx->error == X509_V_OK) && (ok == 2)) + policies_print(NULL, ctx); if (!v_verbose) ERR_clear_error(); return(ok);