Welcome! Log In Create A New Profile

Advanced

[PATCH 4 of 6] SSL: caching certificate revocation lists

Mini Hawthorne
July 23, 2024 03:32PM
# HG changeset patch
# User Mini Hawthorne <mini@f5.com>
# Date 1721762914 0
# Tue Jul 23 19:28:34 2024 +0000
# Node ID 867e05f555e6f593589a0278c865e7dcffe597f4
# Parent 42e86c051200bf00d9ae6e38d6c87a916391b642
SSL: caching certificate revocation lists.

Added ngx_ssl_cache_crl which is similar to certificate caching.
It basically calls X509_CRL versions of APIs instead of X509 versions.

diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -886,17 +886,16 @@ ngx_ssl_trusted_certificate(ngx_conf_t *
ngx_int_t
ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
{
- X509_STORE *store;
- X509_LOOKUP *lookup;
+ int n, i;
+ char *err;
+ X509_CRL *xc;
+ X509_STORE *store;
+ STACK_OF(X509_CRL) *xcsk;

if (crl->len == 0) {
return NGX_OK;
}

- if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
- return NGX_ERROR;
- }
-
store = SSL_CTX_get_cert_store(ssl->ctx);

if (store == NULL) {
@@ -905,20 +904,44 @@ ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *s
return NGX_ERROR;
}

- lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
-
- if (lookup == NULL) {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_STORE_add_lookup() failed");
+ xcsk = ngx_ssl_cache_fetch(cf->cycle, cf->pool, &ngx_ssl_cache_crl,
+ &err, crl, NULL);
+ if (xcsk == NULL) {
+ if (err != NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "failed to load \"%s\": %s", crl->data, err);
+ }
+
return NGX_ERROR;
}

- if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
- == 0)
- {
- ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
- "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
- return NGX_ERROR;
+ n = sk_X509_CRL_num(xcsk);
+
+ for (i = 0; i < n; i++) {
+ xc = sk_X509_CRL_value(xcsk, i);
+
+ if (X509_STORE_add_crl(store, xc) != 1) {
+
+#if !(OPENSSL_VERSION_NUMBER >= 0x1010009fL \
+ || LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
+ u_long error;
+
+ /* not reported in OpenSSL 1.1.0i+ */
+
+ error = ERR_peek_last_error();
+
+ if (ERR_GET_LIB(error) == ERR_LIB_X509
+ && ERR_GET_REASON(error) == X509_R_CERT_ALREADY_IN_HASH_TABLE)
+ {
+ ERR_clear_error();
+ continue;
+ }
+#endif
+
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_STORE_add_crl() failed");
+ return NGX_ERROR;
+ }
}

X509_STORE_set_flags(store,
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -352,6 +352,7 @@ extern int ngx_ssl_index;


extern ngx_ssl_cache_type_t ngx_ssl_cache_cert;
+extern ngx_ssl_cache_type_t ngx_ssl_cache_crl;


#endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */
diff --git a/src/event/ngx_event_openssl_cache.c b/src/event/ngx_event_openssl_cache.c
--- a/src/event/ngx_event_openssl_cache.c
+++ b/src/event/ngx_event_openssl_cache.c
@@ -50,6 +50,10 @@ static void *ngx_ssl_cache_cert_create(n
static void ngx_ssl_cache_cert_free(void *data);
static void *ngx_ssl_cache_cert_ref(char **err, void *data);

+static void *ngx_ssl_cache_crl_create(ngx_str_t *id, char **err, void *data);
+static void ngx_ssl_cache_crl_free(void *data);
+static void *ngx_ssl_cache_crl_ref(char **err, void *data);
+
static BIO *ngx_ssl_cache_create_bio(ngx_str_t *id, char **err);


@@ -69,6 +73,15 @@ ngx_ssl_cache_type_t ngx_ssl_cache_cert
};


+ngx_ssl_cache_type_t ngx_ssl_cache_crl = {
+ "certificate revocation list",
+
+ ngx_ssl_cache_crl_create,
+ ngx_ssl_cache_crl_free,
+ ngx_ssl_cache_crl_ref,
+};
+
+
ngx_module_t ngx_openssl_cache_module = {
NGX_MODULE_V1,
&ngx_openssl_cache_module_ctx, /* module context */
@@ -405,6 +418,96 @@ ngx_ssl_cache_cert_ref(char **err, void
}


+static void *
+ngx_ssl_cache_crl_create(ngx_str_t *id, char **err, void *data)
+{
+ BIO *bio;
+ u_long n;
+ X509_CRL *xc;
+ STACK_OF(X509_CRL) *sk;
+
+ /* start with an empty revocation list */
+ sk = sk_X509_CRL_new_null();
+ if (sk == NULL) {
+ *err = "sk_X509_CRL_new_null() failed";
+ return NULL;
+ }
+
+ /* figure out where to load from */
+ bio = ngx_ssl_cache_create_bio(id, err);
+ if (bio == NULL) {
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+
+ /* read all of the revocations */
+ while ((xc = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
+ if (sk_X509_CRL_push(sk, xc) <= 0) {
+ *err = "sk_X509_CRL_push() failed";
+ BIO_free(bio);
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+ }
+
+ BIO_free(bio);
+
+ n = ERR_peek_last_error();
+ if (sk_X509_CRL_num(sk) == 0
+ || ERR_GET_LIB(n) != ERR_LIB_PEM
+ || ERR_GET_REASON(n) != PEM_R_NO_START_LINE)
+ {
+ /* the failure wasn't "no more revocations to load" */
+ *err = "PEM_read_bio_X509_CRL() failed";
+ sk_X509_CRL_pop_free(sk, X509_CRL_free);
+ return NULL;
+ }
+
+ /* success leaves errors on the error stack */
+ ERR_clear_error();
+
+ return sk;
+}
+
+
+static void
+ngx_ssl_cache_crl_free(void *data)
+{
+ sk_X509_CRL_pop_free(data, X509_CRL_free);
+}
+
+
+static void *
+ngx_ssl_cache_crl_ref(char **err, void *data)
+{
+ int n, i;
+ X509_CRL *xc;
+ STACK_OF(X509_CRL) *sk;
+
+ /* stacks aren't reference-counted, so shallow copy into a new stack */
+ sk = sk_X509_CRL_dup(data);
+ if (sk == NULL) {
+ *err = "sk_X509_CRL_dup() failed";
+ return NULL;
+ }
+
+ /* bump the revocations' reference counts */
+ n = sk_X509_CRL_num(sk);
+
+ for (i = 0; i < n; i++) {
+ xc = sk_X509_CRL_value(sk, i);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+ X509_CRL_up_ref(xc);
+#else
+ CRYPTO_add(&xc->references, 1, CRYPTO_LOCK_X509_CRL);
+#endif
+ }
+
+ return sk;
+}
+
+
static BIO *
ngx_ssl_cache_create_bio(ngx_str_t *id, char **err)
{
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
https://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

[PATCH 1 of 6] SSL: moved certificate storage out of SSL_CTX exdata

Mini Hawthorne 214 July 23, 2024 03:32PM

[PATCH 2 of 6] SSL: object caching

Mini Hawthorne 34 July 23, 2024 03:32PM

Re: [PATCH 2 of 6] SSL: object caching

Aleksei Bavshin 29 August 12, 2024 04:54PM

[PATCH 3 of 6] SSL: caching certificates

Mini Hawthorne 30 July 23, 2024 03:32PM

[PATCH 4 of 6] SSL: caching certificate revocation lists

Mini Hawthorne 36 July 23, 2024 03:32PM

[PATCH 5 of 6] SSL: caching private keys

Mini Hawthorne 40 July 23, 2024 03:32PM

[PATCH 6 of 6] SSL: caching CA certificates

Mini Hawthorne 49 July 23, 2024 03:32PM

Re: [PATCH 1 of 6] SSL: moved certificate storage out of SSL_CTX exdata

Sergey Kandaurov 39 August 21, 2024 09:34AM



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

Online Users

Guests: 147
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 500 on July 15, 2024
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready