@@ -67,6 +67,12 @@ static bool SSL_initialized = false;
67
67
static bool dummy_ssl_passwd_cb_called = false;
68
68
static bool ssl_is_server_start ;
69
69
70
+ static int ssl_protocol_version_to_openssl (int v , const char * guc_name );
71
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L )
72
+ static int SSL_CTX_set_min_proto_version (SSL_CTX * ctx , int version );
73
+ static int SSL_CTX_set_max_proto_version (SSL_CTX * ctx , int version );
74
+ #endif
75
+
70
76
71
77
/* ------------------------------------------------------------ */
72
78
/* Public interface */
@@ -183,8 +189,14 @@ be_tls_init(bool isServerStart)
183
189
goto error ;
184
190
}
185
191
186
- /* disallow SSL v2/v3 */
187
- SSL_CTX_set_options (context , SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 );
192
+ if (ssl_min_protocol_version )
193
+ SSL_CTX_set_min_proto_version (context ,
194
+ ssl_protocol_version_to_openssl (ssl_min_protocol_version ,
195
+ "ssl_min_protocol_version" ));
196
+ if (ssl_max_protocol_version )
197
+ SSL_CTX_set_max_proto_version (context ,
198
+ ssl_protocol_version_to_openssl (ssl_max_protocol_version ,
199
+ "ssl_max_protocol_version" ));
188
200
189
201
/* disallow SSL session tickets */
190
202
#ifdef SSL_OP_NO_TICKET /* added in OpenSSL 0.9.8f */
@@ -1209,3 +1221,110 @@ X509_NAME_to_cstring(X509_NAME *name)
1209
1221
1210
1222
return result ;
1211
1223
}
1224
+
1225
+ /*
1226
+ * Convert TLS protocol version GUC enum to OpenSSL values
1227
+ *
1228
+ * This is a straightforward one-to-one mapping, but doing it this way makes
1229
+ * guc.c independent of OpenSSL availability and version.
1230
+ *
1231
+ * If a version is passed that is not supported by the current OpenSSL
1232
+ * version, then we throw an error, so that subsequent code can assume it's
1233
+ * working with a supported version.
1234
+ */
1235
+ static int
1236
+ ssl_protocol_version_to_openssl (int v , const char * guc_name )
1237
+ {
1238
+ switch (v )
1239
+ {
1240
+ case PG_TLS_ANY :
1241
+ return 0 ;
1242
+ case PG_TLS1_VERSION :
1243
+ return TLS1_VERSION ;
1244
+ case PG_TLS1_1_VERSION :
1245
+ #ifdef TLS1_1_VERSION
1246
+ return TLS1_1_VERSION ;
1247
+ #else
1248
+ goto error ;
1249
+ #endif
1250
+ case PG_TLS1_2_VERSION :
1251
+ #ifdef TLS1_2_VERSION
1252
+ return TLS1_2_VERSION ;
1253
+ #else
1254
+ goto error ;
1255
+ #endif
1256
+ case PG_TLS1_3_VERSION :
1257
+ #ifdef TLS1_3_VERSION
1258
+ return TLS1_3_VERSION ;
1259
+ #else
1260
+ goto error ;
1261
+ #endif
1262
+ }
1263
+
1264
+ error :
1265
+ pg_attribute_unused ();
1266
+ ereport (ERROR ,
1267
+ (errmsg ("%s setting %s not supported by this build" ,
1268
+ guc_name ,
1269
+ GetConfigOption (guc_name , false, false))));
1270
+ return -1 ;
1271
+ }
1272
+
1273
+ /*
1274
+ * Replacements for APIs present in newer versions of OpenSSL
1275
+ */
1276
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L )
1277
+
1278
+ /*
1279
+ * OpenSSL versions that support TLS 1.3 shouldn't get here because they
1280
+ * already have these functions. So we don't have to keep updating the below
1281
+ * code for every new TLS version, and eventually it can go away. But let's
1282
+ * just check this to make sure ...
1283
+ */
1284
+ #ifdef TLS1_3_VERSION
1285
+ #error OpenSSL version mismatch
1286
+ #endif
1287
+
1288
+ static int
1289
+ SSL_CTX_set_min_proto_version (SSL_CTX * ctx , int version )
1290
+ {
1291
+ int ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 ;
1292
+
1293
+ if (version > TLS1_VERSION )
1294
+ ssl_options |= SSL_OP_NO_TLSv1 ;
1295
+ #ifdef TLS1_1_VERSION
1296
+ if (version > TLS1_1_VERSION )
1297
+ ssl_options |= SSL_OP_NO_TLSv1_1 ;
1298
+ #endif
1299
+ #ifdef TLS1_2_VERSION
1300
+ if (version > TLS1_2_VERSION )
1301
+ ssl_options |= SSL_OP_NO_TLSv1_2 ;
1302
+ #endif
1303
+
1304
+ SSL_CTX_set_options (ctx , ssl_options );
1305
+
1306
+ return 1 ; /* success */
1307
+ }
1308
+
1309
+ static int
1310
+ SSL_CTX_set_max_proto_version (SSL_CTX * ctx , int version )
1311
+ {
1312
+ int ssl_options = 0 ;
1313
+
1314
+ AssertArg (version != 0 );
1315
+
1316
+ #ifdef TLS1_1_VERSION
1317
+ if (version < TLS1_1_VERSION )
1318
+ ssl_options |= SSL_OP_NO_TLSv1_1 ;
1319
+ #endif
1320
+ #ifdef TLS1_2_VERSION
1321
+ if (version < TLS1_2_VERSION )
1322
+ ssl_options |= SSL_OP_NO_TLSv1_2 ;
1323
+ #endif
1324
+
1325
+ SSL_CTX_set_options (ctx , ssl_options );
1326
+
1327
+ return 1 ; /* success */
1328
+ }
1329
+
1330
+ #endif /* OPENSSL_VERSION_NUMBER */
0 commit comments