commit 7ce57b9c00522d943a3e6109c9677366b8c5ec7d
Author: Oswald Buddenhagen <[email protected]>
Date:   Sun Jul 27 15:12:37 2014 +0200

    make SSL certificate verification less arcane
    
    instead of using a callback which messes with the certificate chain
    verification, simply let OpenSSL ignore errors during that phase and
    check the result only afterwards.

 src/socket.c |   50 ++++++++++++++++++--------------------------------
 src/socket.h |    1 -
 2 files changed, 18 insertions(+), 33 deletions(-)

diff --git a/src/socket.c b/src/socket.c
index c760c0a..4a8bc6d 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -58,8 +58,6 @@ socket_fail( conn_t *conn )
 }
 
 #ifdef HAVE_LIBSSL
-static int ssl_data_idx;
-
 static int
 ssl_return( const char *func, conn_t *conn, int ret )
 {
@@ -156,10 +154,10 @@ verify_hostname( X509 *cert, const char *hostname )
 static int
 verify_cert_host( const server_conf_t *conf, conn_t *sock )
 {
+       unsigned i;
+       long err;
        X509 *cert;
-
-       if (!conf->host || sock->force_trusted > 0)
-               return 0;
+       STACK_OF(X509_OBJECT) *trusted;
 
        cert = SSL_get_peer_certificate( sock->ssl );
        if (!cert) {
@@ -167,31 +165,22 @@ verify_cert_host( const server_conf_t *conf, conn_t *sock 
)
                return -1;
        }
 
-       return verify_hostname( cert, conf->host );
-}
+       trusted = SSL_CTX_get_cert_store( conf->SSLContext )->objs;
+       for (i = 0; i < conf->num_trusted; i++) {
+               if (!X509_cmp( cert, sk_X509_OBJECT_value( trusted, i 
)->data.x509 ))
+                       return 0;
+       }
 
-static int
-ssl_verify_callback( int ok, X509_STORE_CTX *ctx )
-{
-       SSL *ssl = X509_STORE_CTX_get_ex_data( ctx, 
SSL_get_ex_data_X509_STORE_CTX_idx() );
-       conn_t *conn = SSL_get_ex_data( ssl, ssl_data_idx );
-
-       if (!conn->force_trusted) {
-               X509 *cert = sk_X509_value( ctx->chain, 0 );
-               STACK_OF(X509_OBJECT) *trusted = ctx->ctx->objs;
-               unsigned i;
-
-               conn->force_trusted = -1;
-               for (i = 0; i < conn->conf->num_trusted; i++) {
-                       if (!X509_cmp( cert, sk_X509_OBJECT_value( trusted, i 
)->data.x509 )) {
-                               conn->force_trusted = 1;
-                               break;
-                       }
-               }
+       err = SSL_get_verify_result( sock->ssl );
+       if (err != X509_V_OK) {
+               error( "SSL error connecting %s: %s\n", sock->name, 
ERR_error_string( err, NULL ) );
+               return -1;
        }
-       if (conn->force_trusted > 0)
-               ok = 1;
-       return ok;
+
+       if (!conf->host)
+               return 0; /* SSL on top of a tunnel, no host specified. */
+
+       return verify_hostname( cert, conf->host );
 }
 
 static int
@@ -232,7 +221,7 @@ init_ssl_ctx( const server_conf_t *conf )
                warn( "Warning: Unable to load default certificate files: %s\n",
                      ERR_error_string( ERR_get_error(), 0 ) );
 
-       SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_PEER, 
ssl_verify_callback );
+       SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL );
 
        mconf->ssl_ctx_valid = 1;
        return 1;
@@ -251,7 +240,6 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void 
*aux ) )
        if (!ssl_inited) {
                SSL_library_init();
                SSL_load_error_strings();
-               ssl_data_idx = SSL_get_ex_new_index( 0, NULL, NULL, NULL, NULL 
);
                ssl_inited = 1;
        }
 
@@ -263,7 +251,6 @@ socket_start_tls( conn_t *conn, void (*cb)( int ok, void 
*aux ) )
        conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext );
        SSL_set_fd( conn->ssl, conn->fd );
        SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
-       SSL_set_ex_data( conn->ssl, ssl_data_idx, conn );
        conn->state = SCK_STARTTLS;
        start_tls_p2( conn );
 }
@@ -272,7 +259,6 @@ static void
 start_tls_p2( conn_t *conn )
 {
        if (ssl_return( "connect to", conn, SSL_connect( conn->ssl ) ) > 0) {
-               /* verify whether the server hostname matches the certificate */
                if (verify_cert_host( conn->conf, conn )) {
                        start_tls_p3( conn, 0 );
                } else {
diff --git a/src/socket.h b/src/socket.h
index bfc5ddf..e9c3bca 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -73,7 +73,6 @@ typedef struct {
        char *name;
 #ifdef HAVE_LIBSSL
        SSL *ssl;
-       int force_trusted;
 #endif
 
        void (*bad_callback)( void *aux ); /* async fail while sending or 
listening */

------------------------------------------------------------------------------
Comprehensive Server Monitoring with Site24x7.
Monitor 10 servers for $9/Month.
Get alerted through email, SMS, voice calls or mobile push notifications.
Take corrective actions from your mobile device.
http://p.sf.net/sfu/Zoho
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to