diff -rc stunnel-3.23/configure.ac stunnel-3.23.new/configure.ac
*** stunnel-3.23/configure.ac	Thu Apr  3 02:29:47 2003
--- stunnel-3.23.new/configure.ac	Wed Oct  1 12:07:39 2003
***************
*** 108,113 ****
--- 108,122 ----
  	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 SSL certificate defaults?
  AC_MSG_CHECKING([whether to enable SSL certificate defaults])
  AC_ARG_ENABLE(ssllib-cs,
diff -rc stunnel-3.23/options.c stunnel-3.23.new/options.c
*** stunnel-3.23/options.c	Sun Dec 23 20:08:51 2001
--- stunnel-3.23.new/options.c	Wed Oct  1 12:07:39 2003
***************
*** 72,77 ****
--- 72,80 ----
      options.facility=LOG_DAEMON;
  #endif
      options.session_timeout=300;
+ #ifdef SSL_ENGINE
+     options.hw_engine=NULL;
+ #endif
      options.cipher_list=NULL;
      options.username=NULL;
      options.protocol=NULL;
***************
*** 85,91 ****
      options.output_file=NULL;
      options.local_ip=NULL;
      opterr=0;
!     while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:hC:D:O:E:R:WB:VP:S:o:I:")) != EOF)
          switch (c) {
              case 'A':
                      safecopy(options.cert_file,optarg);
--- 88,94 ----
      options.output_file=NULL;
      options.local_ip=NULL;
      opterr=0;
!     while ((c = getopt(argc, argv, "A:a:cp:v:d:fTl:L:r:s:g:t:u:n:N:H:hC:D:O:E:R:WB:VP:S:o:I:")) != EOF)
          switch (c) {
              case 'A':
                      safecopy(options.cert_file,optarg);
***************
*** 215,220 ****
--- 218,230 ----
              case 'N':
                      servname_selected=optarg;
                  break;
+ 	    case 'H':
+ #ifdef SSL_ENGINE
+ 		options.hw_engine=optarg;
+ #else
+ 		log(LOG_ERR, "-H is only support when compiled with -DSSL_ENGINE");
+ #endif
+ 		break;
              case 'C':
                  options.cipher_list=optarg;
                  break;
***************
*** 323,328 ****
--- 333,341 ----
          "[-c | -T] "
          "[-D level] "
          "[-C cipherlist] "
+ #ifdef SSL_ENGINE
+ 	"[-H ssl_engine]"
+ #endif
          "[-p pemfile] "
          "\n\t"
          "[-v level] "
***************
*** 391,396 ****
--- 404,412 ----
          "\n  -P arg\tspecify pid file { dir/ | filename | none }"
  #endif
          "\n  -C list\tset permitted SSL ciphers"
+ #ifdef SSL_ENGINE
+ 	"\n  -H ssl_engine\tUse openssl engine ssl_engine"
+ #endif
  #if SSLEAY_VERSION_NUMBER >= 0x0090581fL
          "\n  -E socket\tpath to Entropy Gathering Daemon socket"
  #ifdef EGD_SOCKET
diff -rc stunnel-3.23/prototypes.h stunnel-3.23.new/prototypes.h
*** stunnel-3.23/prototypes.h	Thu Apr  3 02:31:41 2003
--- stunnel-3.23.new/prototypes.h	Wed Oct  1 12:07:39 2003
***************
*** 100,105 ****
--- 100,108 ----
      int debug_level;                               /* debug level for syslog */
      int facility;                               /* debug facility for syslog */
      long session_timeout;
+ #ifdef SSL_ENGINE
+     char *hw_engine;
+ #endif
      char *cipher_list;
      char *username;
      char *protocol;
Only in stunnel-3.23.new: prototypes.h.orig
diff -rc stunnel-3.23/ssl.c stunnel-3.23.new/ssl.c
*** stunnel-3.23/ssl.c	Thu Apr  3 02:31:41 2003
--- stunnel-3.23.new/ssl.c	Wed Oct  1 14:34:38 2003
***************
*** 46,51 ****
--- 46,54 ----
  #include <openssl/ssl.h>
  #include <openssl/err.h>
  #include <openssl/rand.h>
+ #ifdef SSL_ENGINE
+ #include <openssl/engine.h>
+ #endif
  #else
  #include <lhash.h>
  #include <ssl.h>
***************
*** 70,81 ****
--- 73,142 ----
  
  SSL_CTX *ctx; /* global SSL context */
  
+ #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() { /* init SSL */
+ #ifdef SSL_ENGINE
+     ENGINE *e;
+ #endif
  
      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&OPT_CLIENT) {
          ctx=SSL_CTX_new(SSLv3_client_method());
      } else { /* Server mode */
***************
*** 92,99 ****
          SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  #endif /* OpenSSL-0.9.6 */
  
!     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
!     SSL_CTX_set_timeout(ctx, options.session_timeout);
      if(options.option&OPT_CERT) {
          if(!SSL_CTX_use_certificate_chain_file(ctx, options.pem)) {
              log(LOG_ERR, "Error reading certificate file: %s", options.pem);
--- 153,167 ----
          SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
  #endif /* OpenSSL-0.9.6 */
  
! #ifdef SSL_ENGINE
!     if(options.hw_engine){
!     	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
!     } else {
!     	SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
!     	SSL_CTX_set_timeout(ctx, options.session_timeout);
!     }
! #endif
! 
      if(options.option&OPT_CERT) {
          if(!SSL_CTX_use_certificate_chain_file(ctx, options.pem)) {
              log(LOG_ERR, "Error reading certificate file: %s", options.pem);
diff -rc stunnel-3.23/stunnel.8 stunnel-3.23.new/stunnel.8
*** stunnel-3.23/stunnel.8	Sun Dec 23 20:11:45 2001
--- stunnel-3.23.new/stunnel.8	Wed Oct  1 12:07:39 2003
***************
*** 191,197 ****
  stunnel \- universal SSL tunnel
  .SH "SYNOPSIS"
  \fBstunnel\fR [\-c\ |\ \-T] [\-D\ [facility.]level] [\-O
! a|l|r:option=value[:value]] [\-o\ file] [\-C\ cipherlist] [\-p
  pemfile] [\-v\ level] [\-A\ certfile] [\-S\ sources] [\-a
  directory] [\-t\ timeout] [\-u\ ident_username] [\-s\ setuid_user]
  [\-g\ setgid_group] [\-n\ protocol] [\-P\ {\ dir/\ |\ filename\ |\ none\ }
--- 191,197 ----
  stunnel \- universal SSL tunnel
  .SH "SYNOPSIS"
  \fBstunnel\fR [\-c\ |\ \-T] [\-D\ [facility.]level] [\-O
! a|l|r:option=value[:value]] [\-o\ file] [\-C\ cipherlist] [\-H\ engine] [\-p
  pemfile] [\-v\ level] [\-A\ certfile] [\-S\ sources] [\-a
  directory] [\-t\ timeout] [\-u\ ident_username] [\-s\ setuid_user]
  [\-g\ setgid_group] [\-n\ protocol] [\-P\ {\ dir/\ |\ filename\ |\ none\ }
***************
*** 261,266 ****
--- 261,268 ----
  .Sp
  A colon delimited list of the ciphers to allow in the \s-1SSL\s0 connection.
  For example \s-1DES\s0\-\s-1CBC3-SHA:IDEA\s0\-\s-1CBC\s0\-\s-1MD5\s0
+ .Ip "\fB\-H\fR engine" 4
+ Select OpenSSL engine.  For example aep
  .Ip "\fB\-c\fR" 4
  client mode (remote service uses \s-1SSL\s0)
  .Sp
***************
*** 528,533 ****
--- 530,537 ----
  
  .IX Item "\fB\-C\fR cipherlist"
  
+ .IX Item "\fB\-H\fR engine"
+ 
  .IX Item "\fB\-c\fR"
  
  .IX Item "\fB\-T\fR"
