Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-07-18 Thread Jacob Champion
On Wed, Jul 17, 2024 at 3:42 PM David Zhang  wrote:
> Totally agree. Either Implementing OCSP requests over HTTP, then parsing
> the response and then saving the results to a file, or using an OpenSSL
> client with a cron job to periodically update the file should work.
> Using a cron job would likely have less impact on PostgreSQL.

Yeah, my preference would be to farm this job out to OpenSSL entirely.
Implementing OCSP-over-HTTP ourselves seems unlikely to buy us much,
for all the work it would give us.

> Totally agree, then we should limit OCSP stapling check for the
> leaf/PostgreSQL server certificate only in v1.

Sounds good. Maybe a future version can implement a check of the full
chain, but I imagine we'll have to follow someone else's lead.

> > A question from ignorance: how does the client decide that the
> > signature on the OCSP response is actually valid for the specific
> > chain in use?
>
> If I understand correctly, the certificate used by the OCSP responder to
> sign the OCSP response must be valid for the specific chain in use, or
> the admins allow to load a new chain to validate the certificate used to
> sign the OCSP response. I think it would be better to make this part to
> be more open.

Okay. That part needs more design work IMO, and solid testing.

> > If it's okay with you, I'd like to volunteer to refactor out the
> > duplicated recipes in sslfiles.mk. I have some particular ideas in
> > mind and don't want to make you play fetch-a-rock. (No pressure to use
> > what I come up with, if you don't like it.)
> That would be great, thanks a lot in advance!

No problem! I've attached two patches that can be optionally applied
on top of yours:
- 0001 simplifies the response generation into a single recipe.
- 0002 is a bigger change that uses `openssl ca` to generate index
files, as opposed to constructing them manually ourselves.

(The makefile will get even smaller without multi-stapling support,
but I didn't want to combine that with the refactor.)

For 0002, I'm wiping the new CA index for each recipe and rebuilding
it from scratch, then copying it into place (this relies on the
.NOTPARALLEL setting up top for correctness). I think there's probably
an even simpler approach, which would be to generate a single index
that can produce all of our desired responses. I can give that a try
once multi-stapling support is pulled out.

> Thanks a lot for reviewing and providing all your feedback!

You're very welcome, thanks for working on this feature!

--Jacob
From 1f4f030233a895586aa7e114c92f4aa213250752 Mon Sep 17 00:00:00 2001
From: Jacob Champion 
Date: Mon, 15 Jul 2024 06:40:07 -0700
Subject: [PATCH 2/2] WIP: move to OpenSSL-constructed index files

---
 src/test/ssl/conf/ocsp.config | 19 +
 src/test/ssl/sslfiles.mk  | 75 ++-
 2 files changed, 48 insertions(+), 46 deletions(-)
 create mode 100644 src/test/ssl/conf/ocsp.config

diff --git a/src/test/ssl/conf/ocsp.config b/src/test/ssl/conf/ocsp.config
new file mode 100644
index 00..831c2f681c
--- /dev/null
+++ b/src/test/ssl/conf/ocsp.config
@@ -0,0 +1,19 @@
+[ ca ]
+default_ca = ocsp
+
+# A shell of a CA, mostly duplicating the server CA, which is used only during
+# the OCSP index generation recipes.
+[ ocsp ]
+dir = ./ssl/
+
+# The database (or "index") is the main thing we want.
+database = ./ssl/ocsp-certindex
+
+# Everything else should all be unused, so we specify whatever's most
+# convenient. In particular there's no need to have a unique cert/key pair for
+# this.
+certificate = ./ssl/server_ca.crt
+private_key = ./ssl/server_ca.key
+serial = ./ssl/ocsp_ca.srl
+default_md = sha256
+policy = policy_match
diff --git a/src/test/ssl/sslfiles.mk b/src/test/ssl/sslfiles.mk
index 9ba88f0be9..bfefa6a33e 100644
--- a/src/test/ssl/sslfiles.mk
+++ b/src/test/ssl/sslfiles.mk
@@ -196,6 +196,7 @@ CLIENT_CERTS := $(CLIENTS:%=ssl/%.crt)
 root_ca_state_files := ssl/root_ca-certindex ssl/root_ca-certindex.attr 
ssl/root_ca.srl
 server_ca_state_files := ssl/server_ca-certindex ssl/server_ca-certindex.attr 
ssl/server_ca.srl
 client_ca_state_files := ssl/client_ca-certindex ssl/client_ca-certindex.attr 
ssl/client_ca.srl
+ocsp_ca_state_files := ssl/ocsp-certindex ssl/ocsp-certindex.attr 
ssl/ocsp_ca.srl
 
 # These are the workhorse recipes. `openssl ca` can't be safely run from
 # parallel processes, so we must mark the entire Makefile .NOTPARALLEL.
@@ -224,6 +225,7 @@ ssl/%.csr: ssl/%.key conf/%.config
 #
 
 .INTERMEDIATE: $(root_ca_state_files) $(server_ca_state_files) 
$(client_ca_state_files)
+.INTERMEDIATE: $(ocsp_ca_state_files)
 
 # OpenSSL requires a directory to put all generated certificates in. We don't
 # use this for anything, but we need a location.
@@ -245,68 +247,49 @@ ssl/%.srl:
 # OCSP
 #
 .INTERMEDIATE: $(OCSPS:%=ssl/%.idx)
+
 # given status 'V' without 'revocation date' to generate an ocsp response with 
status 'good' for 1 days
-ssl/server-ocsp-good.idx: 

Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-07-17 Thread David Zhang

= Design =

It looks like this design relies on the DBA to manually prefetch OCSP
responses for their cert chain, and cache them in the local
ssl_ocsp_file. This is similar to Nginx's ssl_stapling_file directive
[1]. I think this may make sense for a v1 (much less code!), but it's
going to take a lot of good documentation on what, exactly, an admin
has to do to make sure their response file is fresh. IIUC it will
depend on the CA's policy and how they operate their responder.

We should probably be prepared for complaints that we don't run the
client ourselves. A v2 could maybe include an extension for running
the OCSP client in a background worker? Or maybe that's overkill, and
an existing job scheduler extension could do it, but having a custom
worker that could periodically check the response file and provide
warnings when it gets close to expiring might be helpful for admins.
Totally agree. Either Implementing OCSP requests over HTTP, then parsing 
the response and then saving the results to a file, or using an OpenSSL 
client with a cron job to periodically update the file should work. 
Using a cron job would likely have less impact on PostgreSQL.

I am worried about the multi-stapling that is being done in the tests,
for example the server-ca-ocsp-good response file. I think those tests
are cheating a bit. Yes, for this particular case, we can issue a
single signed response for both the intermediate and the leaf -- but
that's only because we issued both of them. What if your intermediate
and your root use different responders [2]? What if your issuer's
responder doesn't even support multiple certs per request [3]?

(Note that OpenSSL still doesn't support multi-stapling [4], even in
TLS 1.3 where we were supposed to get it "for free".)


Totally agree, then we should limit OCSP stapling check for the 
leaf/PostgreSQL server certificate only in v1.



I think it would be good for the sslocspstapling directive to 1) maybe
have a shorter name (cue bikeshed!) and 2) support more than a binary
on/off. For example, the current implementation could use
"disable/require" options, and then a v2 could add "prefer" which
simply sends the status request and honors must-staple extensions on
the certificate. (That should be safe to default to, I think, and it
would let DBAs control the stapling rollout more easily.)


This will definitely give end users more options, especially during the 
transition period.



A question from ignorance: how does the client decide that the
signature on the OCSP response is actually valid for the specific
chain in use?


If I understand correctly, the certificate used by the OCSP responder to 
sign the OCSP response must be valid for the specific chain in use, or 
the admins allow to load a new chain to validate the certificate used to 
sign the OCSP response. I think it would be better to make this part to 
be more open.




= Tests =

I think the tests should record the expected_stderr messages for
failures (see the Code section below for why).

+1

If it turns out that multi-stapling is safe, then IMO the tests should
explicitly test both TLSv1.2 and v1.3, since those protocols differ in
how they handle per-certificate status.

If it's okay with you, I'd like to volunteer to refactor out the
duplicated recipes in sslfiles.mk. I have some particular ideas in
mind and don't want to make you play fetch-a-rock. (No pressure to use
what I come up with, if you don't like it.)

That would be great, thanks a lot in advance!

Because a CRL is a valid fallback for OCSP in practice, I think there
should be some tests for their interaction. (For v1, maybe that's as
simple as "you're not allowed to use both yet", but it should be
explicit.)

+1

= Code =

(this is a very shallow review)

+#define OCSP_CERT_STATUS_OK1
+#define OCSP_CERT_STATUS_NOK   (-1)

Returning f -1 from the callback indicates an internal error, so we're
currently sending the wrong alerts for OCSP failures ("internal error"
rather than "bad certificate status response") and getting unhelpful
error messages from libpq. For cases where the handshake proceeds
correctly but we don't accept the OCSP response status, I think we
should be returning zero.

+1

Also, we should not stomp on the OCSP_ namespace (I thought these
macros were part of the official  API at first).

+1

+   /* set up OCSP stapling callback */
+   SSL_CTX_set_tlsext_status_cb(SSL_context, ocsp_stapling_cb);

It seems like this should only be done if ssl_ocsp_file is set?


+1

Thanks a lot for reviewing and providing all your feedback!


Best regards,

David Zhang





Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-07-15 Thread Jacob Champion
On Tue, Mar 5, 2024 at 4:12 PM David Zhang  wrote:
> This is the third version patch for "Certificate status check using OCSP
> Stapling" with ssl regression test cases added.

Hi David,

Thanks again for working on this! So far I've taken a look at the
design and tests. I've only skimmed the callback implementations; I
plan to review those in more detail once the architecture is nailed
down.

= Design =

It looks like this design relies on the DBA to manually prefetch OCSP
responses for their cert chain, and cache them in the local
ssl_ocsp_file. This is similar to Nginx's ssl_stapling_file directive
[1]. I think this may make sense for a v1 (much less code!), but it's
going to take a lot of good documentation on what, exactly, an admin
has to do to make sure their response file is fresh. IIUC it will
depend on the CA's policy and how they operate their responder.

We should probably be prepared for complaints that we don't run the
client ourselves. A v2 could maybe include an extension for running
the OCSP client in a background worker? Or maybe that's overkill, and
an existing job scheduler extension could do it, but having a custom
worker that could periodically check the response file and provide
warnings when it gets close to expiring might be helpful for admins.

I am worried about the multi-stapling that is being done in the tests,
for example the server-ca-ocsp-good response file. I think those tests
are cheating a bit. Yes, for this particular case, we can issue a
single signed response for both the intermediate and the leaf -- but
that's only because we issued both of them. What if your intermediate
and your root use different responders [2]? What if your issuer's
responder doesn't even support multiple certs per request [3]?

(Note that OpenSSL still doesn't support multi-stapling [4], even in
TLS 1.3 where we were supposed to get it "for free".)

I think it would be good for the sslocspstapling directive to 1) maybe
have a shorter name (cue bikeshed!) and 2) support more than a binary
on/off. For example, the current implementation could use
"disable/require" options, and then a v2 could add "prefer" which
simply sends the status request and honors must-staple extensions on
the certificate. (That should be safe to default to, I think, and it
would let DBAs control the stapling rollout more easily.)

A question from ignorance: how does the client decide that the
signature on the OCSP response is actually valid for the specific
chain in use?

= Tests =

I think the tests should record the expected_stderr messages for
failures (see the Code section below for why).

If it turns out that multi-stapling is safe, then IMO the tests should
explicitly test both TLSv1.2 and v1.3, since those protocols differ in
how they handle per-certificate status.

If it's okay with you, I'd like to volunteer to refactor out the
duplicated recipes in sslfiles.mk. I have some particular ideas in
mind and don't want to make you play fetch-a-rock. (No pressure to use
what I come up with, if you don't like it.)

Because a CRL is a valid fallback for OCSP in practice, I think there
should be some tests for their interaction. (For v1, maybe that's as
simple as "you're not allowed to use both yet", but it should be
explicit.)

= Code =

(this is a very shallow review)

+#define OCSP_CERT_STATUS_OK1
+#define OCSP_CERT_STATUS_NOK   (-1)

Returning f -1 from the callback indicates an internal error, so we're
currently sending the wrong alerts for OCSP failures ("internal error"
rather than "bad certificate status response") and getting unhelpful
error messages from libpq. For cases where the handshake proceeds
correctly but we don't accept the OCSP response status, I think we
should be returning zero.

Also, we should not stomp on the OCSP_ namespace (I thought these
macros were part of the official  API at first).

+   /* set up OCSP stapling callback */
+   SSL_CTX_set_tlsext_status_cb(SSL_context, ocsp_stapling_cb);

It seems like this should only be done if ssl_ocsp_file is set?

Thanks again!
--Jacob

[1] https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_stapling_file
[2] as appears to be the case for postgresql.org
[3] https://community.letsencrypt.org/t/bulk-ocsp-requests/168156/2
[4] https://github.com/openssl/openssl/pull/20945




Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-03-22 Thread Jacob Champion
On Tue, Mar 5, 2024 at 4:12 PM David Zhang  wrote:
> Any comments or feedback would be greatly appreciated!

Hi David -- I haven't had time to get to this for the 17 release
cycle, but I'm interested in this feature and I intend to review it at
some point for 18. I think OCSP will be especially helpful for anyone
relying on sslrootcert=system. Thanks for working on it!

--Jacob




Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-03-05 Thread David Zhang

Hi Hackers,

This is the third version patch for "Certificate status check using OCSP 
Stapling" with ssl regression test cases added.


Here is how I run the ssl regression test:
    ./configure --enable-tap-tests --with-openssl
    make -j
    cd src/test/ssl
    make sslfiles
    make check PG_TEST_EXTRA=ssl

expected results:
    # +++ tap check in src/test/ssl +++
    t/001_ssltests.pl .. ok
    t/002_scram.pl . ok
    t/003_sslinfo.pl ... ok
    All tests successful.
    Files=3, Tests=279, 17 wallclock secs ( 0.05 usr  0.01 sys + 2.32 
cusr  2.16 csys =  4.54 CPU)


    Result: PASS

Notes, before executing the SSL regression tests with the command `make 
check PG_TEST_EXTRA=ssl`, it is necessary to wait for 1 minute after 
running `make sslfiles`. This delay is required because the newly 
generated OCSP responses for the 'expired' test cases need 1 minute to 
pass the nextUpdate period. Once the stapled OCSP response files for the 
tests are committed as test input, there is no need to wait, similar to 
certificate files.


Any comments or feedback would be greatly appreciated!

Thank you,

DavidFrom 99fc46ed0bf05eedbe7539890d946db472617150 Mon Sep 17 00:00:00 2001
From: David Zhang 
Date: Tue, 5 Mar 2024 15:31:22 -0800
Subject: [PATCH 1/3] support certificate status check using OCSP stapling

---
 src/backend/libpq/be-secure-openssl.c |  87 
 src/backend/libpq/be-secure.c |   1 +
 src/backend/utils/misc/guc_tables.c   |  10 +
 src/backend/utils/misc/postgresql.conf.sample |   1 +
 src/include/libpq/libpq.h |   1 +
 src/interfaces/libpq/fe-connect.c |  37 
 src/interfaces/libpq/fe-secure-openssl.c  | 198 ++
 src/interfaces/libpq/libpq-int.h  |   1 +
 8 files changed, 336 insertions(+)

diff --git a/src/backend/libpq/be-secure-openssl.c 
b/src/backend/libpq/be-secure-openssl.c
index e12b1cc9e3..c727634dfa 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -50,6 +50,7 @@
 #include 
 #endif
 #include 
+#include 
 
 
 /* default init hook can be overridden by a shared library */
@@ -81,6 +82,8 @@ static bool ssl_is_server_start;
 static int ssl_protocol_version_to_openssl(int v);
 static const char *ssl_protocol_version_to_string(int v);
 
+static int ocsp_stapling_cb(SSL *ssl);
+
 /* for passing data back from verify_cb() */
 static const char *cert_errdetail;
 
@@ -429,6 +432,9 @@ be_tls_open_server(Port *port)
return -1;
}
 
+   /* set up OCSP stapling callback */
+   SSL_CTX_set_tlsext_status_cb(SSL_context, ocsp_stapling_cb);
+
/* set up debugging/info callback */
SSL_CTX_set_info_callback(SSL_context, info_cb);
 
@@ -1653,3 +1659,84 @@ default_openssl_tls_init(SSL_CTX *context, bool 
isServerStart)
SSL_CTX_set_default_passwd_cb(context, 
dummy_ssl_passwd_cb);
}
 }
+
+/*
+ * OCSP stapling callback function for the server side.
+ *
+ * This function is responsible for providing the OCSP stapling response to
+ * the client during the SSL/TLS handshake, based on the client's request.
+ *
+ * Parameters:
+ *   - ssl: SSL/TLS connection object.
+ *
+ * Returns:
+ *   - SSL_TLSEXT_ERR_OK: OCSP stapling response successfully provided.
+ *   - SSL_TLSEXT_ERR_NOACK: OCSP stapling response not provided due to errors.
+ *
+ * Steps:
+ *   1. Check if the server-side OCSP stapling feature is enabled.
+ *   2. Read OCSP response from file if client requested OCSP stapling.
+ *   3. Set the OCSP stapling response in the SSL/TLS connection.
+ */
+static int ocsp_stapling_cb(SSL *ssl)
+{
+   int resp_len = -1;
+   BIO *bio = NULL;
+   OCSP_RESPONSE   *resp = NULL;
+   unsigned char   *rspder = NULL;
+
+   /* return, if ssl_ocsp_file not enabled on server */
+   if (ssl_ocsp_file == NULL)
+   {
+   ereport(WARNING,
+   (errcode(ERRCODE_CONFIG_FILE_ERROR),
+errmsg("could not find ssl_ocsp_file")));
+   return SSL_TLSEXT_ERR_NOACK;
+   }
+
+   /* whether the client requested OCSP stapling */
+   if (SSL_get_tlsext_status_type(ssl) == TLSEXT_STATUSTYPE_ocsp)
+   {
+   bio = BIO_new_file(ssl_ocsp_file, "r");
+   if (bio == NULL)
+   {
+   ereport(WARNING,
+   (errcode(ERRCODE_CONFIG_FILE_ERROR),
+errmsg("could not read 
ssl_ocsp_file")));
+   return SSL_TLSEXT_ERR_NOACK;
+   }
+
+   resp = d2i_OCSP_RESPONSE_bio(bio, NULL);
+   BIO_free(bio);
+   if (resp == NULL)
+   {
+   ereport(WARNING,
+   (errcode(ERRCODE_PROTOCOL_VIOLATION),
+   

Re: Proposal for implementing OCSP Stapling in PostgreSQL

2024-02-23 Thread David Zhang

Hi Hackers,

This is the 2nd version patch with following updates:

1) Changed the frontend SSL parameter from `ssl_ocsp_stapling` to 
`sslocspstapling` to align with other SSL parameters.


2) Documented both the backend parameter `ssl_ocsp_file` and the 
frontend parameter `sslocspstapling`.


3) Implemented a check for the `nextUpdate` field in the OCSP response. 
If it is present but expired, the TLS connection will fail."


To add the test cases for OCSP Stapling, I think I should 1) add one 
section to conf/cas.config to generate `ocsp_ca.crt`; 2) use this 
`ocsp_ca` to sign some OCSP responses for server side certificates with 
`good`, `revoked` and `unknown`, and then 3) add some test cases to 
t/001_ssltests.pl.


Any comments or feedback would be greatly appreciated!

Thank you,

David


On 2024-02-05 3:51 p.m., David Zhang wrote:

Hello PostgreSQL Hackers,

This proposal suggests implementing OCSP Stapling in PostgreSQL as an 
alternative and more efficient method for checking certificate 
revocation, aligning with the trend shift from Certificate Revocation 
Lists (CRL).



1. benefits
OCSP Stapling offers several advantages over traditional CRL checks, 
including:


*) enhances user trust and real-time certificate verification without 
relying on potentially outdated CRLs.
*) helps address privacy concerns associated with traditional OCSP 
checks, where the client contacts the OCSP responder directly.
*) reduces latency by eliminating the need for the client to perform 
an additional round-trip to the OCSP responder.
*) efficient resource utilization by allowing the server to cache and 
reuse OCSP responses.




2. a POC patch with below changes:
*) a new configuration option 'ssl_ocsp_file' to enable/disable OCSP 
Stapling and specify OCSP responses for PostgreSQL servers. For 
instance, ssl_ocsp_file = '_server.resp'


*) a server-side callback function responsible for generating OCSP 
stapling responses. This function comes into play only when a client 
requests the server's certificate status during the SSL/TLS handshake.


*) a new connection parameter 'ssl_ocsp_stapling' on the client side. 
For example, when 'ssl_ocsp_stapling=1', the psql client will send a 
certificate status request to the PostgreSQL server.


*) a client-side callback function within the libpq interface to 
validate and check the stapled OCSP response received from the server. 
If the server's certificate status is valid, the TLS handshake 
continues; otherwise, the connection is rejected.




3.  test cases for 'make check' are not yet ready as they could be 
complicated, but basic tests can be performed as demonstrated below:
To run the tests, OpenSSL tools are required to simulate the OCSP 
responder for generating OCSP responses. Additionally, initial 
certificate generation, including a self-signed root CA, OCSP response 
signing certificate, and PostgreSQL server certificate, is needed.


*) add ocsp atrributes to openssl.cnf
$ openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

$ diff openssl-ocsp.cnf /etc/ssl/openssl.cnf
204d203
< authorityInfoAccess = OCSP;URI:http://127.0.0.1:6655
232,235d230
< [ v3_ocsp ]
< basicConstraints = CA:FALSE
< keyUsage = nonRepudiation, digitalSignature, keyEncipherment
< extendedKeyUsage = OCSPSigning
255c250
< keyUsage = critical, cRLSign, digitalSignature, keyCertSign
---
>


*) prepare OCSP responder for generating OCSP response
$ mkdir -p demoCA/newcerts
$ touch demoCA/index.txt
$ echo '01' > demoCA/serial

# create a self-signed root CA
$ openssl req -new -nodes -out rootCA.csr -keyout rootCA.key -subj 
"/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=rootCA"
$ openssl x509 -req -in rootCA.csr -days 3650 -extfile 
openssl-ocsp.cnf -extensions v3_ca -signkey rootCA.key -out rootCA.crt


# create a certificate for OCSP responder
$ openssl req -new -nodes -out ocspSigning.csr -keyout ocspSigning.key 
-subj "/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=ocspSigner"
$ openssl ca -keyfile rootCA.key -cert rootCA.crt -in ocspSigning.csr 
-out ocspSigning.crt -config openssl-ocsp.cnf -extensions v3_ocsp

    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y

# create a certificate for PostgreSQL server
$ openssl req -new -nodes -out server.csr -keyout server.key -subj 
"/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=server"
$ openssl ca -batch -days 365 -keyfile rootCA.key -cert rootCA.crt 
-config openssl-ocsp.cnf -out server.crt -infiles server.csr



# start OCSP responder
$ openssl ocsp -index demoCA/index.txt -port 6655 -rsigner 
ocspSigning.crt -rkey ocspSigning.key -CA rootCA.crt -text


# make sure PostgreSQL server's certificate is 'good'
$ openssl ocsp -issuer rootCA.crt -url http://127.0.0.1:6655 
-resp_text -noverify -cert server.crt


# generate OCSP response when certificate status is 'good' and save as 
_server.resp-good:
$ openssl ocsp -issuer rootCA.crt -cert server

Proposal for implementing OCSP Stapling in PostgreSQL

2024-02-05 Thread David Zhang

Hello PostgreSQL Hackers,

This proposal suggests implementing OCSP Stapling in PostgreSQL as an 
alternative and more efficient method for checking certificate 
revocation, aligning with the trend shift from Certificate Revocation 
Lists (CRL).



1. benefits
OCSP Stapling offers several advantages over traditional CRL checks, 
including:


*) enhances user trust and real-time certificate verification without 
relying on potentially outdated CRLs.
*) helps address privacy concerns associated with traditional OCSP 
checks, where the client contacts the OCSP responder directly.
*) reduces latency by eliminating the need for the client to perform an 
additional round-trip to the OCSP responder.
*) efficient resource utilization by allowing the server to cache and 
reuse OCSP responses.




2. a POC patch with below changes:
*) a new configuration option 'ssl_ocsp_file' to enable/disable OCSP 
Stapling and specify OCSP responses for PostgreSQL servers. For 
instance, ssl_ocsp_file = '_server.resp'


*) a server-side callback function responsible for generating OCSP 
stapling responses. This function comes into play only when a client 
requests the server's certificate status during the SSL/TLS handshake.


*) a new connection parameter 'ssl_ocsp_stapling' on the client side. 
For example, when 'ssl_ocsp_stapling=1', the psql client will send a 
certificate status request to the PostgreSQL server.


*) a client-side callback function within the libpq interface to 
validate and check the stapled OCSP response received from the server. 
If the server's certificate status is valid, the TLS handshake 
continues; otherwise, the connection is rejected.




3.  test cases for 'make check' are not yet ready as they could be 
complicated, but basic tests can be performed as demonstrated below:
To run the tests, OpenSSL tools are required to simulate the OCSP 
responder for generating OCSP responses. Additionally, initial 
certificate generation, including a self-signed root CA, OCSP response 
signing certificate, and PostgreSQL server certificate, is needed.


*) add ocsp atrributes to openssl.cnf
$ openssl version
OpenSSL 3.0.2 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022)

$ diff openssl-ocsp.cnf /etc/ssl/openssl.cnf
204d203
< authorityInfoAccess = OCSP;URI:http://127.0.0.1:6655
232,235d230
< [ v3_ocsp ]
< basicConstraints = CA:FALSE
< keyUsage = nonRepudiation, digitalSignature, keyEncipherment
< extendedKeyUsage = OCSPSigning
255c250
< keyUsage = critical, cRLSign, digitalSignature, keyCertSign
---
>


*) prepare OCSP responder for generating OCSP response
$ mkdir -p demoCA/newcerts
$ touch demoCA/index.txt
$ echo '01' > demoCA/serial

# create a self-signed root CA
$ openssl req -new -nodes -out rootCA.csr -keyout rootCA.key -subj 
"/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=rootCA"
$ openssl x509 -req -in rootCA.csr -days 3650 -extfile openssl-ocsp.cnf 
-extensions v3_ca -signkey rootCA.key -out rootCA.crt


# create a certificate for OCSP responder
$ openssl req -new -nodes -out ocspSigning.csr -keyout ocspSigning.key 
-subj "/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=ocspSigner"
$ openssl ca -keyfile rootCA.key -cert rootCA.crt -in ocspSigning.csr 
-out ocspSigning.crt -config openssl-ocsp.cnf -extensions v3_ocsp

    Sign the certificate? [y/n]:y
    1 out of 1 certificate requests certified, commit? [y/n]y

# create a certificate for PostgreSQL server
$ openssl req -new -nodes -out server.csr -keyout server.key -subj 
"/C=CA/ST=BC/L=VAN/O=IDO/OU=DEV/CN=server"
$ openssl ca -batch -days 365 -keyfile rootCA.key -cert rootCA.crt 
-config openssl-ocsp.cnf -out server.crt -infiles server.csr



# start OCSP responder
$ openssl ocsp -index demoCA/index.txt -port 6655 -rsigner 
ocspSigning.crt -rkey ocspSigning.key -CA rootCA.crt -text


# make sure PostgreSQL server's certificate is 'good'
$ openssl ocsp -issuer rootCA.crt -url http://127.0.0.1:6655 -resp_text 
-noverify -cert server.crt


# generate OCSP response when certificate status is 'good' and save as 
_server.resp-good:
$ openssl ocsp -issuer rootCA.crt -cert server.crt -url 
http://127.0.0.1:6655 -respout _server.resp-good



# revoke PostgreSQL server's certificate
$ openssl ca -keyfile rootCA.key -cert rootCA.crt -revoke server.crt

# make sure PostgreSQL server's certificate is 'revoked'
$ openssl ocsp -issuer rootCA.crt -url http://127.0.0.1:6655 -resp_text 
-noverify -cert server.crt


### generate OCSP response when certificate status is 'revoked' and save 
as _server.resp-revoked:
$ openssl ocsp -issuer rootCA.crt -cert server.crt -url 
http://127.0.0.1:6655 -respout _server.resp-revoked



*) setup OCSP stapling on PostgreSQL server side
copy 'rootCA.crt, server.key, server.crt, _server.resp-good, and 
_server.resp-revoked' to pgdata folder and update PostgreSQL server 
configuration by specifying ssl_ocsp_file = '_server.resp', where 
'_server.resp' is either a copy of '_server.resp-good' or 
'_server