Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2eb8e54

Browse files
committed
Fix handling of SCRAM-SHA-256's channel binding with RSA-PSS certificates
OpenSSL 1.1.1 and newer versions have added support for RSA-PSScertificates, which requires the use of a specific routine in OpenSSL todetermine which hash function to use when compiling it when usingchannel binding in SCRAM-SHA-256. X509_get_signature_nid(), that is theoriginal routine the channel binding code has relied on, is not able todetermine which hash algorithm to use for such certificates. However,X509_get_signature_info(), new to OpenSSL 1.1.1, is able to do it. Thiscommit switches the channel binding logic to rely onX509_get_signature_info() over X509_get_signature_nid(), which would bethe choice when building with 1.1.1 or newer.The error could have been triggered on the client or the server, hencelibpq and the backend need to have their related code paths patched.Note that attempting to load an RSA-PSS certificate with OpenSSL 1.1.0or older leads to a failure due to an unsupported algorithm.The discovery of relying on X509_get_signature_info() comes from Jacob,the tests have been written by Heikki (with few tweaks from me), while Ihave bundled the whole together while adding the bits needed for MSVCand meson.This issue exists since channel binding exists, so backpatch all the waydown. Some tests are added in 15~, triggered if compiling with OpenSSL1.1.1 or newer, where the certificate and key files can easily begenerated for RSA-PSS.Reported-by: Gunnar "Nick" BluthAuthor: Jacob Champion, Heikki LinnakangasDiscussion:https://postgr.es/m/17760-b6c61e752ec07060@postgresql.orgBackpatch-through: 11
1 parent301eb3e commit2eb8e54

File tree

8 files changed

+42
-7
lines changed

8 files changed

+42
-7
lines changed

‎configure

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12730,6 +12730,18 @@ if test "x$ac_cv_func_CRYPTO_lock" = xyes; then :
1273012730
#define HAVE_CRYPTO_LOCK 1
1273112731
_ACEOF
1273212732

12733+
fi
12734+
done
12735+
12736+
# Function introduced in OpenSSL 1.1.1.
12737+
for ac_func in X509_get_signature_info
12738+
do :
12739+
ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info"
12740+
if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
12741+
cat >>confdefs.h <<_ACEOF
12742+
#define HAVE_X509_GET_SIGNATURE_INFO 1
12743+
_ACEOF
12744+
1273312745
fi
1273412746
done
1273512747

‎configure.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1277,6 +1277,8 @@ if test "$with_openssl" = yes ; then
12771277
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
12781278
# function was removed.
12791279
AC_CHECK_FUNCS([CRYPTO_lock])
1280+
# Function introduced in OpenSSL 1.1.1.
1281+
AC_CHECK_FUNCS([X509_get_signature_info])
12801282
fi
12811283

12821284
if test "$with_pam" = yes ; then

‎src/backend/libpq/be-secure-openssl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,7 +1243,7 @@ be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
12431243
ptr[0]='\0';
12441244
}
12451245

1246-
#ifdefHAVE_X509_GET_SIGNATURE_NID
1246+
#if defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO)
12471247
char*
12481248
be_tls_get_certificate_hash(Port*port,size_t*len)
12491249
{
@@ -1261,10 +1261,15 @@ be_tls_get_certificate_hash(Port *port, size_t *len)
12611261

12621262
/*
12631263
* Get the signature algorithm of the certificate to determine the hash
1264-
* algorithm to use for the result.
1264+
* algorithm to use for the result. Prefer X509_get_signature_info(),
1265+
* introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
12651266
*/
1267+
#ifHAVE_X509_GET_SIGNATURE_INFO
1268+
if (!X509_get_signature_info(server_cert,&algo_nid,NULL,NULL,NULL))
1269+
#else
12661270
if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
12671271
&algo_nid,NULL))
1272+
#endif
12681273
elog(ERROR,"could not determine server certificate signature algorithm");
12691274

12701275
/*

‎src/include/libpq/libpq-be.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);
283283
* This is not supported with old versions of OpenSSL that don't have
284284
* the X509_get_signature_nid() function.
285285
*/
286-
#if defined(USE_OPENSSL)&& defined(HAVE_X509_GET_SIGNATURE_NID)
286+
#if defined(USE_OPENSSL)&&(defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO))
287287
#defineHAVE_BE_TLS_GET_CERTIFICATE_HASH
288288
externchar*be_tls_get_certificate_hash(Port*port,size_t*len);
289289
#endif

‎src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,9 @@
683683
/* Define to 1 if you have the <winldap.h> header file. */
684684
#undef HAVE_WINLDAP_H
685685

686+
/* Define to 1 if you have the `X509_get_signature_info' function. */
687+
#undef HAVE_X509_GET_SIGNATURE_INFO
688+
686689
/* Define to 1 if you have the `X509_get_signature_nid' function. */
687690
#undef HAVE_X509_GET_SIGNATURE_NID
688691

‎src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
371371
returnn;
372372
}
373373

374-
#ifdefHAVE_X509_GET_SIGNATURE_NID
374+
#if defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO)
375375
char*
376376
pgtls_get_peer_certificate_hash(PGconn*conn,size_t*len)
377377
{
@@ -391,10 +391,15 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
391391

392392
/*
393393
* Get the signature algorithm of the certificate to determine the hash
394-
* algorithm to use for the result.
394+
* algorithm to use for the result. Prefer X509_get_signature_info(),
395+
* introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
395396
*/
397+
#ifHAVE_X509_GET_SIGNATURE_INFO
398+
if (!X509_get_signature_info(peer_cert,&algo_nid,NULL,NULL,NULL))
399+
#else
396400
if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
397401
&algo_nid,NULL))
402+
#endif
398403
{
399404
printfPQExpBuffer(&conn->errorMessage,
400405
libpq_gettext("could not determine server certificate signature algorithm\n"));

‎src/interfaces/libpq/libpq-int.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
755755
* This is not supported with old versions of OpenSSL that don't have
756756
* the X509_get_signature_nid() function.
757757
*/
758-
#if defined(USE_OPENSSL)&& defined(HAVE_X509_GET_SIGNATURE_NID)
758+
#if defined(USE_OPENSSL)&&(defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO))
759759
#defineHAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
760760
externchar*pgtls_get_peer_certificate_hash(PGconn*conn,size_t*len);
761761
#endif

‎src/tools/msvc/Solution.pm

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ sub GenerateFiles
412412
HAVE_WCSTOMBS_L=> 1,
413413
HAVE_WCTYPE_H=> 1,
414414
HAVE_X509_GET_SIGNATURE_NID=> 1,
415+
HAVE_X509_GET_SIGNATURE_INFO=>undef,
415416
HAVE_X86_64_POPCNTQ=>undef,
416417
HAVE__BOOL=>undef,
417418
HAVE__BUILTIN_BSWAP16=>undef,
@@ -522,7 +523,14 @@ sub GenerateFiles
522523

523524
my ($digit1,$digit2,$digit3) =$self->GetOpenSSLVersion();
524525

525-
# More symbols are needed with OpenSSL 1.1.0 and above.
526+
# Symbols needed with OpenSSL 1.1.1 and above.
527+
if ( ($digit1 >='3' &&$digit2 >='0' &&$digit3 >='0')
528+
|| ($digit1 >='1' &&$digit2 >='1' &&$digit3 >='1'))
529+
{
530+
$define{HAVE_X509_GET_SIGNATURE_INFO} = 1;
531+
}
532+
533+
# Symbols needed with OpenSSL 1.1.0 and above.
526534
if ( ($digit1 >='3' &&$digit2 >='0' &&$digit3 >='0')
527535
|| ($digit1 >='1' &&$digit2 >='1' &&$digit3 >='0'))
528536
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp