[PATCH] allow to use engine keyform for server private key

Dmitrii Pichulin pdn at cryptopro.ru
Wed Jul 23 14:58:23 UTC 2014


# HG changeset patch
# User Dmitrii Pichulin
# Date 1406127158 -14400
#      Wed Jul 23 18:52:38 2014 +0400
# Node ID fec1d814c8f363976a1217c81faec3d80e6c718f
# Parent  9de5820bb3e04d7e21727b472a15831ec0b2be1d
allow to use engine keyform for server private key

diff -r 9de5820bb3e0 -r fec1d814c8f3 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Fri Jul 18 20:11:40 2014 +0400
+++ b/src/event/ngx_event_openssl.c	Wed Jul 23 18:52:38 2014 +0400
@@ -11,6 +11,7 @@
 
 
 #define NGX_SSL_PASSWORD_BUFFER_SIZE  4096
+#define NGX_SSL_MAX_ENGINE_NAME_LEN   260
 
 
 typedef struct {
@@ -270,6 +271,10 @@
     u_long       n;
     ngx_str_t   *pwd;
     ngx_uint_t   tries;
+    EVP_PKEY    *pkey;
+    ENGINE      *e;
+    char        *p, *last;
+    char         e_name[NGX_SSL_MAX_ENGINE_NAME_LEN + 1];
 
     if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
         return NGX_ERROR;
@@ -352,6 +357,61 @@
 
     BIO_free(bio);
 
+    if (ngx_strncmp(key->data, "engine:", sizeof("engine:") - 1) == 0) {
+
+        p = (char *) key->data + sizeof("engine:") - 1;
+        last = ngx_strchr(p, ':');
+
+        if (last == NULL || ngx_strchr(last + 1, ':') != NULL) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid syntax: %V", key);
+            return NGX_ERROR;
+        }
+
+        if (last - p > NGX_SSL_MAX_ENGINE_NAME_LEN) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "too long engine name in \"ssl_certificate_key\"");
+            return NGX_ERROR;
+        }
+
+        ngx_memcpy(e_name, p, last - p);
+        e_name[last - p] = 0;
+
+        e = ENGINE_by_id((char *) e_name);
+
+        if (e == NULL) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "ENGINE_by_id(\"%s\") failed", e_name);
+            return NGX_ERROR;
+        }
+
+        pkey = ENGINE_load_private_key(e, (char *) last + 1, 0, 0);
+
+        if (!pkey) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "ENGINE_load_private_key(\"%s\") failed", last + 1);
+            ENGINE_free(e);
+            return NGX_ERROR;
+        }
+
+        if (SSL_CTX_use_PrivateKey(ssl->ctx, pkey) == 0) {
+
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                       "SSL_CTX_use_PrivateKey_file(\"%s\") failed", last + 1);
+            EVP_PKEY_free(pkey);
+            ENGINE_free(e);
+            return NGX_ERROR;
+        }
+
+        EVP_PKEY_free(pkey);
+
+        if (ENGINE_free(e) == 0) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, "ENGINE_free() failed");
+            return NGX_ERROR;
+        }
+
+        return NGX_OK;
+    }
+
     if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
         return NGX_ERROR;
     }



More information about the nginx-devel mailing list