Global configuration parameter "ssl_engine" may be used to specify
openssl engine.
---
 include/proto/ssl_sock.h |  2 ++
 include/types/global.h   |  1 +
 src/cfgparse.c           | 21 +++++++++++++++++++++
 src/haproxy.c            |  3 +++
 src/ssl_sock.c           | 38 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 65 insertions(+)

diff --git a/include/proto/ssl_sock.h b/include/proto/ssl_sock.h
index cb9a1e9..18c220b 100644
--- a/include/proto/ssl_sock.h
+++ b/include/proto/ssl_sock.h
@@ -76,6 +76,8 @@ SSL_CTX *ssl_sock_get_generated_cert(unsigned int key, struct 
bind_conf *bind_co
 int ssl_sock_set_generated_cert(SSL_CTX *ctx, unsigned int key, struct 
bind_conf *bind_conf);
 unsigned int ssl_sock_generated_cert_key(const void *data, size_t len);
 
+void ssl_init_engine(const char *engine_id);
+
 #endif /* _PROTO_SSL_SOCK_H */
 
 /*
diff --git a/include/types/global.h b/include/types/global.h
index b32a09f..9a6e2c9 100644
--- a/include/types/global.h
+++ b/include/types/global.h
@@ -84,6 +84,7 @@ struct global {
 #ifdef USE_OPENSSL
        char *crt_base;             /* base directory path for certificates */
        char *ca_base;              /* base directory path for CAs and CRLs */
+       char *ssl_engine;           /* openssl engine to use */
 #endif
        int uid;
        int gid;
diff --git a/src/cfgparse.c b/src/cfgparse.c
index ec8f6a1..f8ad855 100644
--- a/src/cfgparse.c
+++ b/src/cfgparse.c
@@ -589,6 +589,27 @@ int cfg_parse_global(const char *file, int linenum, char 
**args, int kwm)
                alertif_too_many_args(0, file, linenum, args, &err_code);
                goto out;
        }
+       else if (!strcmp(args[0], "ssl_engine")) {
+#ifdef USE_OPENSSL
+               if (global.ssl_engine != NULL) {
+                       Alert("parsing [%s:%d] : '%s' already specified. 
Continuing.\n", file, linenum, args[0]);
+                       err_code |= ERR_ALERT;
+                       goto out;
+               }
+               if (*(args[1]) == 0) {
+                       Alert("parsing [%s:%d] : '%s' expects a valid engine 
name as an argument.\n", file, linenum, args[0]);
+                       err_code |= ERR_ALERT | ERR_FATAL;
+                       goto out;
+               }
+               qfprintf(stdout, "parsing [%s:%d] : set ssl_engine to '%s'.\n", 
file, linenum, args[1]);
+               global.ssl_engine = strdup(args[1]);
+               ssl_init_engine(global.ssl_engine);
+#else
+               Alert("parsing [%s:%d] : '%s' is not implemented.\n", file, 
linenum, args[0]);
+               err_code |= ERR_ALERT | ERR_FATAL;
+               goto out;
+#endif
+       }
        else if (!strcmp(args[0], "ca-base")) {
 #ifdef USE_OPENSSL
                if(alertif_too_many_args(1, file, linenum, args, &err_code))
diff --git a/src/haproxy.c b/src/haproxy.c
index 5d7d410..69a4551 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -1656,6 +1656,9 @@ void deinit(void)
        ha_wurfl_deinit();
 #endif
 
+#ifdef USE_OPENSSL
+       free(global.ssl_engine);    global.ssl_engine = NULL;
+#endif
        free(global.log_send_hostname); global.log_send_hostname = NULL;
        chunk_destroy(&global.log_tag);
        free(global.chroot);  global.chroot = NULL;
diff --git a/src/ssl_sock.c b/src/ssl_sock.c
index baaa0a1..0b3cee5 100644
--- a/src/ssl_sock.c
+++ b/src/ssl_sock.c
@@ -56,6 +56,8 @@
 #include <import/lru.h>
 #include <import/xxhash.h>
 
+#include <openssl/engine.h>
+
 #include <common/buffer.h>
 #include <common/compat.h>
 #include <common/config.h>
@@ -228,6 +230,42 @@ static forceinline void ssl_sock_dump_errors(struct 
connection *conn)
        }
 }
 
+static ENGINE *engine;
+
+void ssl_init_engine(const char *engine_id)
+{
+       OpenSSL_add_all_algorithms();
+       ENGINE_load_builtin_engines();
+       RAND_set_rand_method(NULL);
+
+       /* grab the structural reference to the engine */
+       engine = ENGINE_by_id(engine_id);
+       if (engine  == NULL) {
+               Alert("Engine %s: failed to get structural reference\n", 
engine_id);
+               exit(-1);
+       }
+
+       if (!ENGINE_init(engine)) {
+               /* the engine couldn't initialise, release it */
+               Alert("Engine %s: failed to initialize\n", engine_id);
+               ENGINE_free(engine);
+               return;
+       }
+
+       if (ENGINE_set_default(engine, ENGINE_METHOD_ALL) == 0) {
+               Alert("Engine %s: ENGINE_set_default failed\n", engine_id);
+               ENGINE_finish(engine);
+               ENGINE_free(engine);
+               return;
+       }
+
+       /* release the functional reference from ENGINE_init() */
+       ENGINE_finish(engine);
+
+       /* release the structural reference from ENGINE_by_id() */
+       ENGINE_free(engine);
+}
+
 /*
  *  This function returns the number of seconds  elapsed
  *  since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) and the
-- 
1.9.1


Reply via email to