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

Commitc0a15e0

Browse files
committed
Always use 2048 bit DH parameters for OpenSSL ephemeral DH ciphers.
1024 bits is considered weak these days, but OpenSSL always passes 1024 asthe key length to the tmp_dh callback. All the code to handle other keylengths is, in fact, dead.To remedy those issues:* Only include hard-coded 2048-bit parameters.* Set the parameters directly with SSL_CTX_set_tmp_dh(), without the callback* The name of the file containing the DH parameters is now a GUC. This replaces the old hardcoded "dh1024.pem" filename. (The files for other key lengths, dh512.pem, dh2048.pem, etc. were never actually used.)This is not a new problem, but it doesn't seem worth the risk and churn tobackport. If you care enough about the strength of the DH parameters onold versions, you can create custom DH parameters, with as many bits as youwish, and put them in the "dh1024.pem" file.Per report by Nicolas Guini and Damian Quiroga. Reviewed by Michael Paquier.Discussion:https://www.postgresql.org/message-id/CAMxBoUyjOOautVozN6ofzym828aNrDjuCcOTcCquxjwS-L2hGQ@mail.gmail.com
1 parentdea6ba9 commitc0a15e0

File tree

6 files changed

+133
-169
lines changed

6 files changed

+133
-169
lines changed

‎doc/src/sgml/config.sgml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1203,6 +1203,30 @@ include_dir 'conf.d'
12031203
</listitem>
12041204
</varlistentry>
12051205

1206+
<varlistentry id="guc-ssl-dh-params-file" xreflabel="ssl_dh_params_file">
1207+
<term><varname>ssl_dh_params_file</varname> (<type>string</type>)
1208+
<indexterm>
1209+
<primary><varname>ssl_dh_params_file</> configuration parameter</primary>
1210+
</indexterm>
1211+
</term>
1212+
<listitem>
1213+
<para>
1214+
Specifies the name of the file containing Diffie-Hellman parameters
1215+
used for so-called ephemeral DH family of SSL ciphers. The default is
1216+
empty, in which case compiled-in default DH parameters used. Using
1217+
custom DH parameters reduces the exposure if an attacker manages to
1218+
crack the well-known compiled-in DH parameters. You can create your own
1219+
DH parameters file with the command
1220+
<command>openssl dhparam -out dhparams.pem 2048</command>.
1221+
</para>
1222+
1223+
<para>
1224+
This parameter can only be set in the <filename>postgresql.conf</>
1225+
file or on the server command line.
1226+
</para>
1227+
</listitem>
1228+
</varlistentry>
1229+
12061230
<varlistentry id="guc-krb-server-keyfile" xreflabel="krb_server_keyfile">
12071231
<term><varname>krb_server_keyfile</varname> (<type>string</type>)
12081232
<indexterm>

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

Lines changed: 95 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include"libpq/libpq.h"
6262
#include"miscadmin.h"
6363
#include"pgstat.h"
64+
#include"storage/fd.h"
6465
#include"storage/latch.h"
6566
#include"tcop/tcopprot.h"
6667
#include"utils/memutils.h"
@@ -71,13 +72,12 @@ static intmy_sock_write(BIO *h, const char *buf, int size);
7172
staticBIO_METHOD*my_BIO_s_socket(void);
7273
staticintmy_SSL_set_fd(Port*port,intfd);
7374

74-
staticDH*load_dh_file(intkeylength);
75+
staticDH*load_dh_file(char*filename,boolisServerStart);
7576
staticDH*load_dh_buffer(constchar*,size_t);
76-
staticDH*generate_dh_parameters(intprime_len,intgenerator);
77-
staticDH*tmp_dh_cb(SSL*s,intis_export,intkeylength);
7877
staticintssl_passwd_cb(char*buf,intsize,intrwflag,void*userdata);
7978
staticintverify_cb(int,X509_STORE_CTX*);
8079
staticvoidinfo_cb(constSSL*ssl,inttype,intargs);
80+
staticboolinitialize_dh(SSL_CTX*context,boolisServerStart);
8181
staticboolinitialize_ecdh(SSL_CTX*context,boolisServerStart);
8282
staticconstchar*SSLerrmessage(unsigned longecode);
8383

@@ -96,37 +96,21 @@ static bool ssl_passwd_cb_called = false;
9696
*As discussed above, EDH protects the confidentiality of
9797
*sessions even if the static private key is compromised,
9898
*so we are *highly* motivated to ensure that we can use
99-
*EDH even if the DBA... or an attacker... deletes the
100-
*$DataDir/dh*.pem files.
99+
*EDH even if the DBA has not provided custom DH parameters.
101100
*
102101
*We could refuse SSL connections unless a good DH parameter
103102
*file exists, but some clients may quietly renegotiate an
104103
*unsecured connection without fully informing the user.
105-
*Very uncool.
106-
*
107-
*Alternatively, the backend could attempt to load these files
108-
*on startup if SSL is enabled - and refuse to start if any
109-
*do not exist - but this would tend to piss off DBAs.
104+
*Very uncool. Alternatively, the system could refuse to start
105+
*if a DH parameters is not specified, but this would tend to
106+
*piss off DBAs.
110107
*
111108
*If you want to create your own hardcoded DH parameters
112109
*for fun and profit, review "Assigned Number for SKIP
113110
*Protocols" (http://www.skip-vpn.org/spec/numbers.html)
114111
*for suggestions.
115112
*/
116113

117-
staticconstcharfile_dh512[]=
118-
"-----BEGIN DH PARAMETERS-----\n\
119-
MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
120-
XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
121-
-----END DH PARAMETERS-----\n";
122-
123-
staticconstcharfile_dh1024[]=
124-
"-----BEGIN DH PARAMETERS-----\n\
125-
MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
126-
jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
127-
ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
128-
-----END DH PARAMETERS-----\n";
129-
130114
staticconstcharfile_dh2048[]=
131115
"-----BEGIN DH PARAMETERS-----\n\
132116
MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
@@ -137,21 +121,6 @@ Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
137121
CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
138122
-----END DH PARAMETERS-----\n";
139123

140-
staticconstcharfile_dh4096[]=
141-
"-----BEGIN DH PARAMETERS-----\n\
142-
MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
143-
l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
144-
Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
145-
Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
146-
VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
147-
alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
148-
sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
149-
ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
150-
OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
151-
AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
152-
KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
153-
-----END DH PARAMETERS-----\n";
154-
155124

156125
/* ------------------------------------------------------------ */
157126
/* Public interface*/
@@ -316,13 +285,14 @@ be_tls_init(bool isServerStart)
316285
gotoerror;
317286
}
318287

319-
/* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
320-
SSL_CTX_set_tmp_dh_callback(context,tmp_dh_cb);
288+
/* disallow SSL v2/v3 */
321289
SSL_CTX_set_options(context,
322290
SSL_OP_SINGLE_DH_USE |
323291
SSL_OP_NO_SSLv2 |SSL_OP_NO_SSLv3);
324292

325-
/* set up ephemeral ECDH keys */
293+
/* set up ephemeral DH and ECDH keys */
294+
if (!initialize_dh(context,isServerStart))
295+
gotoerror;
326296
if (!initialize_ecdh(context,isServerStart))
327297
gotoerror;
328298

@@ -918,53 +888,57 @@ my_SSL_set_fd(Port *port, int fd)
918888
*what we expect it to contain.
919889
*/
920890
staticDH*
921-
load_dh_file(intkeylength)
891+
load_dh_file(char*filename,boolisServerStart)
922892
{
923893
FILE*fp;
924-
charfnbuf[MAXPGPATH];
925894
DH*dh=NULL;
926895
intcodes;
927896

928897
/* attempt to open file. It's not an error if it doesn't exist. */
929-
snprintf(fnbuf,sizeof(fnbuf),"dh%d.pem",keylength);
930-
if ((fp=fopen(fnbuf,"r"))==NULL)
898+
if ((fp=AllocateFile(filename,"r"))==NULL)
899+
{
900+
ereport(isServerStart ?FATAL :LOG,
901+
(errcode_for_file_access(),
902+
errmsg("could not open DH parameters file \"%s\": %m",
903+
filename)));
931904
returnNULL;
905+
}
932906

933-
/*flock(fileno(fp), LOCK_SH); */
934907
dh=PEM_read_DHparams(fp,NULL,NULL,NULL);
935-
/*flock(fileno(fp), LOCK_UN); */
936-
fclose(fp);
908+
FreeFile(fp);
937909

938-
/* is the prime the correct size? */
939-
if (dh!=NULL&&8*DH_size(dh)<keylength)
910+
if (dh==NULL)
940911
{
941-
elog(LOG,"DH errors (%s): %d bits expected, %d bits found",
942-
fnbuf,keylength,8*DH_size(dh));
943-
dh=NULL;
912+
ereport(isServerStart ?FATAL :LOG,
913+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
914+
errmsg("could not load DH parameters file: %s",
915+
SSLerrmessage(ERR_get_error()))));
916+
returnNULL;
944917
}
945918

946919
/* make sure the DH parameters are usable */
947-
if (dh!=NULL)
920+
if (DH_check(dh,&codes)==0)
948921
{
949-
if (DH_check(dh,&codes)==0)
950-
{
951-
elog(LOG,"DH_check error (%s): %s",fnbuf,
952-
SSLerrmessage(ERR_get_error()));
953-
returnNULL;
954-
}
955-
if (codes&DH_CHECK_P_NOT_PRIME)
956-
{
957-
elog(LOG,"DH error (%s): p is not prime",fnbuf);
958-
returnNULL;
959-
}
960-
if ((codes&DH_NOT_SUITABLE_GENERATOR)&&
961-
(codes&DH_CHECK_P_NOT_SAFE_PRIME))
962-
{
963-
elog(LOG,
964-
"DH error (%s): neither suitable generator or safe prime",
965-
fnbuf);
966-
returnNULL;
967-
}
922+
ereport(isServerStart ?FATAL :LOG,
923+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
924+
errmsg("invalid DH parameters: %s",
925+
SSLerrmessage(ERR_get_error()))));
926+
returnNULL;
927+
}
928+
if (codes&DH_CHECK_P_NOT_PRIME)
929+
{
930+
ereport(isServerStart ?FATAL :LOG,
931+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
932+
errmsg("invalid DH parameters: p is not prime")));
933+
returnNULL;
934+
}
935+
if ((codes&DH_NOT_SUITABLE_GENERATOR)&&
936+
(codes&DH_CHECK_P_NOT_SAFE_PRIME))
937+
{
938+
ereport(isServerStart ?FATAL :LOG,
939+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
940+
errmsg("invalid DH parameters: neither suitable generator or safe prime")));
941+
returnNULL;
968942
}
969943

970944
returndh;
@@ -995,102 +969,6 @@ load_dh_buffer(const char *buffer, size_t len)
995969
returndh;
996970
}
997971

998-
/*
999-
*Generate DH parameters.
1000-
*
1001-
*Last resort if we can't load precomputed nor hardcoded
1002-
*parameters.
1003-
*/
1004-
staticDH*
1005-
generate_dh_parameters(intprime_len,intgenerator)
1006-
{
1007-
DH*dh;
1008-
1009-
if ((dh=DH_new())==NULL)
1010-
returnNULL;
1011-
1012-
if (DH_generate_parameters_ex(dh,prime_len,generator,NULL))
1013-
returndh;
1014-
1015-
DH_free(dh);
1016-
returnNULL;
1017-
}
1018-
1019-
/*
1020-
*Generate an ephemeral DH key. Because this can take a long
1021-
*time to compute, we can use precomputed parameters of the
1022-
*common key sizes.
1023-
*
1024-
*Since few sites will bother to precompute these parameter
1025-
*files, we also provide a fallback to the parameters provided
1026-
*by the OpenSSL project.
1027-
*
1028-
*These values can be static (once loaded or computed) since
1029-
*the OpenSSL library can efficiently generate random keys from
1030-
*the information provided.
1031-
*/
1032-
staticDH*
1033-
tmp_dh_cb(SSL*s,intis_export,intkeylength)
1034-
{
1035-
DH*r=NULL;
1036-
staticDH*dh=NULL;
1037-
staticDH*dh512=NULL;
1038-
staticDH*dh1024=NULL;
1039-
staticDH*dh2048=NULL;
1040-
staticDH*dh4096=NULL;
1041-
1042-
switch (keylength)
1043-
{
1044-
case512:
1045-
if (dh512==NULL)
1046-
dh512=load_dh_file(keylength);
1047-
if (dh512==NULL)
1048-
dh512=load_dh_buffer(file_dh512,sizeoffile_dh512);
1049-
r=dh512;
1050-
break;
1051-
1052-
case1024:
1053-
if (dh1024==NULL)
1054-
dh1024=load_dh_file(keylength);
1055-
if (dh1024==NULL)
1056-
dh1024=load_dh_buffer(file_dh1024,sizeoffile_dh1024);
1057-
r=dh1024;
1058-
break;
1059-
1060-
case2048:
1061-
if (dh2048==NULL)
1062-
dh2048=load_dh_file(keylength);
1063-
if (dh2048==NULL)
1064-
dh2048=load_dh_buffer(file_dh2048,sizeoffile_dh2048);
1065-
r=dh2048;
1066-
break;
1067-
1068-
case4096:
1069-
if (dh4096==NULL)
1070-
dh4096=load_dh_file(keylength);
1071-
if (dh4096==NULL)
1072-
dh4096=load_dh_buffer(file_dh4096,sizeoffile_dh4096);
1073-
r=dh4096;
1074-
break;
1075-
1076-
default:
1077-
if (dh==NULL)
1078-
dh=load_dh_file(keylength);
1079-
r=dh;
1080-
}
1081-
1082-
/* this may take a long time, but it may be necessary... */
1083-
if (r==NULL||8*DH_size(r)<keylength)
1084-
{
1085-
ereport(DEBUG2,
1086-
(errmsg_internal("DH: generating parameters (%d bits)",
1087-
keylength)));
1088-
r=generate_dh_parameters(keylength,DH_GENERATOR_2);
1089-
}
1090-
1091-
returnr;
1092-
}
1093-
1094972
/*
1095973
*Passphrase collection callback
1096974
*
@@ -1172,6 +1050,54 @@ info_cb(const SSL *ssl, int type, int args)
11721050
}
11731051
}
11741052

1053+
/*
1054+
* Set DH parameters for generating ephemeral DH keys. The
1055+
* DH parameters can take a long time to compute, so they must be
1056+
* precomputed.
1057+
*
1058+
* Since few sites will bother to create a parameter file, we also
1059+
* also provide a fallback to the parameters provided by the
1060+
* OpenSSL project.
1061+
*
1062+
* These values can be static (once loaded or computed) since the
1063+
* OpenSSL library can efficiently generate random keys from the
1064+
* information provided.
1065+
*/
1066+
staticbool
1067+
initialize_dh(SSL_CTX*context,boolisServerStart)
1068+
{
1069+
DH*dh=NULL;
1070+
1071+
SSL_CTX_set_options(context,SSL_OP_SINGLE_DH_USE);
1072+
1073+
if (ssl_dh_params_file[0])
1074+
dh=load_dh_file(ssl_dh_params_file,isServerStart);
1075+
if (!dh)
1076+
dh=load_dh_buffer(file_dh2048,sizeoffile_dh2048);
1077+
if (!dh)
1078+
{
1079+
ereport(isServerStart ?FATAL :LOG,
1080+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1081+
(errmsg("DH: could not load DH parameters"))));
1082+
return false;
1083+
}
1084+
1085+
if (SSL_CTX_set_tmp_dh(context,dh)!=1)
1086+
{
1087+
ereport(isServerStart ?FATAL :LOG,
1088+
(errcode(ERRCODE_CONFIG_FILE_ERROR),
1089+
(errmsg("DH: could not set DH parameters: %s",
1090+
SSLerrmessage(ERR_get_error())))));
1091+
return false;
1092+
}
1093+
return true;
1094+
}
1095+
1096+
/*
1097+
* Set ECDH parameters for generating ephemeral Elliptic Curve DH
1098+
* keys. This is much simpler than the DH parameters, as we just
1099+
* need to provide the name of the curve to OpenSSL.
1100+
*/
11751101
staticbool
11761102
initialize_ecdh(SSL_CTX*context,boolisServerStart)
11771103
{

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ char *ssl_cert_file;
4444
char*ssl_key_file;
4545
char*ssl_ca_file;
4646
char*ssl_crl_file;
47+
char*ssl_dh_params_file;
4748

4849
#ifdefUSE_SSL
4950
boolssl_loaded_verify_locations= false;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp