Alas, I meant to send this in weeks ago, before it was too
late for 0.9.7; also apologies if this comes as a duplicate
(we're changing email addresses here, this can cause obvious
chicken-related problems with subscribers-post-only lists...).

This is a patch to actually hand the user-supplied argument
into calls to app_verify_callback. It affects the following 5
files:

ssl/ssl.h
ssl/ssl_cert.c
ssl/ssl_lib.c
ssl/ssltest.c
test/testssl

In the first three cases, the change is 1-3 lines of code,
and a few more lines of comments (e.g. removing comments
saying that the argument is ignored); there's a slightly
larger chunk of code to test it in ssltest.c. The implementation
was done against the 12/09 snapshot, and the patch re-generated
and re-tested against the 2/12 snapshot. (The patch applies
cleanly to 2/13 as well, but that snap fails to build for me for
unrelated reasons already mentioned on the list.)

thanks,
Diana Smetters
PARC

==============================================================
<BEGIN LONG BACKGROUND/RATIONALE, SKIP IF UNINTERESTED>

Why this is useful: I'm looking at generating
an updated Java SSL package that wraps OpenSSL and matches the
JDK1.4 SSL APIs (there is at least one Java wrapper for OpenSSL,
but it doesn't match any of the recent APIs distributed by Sun).
One of the things offered by this API is the ability to have the
code verifying the certificates passed in the handshake do so by
calling back into a piece of arbitrary Java code. That Java code
can be object instance specific (e.g. it can depend on state contained
in a particular object instance), and the object providing it is tied
to a particular SSL context. That means to find the code to call back
into from the OpenSSL side, you have to know which particular Java object
instance contains that code. Without passing either the SSL context
or an argument into the app_verify_callback, it's hard to do that
(there might be some table-based hack you could do, but...).

Since the API was already defined to take an app-specified argument,
it seems the most effective solution would be to fix the bug whereby
the argument is ignored. Taking the alternate route of relying on
the built-in verification algorithms and then using the verify_callback
at the end to override the built-in behavior had two problems:
first, that callback takes no app-defined args, and there's no
reasonable way to change that. Second, it is very likely to end up
with duplicated work, as the app isn't going to know that all that
checking is being done ahead for it; it isn't in other Java SSL
implementations that are using these callback mechanisms, and
so relying on it would prevent this being a drop-in  replacement.

Keep in mind that 99.9% of Java applications using SSL do *not* use
this option to manage verification themselves, they rely on built-in
behavior provided by their SSL package. (In this case, that would
result in them using OpenSSL's standard chain verification code.)
I'm hoping to distribute this work freely; it'll be a lot easier for
people to use if it doesn't require patching OpenSSL.
If there's a better way of doing this that I've missed, I'd love
to hear about it offline.

Personally, I like and use this feature of the Java API because
I do research in things like new ways of handling trust management,
certificates, etc.

<END BACKGROUND>

diff -ur ./ssl/ssl.h ../openssl-SNAP-20020212/ssl/ssl.h
--- ./ssl/ssl.h Mon Jan 14 16:03:04 2002
+++ ../openssl-SNAP-20020212/ssl/ssl.h  Thu Feb 14 12:03:14 2002
@@ -608,7 +608,7 @@
 
        /* if defined, these override the X509_verify_cert() calls */
        int (*app_verify_callback)();
-       char *app_verify_arg; /* never used; should be void * */
+       void *app_verify_arg; /* app-supplied argument passed to callback function */
 
        /* Default password callback. */
        pem_password_cb *default_passwd_callback;
@@ -1232,7 +1232,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)(),void *arg);
 #ifndef OPENSSL_NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 #endif
diff -ur ./ssl/ssl_cert.c ../openssl-SNAP-20020212/ssl/ssl_cert.c
--- ./ssl/ssl_cert.c    Wed Oct 24 09:01:31 2001
+++ ../openssl-SNAP-20020212/ssl/ssl_cert.c     Thu Feb 14 12:03:14 2002
@@ -483,7 +483,7 @@
                X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
 
        if (s->ctx->app_verify_callback != NULL)
-               i=s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */
+               i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); 
        else
                {
 #ifndef OPENSSL_NO_X509_VERIFY
diff -ur ./ssl/ssl_lib.c ../openssl-SNAP-20020212/ssl/ssl_lib.c
--- ./ssl/ssl_lib.c     Fri Feb  8 08:00:55 2002
+++ ../openssl-SNAP-20020212/ssl/ssl_lib.c      Thu Feb 14 12:03:14 2002
@@ -1445,15 +1445,15 @@
        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)(),void *arg)
        {
        /* now
-        *     int (*cb)(X509_STORE_CTX *),
-        * but should be
-        *     int (*cb)(X509_STORE_CTX *, void *arg)
+        *     int (*cb)(X509_STORE_CTX *ctx, void *arg)
+        *
+        * on verification failure, cb should set ctx->error
         */
        ctx->app_verify_callback=cb;
-       ctx->app_verify_arg=arg; /* never used */
+       ctx->app_verify_arg=arg; /* passed to callback */
        }
 
 void SSL_CTX_set_verify(SSL_CTX *ctx,int mode,int (*cb)(int, X509_STORE_CTX *))
diff -ur ./ssl/ssltest.c ../openssl-SNAP-20020212/ssl/ssltest.c
--- ./ssl/ssltest.c     Mon Sep 10 03:02:02 2001
+++ ../openssl-SNAP-20020212/ssl/ssltest.c      Thu Feb 14 12:03:14 2002
@@ -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);
+                       }
                }
        
        {
@@ -1428,6 +1445,25 @@
                case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
                        ok=1;
                        }
+               }
+
+       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",
+                       ctx, 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);
diff -ur ./test/testssl ../openssl-SNAP-20020212/test/testssl
--- ./test/testssl      Thu Nov 30 04:00:50 2000
+++ ../openssl-SNAP-20020212/test/testssl       Thu Feb 14 12:03:14 2002
@@ -116,6 +116,9 @@
 echo test sslv2/sslv3 with both client and server authentication via BIO pair
 $ssltest -bio_pair -server_auth -client_auth $CA $extra || exit 1
 
+echo test sslv2/sslv3 with both client and server authentication via BIO pair and app 
+verify
+$ssltest -bio_pair -server_auth -client_auth -app_verify $CA $extra || exit 1
+
 #############################################################################
 
 echo test tls1 with 1024bit anonymous DH, multiple handshakes

Reply via email to