diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c index a7b389444..2b5c3ab93 100644 --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -82,6 +82,7 @@ static time_t ngx_ssl_parse_time( 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); @@ -94,6 +95,13 @@ static ngx_command_t ngx_openssl_commands[] = { 0, NULL }, + { ngx_string("ssl_provider"), + NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_1MORE, + ngx_openssl_provider, + 0, + 0, + NULL }, + ngx_null_command }; @@ -5982,6 +5990,84 @@ 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) +{ +#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) + + u_char *p; + ngx_uint_t i; + ngx_str_t *value; + OSSL_PARAM *param; + ngx_array_t params; + + if (cf->cycle->modules_used) { + return "is specified too late"; + } + + value = cf->args->elts; + + if (OSSL_PROVIDER_available(NULL, (char *) value[1].data)) { + ngx_conf_log_error(NGX_LOG_INFO, cf, 0, + "ssl_provider \"%V\" is already loaded", &value[1]); + return NGX_CONF_OK; + } + + if (ngx_array_init(¶ms, cf->pool, cf->args->nelts - 1, + sizeof(OSSL_PARAM)) + != NGX_OK) + { + return NGX_CONF_ERROR; + } + + ngx_memzero(params.elts, (cf->args->nelts - 1) * sizeof(OSSL_PARAM)); + + for (i = 2; i < cf->args->nelts; i++) { + p = (u_char *) ngx_strchr(value[i].data, '='); + + if (p == NULL) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[i]); + return NGX_CONF_ERROR; + } + + param = ngx_array_push(¶ms); + if (param == NULL) { + return NGX_CONF_ERROR; + } + + *p++ = '\0'; + + param->key = (char *) value[i].data; + param->data_type = OSSL_PARAM_UTF8_STRING; + param->data = p; + param->data_size = value[i].data + value[i].len - p; + } + + param = ngx_array_push(¶ms); + if (param == NULL) { + return NGX_CONF_ERROR; + } + + if (OSSL_PROVIDER_load_ex(NULL, (char* ) value[1].data, + (params.nelts > 1) ? params.elts : NULL) + == NULL) + { + ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, + "OSSL_PROVIDER_load_ex(\"%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 --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h index 9e68deb44..7c2a0f6dd 100644 --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -38,6 +38,9 @@ #ifndef OPENSSL_NO_OCSP #include #endif +#if (OPENSSL_VERSION_NUMBER >= 0x30200000L) +#include +#endif #include #include #include