diff options
-rwxr-xr-x | configure | 12 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | src/backend/libpq/be-secure-openssl.c | 9 | ||||
-rw-r--r-- | src/include/libpq/libpq-be.h | 2 | ||||
-rw-r--r-- | src/include/pg_config.h.in | 3 | ||||
-rw-r--r-- | src/interfaces/libpq/fe-secure-openssl.c | 9 | ||||
-rw-r--r-- | src/interfaces/libpq/libpq-int.h | 2 | ||||
-rw-r--r-- | src/tools/msvc/Solution.pm | 9 |
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')) { |