# HG changeset patch # User Nick Bogdanov <nickrbogda...@gmail.com> # Date 1677975659 28800 # Sat Mar 04 16:20:59 2023 -0800 # Node ID a00302750c65e122292da5094093e45f2f644600 # 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. In my setup, the initial handshake time increased from 5ms->67ms after enabling TPM2. More details here: https://github.com/tpm2-software/tpm2-openssl/issues/58 diff -r cffaf3f2eec8 -r a00302750c65 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 a00302750c65 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 a00302750c65 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