Alas, I meant to send this in weeks ago, before it was too
late for 0.9.7...

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, at least to me: 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 required 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 C 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
seemed the most effective solution would be to fix the bug whereby
the argument is ignored. Taking the 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, it 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 the SSL package. (In this
case, they would be using OpenSSL's standard chain verification code.)
If there's a better way of doing this that I've missed, I'd love
to hear about it offline.

The reason I fall into that .01% of people who muck with this stuff
is that I'm a researcher, doing experiments in new ways of handling
trust management, certificates, etc. I'd love to be able to take
advantage of the speed and stability of OpenSSL in deploying such
experimental projects to test users; this is an important piece of
flexibility that would make that much easier.

<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