Add 'void *' argument to app_verify_callback.

Submitted by: D. K. Smetters <smetters@parc.xerox.com>
Reviewed by: Bodo Moeller
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 05fa9ee..af4a7e8 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -607,8 +607,10 @@
 	int references;
 
 	/* if defined, these override the X509_verify_cert() calls */
-	int (*app_verify_callback)();
-	char *app_verify_arg; /* never used; should be void * */
+	int (*app_verify_callback)(X509_STORE_CTX *, void *);
+	void *app_verify_arg;
+	/* before OpenSSL 0.9.7, 'app_verify_arg' was ignored
+	 * ('app_verify_callback' was called with just one argument) */
 
 	/* Default password callback. */
 	pem_password_cb *default_passwd_callback;
@@ -1232,7 +1234,7 @@
 void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,
 			int (*callback)(int, X509_STORE_CTX *));
 void SSL_CTX_set_verify_depth(SSL_CTX *ctx,int depth);
-void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(),char *arg);
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg);
 #ifndef OPENSSL_NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 #endif
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index d785847..1a873d2 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -483,7 +483,11 @@
 		X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
 
 	if (s->ctx->app_verify_callback != NULL)
+#if 1 /* new with OpenSSL 0.9.7 */
+		i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
+#else
 		i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
+#endif
 	else
 		{
 #ifndef OPENSSL_NO_X509_VERIFY
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index eaf1abd..df307a8 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -1443,15 +1443,10 @@
 	ctx->default_passwd_callback_userdata=u;
 	}
 
-void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,int (*cb)(),char *arg)
+void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *,void *), void *arg)
 	{
-	/* now
-	 *     int (*cb)(X509_STORE_CTX *),
-	 * but should be
-	 *     int (*cb)(X509_STORE_CTX *, void *arg)
-	 */
 	ctx->app_verify_callback=cb;
-	ctx->app_verify_arg=arg; /* never used */
+	ctx->app_verify_arg=arg;
 	}
 
 void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 7d6b53e..2ef9ae7 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -158,6 +158,10 @@
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export,int keylength);
 static void free_tmp_rsa(void);
 #endif
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg);
+#define APP_CALLBACK "Test Callback Argument"
+static char *app_verify_arg = APP_CALLBACK;
+
 #ifndef OPENSSL_NO_DH
 static DH *get_dh512(void);
 static DH *get_dh1024(void);
@@ -336,6 +340,7 @@
 	int tls1=0,ssl2=0,ssl3=0,ret=1;
 	int client_auth=0;
 	int server_auth=0,i;
+	int app_verify=0;
 	char *server_cert=TEST_SERVER_CERT;
 	char *server_key=NULL;
 	char *client_cert=TEST_CLIENT_CERT;
@@ -489,6 +494,10 @@
 			{
 			comp = COMP_RLE;
 			}
+		else if	(strcmp(*argv,"-app_verify") == 0)
+			{
+			app_verify = 1;
+			}
 		else
 			{
 			fprintf(stderr,"unknown option %s\n",*argv);
@@ -640,12 +649,20 @@
 		SSL_CTX_set_verify(s_ctx,
 			SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
 			verify_callback);
+		if (app_verify) 
+			{
+			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
+			}
 		}
 	if (server_auth)
 		{
 		BIO_printf(bio_err,"server authentication\n");
 		SSL_CTX_set_verify(c_ctx,SSL_VERIFY_PEER,
 			verify_callback);
+		if (app_verify) 
+			{
+			SSL_CTX_set_cert_verify_callback(s_ctx, app_verify_callback, app_verify_arg);
+			}
 		}
 	
 	{
@@ -1433,6 +1450,25 @@
 	return(ok);
 	}
 
+static int MS_CALLBACK app_verify_callback(X509_STORE_CTX *ctx, void *arg)
+	{
+	char *s = NULL,buf[256];
+	int ok=1;
+
+	fprintf(stderr, "In app_verify_callback, allowing cert. ");
+	fprintf(stderr, "Arg is: %s\n", (char *)arg);
+	fprintf(stderr, "Finished printing do we have a context? 0x%x a cert? 0x%x\n",
+			(unsigned int)ctx, (unsigned int)ctx->cert);
+	if (ctx->cert)
+		s=X509_NAME_oneline(X509_get_subject_name(ctx->cert),buf,256);
+	if (s != NULL)
+		{
+			fprintf(stderr,"cert depth=%d %s\n",ctx->error_depth,buf);
+		}
+
+	return(ok);
+	}
+
 #ifndef OPENSSL_NO_RSA
 static RSA *rsa_tmp=NULL;