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

Dmitrii Pichulin pdn at cryptopro.ru
Tue Jul 22 11:16:35 UTC 2014


# HG changeset patch
# User Dmitrii Pichulin <pdn at cryptopro.ru>
# Date 1406021876 -14400
#      Tue Jul 22 13:37:56 2014 +0400
# Node ID 638389b21e0e1522ed8b8205012f5af562dc50c7
# Parent  63d7d69d0fe48e030ff9fc520c7036dbd1ebc13f
allow to use engine keyform for server private key

diff -r 63d7d69d0fe4 -r 638389b21e0e src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/event/ngx_event_openssl.c	Tue Jul 22 13:37:56 2014 +0400
@@ -257,11 +257,31 @@
 
 ngx_int_t
 ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
-    ngx_str_t *key)
+    ngx_str_t *key, ngx_str_t *keyform, ngx_str_t *engine)
 {
-    BIO     *bio;
-    X509    *x509;
-    u_long   n;
+    BIO        *bio;
+    X509       *x509;
+    u_long      n;
+    ngx_uint_t  ssl_use_engine_keyform = 0;
+
+    if (keyform->len) {
+
+        if (ngx_strcmp(keyform->data, "ENGINE") == 0) {
+            ssl_use_engine_keyform = 1;
+
+        } else if (ngx_strcmp(keyform->data, "PEM") != 0) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                               "invalid parameter: %V", keyform);
+            return NGX_ERROR;
+        }
+    }
+
+    if (ssl_use_engine_keyform && engine->len == 0) {
+            ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+                             "no \"ssl_certificate_engine\" is defined "
+                             "while \"ssl_certificate_keyform\" is \"ENGINE\"");
+            return NGX_ERROR;
+    }
 
     if (ngx_conf_full_name(cf->cycle, cert, 1) != NGX_OK) {
         return NGX_ERROR;
@@ -344,17 +364,51 @@
 
     BIO_free(bio);
 
-    if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
-        return NGX_ERROR;
-    }
-
-    if (SSL_CTX_use_PrivateKey_file(ssl->ctx, (char *) key->data,
-                                    SSL_FILETYPE_PEM)
-        == 0)
-    {
-        ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
-                      "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data);
-        return NGX_ERROR;
+    if (ssl_use_engine_keyform) {
+        EVP_PKEY   *pkey;
+        ENGINE     *e;
+
+        e = ENGINE_by_id((const char *) engine->data);
+
+        if (e == NULL) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "ENGINE_by_id(\"%s\") failed", engine->data);
+            return NGX_ERROR;
+        }
+
+        pkey = ENGINE_load_private_key(e, (const char *)key->data, 0, 0);
+
+        ENGINE_free(e);
+
+        if (!pkey) {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                          "ENGINE_load_private_key(\"%s\") failed", key->data);
+            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", key->data);
+            EVP_PKEY_free(pkey);
+            return NGX_ERROR;
+        }
+
+        EVP_PKEY_free(pkey);
+
+    } else {
+
+        if (ngx_conf_full_name(cf->cycle, key, 1) != NGX_OK) {
+            return NGX_ERROR;
+        }
+
+        if (SSL_CTX_use_PrivateKey_file(ssl->ctx, 
+                                        (char *) key->data, SSL_FILETYPE_PEM)
+            == 0)
+        {
+            ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+                       "SSL_CTX_use_PrivateKey_file(\"%s\") failed", key->data);
+            return NGX_ERROR;
+        }
     }
 
     return NGX_OK;
diff -r 63d7d69d0fe4 -r 638389b21e0e src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/event/ngx_event_openssl.h	Tue Jul 22 13:37:56 2014 +0400
@@ -112,7 +112,7 @@
 ngx_int_t ngx_ssl_init(ngx_log_t *log);
 ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data);
 ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
-    ngx_str_t *cert, ngx_str_t *key);
+    ngx_str_t *cert, ngx_str_t *key, ngx_str_t *keyform, ngx_str_t *engine);
 ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
     ngx_str_t *cert, ngx_int_t depth);
 ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
diff -r 63d7d69d0fe4 -r 638389b21e0e src/http/modules/ngx_http_ssl_module.c
--- a/src/http/modules/ngx_http_ssl_module.c	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/http/modules/ngx_http_ssl_module.c	Tue Jul 22 13:37:56 2014 +0400
@@ -91,6 +91,20 @@
       offsetof(ngx_http_ssl_srv_conf_t, certificate_key),
       NULL },
 
+    { ngx_string("ssl_certificate_keyform"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, certificate_keyform),
+      NULL },
+
+    { ngx_string("ssl_certificate_engine"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_str_slot,
+      NGX_HTTP_SRV_CONF_OFFSET,
+      offsetof(ngx_http_ssl_srv_conf_t, certificate_engine),
+      NULL },
+
     { ngx_string("ssl_dhparam"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_str_slot,
@@ -562,6 +576,10 @@
 
     ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
     ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
+    ngx_conf_merge_str_value(conf->certificate_keyform,
+                         prev->certificate_keyform, "");
+    ngx_conf_merge_str_value(conf->certificate_engine,
+                         prev->certificate_engine, "");
 
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
@@ -652,7 +670,8 @@
     cln->data = &conf->ssl;
 
     if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
-                            &conf->certificate_key)
+                            &conf->certificate_key, &conf->certificate_keyform,
+                            &conf->certificate_engine)
         != NGX_OK)
     {
         return NGX_CONF_ERROR;
diff -r 63d7d69d0fe4 -r 638389b21e0e src/http/modules/ngx_http_ssl_module.h
--- a/src/http/modules/ngx_http_ssl_module.h	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/http/modules/ngx_http_ssl_module.h	Tue Jul 22 13:37:56 2014 +0400
@@ -34,6 +34,9 @@
 
     ngx_str_t                       certificate;
     ngx_str_t                       certificate_key;
+    ngx_str_t                       certificate_keyform;
+    ngx_str_t                       certificate_engine;
+
     ngx_str_t                       dhparam;
     ngx_str_t                       ecdh_curve;
     ngx_str_t                       client_certificate;
diff -r 63d7d69d0fe4 -r 638389b21e0e src/mail/ngx_mail_ssl_module.c
--- a/src/mail/ngx_mail_ssl_module.c	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/mail/ngx_mail_ssl_module.c	Tue Jul 22 13:37:56 2014 +0400
@@ -230,6 +230,10 @@
 
     ngx_conf_merge_str_value(conf->certificate, prev->certificate, "");
     ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, "");
+    ngx_conf_merge_str_value(conf->certificate_keyform,
+                         prev->certificate_keyform, "");
+    ngx_conf_merge_str_value(conf->certificate_engine,
+                         prev->certificate_engine, "");
 
     ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, "");
 
@@ -302,7 +306,8 @@
     cln->data = &conf->ssl;
 
     if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate,
-                            &conf->certificate_key)
+                            &conf->certificate_key, &conf->certificate_keyform,
+                            &conf->certificate_engine)
         != NGX_OK)
     {
         return NGX_CONF_ERROR;
diff -r 63d7d69d0fe4 -r 638389b21e0e src/mail/ngx_mail_ssl_module.h
--- a/src/mail/ngx_mail_ssl_module.h	Fri Jun 20 12:55:41 2014 +0400
+++ b/src/mail/ngx_mail_ssl_module.h	Tue Jul 22 13:37:56 2014 +0400
@@ -34,6 +34,9 @@
 
     ngx_str_t        certificate;
     ngx_str_t        certificate_key;
+    ngx_str_t        certificate_keyform;
+    ngx_str_t        certificate_engine;
+
     ngx_str_t        dhparam;
     ngx_str_t        ecdh_curve;
 



More information about the nginx-devel mailing list