[PATCH] Support loading server certificate from HW token

Lubos Uhliarik luhliari at redhat.com
Mon Apr 27 11:53:17 UTC 2020


# HG changeset patch
# User Lubos Uhliarik <luhliari at redhat.com>
# Date 1587988141 -7200
#      Mon Apr 27 13:49:01 2020 +0200
# Node ID 8fe8445769f77165f793a4fd016a134aa1ad373c
# Parent  716eddd74bc2831537f5b3f7ecd16ad3e516d043
Support loading server certificate from HW token

Nginx supports loading private key from HW token, but does not support
loading certificate. This patch adds functionality which allows to load
server certificate with a specified id from OpenSSL engine.

diff -r 716eddd74bc2 -r 8fe8445769f7 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c	Thu Apr 23 15:10:26 2020 +0300
+++ b/src/event/ngx_event_openssl.c	Mon Apr 27 13:49:01 2020 +0200
@@ -609,6 +609,71 @@
     X509    *x509, *temp;
     u_long   n;
 
+    if (ngx_strncmp(cert->data, "engine:", sizeof("engine:") - 1) == 0) {
+
+#ifndef OPENSSL_NO_ENGINE
+
+        u_char  *p, *last;
+        ENGINE  *engine;
+
+        p = cert->data + sizeof("engine:") - 1;
+        last = (u_char *) ngx_strchr(p, ':');
+
+        if (last == NULL) {
+            *err = "invalid syntax";
+            return NULL;
+        }
+
+        *last = '\0';
+
+        engine = ENGINE_by_id((char *) p);
+
+        if (engine == NULL) {
+            *err = "ENGINE_by_id() failed";
+            return NULL;
+        }
+
+        if (!ENGINE_init(engine)) {
+            *err = "ENGINE_init() failed";
+            ENGINE_free(engine);
+            return NULL;
+        }
+
+        *last++ = ':';
+
+        struct {
+            const char *cert_id;
+            X509 *cert;
+        } params = { (char *) last, NULL };
+
+        if (!ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &params, NULL, 1)) {
+            *err = "ENGINE_ctrl_cmd() failed - Unable to get the certificate";
+            ENGINE_free(engine);
+            return NULL;
+        }
+
+        ENGINE_finish(engine);
+        ENGINE_free(engine);
+
+        /* set chain to null */
+
+        *chain = sk_X509_new_null();
+        if (*chain == NULL) {
+           *err = "sk_X509_new_null() failed";
+           X509_free(params.cert);
+           return NULL;
+        }
+
+        return params.cert;
+
+#else
+
+        *err = "loading \"engine:...\" certificate is not supported";
+        return NULL;
+
+#endif
+    }
+
     if (ngx_strncmp(cert->data, "data:", sizeof("data:") - 1) == 0) {
 
         bio = BIO_new_mem_buf(cert->data + sizeof("data:") - 1,



More information about the nginx-devel mailing list