710a6d
From 4e5f12d6584536ead82d20554d8f3f2ab0107b0b Mon Sep 17 00:00:00 2001
710a6d
From: Lubos Uhliarik <luhliari@redhat.com>
710a6d
Date: Fri, 30 Apr 2021 13:07:45 +0000
710a6d
Subject: [PATCH 3/3] Support loading certificates from hardware token (PKCS#11)
710a6d
710a6d
---
710a6d
 src/event/ngx_event_openssl.c | 65 +++++++++++++++++++++++++++++++++++
710a6d
 1 file changed, 65 insertions(+)
710a6d
710a6d
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
710a6d
index d762d6b..270b200 100644
710a6d
--- a/src/event/ngx_event_openssl.c
710a6d
+++ b/src/event/ngx_event_openssl.c
710a6d
@@ -617,6 +617,71 @@ ngx_ssl_load_certificate(ngx_pool_t *pool, char **err, ngx_str_t *cert,
710a6d
     X509    *x509, *temp;
710a6d
     u_long   n;
710a6d
 
710a6d
+    if (ngx_strncmp(cert->data, "engine:", sizeof("engine:") - 1) == 0) {
710a6d
+
710a6d
+#ifndef OPENSSL_NO_ENGINE
710a6d
+
710a6d
+        u_char  *p, *last;
710a6d
+        ENGINE  *engine;
710a6d
+
710a6d
+        p = cert->data + sizeof("engine:") - 1;
710a6d
+        last = (u_char *) ngx_strchr(p, ':');
710a6d
+
710a6d
+        if (last == NULL) {
710a6d
+            *err = "invalid syntax";
710a6d
+            return NULL;
710a6d
+        }
710a6d
+
710a6d
+        *last = '\0';
710a6d
+
710a6d
+        engine = ENGINE_by_id((char *) p);
710a6d
+
710a6d
+        if (engine == NULL) {
710a6d
+            *err = "ENGINE_by_id() failed";
710a6d
+            return NULL;
710a6d
+        }
710a6d
+
710a6d
+        if (!ENGINE_init(engine)) {
710a6d
+            *err = "ENGINE_init() failed";
710a6d
+            ENGINE_free(engine);
710a6d
+            return NULL;
710a6d
+        }
710a6d
+
710a6d
+        *last++ = ':';
710a6d
+
710a6d
+        struct {
710a6d
+            const char *cert_id;
710a6d
+            X509 *cert;
710a6d
+        } params = { (char *) last, NULL };
710a6d
+
710a6d
+        if (!ENGINE_ctrl_cmd(engine, "LOAD_CERT_CTRL", 0, &params, NULL, 1)) {
710a6d
+            *err = "ENGINE_ctrl_cmd() failed - Unable to get the certificate";
710a6d
+            ENGINE_free(engine);
710a6d
+            return NULL;
710a6d
+        }
710a6d
+
710a6d
+        ENGINE_finish(engine);
710a6d
+        ENGINE_free(engine);
710a6d
+
710a6d
+        /* set chain to null */
710a6d
+
710a6d
+        *chain = sk_X509_new_null();
710a6d
+        if (*chain == NULL) {
710a6d
+           *err = "sk_X509_new_null() failed";
710a6d
+           X509_free(params.cert);
710a6d
+           return NULL;
710a6d
+        }
710a6d
+
710a6d
+        return params.cert;
710a6d
+
710a6d
+#else
710a6d
+
710a6d
+        *err = "loading \"engine:...\" certificate is not supported";
710a6d
+        return NULL;
710a6d
+
710a6d
+#endif
710a6d
+    }
710a6d
+
710a6d
     if (ngx_strncmp(cert->data, "data:", sizeof("data:") - 1) == 0) {
710a6d
 
710a6d
         bio = BIO_new_mem_buf(cert->data + sizeof("data:") - 1,
710a6d
-- 
710a6d
2.26.3
710a6d