Reformat smime utility.

Add support for policy checking in verify utility.
diff --git a/apps/apps.c b/apps/apps.c
index 6bc3562..4121e47 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -2141,10 +2141,14 @@
 	}
 #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 @@
 			}
 		(*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 @@
 		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 @@
 	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, " <empty>\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 ede0c46..7d87963 100644
--- a/apps/apps.h
+++ b/apps/apps.h
@@ -317,7 +317,9 @@
 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 4e68643..57ac6d8 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -365,7 +365,7 @@
 			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 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, " <empty>\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 @@
 		&& ((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 6a93c01..f7c85b8 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -79,13 +79,14 @@
 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 @@
 				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 @@
 #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 @@
         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 @@
 								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 @@
 
 	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 @@
 		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);