changeset 7477:c74904a17021

SSL: support for parsing PEM certificates from memory. This makes it possible to provide certificates directly via variables in ssl_certificate / ssl_certificate_key directives, without using intermediate files.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 09 Mar 2019 03:03:56 +0300
parents b6dc8a12c07a
children 4f9b72a229c1
files src/event/ngx_event_openssl.c
diffstat 1 files changed, 46 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -611,23 +611,29 @@ ngx_ssl_load_certificate(ngx_pool_t *poo
     X509    *x509, *temp;
     u_long   n;
 
-    if (ngx_get_full_name(pool, (ngx_str_t *) &ngx_cycle->conf_prefix, cert)
-        != NGX_OK)
-    {
-        *err = NULL;
-        return NULL;
-    }
-
-    /*
-     * we can't use SSL_CTX_use_certificate_chain_file() as it doesn't
-     * allow to access certificate later from SSL_CTX, so we reimplement
-     * it here
-     */
-
-    bio = BIO_new_file((char *) cert->data, "r");
-    if (bio == NULL) {
-        *err = "BIO_new_file() failed";
-        return NULL;
+    if (ngx_strncmp(cert->data, "data:", sizeof("data:") - 1) == 0) {
+
+        bio = BIO_new_mem_buf(cert->data + sizeof("data:") - 1,
+                              cert->len - (sizeof("data:") - 1));
+        if (bio == NULL) {
+            *err = "BIO_new_mem_buf() failed";
+            return NULL;
+        }
+
+    } else {
+
+        if (ngx_get_full_name(pool, (ngx_str_t *) &ngx_cycle->conf_prefix, cert)
+            != NGX_OK)
+        {
+            *err = NULL;
+            return NULL;
+        }
+
+        bio = BIO_new_file((char *) cert->data, "r");
+        if (bio == NULL) {
+            *err = "BIO_new_file() failed";
+            return NULL;
+        }
     }
 
     /* certificate itself */
@@ -743,17 +749,29 @@ ngx_ssl_load_certificate_key(ngx_pool_t 
 #endif
     }
 
-    if (ngx_get_full_name(pool, (ngx_str_t *) &ngx_cycle->conf_prefix, key)
-        != NGX_OK)
-    {
-        *err = NULL;
-        return NULL;
-    }
-
-    bio = BIO_new_file((char *) key->data, "r");
-    if (bio == NULL) {
-        *err = "BIO_new_file() failed";
-        return NULL;
+    if (ngx_strncmp(key->data, "data:", sizeof("data:") - 1) == 0) {
+
+        bio = BIO_new_mem_buf(key->data + sizeof("data:") - 1,
+                              key->len - (sizeof("data:") - 1));
+        if (bio == NULL) {
+            *err = "BIO_new_mem_buf() failed";
+            return NULL;
+        }
+
+    } else {
+
+        if (ngx_get_full_name(pool, (ngx_str_t *) &ngx_cycle->conf_prefix, key)
+            != NGX_OK)
+        {
+            *err = NULL;
+            return NULL;
+        }
+
+        bio = BIO_new_file((char *) key->data, "r");
+        if (bio == NULL) {
+            *err = "BIO_new_file() failed";
+            return NULL;
+        }
     }
 
     if (passwords) {