SSL add ocsp_responder_certificate directive

This directive permit to define a set of trusted PEM encoded OCSP responder certificates
This commit is contained in:
Yoann Guion 2024-11-19 11:20:37 +01:00
parent 36ca44f26f
commit bad07affb6
7 changed files with 58 additions and 10 deletions

View File

@ -592,6 +592,7 @@ syn keyword ngxDirective contained ssl_handshake_timeout
syn keyword ngxDirective contained ssl_ocsp
syn keyword ngxDirective contained ssl_ocsp_cache
syn keyword ngxDirective contained ssl_ocsp_responder
syn keyword ngxDirective contained ssl_ocsp_responder_certificate
syn keyword ngxDirective contained ssl_password_file
syn keyword ngxDirective contained ssl_prefer_server_ciphers
syn keyword ngxDirective contained ssl_preread

View File

@ -220,7 +220,7 @@ ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify);
ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);
ngx_int_t ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
ngx_int_t ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder, ngx_str_t *ocsp_responder_certificate,
ngx_uint_t depth, ngx_shm_zone_t *shm_zone);
ngx_int_t ngx_ssl_ocsp_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_resolver_t *resolver, ngx_msec_t resolver_timeout);

View File

@ -57,6 +57,7 @@ typedef struct {
ngx_shm_zone_t *shm_zone;
ngx_resolver_t *resolver;
STACK_OF(X509) *responder_chain;
ngx_msec_t resolver_timeout;
} ngx_ssl_ocsp_conf_t;
@ -97,6 +98,7 @@ struct ngx_ssl_ocsp_ctx_s {
X509 *cert;
X509 *issuer;
STACK_OF(X509) *chain;
STACK_OF(X509) *responder_chain;
int status;
time_t valid;
@ -804,7 +806,7 @@ ngx_ssl_stapling_cleanup(void *data)
ngx_int_t
ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder, ngx_str_t *ocsp_responder_certificate,
ngx_uint_t depth, ngx_shm_zone_t *shm_zone)
{
ngx_url_t u;
@ -855,6 +857,24 @@ ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
ocf->port = u.port;
}
char *err;
STACK_OF(X509) *chain;
if (ocsp_responder_certificate != NULL && ocsp_responder_certificate->len) {
chain = ngx_ssl_cache_fetch(cf, NGX_SSL_CACHE_CERT, &err, ocsp_responder_certificate, NULL);
if (chain == NULL) {
if (err != NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"cannot load ocsp responder certificate \"%s\": %s",
ocsp_responder_certificate->data, err);
}
return NGX_ERROR;
}
else{
ocf->responder_chain = chain;
}
}
if (SSL_CTX_set_ex_data(ssl->ctx, ngx_ssl_ocsp_index, ocf) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_set_ex_data() failed");
@ -1046,6 +1066,7 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
ctx->cert = sk_X509_value(ocsp->certs, ocsp->ncert);
ctx->issuer = sk_X509_value(ocsp->certs, ocsp->ncert + 1);
ctx->chain = ocsp->certs;
ctx->responder_chain = ocf->responder_chain;
ctx->resolver = ocf->resolver;
ctx->resolver_timeout = ocf->resolver_timeout;
@ -2408,10 +2429,20 @@ ngx_ssl_ocsp_verify(ngx_ssl_ocsp_ctx_t *ctx)
goto error;
}
if (OCSP_basic_verify(basic, ctx->chain, store, ctx->flags) != 1) {
ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
"OCSP_basic_verify() failed");
goto error;
if (ctx->responder_chain != NULL) {
ctx->flags |= OCSP_TRUSTOTHER;
if (OCSP_basic_verify(basic, ctx->responder_chain, store, ctx->flags) != 1) {
ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
"OCSP_basic_verify() failed");
goto error;
}
}
else {
if (OCSP_basic_verify(basic, ctx->chain, store, ctx->flags) != 1) {
ngx_ssl_error(NGX_LOG_ERR, ctx->log, 0,
"OCSP_basic_verify() failed");
goto error;
}
}
id = OCSP_cert_to_id(NULL, ctx->cert, ctx->issuer);
@ -2768,7 +2799,7 @@ ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_int_t
ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder,
ngx_ssl_ocsp(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *responder, ngx_str_t *ocsp_responder_certificate,
ngx_uint_t depth, ngx_shm_zone_t *shm_zone)
{
ngx_log_error(NGX_LOG_EMERG, ssl->log, 0,

View File

@ -234,7 +234,14 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, ocsp_responder),
NULL },
{ ngx_string("ssl_ocsp_cache"),
{ ngx_string("ssl_ocsp_responder_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, ocsp_responder_certificate),
NULL },
{ ngx_string("ssl_ocsp_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_http_ssl_ocsp_cache,
NGX_HTTP_SRV_CONF_OFFSET,
@ -833,7 +840,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, &conf->ocsp_responder_certificate, conf->ocsp,
conf->ocsp_cache_zone)
!= NGX_OK)
{

View File

@ -56,6 +56,7 @@ typedef struct {
ngx_uint_t ocsp;
ngx_str_t ocsp_responder;
ngx_str_t ocsp_responder_certificate;
ngx_shm_zone_t *ocsp_cache_zone;
ngx_flag_t stapling;

View File

@ -236,6 +236,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
offsetof(ngx_stream_ssl_srv_conf_t, ocsp_responder),
NULL },
{ ngx_string("ssl_ocsp_responder_certificate"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_ssl_srv_conf_t, ocsp_responder_certificate),
NULL },
{ ngx_string("ssl_ocsp_cache"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_stream_ssl_ocsp_cache,
@ -1054,7 +1061,7 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, conf->ocsp,
if (ngx_ssl_ocsp(cf, &conf->ssl, &conf->ocsp_responder, &conf->ocsp_responder_certificate, conf->ocsp,
conf->ocsp_cache_zone)
!= NGX_OK)
{

View File

@ -56,6 +56,7 @@ typedef struct {
ngx_uint_t ocsp;
ngx_str_t ocsp_responder;
ngx_str_t ocsp_responder_certificate;
ngx_shm_zone_t *ocsp_cache_zone;
ngx_flag_t stapling;