Browse Source

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.
Oswald Buddenhagen 11 năm trước cách đây
mục cha
commit
7ce57b9c00
2 tập tin đã thay đổi với 18 bổ sung33 xóa
  1. 18 32
      src/socket.c
  2. 0 1
      src/socket.h

+ 18 - 32
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 {

+ 0 - 1
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 */