Welcome! Log In Create A New Profile

Advanced

[PATCH] Add ssl_provider directive (ticket #2449)

Nick Bogdanov
March 04, 2023 07:56PM
# HG changeset patch
# User Nick Bogdanov <nickrbogdanov@gmail.com>
# Date 1677975659 28800
# Sat Mar 04 16:20:59 2023 -0800
# Node ID 8cb34ae16de2408cbe91832194baac6ae299f251
# Parent cffaf3f2eec8fd33605c2a37814f5ffc30371989
Add ssl_provider directive (ticket #2449)

This change allows nginx to load modules that use the new OpenSSL
Provider interface. My primary use case involves securing the
webserver's private TLS key using a TPM2 chip, so it can't be stolen
if the server is compromised. The way I tested this is as follows:

1. Install basic TPM2 support. On Ubuntu 22.04 I used

apt install tpm2-tools tpm2-abrmd libtss2-tcti-tabrmd0

2. Install https://github.com/tpm2-software/tpm2-openssl . Version
1.2.0-rc0 or higher is required. At the time of this writing, it's
likely you'll have to build from source.

3. Generate a parent key on your TPM (one-time setup):

tpm2_createprimary -C o -g sha256 -G ecc -c primary_sh.ctx

tpm2_evictcontrol -C o -c 0x81000001 || true

tpm2_evictcontrol -C o -c primary_sh.ctx 0x81000001

4. Generate a TPM-backed RSA privkey and a corresponding self-signed
x509 cert:

openssl genpkey -provider tpm2 -algorithm RSA
-pkeyopt parent:0x81000001 -out rsakey.pem

openssl req -provider tpm2 -provider default -x509
-subj "/C=GB/CN=foo" -key rsakey.pem -out rsacert.pem

rsakey.pem will start with "-----BEGIN TSS2 PRIVATE KEY-----" to indicate
that the key material is encrypted with a key that is only available inside
the TPM chip.

5. At the start of nginx.conf, tell nginx to use the tpm2 provider
first, and then fall back to the default provider for unsupported
operations:

ssl_provider tpm2;
ssl_provider default;

6. Inside a "server {" section for an existing TLS server, point nginx
to the new TPM-backed cert and key:

ssl_certificate /tmp/rsacert.pem;
ssl_certificate_key /tmp/rsakey.pem;

If the ssl_provider option took effect, it will be able to recognize
the new TSS2 rsakey.pem and instruct the TPM chip to handle the signing
operation during the TLS handshake.

diff -r cffaf3f2eec8 -r 8cb34ae16de2 contrib/vim/syntax/nginx.vim
--- a/contrib/vim/syntax/nginx.vim Thu Feb 02 23:38:48 2023 +0300
+++ b/contrib/vim/syntax/nginx.vim Sat Mar 04 16:20:59 2023 -0800
@@ -620,6 +620,7 @@
syn keyword ngxDirective contained ssl_prefer_server_ciphers
syn keyword ngxDirective contained ssl_preread
syn keyword ngxDirective contained ssl_protocols
+syn keyword ngxDirective contained ssl_provider
syn keyword ngxDirective contained ssl_reject_handshake
syn keyword ngxDirective contained ssl_session_cache
syn keyword ngxDirective contained ssl_session_ticket_key
diff -r cffaf3f2eec8 -r 8cb34ae16de2 src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c Thu Feb 02 23:38:48 2023 +0300
+++ b/src/event/ngx_event_openssl.c Sat Mar 04 16:20:59 2023 -0800
@@ -90,6 +90,7 @@

static void *ngx_openssl_create_conf(ngx_cycle_t *cycle);
static char *ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_openssl_provider(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void ngx_openssl_exit(ngx_cycle_t *cycle);


@@ -102,6 +103,13 @@
0,
NULL },

+ { ngx_string("ssl_provider"),
+ NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
+ ngx_openssl_provider,
+ 0,
+ 0,
+ NULL },
+
ngx_null_command
};

@@ -5939,6 +5947,26 @@
#endif
}

+static char *
+ngx_openssl_provider(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+#ifdef OPENSSL_PROVIDER_SUPPORT
+ ngx_str_t *value = cf->args->elts;
+
+ if (OSSL_PROVIDER_load(NULL, (char *)value[1].data) == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
+ "OSSL_PROVIDER_load(\"%V\") failed", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+
+#else
+
+ return "is not supported";
+
+#endif
+}

static void
ngx_openssl_exit(ngx_cycle_t *cycle)
diff -r cffaf3f2eec8 -r 8cb34ae16de2 src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h Thu Feb 02 23:38:48 2023 +0300
+++ b/src/event/ngx_event_openssl.h Sat Mar 04 16:20:59 2023 -0800
@@ -28,6 +28,10 @@
#ifndef OPENSSL_NO_OCSP
#include <openssl/ocsp.h>
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+#include <openssl/provider.h>
+#define OPENSSL_PROVIDER_SUPPORT
+#endif
#include <openssl/rand.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH] Add ssl_provider directive (ticket #2449)

Nick Bogdanov 366 March 04, 2023 07:56PM

Re: [PATCH] Add ssl_provider directive (ticket #2449)

splitice 159 March 04, 2023 08:04PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 204
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready