aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure12
-rw-r--r--configure.in2
-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
8 files changed, 41 insertions, 7 deletions
diff --git a/configure b/configure
index 648e367678f..7b97a409a8e 100755
--- a/configure
+++ b/configure
@@ -12661,6 +12661,18 @@ _ACEOF
fi
done
+ # Function introduced in OpenSSL 1.1.1.
+ for ac_func in X509_get_signature_info
+do :
+ ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info"
+if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_X509_GET_SIGNATURE_INFO 1
+_ACEOF
+
+fi
+done
+
# SSL_clear_options is a macro in OpenSSL from 0.9.8 to 1.0.2, and
# a function from 1.1.0 onwards so we cannot use AC_CHECK_FUNCS.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_clear_options" >&5
diff --git a/configure.in b/configure.in
index 91d12c7de42..6a89b798537 100644
--- a/configure.in
+++ b/configure.in
@@ -1292,6 +1292,8 @@ if test "$with_openssl" = yes ; then
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
# function was removed.
AC_CHECK_FUNCS([CRYPTO_lock])
+ # Function introduced in OpenSSL 1.1.1.
+ AC_CHECK_FUNCS([X509_get_signature_info])
# SSL_clear_options is a macro in OpenSSL from 0.9.8 to 1.0.2, and
# a function from 1.1.0 onwards so we cannot use AC_CHECK_FUNCS.
AC_CACHE_CHECK([for SSL_clear_options], ac_cv_func_ssl_clear_options,
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 106cde08670..b0a1f7258a0 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -1193,7 +1193,7 @@ be_tls_get_peer_serial(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)
{
@@ -1211,10 +1211,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 96ed175523c..457fd55cfaf 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -282,7 +282,7 @@ extern void be_tls_get_peer_serial(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 84ee764daf3..d42f78b1172 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -733,6 +733,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 a19bce8e3c2..5948a379838 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 1b13e0ab166..a443418699f 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -750,7 +750,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 3815a7fb972..04e417901f9 100644
--- a/src/tools/msvc/Solution.pm
+++ b/src/tools/msvc/Solution.pm
@@ -253,7 +253,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'))
{