summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/be-secure-openssl.c9
-rw-r--r--src/include/libpq/libpq-be.h2
-rw-r--r--src/include/pg_config.h.in3
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c9
-rw-r--r--src/interfaces/libpq/libpq-int.h2
-rw-r--r--src/tools/msvc/Solution.pm9
6 files changed, 27 insertions, 7 deletions
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 795c2198a31..e307bfea823 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -1127,7 +1127,7 @@ be_tls_get_peerdn_name(Port *port, char *ptr, size_t len)
ptr[0] = '\0';
}
-#ifdef HAVE_X509_GET_SIGNATURE_NID
+#if defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO)
char *
be_tls_get_certificate_hash(Port *port, size_t *len)
{
@@ -1145,10 +1145,15 @@ be_tls_get_certificate_hash(Port *port, size_t *len)
/*
* Get the signature algorithm of the certificate to determine the hash
- * algorithm to use for the result.
+ * algorithm to use for the result. Prefer X509_get_signature_info(),
+ * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
*/
+#if HAVE_X509_GET_SIGNATURE_INFO
+ if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
+#else
if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
&algo_nid, NULL))
+#endif
elog(ERROR, "could not determine server certificate signature algorithm");
/*
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index 20b9342808e..4562163d281 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -270,7 +270,7 @@ extern void be_tls_get_peerdn_name(Port *port, char *ptr, size_t len);
* This is not supported with old versions of OpenSSL that don't have
* the X509_get_signature_nid() function.
*/
-#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID)
+#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO))
#define HAVE_BE_TLS_GET_CERTIFICATE_HASH
extern char *be_tls_get_certificate_hash(Port *port, size_t *len);
#endif
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 39bf3afca19..912132dbc5b 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -715,6 +715,9 @@
/* Define to 1 if you have the <winldap.h> header file. */
#undef HAVE_WINLDAP_H
+/* Define to 1 if you have the `X509_get_signature_info' function. */
+#undef HAVE_X509_GET_SIGNATURE_INFO
+
/* Define to 1 if you have the `X509_get_signature_nid' function. */
#undef HAVE_X509_GET_SIGNATURE_NID
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index d81cb25a0cf..55e231e8493 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -369,7 +369,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
return n;
}
-#ifdef HAVE_X509_GET_SIGNATURE_NID
+#if defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO)
char *
pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
{
@@ -389,10 +389,15 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
/*
* Get the signature algorithm of the certificate to determine the hash
- * algorithm to use for the result.
+ * algorithm to use for the result. Prefer X509_get_signature_info(),
+ * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
*/
+#if HAVE_X509_GET_SIGNATURE_INFO
+ if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
+#else
if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
&algo_nid, NULL))
+#endif
{
printfPQExpBuffer(&conn->errorMessage,
libpq_gettext("could not determine server certificate signature algorithm\n"));
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 9af7b6e68ce..632bc09e5fd 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -725,7 +725,7 @@ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
* This is not supported with old versions of OpenSSL that don't have
* the X509_get_signature_nid() function.
*/
-#if defined(USE_OPENSSL) && defined(HAVE_X509_GET_SIGNATURE_NID)
+#if defined(USE_OPENSSL) && (defined(HAVE_X509_GET_SIGNATURE_NID) || defined(HAVE_X509_GET_SIGNATURE_INFO))
#define HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
extern char *pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len);
#endif
diff --git a/src/tools/msvc/Solution.pm b/src/tools/msvc/Solution.pm
index 60293c7a88f..984d63f5d77 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -257,7 +257,14 @@ sub GenerateFiles
my ($digit1, $digit2, $digit3) = $self->GetOpenSSLVersion();
- # More symbols are needed with OpenSSL 1.1.0 and above.
+ # Symbols needed with OpenSSL 1.1.1 and above.
+ if ( ($digit1 >= '3' && $digit2 >= '0' && $digit3 >= '0')
+ || ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '1'))
+ {
+ print $o "#define HAVE_X509_GET_SIGNATURE_INFO 1\n";
+ }
+
+ # Symbols needed with OpenSSL 1.1.0 and above.
if ( ($digit1 >= '3' && $digit2 >= '0' && $digit3 >= '0')
|| ($digit1 >= '1' && $digit2 >= '1' && $digit3 >= '0'))
{