diff -rc stunnel-4.05/configure.ac stunnel-4.05.new/configure.ac
*** stunnel-4.05/configure.ac	2003-12-28 20:47:49.000000000 +0000
--- stunnel-4.05.new/configure.ac	2004-07-19 11:53:22.000000000 +0100
***************
*** 83,88 ****
--- 83,96 ----
  	AC_DEFINE_UNQUOTED(RANDOM_FILE, "$RANDOM_FILE")
  fi
  
+ dnl Use SSL Engine?
+ AC_MSG_CHECKING([whether to build with OpenSSL engine capability])
+ AC_ARG_ENABLE(ssl-engine,
+ [  --enable-ssl-engine	Build with OpenSSL engine capability],
+     [ AC_MSG_RESULT([yes]); AC_DEFINE(SSL_ENGINE) ],
+     [ AC_MSG_RESULT([no]) ]
+ )
+ 
  dnl Use RSA?
  AC_MSG_CHECKING([whether to disable RSA support])
  AC_ARG_ENABLE(rsa,
diff -rc stunnel-4.05/src/options.c stunnel-4.05.new/src/options.c
*** stunnel-4.05/src/options.c	2004-01-25 17:25:52.000000000 +0000
--- stunnel-4.05.new/src/options.c	2004-07-19 11:53:22.000000000 +0100
***************
*** 483,489 ****
          log_raw("%-15s = service name", "service");
          break;
      }
! 
      /* session */
      switch(cmd) {
      case CMD_INIT:
--- 483,509 ----
          log_raw("%-15s = service name", "service");
          break;
      }
!     
! #ifdef SSL_ENGINE
!     /* OpenSSL Engine */
!     switch(cmd) {
!     case CMD_INIT:
!         options.hw_engine=NULL;
!         break;
!     case CMD_EXEC:
!         if(strcasecmp(opt, "SSLEngine"))
!             break;
!             options.hw_engine=stralloc(arg);
!         return NULL; /* OK */
!     case CMD_DEFAULT:
! 	log_raw("%-15s = %s", "SSL engine", "openssl");
!         break;
!     case CMD_HELP:
!         log_raw("%-15s = OpenSSL Engine to use e.g. aep", "SSLEngine");
!         break;
!     }
! #endif
!     
      /* session */
      switch(cmd) {
      case CMD_INIT:
diff -rc stunnel-4.05/src/prototypes.h stunnel-4.05.new/src/prototypes.h
*** stunnel-4.05/src/prototypes.h	2004-02-10 19:15:05.000000000 +0000
--- stunnel-4.05.new/src/prototypes.h	2004-07-19 11:53:22.000000000 +0100
***************
*** 105,110 ****
--- 105,113 ----
      char *rand_file;                                /* file with random data */
      int random_bytes;                       /* how many random bytes to read */
      long session_timeout;
+ #ifdef SSL_ENGINE
+     char *hw_engine;
+ #endif 
      int verify_level;
      int verify_use_only_my;
      long ssl_options;
diff -rc stunnel-4.05/src/ssl.c stunnel-4.05.new/src/ssl.c
*** stunnel-4.05/src/ssl.c	2004-01-25 19:26:03.000000000 +0000
--- stunnel-4.05.new/src/ssl.c	2004-07-19 11:53:22.000000000 +0100
***************
*** 31,36 ****
--- 31,40 ----
  #include <starlet.h>
  #endif /* __vms */
  
+ #ifdef SSL_ENGINE
+ #include "openssl/engine.h"
+ #endif
+ 
  #ifndef NO_RSA
  
  /* Cache temporary keys up to 2048 bits */
***************
*** 66,85 ****
  
  SSL_CTX *ctx; /* global SSL context */
  static X509_STORE *revocation_store=NULL;
  
  void context_init(void) { /* init SSL */
      int i;
  
- #if SSLEAY_VERSION_NUMBER >= 0x00907000L
-     /* Load all bundled ENGINEs into memory and make them visible */
-     ENGINE_load_builtin_engines();
-     /* Register all of them for every algorithm they collectively implement */
-     ENGINE_register_all_complete();
- #endif
      if(!init_prng())
          log(LOG_INFO, "PRNG seeded successfully");
      SSLeay_add_ssl_algorithms();
      SSL_load_error_strings();
      if(options.option.client) {
          ctx=SSL_CTX_new(SSLv3_client_method());
      } else { /* Server mode */
--- 70,140 ----
  
  SSL_CTX *ctx; /* global SSL context */
  static X509_STORE *revocation_store=NULL;
+   
+ #ifdef SSL_ENGINE
+ static ENGINE *try_load_engine(const char* engine)
+ {
+ 	ENGINE *e = ENGINE_by_id("dynamic");
+ 	if (e){
+ 		if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
+ 			|| !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)){
+ 			ENGINE_free(e);
+ 			e = NULL;
+ 		}
+ 	}
+ 	return e;
+ }
+ 	
+ ENGINE* setup_engine()
+ {
+ 	ENGINE *e = NULL;
+ #if OPENSSL_VERSION_NUMBER > 0x000907000L
+ 	ENGINE_load_builtin_engines();
+ 
+ 	if((e = ENGINE_by_id(options.hw_engine)) == NULL
+ 		&& (e = try_load_engine(options.hw_engine)) == NULL){
+ 		log(LOG_ERR, "Invalid SSL Hardware Engine: %s", options.hw_engine);
+ 		return NULL;
+ 	}
+ #else
+ 	if((e = ENGINE_by_id(options.hw_engine)) == NULL){
+ 	    log(LOG_ERR, "Invalid SSL Hardware Engine: %s", options.hw_engine);
+ 	    sslerror("Invalid Engine.");
+ 		return NULL;
+         }
+ #endif   	
+ 	if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)){
+ 	    log(LOG_ERR, "Problem using specified engine: %s", options.hw_engine);
+ 	    sslerror("Error using engine.");
+ 	    return NULL;
+     	}
+ 	
+ 	return e;
+ }
+ #endif
  
  void context_init(void) { /* init SSL */
+ #ifdef SSL_ENGINE
+ 	ENGINE *e;
+ #endif
      int i;
  
      if(!init_prng())
          log(LOG_INFO, "PRNG seeded successfully");
      SSLeay_add_ssl_algorithms();
      SSL_load_error_strings();
+ 
+ #ifdef SSL_ENGINE
+     if(options.hw_engine){
+ 	e = setup_engine();
+ 	if(e){
+        		log(LOG_INFO, "Using SSL Hardware engine: %s", options.hw_engine);
+ 	} else {
+ 		exit(1);
+ 	}
+     }
+ #endif
+ 
      if(options.option.client) {
          ctx=SSL_CTX_new(SSLv3_client_method());
      } else { /* Server mode */
