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

Commit5fd6105

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 parenta9fa6d7 commit5fd6105

File tree

14 files changed

+145
-11
lines changed

14 files changed

+145
-11
lines changed

‎configure

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

13263+
fi
13264+
done
13265+
13266+
# Function introduced in OpenSSL 1.1.1.
13267+
for ac_func in X509_get_signature_info
13268+
do :
13269+
ac_fn_c_check_func "$LINENO" "X509_get_signature_info" "ac_cv_func_X509_get_signature_info"
13270+
if test "x$ac_cv_func_X509_get_signature_info" = xyes; then :
13271+
cat >>confdefs.h <<_ACEOF
13272+
#define HAVE_X509_GET_SIGNATURE_INFO 1
13273+
_ACEOF
13274+
1326313275
fi
1326413276
done
1326513277

‎configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,6 +1352,8 @@ if test "$with_ssl" = openssl ; then
13521352
# thread-safety. In 1.1.0, it's no longer required, and CRYPTO_lock()
13531353
# function was removed.
13541354
AC_CHECK_FUNCS([CRYPTO_lock])
1355+
# Function introduced in OpenSSL 1.1.1.
1356+
AC_CHECK_FUNCS([X509_get_signature_info])
13551357
AC_DEFINE([USE_OPENSSL],1,[Define to 1 to build with OpenSSL support. (--with-ssl=openssl)])
13561358
elif test "$with_ssl" != no ; then
13571359
AC_MSG_ERROR([--with-ssl must specify openssl])

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

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

1323-
#ifdefHAVE_X509_GET_SIGNATURE_NID
1323+
#if defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO)
13241324
char*
13251325
be_tls_get_certificate_hash(Port*port,size_t*len)
13261326
{
@@ -1338,10 +1338,15 @@ be_tls_get_certificate_hash(Port *port, size_t *len)
13381338

13391339
/*
13401340
* Get the signature algorithm of the certificate to determine the hash
1341-
* algorithm to use for the result.
1341+
* algorithm to use for the result. Prefer X509_get_signature_info(),
1342+
* introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
13421343
*/
1344+
#ifHAVE_X509_GET_SIGNATURE_INFO
1345+
if (!X509_get_signature_info(server_cert,&algo_nid,NULL,NULL,NULL))
1346+
#else
13431347
if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
13441348
&algo_nid,NULL))
1349+
#endif
13451350
elog(ERROR,"could not determine server certificate signature algorithm");
13461351

13471352
/*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ extern void be_tls_get_peer_serial(Port *port, char *ptr, size_t len);
300300
* This is not supported with old versions of OpenSSL that don't have
301301
* the X509_get_signature_nid() function.
302302
*/
303-
#if defined(USE_OPENSSL)&& defined(HAVE_X509_GET_SIGNATURE_NID)
303+
#if defined(USE_OPENSSL)&&(defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO))
304304
#defineHAVE_BE_TLS_GET_CERTIFICATE_HASH
305305
externchar*be_tls_get_certificate_hash(Port*port,size_t*len);
306306
#endif

‎src/include/pg_config.h.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@
718718
/* Define to 1 if you have the `writev' function. */
719719
#undef HAVE_WRITEV
720720

721+
/* Define to 1 if you have the `X509_get_signature_info' function. */
722+
#undef HAVE_X509_GET_SIGNATURE_INFO
723+
721724
/* Define to 1 if you have the `X509_get_signature_nid' function. */
722725
#undef HAVE_X509_GET_SIGNATURE_NID
723726

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
380380
returnn;
381381
}
382382

383-
#ifdefHAVE_X509_GET_SIGNATURE_NID
383+
#if defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO)
384384
char*
385385
pgtls_get_peer_certificate_hash(PGconn*conn,size_t*len)
386386
{
@@ -400,10 +400,15 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
400400

401401
/*
402402
* Get the signature algorithm of the certificate to determine the hash
403-
* algorithm to use for the result.
403+
* algorithm to use for the result. Prefer X509_get_signature_info(),
404+
* introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
404405
*/
406+
#ifHAVE_X509_GET_SIGNATURE_INFO
407+
if (!X509_get_signature_info(peer_cert,&algo_nid,NULL,NULL,NULL))
408+
#else
405409
if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
406410
&algo_nid,NULL))
411+
#endif
407412
{
408413
appendPQExpBufferStr(&conn->errorMessage,
409414
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
@@ -804,7 +804,7 @@ extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
804804
* This is not supported with old versions of OpenSSL that don't have
805805
* the X509_get_signature_nid() function.
806806
*/
807-
#if defined(USE_OPENSSL)&& defined(HAVE_X509_GET_SIGNATURE_NID)
807+
#if defined(USE_OPENSSL)&&(defined(HAVE_X509_GET_SIGNATURE_NID)|| defined(HAVE_X509_GET_SIGNATURE_INFO))
808808
#defineHAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
809809
externchar*pgtls_get_peer_certificate_hash(PGconn*conn,size_t*len);
810810
#endif

‎src/test/ssl/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ ssl/ subdirectory. The Makefile also contains a rule, "make sslfiles", to
9292
recreate them if you need to make changes. "make sslfiles-clean" is required
9393
in order to recreate the full set of keypairs and certificates. To rebuild
9494
separate files, touch (or remove) the files in question and run "make sslfiles".
95+
This step requires at least OpenSSL 1.1.1.
9596

9697
TODO
9798
====
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# An OpenSSL format CSR config file for creating a server certificate.
2+
#
3+
# This is identical to server-cn-only certificate, but we specify
4+
# RSA-PSS as the algorithm on the command line.
5+
6+
[ req ]
7+
distinguished_name = req_distinguished_name
8+
prompt = no
9+
10+
[ req_distinguished_name ]
11+
CN = common-name.pg-ssltest.test
12+
OU = PostgreSQL test suite
13+
14+
# No Subject Alternative Names

‎src/test/ssl/ssl/server-rsapss.crt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDezCCAi4CFCrZutHsw0Vl3OCgOmvtL0I/XAZyMEIGCSqGSIb3DQEBCjA1oA8w
3+
DQYJYIZIAWUDBAIBBQChHDAaBgkqhkiG9w0BAQgwDQYJYIZIAWUDBAIBBQCiBAIC
4+
AN4wRjEkMCIGA1UEAwwbY29tbW9uLW5hbWUucGctc3NsdGVzdC50ZXN0MR4wHAYD
5+
VQQLDBVQb3N0Z3JlU1FMIHRlc3Qgc3VpdGUwHhcNMjMwMjEzMDEyMjA2WhcNMjMw
6+
MzE1MDEyMjA2WjBGMSQwIgYDVQQDDBtjb21tb24tbmFtZS5wZy1zc2x0ZXN0LnRl
7+
c3QxHjAcBgNVBAsMFVBvc3RncmVTUUwgdGVzdCBzdWl0ZTCCASAwCwYJKoZIhvcN
8+
AQEKA4IBDwAwggEKAoIBAQC6YtrZZukJ4n31gKpcIOl65D9roe2jzcIBX1AZq1fR
9+
I6qmt7aR0iFCKEy9D2fs6lM+NVQSurg7b0gKL+XoOadySAxALIrUwcCQM7rZvUR0
10+
aKo3Qm0U00ir4x0i73/sTpY25zBSFoqGldmlqiIIWxpe8hqZEc6Sc78Bs2FaAa9A
11+
5sTLaX5nG6jyreJweLcmv+TYFVqxNq7Y7tC67zWXr6r49JBkSHSibzBr/uFxOGsP
12+
B9hwGo4/foACjeDNAT0vjwMLnV19Sd2zf9daBo+sd9bCj2C5CpOyXxFtO7cMh0tP
13+
U3ZqcYPViFxcPObmhnJgqlBbgZD/WLxm1aFgUYjqMQ47AgMBAAEwQgYJKoZIhvcN
14+
AQEKMDWgDzANBglghkgBZQMEAgEFAKEcMBoGCSqGSIb3DQEBCDANBglghkgBZQME
15+
AgEFAKIEAgIA3gOCAQEAQpYu7fz9iz8CplCOp4SJ1eO9UjbtdxzvuaVR751TfYrX
16+
OO19jq7YyWgqJDwROnDJBFEy9B+HaXTfscEHpGIHAIpx7S7az/gLnO90HshXcK+/
17+
CbjW9axRB9TrD2zOrISl9NSuEZ5tbd5/Ml2yzY85CCjYPuNy+euH5XgcXcwF3Q49
18+
G5eDJnaCCYzwdEOZY8ris9o9go8aL6zNAfhUKToRUfeoBCStOLZSgb6d/IKRB9eg
19+
M0FImsMI3j5zHCiH0HhMwCRFRuZqTp1EMBHANIJncTZSGWQyKQ71zO/l/3YzwNfm
20+
c2gyeh0DJWFkEZD3spWs8K6UEoTESP6Ivj47LmnWjg==
21+
-----END CERTIFICATE-----

‎src/test/ssl/ssl/server-rsapss.key

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADALBgkqhkiG9w0BAQoEggSpMIIEpQIBAAKCAQEAumLa2WbpCeJ99YCq
3+
XCDpeuQ/a6Hto83CAV9QGatX0SOqpre2kdIhQihMvQ9n7OpTPjVUErq4O29ICi/l
4+
6DmnckgMQCyK1MHAkDO62b1EdGiqN0JtFNNIq+MdIu9/7E6WNucwUhaKhpXZpaoi
5+
CFsaXvIamRHOknO/AbNhWgGvQObEy2l+Zxuo8q3icHi3Jr/k2BVasTau2O7Quu81
6+
l6+q+PSQZEh0om8wa/7hcThrDwfYcBqOP36AAo3gzQE9L48DC51dfUnds3/XWgaP
7+
rHfWwo9guQqTsl8RbTu3DIdLT1N2anGD1YhcXDzm5oZyYKpQW4GQ/1i8ZtWhYFGI
8+
6jEOOwIDAQABAoIBAAPXZpi55PdieTXUQpxPxDJpx01p4IdAKoRzS3EwkP99d/sR
9+
qNCekaUyIW9UqT2Hx2Tb1MzCBUZQ40I1614fehK5C2sFdtnls8/gdaIe7FqwIYxA
10+
lcxhpvjHX2Ht8gLc8OvpC5vDOJkZymZsHM8qa8zcTD/AzzNBOpdHqwdES58YoqEb
11+
5LOVLBRIoLli2eAWrrnoYl7MQuh3CHHtWGjn3drTzg6Tl2umfNhTMFANZssNexl4
12+
6npPHBASdevWWsqB8GXD56PaqWxxnjtwzk06lRbloSQYJOicI8OK7eaySpRuHpZV
13+
3vJKhY3bcRN6joxveXA7jaAPSBvNXp2w5fQ1b2ECgYEA1mzqOCln87aaLzZ1KlWL
14+
QfxcXmcke1lJgbhW+iEh6iht2OmBlntAlIVv/D3yBDhNrHdrNlUcWvm+VSrbVyxn
15+
6e1RWHAGPzZNhpcg4odxdI6Oton/OBtsEQ7A6UJ6S7bPTVGVwi9fA4fI0Pfne0wV
16+
IeJHvjDZboOBi6TF2thcJ2sCgYEA3oYzAt4tEiA+nQyNnP4nWZ17XONA6H8yVeUY
17+
Sk6eczg8eGAQz9afVtbSI3uRIfQbQ1+mjaUl4pVej2UDXcROpYHgwCLJRBBDbzzB
18+
4IcPh2woFGZOScQu9Q64C8g6MH4zm3WkFvXyJF3j3dHGFZGq8nmwEARJgAsQ6Yig
19+
kYL8+HECgYEAtuKUbqxaPlL7dNNU4XOu3+v3eIkuY4qHGH36qUKDI62x6zVWUtvy
20+
+/pHxnOrLRA8p6H/LosvMSUbwpZYGCUGyE2iePSrT1TokKfr42o0SX6hmG1g4iD5
21+
bh8QSKNrnZJhg4fXXJV8y40PqbQXmmENESZnnH8bpJfDcTBrlLm+99sCgYEA3F1f
22+
xPZLAglGmHZnA1K5m0iWc01l6RiVu3RNksC6r3XAhKD15S0wzGme3p6vAkXgfd8K
23+
bHlgxDuR0kWBiOkvzT2KWhvY3vuQHGe5w+VcnoqgQltyKiELM4mo/5oA7ib8anac
24+
0lQrwJHuZ6wnExMXjFqv3ZyxQQk0bWDtSkzCwjECgYEAusqqCAmryRFWdOif2z+Z
25+
3vfseSvBdQMj2FO7weqCVPV4Gnae0TO7A1bUpVX/pfkDEPitt5oUgS2KTozW5vwz
26+
yaQTSB8RO8EG66GURZvPs3Cerkyrgk/OMmbCv3B0ALwhPMBqpemJqeBOuyaAjY8W
27+
Tqb6E2ofRlYND0xH83gCTig=
28+
-----END PRIVATE KEY-----

‎src/test/ssl/sslfiles.mk

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,17 @@ SERVERS := server-cn-and-alt-names \
3636
CLIENTS := client client-dn client-revoked client_ext
3737

3838
#
39-
# To add a new non-standardkey, add it toSPECIAL_KEYS and then add a recipe
40-
# for creating it to the "Special-casekeys" section below.
39+
# To add a new non-standardcertificate, add it toSPECIAL_CERTS and then add
40+
#a recipefor creating it to the "Special-casecertificates" section below.
4141
#
42+
SPECIAL_CERTS := ssl/server-rsapss.crt
43+
44+
# Likewise for non-standard keys
4245
SPECIAL_KEYS := ssl/server-password.key\
4346
ssl/client-der.key\
4447
ssl/client-encrypted-pem.key\
45-
ssl/client-encrypted-der.key
48+
ssl/client-encrypted-der.key\
49+
ssl/server-rsapss.key
4650

4751
#
4852
# These files are just concatenations of other files. You can add new ones to
@@ -65,7 +69,13 @@ CRLS := ssl/root.crl \
6569
ssl/client.crl\
6670
ssl/server.crl
6771

68-
SSLFILES :=$(STANDARD_CERTS)$(STANDARD_KEYS)$(SPECIAL_KEYS)$(COMBINATIONS)$(CRLS)
72+
SSLFILES :=\
73+
$(STANDARD_CERTS)\
74+
$(STANDARD_KEYS)\
75+
$(SPECIAL_CERTS)\
76+
$(SPECIAL_KEYS)\
77+
$(COMBINATIONS)\
78+
$(CRLS)
6979
SSLDIRS := ssl/client-crldir\
7080
ssl/server-crldir\
7181
ssl/root+client-crldir\
@@ -85,6 +95,10 @@ sslfiles: $(SSLFILES) $(SSLDIRS)
8595
ssl/root_ca.crt: ssl/root_ca.key conf/root_ca.config
8696
openssl req -new -x509 -config conf/root_ca.config -days 10000 -key$< -out$@
8797

98+
# Certificate using RSA-PSS algorithm. Also self-signed.
99+
ssl/server-rsapss.crt: ssl/server-rsapss.key conf/server-rsapss.config
100+
$(OPENSSL) req -new -x509 -config conf/server-rsapss.config -key$< -out$@
101+
88102
#
89103
# Special-case keys
90104
#
@@ -95,6 +109,10 @@ ssl/root_ca.crt: ssl/root_ca.key conf/root_ca.config
95109
ssl/server-password.key: ssl/server-cn-only.key
96110
openssl rsa -aes256 -in$< -out$@ -passout'pass:secret1'
97111

112+
# Key that uses the RSA-PSS algorithm
113+
ssl/server-rsapss.key:
114+
$(OPENSSL) genpkey -algorithm rsa-pss -out$@
115+
98116
# DER-encoded version of client.key
99117
ssl/client-der.key: ssl/client.key
100118
openssl rsa -in$< -outform DER -out$@

‎src/test/ssl/t/002_scram.pl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ sub switch_server_cert
4242
# Determine whether build supports tls-server-end-point.
4343
my$supports_tls_server_end_point =
4444
check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1");
45+
# Determine whether build supports detection of hash algorithms for
46+
# RSA-PSS certificates.
47+
my$supports_rsapss_certs =
48+
check_pg_config("#define HAVE_X509_GET_SIGNATURE_INFO 1");
4549

4650
# Allocation of base connection string shared among multiple tests.
4751
my$common_connstr;
@@ -132,4 +136,17 @@ sub switch_server_cert
132136
qr/connection authenticated: identity="ssltestuser" method=scram-sha-256/
133137
]);
134138

139+
# Now test with a server certificate that uses the RSA-PSS algorithm.
140+
# This checks that the certificate can be loaded and that channel binding
141+
# works. (see bug #17760)
142+
if ($supports_rsapss_certs)
143+
{
144+
switch_server_cert($node,certfile=>'server-rsapss');
145+
$node->connect_ok(
146+
"$common_connstr user=ssltestuser channel_binding=require",
147+
"SCRAM with SSL and channel_binding=require, server certificate uses 'rsassaPss'",
148+
log_like=> [
149+
qr/connection authenticated: identity="ssltestuser" method=scram-sha-256/
150+
]);
151+
}
135152
done_testing();

‎src/tools/msvc/Solution.pm

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ sub GenerateFiles
433433
HAVE_WCTYPE_H=> 1,
434434
HAVE_WRITEV=>undef,
435435
HAVE_X509_GET_SIGNATURE_NID=> 1,
436+
HAVE_X509_GET_SIGNATURE_INFO=>undef,
436437
HAVE_X86_64_POPCNTQ=>undef,
437438
HAVE__BOOL=>undef,
438439
HAVE__BUILTIN_BSWAP16=>undef,
@@ -553,7 +554,14 @@ sub GenerateFiles
553554

554555
my ($digit1,$digit2,$digit3) =$self->GetOpenSSLVersion();
555556

556-
# More symbols are needed with OpenSSL 1.1.0 and above.
557+
# Symbols needed with OpenSSL 1.1.1 and above.
558+
if ( ($digit1 >='3' &&$digit2 >='0' &&$digit3 >='0')
559+
|| ($digit1 >='1' &&$digit2 >='1' &&$digit3 >='1'))
560+
{
561+
$define{HAVE_X509_GET_SIGNATURE_INFO} = 1;
562+
}
563+
564+
# Symbols needed with OpenSSL 1.1.0 and above.
557565
if ( ($digit1 >='3' &&$digit2 >='0' &&$digit3 >='0')
558566
|| ($digit1 >='1' &&$digit2 >='1' &&$digit3 >='0'))
559567
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp