PostgreSQL Source Code  git master
fe-secure-openssl.c File Reference
#include "postgres_fe.h"
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include "libpq-fe.h"
#include "fe-auth.h"
#include "fe-secure-common.h"
#include "libpq-int.h"
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <pthread.h>
#include "common/openssl.h"
#include <openssl/conf.h>
#include <openssl/x509v3.h>
Include dependency graph for fe-secure-openssl.c:

Go to the source code of this file.

Macros

#define SSL_ERR_LEN   128
 
#define BIO_get_data(bio)   (bio->ptr)
 
#define BIO_set_data(bio, data)   (bio->ptr = data)
 

Functions

static int verify_cb (int ok, X509_STORE_CTX *ctx)
 
static int openssl_verify_peer_name_matches_certificate_name (PGconn *conn, ASN1_STRING *name_entry, char **store_name)
 
static int openssl_verify_peer_name_matches_certificate_ip (PGconn *conn, ASN1_OCTET_STRING *addr_entry, char **store_name)
 
static void destroy_ssl_system (void)
 
static int initialize_SSL (PGconn *conn)
 
static PostgresPollingStatusType open_client_SSL (PGconn *conn)
 
static char * SSLerrmessage (unsigned long ecode)
 
static void SSLerrfree (char *buf)
 
static int PQssl_passwd_cb (char *buf, int size, int rwflag, void *userdata)
 
static int my_sock_read (BIO *h, char *buf, int size)
 
static int my_sock_write (BIO *h, const char *buf, int size)
 
static BIO_METHOD * my_BIO_s_socket (void)
 
static int my_SSL_set_fd (PGconn *conn, int fd)
 
static int ssl_protocol_version_to_openssl (const char *protocol)
 
void pgtls_init_library (bool do_ssl, int do_crypto)
 
PostgresPollingStatusType pgtls_open_client (PGconn *conn)
 
ssize_t pgtls_read (PGconn *conn, void *ptr, size_t len)
 
bool pgtls_read_pending (PGconn *conn)
 
ssize_t pgtls_write (PGconn *conn, const void *ptr, size_t len)
 
char * pgtls_get_peer_certificate_hash (PGconn *conn, size_t *len)
 
static bool is_ip_address (const char *host)
 
int pgtls_verify_peer_name_matches_certificate_guts (PGconn *conn, int *names_examined, char **first_name)
 
int pgtls_init (PGconn *conn, bool do_ssl, bool do_crypto)
 
void pgtls_close (PGconn *conn)
 
void * PQgetssl (PGconn *conn)
 
void * PQsslStruct (PGconn *conn, const char *struct_name)
 
const char *const * PQsslAttributeNames (PGconn *conn)
 
const char * PQsslAttribute (PGconn *conn, const char *attribute_name)
 
int PQdefaultSSLKeyPassHook_OpenSSL (char *buf, int size, PGconn *conn)
 
PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL (void)
 
void PQsetSSLKeyPassHook_OpenSSL (PQsslKeyPassHook_OpenSSL_type hook)
 

Variables

static bool pq_init_ssl_lib = true
 
static bool pq_init_crypto_lib = true
 
static bool ssl_lib_initialized = false
 
static long crypto_open_connections = 0
 
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER
 
static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL
 
static char ssl_nomem [] = "out of memory allocating error description"
 
static BIO_METHOD * my_bio_methods
 

Macro Definition Documentation

◆ BIO_get_data

#define BIO_get_data (   bio)    (bio->ptr)

Definition at line 1819 of file fe-secure-openssl.c.

◆ BIO_set_data

#define BIO_set_data (   bio,
  data 
)    (bio->ptr = data)

Definition at line 1820 of file fe-secure-openssl.c.

◆ SSL_ERR_LEN

#define SSL_ERR_LEN   128

Definition at line 1685 of file fe-secure-openssl.c.

Function Documentation

◆ destroy_ssl_system()

static void destroy_ssl_system ( void  )
static

Definition at line 868 of file fe-secure-openssl.c.

869 {
870 #if defined(HAVE_CRYPTO_LOCK)
871  /* Mutex is created in pgtls_init() */
873  return;
874 
877 
879  {
880  /*
881  * No connections left, unregister libcrypto callbacks, if no one
882  * registered different ones in the meantime.
883  */
884  if (CRYPTO_get_locking_callback() == pq_lockingcallback)
885  CRYPTO_set_locking_callback(NULL);
886  if (CRYPTO_get_id_callback() == pq_threadidcallback)
887  CRYPTO_set_id_callback(NULL);
888 
889  /*
890  * We don't free the lock array. If we get another connection in this
891  * process, we will just re-use them with the existing mutexes.
892  *
893  * This means we leak a little memory on repeated load/unload of the
894  * library.
895  */
896  }
897 
899 #endif
900 }
static bool pq_init_crypto_lib
static long crypto_open_connections
static pthread_mutex_t ssl_config_mutex
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45

References crypto_open_connections, pq_init_crypto_lib, pthread_mutex_lock(), pthread_mutex_unlock(), and ssl_config_mutex.

Referenced by pgtls_close().

◆ initialize_SSL()

static int initialize_SSL ( PGconn conn)
static

Definition at line 909 of file fe-secure-openssl.c.

910 {
911  SSL_CTX *SSL_context;
912  struct stat buf;
913  char homedir[MAXPGPATH];
914  char fnbuf[MAXPGPATH];
915  char sebuf[PG_STRERROR_R_BUFLEN];
916  bool have_homedir;
917  bool have_cert;
918  bool have_rootcert;
919  EVP_PKEY *pkey = NULL;
920 
921  /*
922  * We'll need the home directory if any of the relevant parameters are
923  * defaulted. If pqGetHomeDirectory fails, act as though none of the
924  * files could be found.
925  */
926  if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
927  !(conn->sslkey && strlen(conn->sslkey) > 0) ||
928  !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
929  !((conn->sslcrl && strlen(conn->sslcrl) > 0) ||
930  (conn->sslcrldir && strlen(conn->sslcrldir) > 0)))
931  have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
932  else /* won't need it */
933  have_homedir = false;
934 
935  /*
936  * Create a new SSL_CTX object.
937  *
938  * We used to share a single SSL_CTX between all connections, but it was
939  * complicated if connections used different certificates. So now we
940  * create a separate context for each connection, and accept the overhead.
941  */
942  SSL_context = SSL_CTX_new(SSLv23_method());
943  if (!SSL_context)
944  {
945  char *err = SSLerrmessage(ERR_get_error());
946 
947  libpq_append_conn_error(conn, "could not create SSL context: %s", err);
948  SSLerrfree(err);
949  return -1;
950  }
951 
952  /*
953  * Delegate the client cert password prompt to the libpq wrapper callback
954  * if any is defined.
955  *
956  * If the application hasn't installed its own and the sslpassword
957  * parameter is non-null, we install ours now to make sure we supply
958  * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin.
959  *
960  * This will replace OpenSSL's default PEM_def_callback (which prompts on
961  * stdin), but we're only setting it for this SSL context so it's
962  * harmless.
963  */
964  if (PQsslKeyPassHook
965  || (conn->sslpassword && strlen(conn->sslpassword) > 0))
966  {
967  SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb);
968  SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn);
969  }
970 
971 #ifdef HAVE_SSL_CTX_SET_CERT_CB
972  /* Set up a certificate selection callback. */
973  SSL_CTX_set_cert_cb(SSL_context, cert_cb, conn);
974 #endif
975 
976  /* Disable old protocol versions */
977  SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
978 
979  /* Set the minimum and maximum protocol versions if necessary */
981  strlen(conn->ssl_min_protocol_version) != 0)
982  {
983  int ssl_min_ver;
984 
986 
987  if (ssl_min_ver == -1)
988  {
989  libpq_append_conn_error(conn, "invalid value \"%s\" for minimum SSL protocol version",
991  SSL_CTX_free(SSL_context);
992  return -1;
993  }
994 
995  if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver))
996  {
997  char *err = SSLerrmessage(ERR_get_error());
998 
999  libpq_append_conn_error(conn, "could not set minimum SSL protocol version: %s", err);
1000  SSLerrfree(err);
1001  SSL_CTX_free(SSL_context);
1002  return -1;
1003  }
1004  }
1005 
1007  strlen(conn->ssl_max_protocol_version) != 0)
1008  {
1009  int ssl_max_ver;
1010 
1012 
1013  if (ssl_max_ver == -1)
1014  {
1015  libpq_append_conn_error(conn, "invalid value \"%s\" for maximum SSL protocol version",
1017  SSL_CTX_free(SSL_context);
1018  return -1;
1019  }
1020 
1021  if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver))
1022  {
1023  char *err = SSLerrmessage(ERR_get_error());
1024 
1025  libpq_append_conn_error(conn, "could not set maximum SSL protocol version: %s", err);
1026  SSLerrfree(err);
1027  SSL_CTX_free(SSL_context);
1028  return -1;
1029  }
1030  }
1031 
1032  /*
1033  * Disable OpenSSL's moving-write-buffer sanity check, because it causes
1034  * unnecessary failures in nonblocking send cases.
1035  */
1036  SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
1037 
1038  /*
1039  * If the root cert file exists, load it so we can perform certificate
1040  * verification. If sslmode is "verify-full" we will also do further
1041  * verification after the connection has been completed.
1042  */
1043  if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
1044  strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
1045  else if (have_homedir)
1046  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
1047  else
1048  fnbuf[0] = '\0';
1049 
1050  if (strcmp(fnbuf, "system") == 0)
1051  {
1052  /*
1053  * The "system" sentinel value indicates that we should load whatever
1054  * root certificates are installed for use by OpenSSL; these locations
1055  * differ by platform. Note that the default system locations may be
1056  * further overridden by the SSL_CERT_DIR and SSL_CERT_FILE
1057  * environment variables.
1058  */
1059  if (SSL_CTX_set_default_verify_paths(SSL_context) != 1)
1060  {
1061  char *err = SSLerrmessage(ERR_get_error());
1062 
1063  libpq_append_conn_error(conn, "could not load system root certificate paths: %s",
1064  err);
1065  SSLerrfree(err);
1066  SSL_CTX_free(SSL_context);
1067  return -1;
1068  }
1069  have_rootcert = true;
1070  }
1071  else if (fnbuf[0] != '\0' &&
1072  stat(fnbuf, &buf) == 0)
1073  {
1074  X509_STORE *cvstore;
1075 
1076  if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
1077  {
1078  char *err = SSLerrmessage(ERR_get_error());
1079 
1080  libpq_append_conn_error(conn, "could not read root certificate file \"%s\": %s",
1081  fnbuf, err);
1082  SSLerrfree(err);
1083  SSL_CTX_free(SSL_context);
1084  return -1;
1085  }
1086 
1087  if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
1088  {
1089  char *fname = NULL;
1090  char *dname = NULL;
1091 
1092  if (conn->sslcrl && strlen(conn->sslcrl) > 0)
1093  fname = conn->sslcrl;
1094  if (conn->sslcrldir && strlen(conn->sslcrldir) > 0)
1095  dname = conn->sslcrldir;
1096 
1097  /* defaults to use the default CRL file */
1098  if (!fname && !dname && have_homedir)
1099  {
1100  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
1101  fname = fnbuf;
1102  }
1103 
1104  /* Set the flags to check against the complete CRL chain */
1105  if ((fname || dname) &&
1106  X509_STORE_load_locations(cvstore, fname, dname) == 1)
1107  {
1108  X509_STORE_set_flags(cvstore,
1109  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1110  }
1111 
1112  /* if not found, silently ignore; we do not require CRL */
1113  ERR_clear_error();
1114  }
1115  have_rootcert = true;
1116  }
1117  else
1118  {
1119  /*
1120  * stat() failed; assume root file doesn't exist. If sslmode is
1121  * verify-ca or verify-full, this is an error. Otherwise, continue
1122  * without performing any server cert verification.
1123  */
1124  if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
1125  {
1126  /*
1127  * The only way to reach here with an empty filename is if
1128  * pqGetHomeDirectory failed. That's a sufficiently unusual case
1129  * that it seems worth having a specialized error message for it.
1130  */
1131  if (fnbuf[0] == '\0')
1132  libpq_append_conn_error(conn, "could not get home directory to locate root certificate file\n"
1133  "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.");
1134  else
1135  libpq_append_conn_error(conn, "root certificate file \"%s\" does not exist\n"
1136  "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.", fnbuf);
1137  SSL_CTX_free(SSL_context);
1138  return -1;
1139  }
1140  have_rootcert = false;
1141  }
1142 
1143  /* Read the client certificate file */
1144  if (conn->sslcert && strlen(conn->sslcert) > 0)
1145  strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
1146  else if (have_homedir)
1147  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
1148  else
1149  fnbuf[0] = '\0';
1150 
1151  if (conn->sslcertmode[0] == 'd') /* disable */
1152  {
1153  /* don't send a client cert even if we have one */
1154  have_cert = false;
1155  }
1156  else if (fnbuf[0] == '\0')
1157  {
1158  /* no home directory, proceed without a client cert */
1159  have_cert = false;
1160  }
1161  else if (stat(fnbuf, &buf) != 0)
1162  {
1163  /*
1164  * If file is not present, just go on without a client cert; server
1165  * might or might not accept the connection. Any other error,
1166  * however, is grounds for complaint.
1167  */
1168  if (errno != ENOENT && errno != ENOTDIR)
1169  {
1170  libpq_append_conn_error(conn, "could not open certificate file \"%s\": %s",
1171  fnbuf, strerror_r(errno, sebuf, sizeof(sebuf)));
1172  SSL_CTX_free(SSL_context);
1173  return -1;
1174  }
1175  have_cert = false;
1176  }
1177  else
1178  {
1179  /*
1180  * Cert file exists, so load it. Since OpenSSL doesn't provide the
1181  * equivalent of "SSL_use_certificate_chain_file", we have to load it
1182  * into the SSL context, rather than the SSL object.
1183  */
1184  if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
1185  {
1186  char *err = SSLerrmessage(ERR_get_error());
1187 
1188  libpq_append_conn_error(conn, "could not read certificate file \"%s\": %s",
1189  fnbuf, err);
1190  SSLerrfree(err);
1191  SSL_CTX_free(SSL_context);
1192  return -1;
1193  }
1194 
1195  /* need to load the associated private key, too */
1196  have_cert = true;
1197  }
1198 
1199  /*
1200  * The SSL context is now loaded with the correct root and client
1201  * certificates. Create a connection-specific SSL object. The private key
1202  * is loaded directly into the SSL object. (We could load the private key
1203  * into the context, too, but we have done it this way historically, and
1204  * it doesn't really matter.)
1205  */
1206  if (!(conn->ssl = SSL_new(SSL_context)) ||
1207  !SSL_set_app_data(conn->ssl, conn) ||
1209  {
1210  char *err = SSLerrmessage(ERR_get_error());
1211 
1212  libpq_append_conn_error(conn, "could not establish SSL connection: %s", err);
1213  SSLerrfree(err);
1214  SSL_CTX_free(SSL_context);
1215  return -1;
1216  }
1217  conn->ssl_in_use = true;
1218 
1219  /*
1220  * SSL contexts are reference counted by OpenSSL. We can free it as soon
1221  * as we have created the SSL object, and it will stick around for as long
1222  * as it's actually needed.
1223  */
1224  SSL_CTX_free(SSL_context);
1225  SSL_context = NULL;
1226 
1227  /*
1228  * Set Server Name Indication (SNI), if enabled by connection parameters.
1229  * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
1230  * or IPv6).
1231  */
1232  if (conn->sslsni && conn->sslsni[0] == '1')
1233  {
1234  const char *host = conn->connhost[conn->whichhost].host;
1235 
1236  if (host && host[0] &&
1237  !(strspn(host, "0123456789.") == strlen(host) ||
1238  strchr(host, ':')))
1239  {
1240  if (SSL_set_tlsext_host_name(conn->ssl, host) != 1)
1241  {
1242  char *err = SSLerrmessage(ERR_get_error());
1243 
1244  libpq_append_conn_error(conn, "could not set SSL Server Name Indication (SNI): %s", err);
1245  SSLerrfree(err);
1246  return -1;
1247  }
1248  }
1249  }
1250 
1251  /*
1252  * Read the SSL key. If a key is specified, treat it as an engine:key
1253  * combination if there is colon present - we don't support files with
1254  * colon in the name. The exception is if the second character is a colon,
1255  * in which case it can be a Windows filename with drive specification.
1256  */
1257  if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0)
1258  {
1259 #ifdef USE_SSL_ENGINE
1260  if (strchr(conn->sslkey, ':')
1261 #ifdef WIN32
1262  && conn->sslkey[1] != ':'
1263 #endif
1264  )
1265  {
1266  /* Colon, but not in second character, treat as engine:key */
1267  char *engine_str = strdup(conn->sslkey);
1268  char *engine_colon;
1269 
1270  if (engine_str == NULL)
1271  {
1272  libpq_append_conn_error(conn, "out of memory");
1273  return -1;
1274  }
1275 
1276  /* cannot return NULL because we already checked before strdup */
1277  engine_colon = strchr(engine_str, ':');
1278 
1279  *engine_colon = '\0'; /* engine_str now has engine name */
1280  engine_colon++; /* engine_colon now has key name */
1281 
1282  conn->engine = ENGINE_by_id(engine_str);
1283  if (conn->engine == NULL)
1284  {
1285  char *err = SSLerrmessage(ERR_get_error());
1286 
1287  libpq_append_conn_error(conn, "could not load SSL engine \"%s\": %s",
1288  engine_str, err);
1289  SSLerrfree(err);
1290  free(engine_str);
1291  return -1;
1292  }
1293 
1294  if (ENGINE_init(conn->engine) == 0)
1295  {
1296  char *err = SSLerrmessage(ERR_get_error());
1297 
1298  libpq_append_conn_error(conn, "could not initialize SSL engine \"%s\": %s",
1299  engine_str, err);
1300  SSLerrfree(err);
1301  ENGINE_free(conn->engine);
1302  conn->engine = NULL;
1303  free(engine_str);
1304  return -1;
1305  }
1306 
1307  pkey = ENGINE_load_private_key(conn->engine, engine_colon,
1308  NULL, NULL);
1309  if (pkey == NULL)
1310  {
1311  char *err = SSLerrmessage(ERR_get_error());
1312 
1313  libpq_append_conn_error(conn, "could not read private SSL key \"%s\" from engine \"%s\": %s",
1314  engine_colon, engine_str, err);
1315  SSLerrfree(err);
1316  ENGINE_finish(conn->engine);
1317  ENGINE_free(conn->engine);
1318  conn->engine = NULL;
1319  free(engine_str);
1320  return -1;
1321  }
1322  if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
1323  {
1324  char *err = SSLerrmessage(ERR_get_error());
1325 
1326  libpq_append_conn_error(conn, "could not load private SSL key \"%s\" from engine \"%s\": %s",
1327  engine_colon, engine_str, err);
1328  SSLerrfree(err);
1329  ENGINE_finish(conn->engine);
1330  ENGINE_free(conn->engine);
1331  conn->engine = NULL;
1332  free(engine_str);
1333  return -1;
1334  }
1335 
1336  free(engine_str);
1337 
1338  fnbuf[0] = '\0'; /* indicate we're not going to load from a
1339  * file */
1340  }
1341  else
1342 #endif /* USE_SSL_ENGINE */
1343  {
1344  /* PGSSLKEY is not an engine, treat it as a filename */
1345  strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
1346  }
1347  }
1348  else if (have_homedir)
1349  {
1350  /* No PGSSLKEY specified, load default file */
1351  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
1352  }
1353  else
1354  fnbuf[0] = '\0';
1355 
1356  if (have_cert && fnbuf[0] != '\0')
1357  {
1358  /* read the client key from file */
1359 
1360  if (stat(fnbuf, &buf) != 0)
1361  {
1362  if (errno == ENOENT)
1363  libpq_append_conn_error(conn, "certificate present, but not private key file \"%s\"",
1364  fnbuf);
1365  else
1366  libpq_append_conn_error(conn, "could not stat private key file \"%s\": %m",
1367  fnbuf);
1368  return -1;
1369  }
1370 
1371  /* Key file must be a regular file */
1372  if (!S_ISREG(buf.st_mode))
1373  {
1374  libpq_append_conn_error(conn, "private key file \"%s\" is not a regular file",
1375  fnbuf);
1376  return -1;
1377  }
1378 
1379  /*
1380  * Refuse to load world-readable key files. We accept root-owned
1381  * files with mode 0640 or less, so that we can access system-wide
1382  * certificates if we have a supplementary group membership that
1383  * allows us to read 'em. For files with non-root ownership, require
1384  * mode 0600 or less. We need not check the file's ownership exactly;
1385  * if we're able to read it despite it having such restrictive
1386  * permissions, it must have the right ownership.
1387  *
1388  * Note: be very careful about tightening these rules. Some people
1389  * expect, for example, that a client process running as root should
1390  * be able to use a non-root-owned key file.
1391  *
1392  * Note that roughly similar checks are performed in
1393  * src/backend/libpq/be-secure-common.c so any changes here may need
1394  * to be made there as well. However, this code caters for the case
1395  * of current user == root, while that code does not.
1396  *
1397  * Ideally we would do similar permissions checks on Windows, but it
1398  * is not clear how that would work since Unix-style permissions may
1399  * not be available.
1400  */
1401 #if !defined(WIN32) && !defined(__CYGWIN__)
1402  if (buf.st_uid == 0 ?
1403  buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO) :
1404  buf.st_mode & (S_IRWXG | S_IRWXO))
1405  {
1407  "private key file \"%s\" has group or world access; file must have permissions u=rw (0600) or less if owned by the current user, or permissions u=rw,g=r (0640) or less if owned by root",
1408  fnbuf);
1409  return -1;
1410  }
1411 #endif
1412 
1413  if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
1414  {
1415  char *err = SSLerrmessage(ERR_get_error());
1416 
1417  /*
1418  * We'll try to load the file in DER (binary ASN.1) format, and if
1419  * that fails too, report the original error. This could mask
1420  * issues where there's something wrong with a DER-format cert,
1421  * but we'd have to duplicate openssl's format detection to be
1422  * smarter than this. We can't just probe for a leading -----BEGIN
1423  * because PEM can have leading non-matching lines and blanks.
1424  * OpenSSL doesn't expose its get_name(...) and its PEM routines
1425  * don't differentiate between failure modes in enough detail to
1426  * let us tell the difference between "not PEM, try DER" and
1427  * "wrong password".
1428  */
1429  if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1)
1430  {
1431  libpq_append_conn_error(conn, "could not load private key file \"%s\": %s",
1432  fnbuf, err);
1433  SSLerrfree(err);
1434  return -1;
1435  }
1436 
1437  SSLerrfree(err);
1438  }
1439  }
1440 
1441  /* verify that the cert and key go together */
1442  if (have_cert &&
1443  SSL_check_private_key(conn->ssl) != 1)
1444  {
1445  char *err = SSLerrmessage(ERR_get_error());
1446 
1447  libpq_append_conn_error(conn, "certificate does not match private key file \"%s\": %s",
1448  fnbuf, err);
1449  SSLerrfree(err);
1450  return -1;
1451  }
1452 
1453  /*
1454  * If a root cert was loaded, also set our certificate verification
1455  * callback.
1456  */
1457  if (have_rootcert)
1458  SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
1459 
1460  /*
1461  * Set compression option if necessary.
1462  */
1463  if (conn->sslcompression && conn->sslcompression[0] == '0')
1464  SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1465  else
1466  SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1467 
1468  return 0;
1469 }
static SSL_CTX * SSL_context
void err(int eval, const char *fmt,...)
Definition: err.c:43
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:7756
void libpq_append_conn_error(PGconn *conn, const char *fmt,...)
Definition: fe-misc.c:1312
static int ssl_protocol_version_to_openssl(const char *protocol)
static int my_SSL_set_fd(PGconn *conn, int fd)
static void SSLerrfree(char *buf)
static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook
static int verify_cb(int ok, X509_STORE_CTX *ctx)
static int PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static char * SSLerrmessage(unsigned long ecode)
#define free(a)
Definition: header.h:65
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:67
#define PG_STRERROR_R_BUFLEN
Definition: port.h:256
#define snprintf
Definition: port.h:238
#define strerror_r
Definition: port.h:255
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
PGconn * conn
Definition: streamutil.c:54
char * host
Definition: libpq-int.h:346
char * sslrootcert
Definition: libpq-int.h:396
char * sslcompression
Definition: libpq-int.h:391
pgsocket sock
Definition: libpq-int.h:459
char * sslcrldir
Definition: libpq-int.h:398
char * sslcrl
Definition: libpq-int.h:397
char * ssl_max_protocol_version
Definition: libpq-int.h:407
char * sslcert
Definition: libpq-int.h:393
char * sslcertmode
Definition: libpq-int.h:395
char * sslpassword
Definition: libpq-int.h:394
char * sslmode
Definition: libpq-int.h:390
char * ssl_min_protocol_version
Definition: libpq-int.h:406
char * sslkey
Definition: libpq-int.h:392
int whichhost
Definition: libpq-int.h:441
char * sslsni
Definition: libpq-int.h:399
pg_conn_host * connhost
Definition: libpq-int.h:442
bool ssl_in_use
Definition: libpq-int.h:547
#define S_IXGRP
Definition: win32_port.h:307
#define stat
Definition: win32_port.h:284
#define S_IRWXG
Definition: win32_port.h:310
#define S_IRWXO
Definition: win32_port.h:322
#define S_ISREG(m)
Definition: win32_port.h:328
#define S_IWGRP
Definition: win32_port.h:304

References buf, conn, pg_conn::connhost, err(), free, pg_conn_host::host, libpq_append_conn_error(), MAXPGPATH, my_SSL_set_fd(), PG_STRERROR_R_BUFLEN, pqGetHomeDirectory(), PQssl_passwd_cb(), PQsslKeyPassHook, S_IRWXG, S_IRWXO, S_ISREG, S_IWGRP, S_IXGRP, snprintf, pg_conn::sock, SSL_context, SSL_CTX_set_max_proto_version(), SSL_CTX_set_min_proto_version(), pg_conn::ssl_in_use, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, ssl_protocol_version_to_openssl(), pg_conn::sslcert, pg_conn::sslcertmode, pg_conn::sslcompression, pg_conn::sslcrl, pg_conn::sslcrldir, SSLerrfree(), SSLerrmessage(), pg_conn::sslkey, pg_conn::sslmode, pg_conn::sslpassword, pg_conn::sslrootcert, pg_conn::sslsni, stat, strerror_r, strlcpy(), verify_cb(), and pg_conn::whichhost.

Referenced by pgtls_open_client().

◆ is_ip_address()

static bool is_ip_address ( const char *  host)
static

Definition at line 553 of file fe-secure-openssl.c.

554 {
555  struct in_addr dummy4;
556 #ifdef HAVE_INET_PTON
557  struct in6_addr dummy6;
558 #endif
559 
560  return inet_aton(host, &dummy4)
561 #ifdef HAVE_INET_PTON
562  || (inet_pton(AF_INET6, host, &dummy6) == 1)
563 #endif
564  ;
565 }
int inet_aton(const char *cp, struct in_addr *addr)
Definition: inet_aton.c:56

References inet_aton().

Referenced by pgtls_verify_peer_name_matches_certificate_guts().

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

Definition at line 1886 of file fe-secure-openssl.c.

1887 {
1888  if (!my_bio_methods)
1889  {
1890  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
1891 #ifdef HAVE_BIO_METH_NEW
1892  int my_bio_index;
1893 
1894  my_bio_index = BIO_get_new_index();
1895  if (my_bio_index == -1)
1896  return NULL;
1897  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
1898  my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
1899  if (!my_bio_methods)
1900  return NULL;
1901 
1902  /*
1903  * As of this writing, these functions never fail. But check anyway,
1904  * like OpenSSL's own examples do.
1905  */
1906  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
1907  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
1908  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
1909  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
1910  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
1911  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
1912  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
1913  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
1914  {
1915  BIO_meth_free(my_bio_methods);
1916  my_bio_methods = NULL;
1917  return NULL;
1918  }
1919 #else
1920  my_bio_methods = malloc(sizeof(BIO_METHOD));
1921  if (!my_bio_methods)
1922  return NULL;
1923  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
1924  my_bio_methods->bread = my_sock_read;
1925  my_bio_methods->bwrite = my_sock_write;
1926 #endif
1927  }
1928  return my_bio_methods;
1929 }
static BIO_METHOD * my_bio_methods
static int my_sock_write(BIO *h, const char *buf, int size)
static int my_sock_read(BIO *h, char *buf, int size)
#define malloc(a)
Definition: header.h:50

References malloc, my_bio_methods, my_sock_read(), and my_sock_write().

Referenced by my_SSL_set_fd().

◆ my_sock_read()

static int my_sock_read ( BIO *  h,
char *  buf,
int  size 
)
static

Definition at line 1826 of file fe-secure-openssl.c.

1827 {
1828  int res;
1829 
1830  res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
1831  BIO_clear_retry_flags(h);
1832  if (res < 0)
1833  {
1834  /* If we were interrupted, tell caller to retry */
1835  switch (SOCK_ERRNO)
1836  {
1837 #ifdef EAGAIN
1838  case EAGAIN:
1839 #endif
1840 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1841  case EWOULDBLOCK:
1842 #endif
1843  case EINTR:
1844  BIO_set_retry_read(h);
1845  break;
1846 
1847  default:
1848  break;
1849  }
1850  }
1851 
1852  return res;
1853 }
#define BIO_get_data(bio)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:208
#define SOCK_ERRNO
Definition: libpq-int.h:921
#define EINTR
Definition: win32_port.h:374
#define EWOULDBLOCK
Definition: win32_port.h:380
#define EAGAIN
Definition: win32_port.h:372

References BIO_get_data, buf, EAGAIN, EINTR, EWOULDBLOCK, pqsecure_raw_read(), res, and SOCK_ERRNO.

Referenced by my_BIO_s_socket().

◆ my_sock_write()

static int my_sock_write ( BIO *  h,
const char *  buf,
int  size 
)
static

Definition at line 1856 of file fe-secure-openssl.c.

1857 {
1858  int res;
1859 
1860  res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
1861  BIO_clear_retry_flags(h);
1862  if (res < 0)
1863  {
1864  /* If we were interrupted, tell caller to retry */
1865  switch (SOCK_ERRNO)
1866  {
1867 #ifdef EAGAIN
1868  case EAGAIN:
1869 #endif
1870 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1871  case EWOULDBLOCK:
1872 #endif
1873  case EINTR:
1874  BIO_set_retry_write(h);
1875  break;
1876 
1877  default:
1878  break;
1879  }
1880  }
1881 
1882  return res;
1883 }
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:324

References BIO_get_data, buf, EAGAIN, EINTR, EWOULDBLOCK, pqsecure_raw_write(), res, and SOCK_ERRNO.

Referenced by my_BIO_s_socket().

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( PGconn conn,
int  fd 
)
static

Definition at line 1933 of file fe-secure-openssl.c.

1934 {
1935  int ret = 0;
1936  BIO *bio;
1937  BIO_METHOD *bio_method;
1938 
1939  bio_method = my_BIO_s_socket();
1940  if (bio_method == NULL)
1941  {
1942  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
1943  goto err;
1944  }
1945  bio = BIO_new(bio_method);
1946  if (bio == NULL)
1947  {
1948  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
1949  goto err;
1950  }
1951  BIO_set_data(bio, conn);
1952 
1953  SSL_set_bio(conn->ssl, bio, bio);
1954  BIO_set_fd(bio, fd, BIO_NOCLOSE);
1955  ret = 1;
1956 err:
1957  return ret;
1958 }
static BIO_METHOD * my_BIO_s_socket(void)
#define BIO_set_data(bio, data)
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References BIO_set_data, conn, err(), fd(), and my_BIO_s_socket().

Referenced by initialize_SSL().

◆ open_client_SSL()

static PostgresPollingStatusType open_client_SSL ( PGconn conn)
static

Definition at line 1475 of file fe-secure-openssl.c.

1476 {
1477  int r;
1478 
1479  SOCK_ERRNO_SET(0);
1480  ERR_clear_error();
1481  r = SSL_connect(conn->ssl);
1482  if (r <= 0)
1483  {
1484  int save_errno = SOCK_ERRNO;
1485  int err = SSL_get_error(conn->ssl, r);
1486  unsigned long ecode;
1487 
1488  ecode = ERR_get_error();
1489  switch (err)
1490  {
1491  case SSL_ERROR_WANT_READ:
1492  return PGRES_POLLING_READING;
1493 
1494  case SSL_ERROR_WANT_WRITE:
1495  return PGRES_POLLING_WRITING;
1496 
1497  case SSL_ERROR_SYSCALL:
1498  {
1499  char sebuf[PG_STRERROR_R_BUFLEN];
1500  unsigned long vcode;
1501 
1502  vcode = SSL_get_verify_result(conn->ssl);
1503 
1504  /*
1505  * If we get an X509 error here for failing to load the
1506  * local issuer cert, without an error in the socket layer
1507  * it means that verification failed due to a missing
1508  * system CA pool without it being a protocol error. We
1509  * inspect the sslrootcert setting to ensure that the user
1510  * was using the system CA pool. For other errors, log
1511  * them using the normal SYSCALL logging.
1512  */
1513  if (!save_errno && vcode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY &&
1514  strcmp(conn->sslrootcert, "system") == 0)
1515  libpq_append_conn_error(conn, "SSL error: certificate verify failed: %s",
1516  X509_verify_cert_error_string(vcode));
1517  else if (r == -1)
1518  libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
1519  SOCK_STRERROR(save_errno, sebuf, sizeof(sebuf)));
1520  else
1521  libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
1522  pgtls_close(conn);
1523  return PGRES_POLLING_FAILED;
1524  }
1525  case SSL_ERROR_SSL:
1526  {
1527  char *err = SSLerrmessage(ecode);
1528 
1529  libpq_append_conn_error(conn, "SSL error: %s", err);
1530  SSLerrfree(err);
1531  switch (ERR_GET_REASON(ecode))
1532  {
1533  /*
1534  * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
1535  * TLSV1_ALERT_PROTOCOL_VERSION have been observed
1536  * when trying to communicate with an old OpenSSL
1537  * library, or when the client and server specify
1538  * disjoint protocol ranges.
1539  * NO_PROTOCOLS_AVAILABLE occurs if there's a
1540  * local misconfiguration (which can happen
1541  * despite our checks, if openssl.cnf injects a
1542  * limit we didn't account for). It's not very
1543  * clear what would make OpenSSL return the other
1544  * codes listed here, but a hint about protocol
1545  * versions seems like it's appropriate for all.
1546  */
1547  case SSL_R_NO_PROTOCOLS_AVAILABLE:
1548  case SSL_R_UNSUPPORTED_PROTOCOL:
1549  case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
1550  case SSL_R_UNKNOWN_PROTOCOL:
1551  case SSL_R_UNKNOWN_SSL_VERSION:
1552  case SSL_R_UNSUPPORTED_SSL_VERSION:
1553  case SSL_R_WRONG_SSL_VERSION:
1554  case SSL_R_WRONG_VERSION_NUMBER:
1555  case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
1556 #ifdef SSL_R_VERSION_TOO_HIGH
1557  case SSL_R_VERSION_TOO_HIGH:
1558  case SSL_R_VERSION_TOO_LOW:
1559 #endif
1560  libpq_append_conn_error(conn, "This may indicate that the server does not support any SSL protocol version between %s and %s.",
1563  MIN_OPENSSL_TLS_VERSION,
1566  MAX_OPENSSL_TLS_VERSION);
1567  break;
1568  default:
1569  break;
1570  }
1571  pgtls_close(conn);
1572  return PGRES_POLLING_FAILED;
1573  }
1574 
1575  default:
1576  libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
1577  pgtls_close(conn);
1578  return PGRES_POLLING_FAILED;
1579  }
1580  }
1581 
1582  /*
1583  * We already checked the server certificate in initialize_SSL() using
1584  * SSL_CTX_set_verify(), if root.crt exists.
1585  */
1586 
1587  /* get server certificate */
1588  conn->peer = SSL_get_peer_certificate(conn->ssl);
1589  if (conn->peer == NULL)
1590  {
1591  char *err = SSLerrmessage(ERR_get_error());
1592 
1593  libpq_append_conn_error(conn, "certificate could not be obtained: %s", err);
1594  SSLerrfree(err);
1595  pgtls_close(conn);
1596  return PGRES_POLLING_FAILED;
1597  }
1598 
1600  {
1601  pgtls_close(conn);
1602  return PGRES_POLLING_FAILED;
1603  }
1604 
1605  /* SSL handshake is complete */
1606  return PGRES_POLLING_OK;
1607 }
bool pq_verify_peer_name_matches_certificate(PGconn *conn)
void pgtls_close(PGconn *conn)
@ PGRES_POLLING_OK
Definition: libpq-fe.h:89
@ PGRES_POLLING_READING
Definition: libpq-fe.h:87
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:88
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:86
#define SOCK_STRERROR
Definition: libpq-int.h:922
#define SOCK_ERRNO_SET(e)
Definition: libpq-int.h:923

References conn, err(), libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, PGRES_POLLING_FAILED, PGRES_POLLING_OK, PGRES_POLLING_READING, PGRES_POLLING_WRITING, pgtls_close(), pq_verify_peer_name_matches_certificate(), SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, SSLerrfree(), SSLerrmessage(), and pg_conn::sslrootcert.

Referenced by pgtls_open_client().

◆ openssl_verify_peer_name_matches_certificate_ip()

static int openssl_verify_peer_name_matches_certificate_ip ( PGconn conn,
ASN1_OCTET_STRING *  addr_entry,
char **  store_name 
)
static

Definition at line 524 of file fe-secure-openssl.c.

527 {
528  int len;
529  const unsigned char *addrdata;
530 
531  /* Should not happen... */
532  if (addr_entry == NULL)
533  {
534  libpq_append_conn_error(conn, "SSL certificate's address entry is missing");
535  return -1;
536  }
537 
538  /*
539  * GEN_IPADD is an OCTET STRING containing an IP address in network byte
540  * order.
541  */
542 #ifdef HAVE_ASN1_STRING_GET0_DATA
543  addrdata = ASN1_STRING_get0_data(addr_entry);
544 #else
545  addrdata = ASN1_STRING_data(addr_entry);
546 #endif
547  len = ASN1_STRING_length(addr_entry);
548 
549  return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name);
550 }
int pq_verify_peer_name_matches_certificate_ip(PGconn *conn, const unsigned char *ipdata, size_t iplen, char **store_name)
const void size_t len

References conn, len, libpq_append_conn_error(), and pq_verify_peer_name_matches_certificate_ip().

Referenced by pgtls_verify_peer_name_matches_certificate_guts().

◆ openssl_verify_peer_name_matches_certificate_name()

static int openssl_verify_peer_name_matches_certificate_name ( PGconn conn,
ASN1_STRING *  name_entry,
char **  store_name 
)
static

Definition at line 491 of file fe-secure-openssl.c.

493 {
494  int len;
495  const unsigned char *namedata;
496 
497  /* Should not happen... */
498  if (name_entry == NULL)
499  {
500  libpq_append_conn_error(conn, "SSL certificate's name entry is missing");
501  return -1;
502  }
503 
504  /*
505  * GEN_DNS can be only IA5String, equivalent to US ASCII.
506  */
507 #ifdef HAVE_ASN1_STRING_GET0_DATA
508  namedata = ASN1_STRING_get0_data(name_entry);
509 #else
510  namedata = ASN1_STRING_data(name_entry);
511 #endif
512  len = ASN1_STRING_length(name_entry);
513 
514  /* OK to cast from unsigned to plain char, since it's all ASCII. */
515  return pq_verify_peer_name_matches_certificate_name(conn, (const char *) namedata, len, store_name);
516 }
int pq_verify_peer_name_matches_certificate_name(PGconn *conn, const char *namedata, size_t namelen, char **store_name)

References conn, len, libpq_append_conn_error(), and pq_verify_peer_name_matches_certificate_name().

Referenced by pgtls_verify_peer_name_matches_certificate_guts().

◆ pgtls_close()

void pgtls_close ( PGconn conn)

Definition at line 1610 of file fe-secure-openssl.c.

1611 {
1612  bool destroy_needed = false;
1613 
1614  if (conn->ssl_in_use)
1615  {
1616  if (conn->ssl)
1617  {
1618  /*
1619  * We can't destroy everything SSL-related here due to the
1620  * possible later calls to OpenSSL routines which may need our
1621  * thread callbacks, so set a flag here and check at the end.
1622  */
1623 
1624  SSL_shutdown(conn->ssl);
1625  SSL_free(conn->ssl);
1626  conn->ssl = NULL;
1627  conn->ssl_in_use = false;
1628 
1629  destroy_needed = true;
1630  }
1631 
1632  if (conn->peer)
1633  {
1634  X509_free(conn->peer);
1635  conn->peer = NULL;
1636  }
1637 
1638 #ifdef USE_SSL_ENGINE
1639  if (conn->engine)
1640  {
1641  ENGINE_finish(conn->engine);
1642  ENGINE_free(conn->engine);
1643  conn->engine = NULL;
1644  }
1645 #endif
1646  }
1647  else
1648  {
1649  /*
1650  * In the non-SSL case, just remove the crypto callbacks if the
1651  * connection has then loaded. This code path has no dependency on
1652  * any pending SSL calls.
1653  */
1654  if (conn->crypto_loaded)
1655  destroy_needed = true;
1656  }
1657 
1658  /*
1659  * This will remove our crypto locking hooks if this is the last
1660  * connection using libcrypto which means we must wait to call it until
1661  * after all the potential SSL calls have been made, otherwise we can end
1662  * up with a race condition and possible deadlocks.
1663  *
1664  * See comments above destroy_ssl_system().
1665  */
1666  if (destroy_needed)
1667  {
1669  conn->crypto_loaded = false;
1670  }
1671 }
static void destroy_ssl_system(void)

References conn, destroy_ssl_system(), and pg_conn::ssl_in_use.

Referenced by open_client_SSL(), pgtls_open_client(), and pqsecure_close().

◆ pgtls_get_peer_certificate_hash()

char* pgtls_get_peer_certificate_hash ( PGconn conn,
size_t *  len 
)

Definition at line 361 of file fe-secure-openssl.c.

362 {
363  X509 *peer_cert;
364  const EVP_MD *algo_type;
365  unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
366  unsigned int hash_size;
367  int algo_nid;
368  char *cert_hash;
369 
370  *len = 0;
371 
372  if (!conn->peer)
373  return NULL;
374 
375  peer_cert = conn->peer;
376 
377  /*
378  * Get the signature algorithm of the certificate to determine the hash
379  * algorithm to use for the result. Prefer X509_get_signature_info(),
380  * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
381  */
382 #if HAVE_X509_GET_SIGNATURE_INFO
383  if (!X509_get_signature_info(peer_cert, &algo_nid, NULL, NULL, NULL))
384 #else
385  if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
386  &algo_nid, NULL))
387 #endif
388  {
389  libpq_append_conn_error(conn, "could not determine server certificate signature algorithm");
390  return NULL;
391  }
392 
393  /*
394  * The TLS server's certificate bytes need to be hashed with SHA-256 if
395  * its signature algorithm is MD5 or SHA-1 as per RFC 5929
396  * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
397  * is used, the same hash as the signature algorithm is used.
398  */
399  switch (algo_nid)
400  {
401  case NID_md5:
402  case NID_sha1:
403  algo_type = EVP_sha256();
404  break;
405  default:
406  algo_type = EVP_get_digestbynid(algo_nid);
407  if (algo_type == NULL)
408  {
409  libpq_append_conn_error(conn, "could not find digest for NID %s",
410  OBJ_nid2sn(algo_nid));
411  return NULL;
412  }
413  break;
414  }
415 
416  if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
417  {
418  libpq_append_conn_error(conn, "could not generate peer certificate hash");
419  return NULL;
420  }
421 
422  /* save result */
423  cert_hash = malloc(hash_size);
424  if (cert_hash == NULL)
425  {
426  libpq_append_conn_error(conn, "out of memory");
427  return NULL;
428  }
429  memcpy(cert_hash, hash, hash_size);
430  *len = hash_size;
431 
432  return cert_hash;
433 }
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715

References conn, hash(), len, libpq_append_conn_error(), and malloc.

Referenced by build_client_final_message().

◆ pgtls_init()

int pgtls_init ( PGconn conn,
bool  do_ssl,
bool  do_crypto 
)

Definition at line 768 of file fe-secure-openssl.c.

769 {
770 #ifdef WIN32
771  /* Also see similar code in fe-connect.c, default_threadlock() */
772  if (ssl_config_mutex == NULL)
773  {
774  while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
775  /* loop, another thread own the lock */ ;
776  if (ssl_config_mutex == NULL)
777  {
779  return -1;
780  }
781  InterlockedExchange(&win32_ssl_create_mutex, 0);
782  }
783 #endif
785  return -1;
786 
787 #ifdef HAVE_CRYPTO_LOCK
788  if (pq_init_crypto_lib)
789  {
790  /*
791  * If necessary, set up an array to hold locks for libcrypto.
792  * libcrypto will tell us how big to make this array.
793  */
794  if (pq_lockarray == NULL)
795  {
796  int i;
797 
798  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
799  if (!pq_lockarray)
800  {
802  return -1;
803  }
804  for (i = 0; i < CRYPTO_num_locks(); i++)
805  {
806  if (pthread_mutex_init(&pq_lockarray[i], NULL))
807  {
808  free(pq_lockarray);
809  pq_lockarray = NULL;
811  return -1;
812  }
813  }
814  }
815 
816  if (do_crypto && !conn->crypto_loaded)
817  {
818  if (crypto_open_connections++ == 0)
819  {
820  /*
821  * These are only required for threaded libcrypto
822  * applications, but make sure we don't stomp on them if
823  * they're already set.
824  */
825  if (CRYPTO_get_id_callback() == NULL)
826  CRYPTO_set_id_callback(pq_threadidcallback);
827  if (CRYPTO_get_locking_callback() == NULL)
828  CRYPTO_set_locking_callback(pq_lockingcallback);
829  }
830 
831  conn->crypto_loaded = true;
832  }
833  }
834 #endif /* HAVE_CRYPTO_LOCK */
835 
836  if (!ssl_lib_initialized && do_ssl)
837  {
838  if (pq_init_ssl_lib)
839  {
840 #ifdef HAVE_OPENSSL_INIT_SSL
841  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
842 #else
843  OPENSSL_config(NULL);
844  SSL_library_init();
845  SSL_load_error_strings();
846 #endif
847  }
848  ssl_lib_initialized = true;
849  }
850 
852  return 0;
853 }
static bool ssl_lib_initialized
static bool pq_init_ssl_lib
int i
Definition: isn.c:73
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8

References conn, crypto_open_connections, free, i, malloc, pq_init_crypto_lib, pq_init_ssl_lib, pthread_mutex_init(), pthread_mutex_lock(), pthread_mutex_unlock(), ssl_config_mutex, and ssl_lib_initialized.

Referenced by pqsecure_initialize().

◆ pgtls_init_library()

void pgtls_init_library ( bool  do_ssl,
int  do_crypto 
)

Definition at line 109 of file fe-secure-openssl.c.

110 {
111  /*
112  * Disallow changing the flags while we have open connections, else we'd
113  * get completely confused.
114  */
115  if (crypto_open_connections != 0)
116  return;
117 
118  pq_init_ssl_lib = do_ssl;
119  pq_init_crypto_lib = do_crypto;
120 }

References crypto_open_connections, pq_init_crypto_lib, and pq_init_ssl_lib.

Referenced by PQinitOpenSSL(), and PQinitSSL().

◆ pgtls_open_client()

PostgresPollingStatusType pgtls_open_client ( PGconn conn)

Definition at line 123 of file fe-secure-openssl.c.

124 {
125  /* First time through? */
126  if (conn->ssl == NULL)
127  {
128  /*
129  * Create a connection-specific SSL object, and load client
130  * certificate, private key, and trusted CA certs.
131  */
132  if (initialize_SSL(conn) != 0)
133  {
134  /* initialize_SSL already put a message in conn->errorMessage */
135  pgtls_close(conn);
136  return PGRES_POLLING_FAILED;
137  }
138  }
139 
140  /* Begin or continue the actual handshake */
141  return open_client_SSL(conn);
142 }
static int initialize_SSL(PGconn *conn)
static PostgresPollingStatusType open_client_SSL(PGconn *conn)

References conn, initialize_SSL(), open_client_SSL(), PGRES_POLLING_FAILED, and pgtls_close().

Referenced by pqsecure_open_client().

◆ pgtls_read()

ssize_t pgtls_read ( PGconn conn,
void *  ptr,
size_t  len 
)

Definition at line 145 of file fe-secure-openssl.c.

146 {
147  ssize_t n;
148  int result_errno = 0;
149  char sebuf[PG_STRERROR_R_BUFLEN];
150  int err;
151  unsigned long ecode;
152 
153 rloop:
154 
155  /*
156  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
157  * queue. In general, the current thread's error queue must be empty
158  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
159  * not work reliably. Since the possibility exists that other OpenSSL
160  * clients running in the same thread but not under our control will fail
161  * to call ERR_get_error() themselves (after their own I/O operations),
162  * pro-actively clear the per-thread error queue now.
163  */
164  SOCK_ERRNO_SET(0);
165  ERR_clear_error();
166  n = SSL_read(conn->ssl, ptr, len);
167  err = SSL_get_error(conn->ssl, n);
168 
169  /*
170  * Other clients of OpenSSL may fail to call ERR_get_error(), but we
171  * always do, so as to not cause problems for OpenSSL clients that don't
172  * call ERR_clear_error() defensively. Be sure that this happens by
173  * calling now. SSL_get_error() relies on the OpenSSL per-thread error
174  * queue being intact, so this is the earliest possible point
175  * ERR_get_error() may be called.
176  */
177  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
178  switch (err)
179  {
180  case SSL_ERROR_NONE:
181  if (n < 0)
182  {
183  /* Not supposed to happen, so we don't translate the msg */
185  "SSL_read failed but did not provide error information\n");
186  /* assume the connection is broken */
187  result_errno = ECONNRESET;
188  }
189  break;
190  case SSL_ERROR_WANT_READ:
191  n = 0;
192  break;
193  case SSL_ERROR_WANT_WRITE:
194 
195  /*
196  * Returning 0 here would cause caller to wait for read-ready,
197  * which is not correct since what SSL wants is wait for
198  * write-ready. The former could get us stuck in an infinite
199  * wait, so don't risk it; busy-loop instead.
200  */
201  goto rloop;
202  case SSL_ERROR_SYSCALL:
203  if (n < 0)
204  {
205  result_errno = SOCK_ERRNO;
206  if (result_errno == EPIPE ||
207  result_errno == ECONNRESET)
208  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
209  "\tThis probably means the server terminated abnormally\n"
210  "\tbefore or while processing the request.");
211  else
212  libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
213  SOCK_STRERROR(result_errno,
214  sebuf, sizeof(sebuf)));
215  }
216  else
217  {
218  libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
219  /* assume the connection is broken */
220  result_errno = ECONNRESET;
221  n = -1;
222  }
223  break;
224  case SSL_ERROR_SSL:
225  {
226  char *errm = SSLerrmessage(ecode);
227 
228  libpq_append_conn_error(conn, "SSL error: %s", errm);
229  SSLerrfree(errm);
230  /* assume the connection is broken */
231  result_errno = ECONNRESET;
232  n = -1;
233  break;
234  }
235  case SSL_ERROR_ZERO_RETURN:
236 
237  /*
238  * Per OpenSSL documentation, this error code is only returned for
239  * a clean connection closure, so we should not report it as a
240  * server crash.
241  */
242  libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
243  result_errno = ECONNRESET;
244  n = -1;
245  break;
246  default:
247  libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
248  /* assume the connection is broken */
249  result_errno = ECONNRESET;
250  n = -1;
251  break;
252  }
253 
254  /* ensure we return the intended errno to caller */
255  SOCK_ERRNO_SET(result_errno);
256 
257  return n;
258 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
PQExpBufferData errorMessage
Definition: libpq-int.h:617
#define ECONNRESET
Definition: win32_port.h:384

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_read().

◆ pgtls_read_pending()

bool pgtls_read_pending ( PGconn conn)

Definition at line 261 of file fe-secure-openssl.c.

262 {
263  return SSL_pending(conn->ssl) > 0;
264 }

References conn.

Referenced by pqSocketCheck().

◆ pgtls_verify_peer_name_matches_certificate_guts()

int pgtls_verify_peer_name_matches_certificate_guts ( PGconn conn,
int *  names_examined,
char **  first_name 
)

Definition at line 573 of file fe-secure-openssl.c.

576 {
577  STACK_OF(GENERAL_NAME) * peer_san;
578  int i;
579  int rc = 0;
580  char *host = conn->connhost[conn->whichhost].host;
581  int host_type;
582  bool check_cn = true;
583 
584  Assert(host && host[0]); /* should be guaranteed by caller */
585 
586  /*
587  * We try to match the NSS behavior here, which is a slight departure from
588  * the spec but seems to make more intuitive sense:
589  *
590  * If connhost contains a DNS name, and the certificate's SANs contain any
591  * dNSName entries, then we'll ignore the Subject Common Name entirely;
592  * otherwise, we fall back to checking the CN. (This behavior matches the
593  * RFC.)
594  *
595  * If connhost contains an IP address, and the SANs contain iPAddress
596  * entries, we again ignore the CN. Otherwise, we allow the CN to match,
597  * EVEN IF there is a dNSName in the SANs. (RFC 6125 prohibits this: "A
598  * client MUST NOT seek a match for a reference identifier of CN-ID if the
599  * presented identifiers include a DNS-ID, SRV-ID, URI-ID, or any
600  * application-specific identifier types supported by the client.")
601  *
602  * NOTE: Prior versions of libpq did not consider iPAddress entries at
603  * all, so this new behavior might break a certificate that has different
604  * IP addresses in the Subject CN and the SANs.
605  */
606  if (is_ip_address(host))
607  host_type = GEN_IPADD;
608  else
609  host_type = GEN_DNS;
610 
611  /*
612  * First, get the Subject Alternative Names (SANs) from the certificate,
613  * and compare them against the originally given hostname.
614  */
615  peer_san = (STACK_OF(GENERAL_NAME) *)
616  X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
617 
618  if (peer_san)
619  {
620  int san_len = sk_GENERAL_NAME_num(peer_san);
621 
622  for (i = 0; i < san_len; i++)
623  {
624  const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
625  char *alt_name = NULL;
626 
627  if (name->type == host_type)
628  {
629  /*
630  * This SAN is of the same type (IP or DNS) as our host name,
631  * so don't allow a fallback check of the CN.
632  */
633  check_cn = false;
634  }
635 
636  if (name->type == GEN_DNS)
637  {
638  (*names_examined)++;
640  name->d.dNSName,
641  &alt_name);
642  }
643  else if (name->type == GEN_IPADD)
644  {
645  (*names_examined)++;
647  name->d.iPAddress,
648  &alt_name);
649  }
650 
651  if (alt_name)
652  {
653  if (!*first_name)
654  *first_name = alt_name;
655  else
656  free(alt_name);
657  }
658 
659  if (rc != 0)
660  {
661  /*
662  * Either we hit an error or a match, and either way we should
663  * not fall back to the CN.
664  */
665  check_cn = false;
666  break;
667  }
668  }
669  sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
670  }
671 
672  /*
673  * If there is no subjectAltName extension of the matching type, check the
674  * Common Name.
675  *
676  * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
677  * dNSName is present, the CN must be ignored. We break this rule if host
678  * is an IP address; see the comment above.)
679  */
680  if (check_cn)
681  {
682  X509_NAME *subject_name;
683 
684  subject_name = X509_get_subject_name(conn->peer);
685  if (subject_name != NULL)
686  {
687  int cn_index;
688 
689  cn_index = X509_NAME_get_index_by_NID(subject_name,
690  NID_commonName, -1);
691  if (cn_index >= 0)
692  {
693  char *common_name = NULL;
694 
695  (*names_examined)++;
697  X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
698  &common_name);
699 
700  if (common_name)
701  {
702  if (!*first_name)
703  *first_name = common_name;
704  else
705  free(common_name);
706  }
707  }
708  }
709  }
710 
711  return rc;
712 }
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry, char **store_name)
static int openssl_verify_peer_name_matches_certificate_ip(PGconn *conn, ASN1_OCTET_STRING *addr_entry, char **store_name)
static bool is_ip_address(const char *host)
Assert(fmt[strlen(fmt) - 1] !='\n')
const char * name

References Assert(), conn, pg_conn::connhost, free, pg_conn_host::host, i, is_ip_address(), name, openssl_verify_peer_name_matches_certificate_ip(), openssl_verify_peer_name_matches_certificate_name(), and pg_conn::whichhost.

Referenced by pq_verify_peer_name_matches_certificate().

◆ pgtls_write()

ssize_t pgtls_write ( PGconn conn,
const void *  ptr,
size_t  len 
)

Definition at line 267 of file fe-secure-openssl.c.

268 {
269  ssize_t n;
270  int result_errno = 0;
271  char sebuf[PG_STRERROR_R_BUFLEN];
272  int err;
273  unsigned long ecode;
274 
275  SOCK_ERRNO_SET(0);
276  ERR_clear_error();
277  n = SSL_write(conn->ssl, ptr, len);
278  err = SSL_get_error(conn->ssl, n);
279  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
280  switch (err)
281  {
282  case SSL_ERROR_NONE:
283  if (n < 0)
284  {
285  /* Not supposed to happen, so we don't translate the msg */
287  "SSL_write failed but did not provide error information\n");
288  /* assume the connection is broken */
289  result_errno = ECONNRESET;
290  }
291  break;
292  case SSL_ERROR_WANT_READ:
293 
294  /*
295  * Returning 0 here causes caller to wait for write-ready, which
296  * is not really the right thing, but it's the best we can do.
297  */
298  n = 0;
299  break;
300  case SSL_ERROR_WANT_WRITE:
301  n = 0;
302  break;
303  case SSL_ERROR_SYSCALL:
304  if (n < 0)
305  {
306  result_errno = SOCK_ERRNO;
307  if (result_errno == EPIPE || result_errno == ECONNRESET)
308  libpq_append_conn_error(conn, "server closed the connection unexpectedly\n"
309  "\tThis probably means the server terminated abnormally\n"
310  "\tbefore or while processing the request.");
311  else
312  libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
313  SOCK_STRERROR(result_errno,
314  sebuf, sizeof(sebuf)));
315  }
316  else
317  {
318  libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
319  /* assume the connection is broken */
320  result_errno = ECONNRESET;
321  n = -1;
322  }
323  break;
324  case SSL_ERROR_SSL:
325  {
326  char *errm = SSLerrmessage(ecode);
327 
328  libpq_append_conn_error(conn, "SSL error: %s", errm);
329  SSLerrfree(errm);
330  /* assume the connection is broken */
331  result_errno = ECONNRESET;
332  n = -1;
333  break;
334  }
335  case SSL_ERROR_ZERO_RETURN:
336 
337  /*
338  * Per OpenSSL documentation, this error code is only returned for
339  * a clean connection closure, so we should not report it as a
340  * server crash.
341  */
342  libpq_append_conn_error(conn, "SSL connection has been closed unexpectedly");
343  result_errno = ECONNRESET;
344  n = -1;
345  break;
346  default:
347  libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
348  /* assume the connection is broken */
349  result_errno = ECONNRESET;
350  n = -1;
351  break;
352  }
353 
354  /* ensure we return the intended errno to caller */
355  SOCK_ERRNO_SET(result_errno);
356 
357  return n;
358 }

References appendPQExpBufferStr(), conn, ECONNRESET, err(), pg_conn::errorMessage, len, libpq_append_conn_error(), PG_STRERROR_R_BUFLEN, SOCK_ERRNO, SOCK_ERRNO_SET, SOCK_STRERROR, SSLerrfree(), and SSLerrmessage().

Referenced by pqsecure_write().

◆ PQdefaultSSLKeyPassHook_OpenSSL()

int PQdefaultSSLKeyPassHook_OpenSSL ( char *  buf,
int  size,
PGconn conn 
)

Definition at line 1966 of file fe-secure-openssl.c.

1967 {
1968  if (conn && conn->sslpassword)
1969  {
1970  if (strlen(conn->sslpassword) + 1 > size)
1971  fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
1972  strncpy(buf, conn->sslpassword, size);
1973  buf[size - 1] = '\0';
1974  return strlen(buf);
1975  }
1976  else
1977  {
1978  buf[0] = '\0';
1979  return 0;
1980  }
1981 }
#define libpq_gettext(x)
Definition: libpq-int.h:900
#define fprintf
Definition: port.h:242

References buf, conn, fprintf, libpq_gettext, and pg_conn::sslpassword.

Referenced by PQssl_passwd_cb().

◆ PQgetssl()

void* PQgetssl ( PGconn conn)

Definition at line 1726 of file fe-secure-openssl.c.

1727 {
1728  if (!conn)
1729  return NULL;
1730  return conn->ssl;
1731 }

References conn.

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

Definition at line 1984 of file fe-secure-openssl.c.

1985 {
1986  return PQsslKeyPassHook;
1987 }

References PQsslKeyPassHook.

◆ PQsetSSLKeyPassHook_OpenSSL()

void PQsetSSLKeyPassHook_OpenSSL ( PQsslKeyPassHook_OpenSSL_type  hook)

Definition at line 1990 of file fe-secure-openssl.c.

1991 {
1992  PQsslKeyPassHook = hook;
1993 }

References PQsslKeyPassHook.

◆ PQssl_passwd_cb()

static int PQssl_passwd_cb ( char *  buf,
int  size,
int  rwflag,
void *  userdata 
)
static

Definition at line 2001 of file fe-secure-openssl.c.

2002 {
2003  PGconn *conn = userdata;
2004 
2005  if (PQsslKeyPassHook)
2006  return PQsslKeyPassHook(buf, size, conn);
2007  else
2008  return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
2009 }
int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)

References buf, conn, PQdefaultSSLKeyPassHook_OpenSSL(), and PQsslKeyPassHook.

Referenced by initialize_SSL().

◆ PQsslAttribute()

const char* PQsslAttribute ( PGconn conn,
const char *  attribute_name 
)

Definition at line 1770 of file fe-secure-openssl.c.

1771 {
1772  if (!conn)
1773  {
1774  /* PQsslAttribute(NULL, "library") reports the default SSL library */
1775  if (strcmp(attribute_name, "library") == 0)
1776  return "OpenSSL";
1777  return NULL;
1778  }
1779 
1780  /* All attributes read as NULL for a non-encrypted connection */
1781  if (conn->ssl == NULL)
1782  return NULL;
1783 
1784  if (strcmp(attribute_name, "library") == 0)
1785  return "OpenSSL";
1786 
1787  if (strcmp(attribute_name, "key_bits") == 0)
1788  {
1789  static char sslbits_str[12];
1790  int sslbits;
1791 
1792  SSL_get_cipher_bits(conn->ssl, &sslbits);
1793  snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
1794  return sslbits_str;
1795  }
1796 
1797  if (strcmp(attribute_name, "cipher") == 0)
1798  return SSL_get_cipher(conn->ssl);
1799 
1800  if (strcmp(attribute_name, "compression") == 0)
1801  return SSL_get_current_compression(conn->ssl) ? "on" : "off";
1802 
1803  if (strcmp(attribute_name, "protocol") == 0)
1804  return SSL_get_version(conn->ssl);
1805 
1806  return NULL; /* unknown attribute */
1807 }

References conn, and snprintf.

Referenced by print_ssl_library(), and printSSLInfo().

◆ PQsslAttributeNames()

const char* const* PQsslAttributeNames ( PGconn conn)

Definition at line 1744 of file fe-secure-openssl.c.

1745 {
1746  static const char *const openssl_attrs[] = {
1747  "library",
1748  "key_bits",
1749  "cipher",
1750  "compression",
1751  "protocol",
1752  NULL
1753  };
1754  static const char *const empty_attrs[] = {NULL};
1755 
1756  if (!conn)
1757  {
1758  /* Return attributes of default SSL library */
1759  return openssl_attrs;
1760  }
1761 
1762  /* No attrs for unencrypted connection */
1763  if (conn->ssl == NULL)
1764  return empty_attrs;
1765 
1766  return openssl_attrs;
1767 }

References conn.

◆ PQsslStruct()

void* PQsslStruct ( PGconn conn,
const char *  struct_name 
)

Definition at line 1734 of file fe-secure-openssl.c.

1735 {
1736  if (!conn)
1737  return NULL;
1738  if (strcmp(struct_name, "OpenSSL") == 0)
1739  return conn->ssl;
1740  return NULL;
1741 }

References conn.

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( const char *  protocol)
static

Definition at line 2022 of file fe-secure-openssl.c.

2023 {
2024  if (pg_strcasecmp("TLSv1", protocol) == 0)
2025  return TLS1_VERSION;
2026 
2027 #ifdef TLS1_1_VERSION
2028  if (pg_strcasecmp("TLSv1.1", protocol) == 0)
2029  return TLS1_1_VERSION;
2030 #endif
2031 
2032 #ifdef TLS1_2_VERSION
2033  if (pg_strcasecmp("TLSv1.2", protocol) == 0)
2034  return TLS1_2_VERSION;
2035 #endif
2036 
2037 #ifdef TLS1_3_VERSION
2038  if (pg_strcasecmp("TLSv1.3", protocol) == 0)
2039  return TLS1_3_VERSION;
2040 #endif
2041 
2042  return -1;
2043 }
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36

References pg_strcasecmp().

Referenced by initialize_SSL().

◆ SSLerrfree()

static void SSLerrfree ( char *  buf)
static

Definition at line 1712 of file fe-secure-openssl.c.

1713 {
1714  if (buf != ssl_nomem)
1715  free(buf);
1716 }
static char ssl_nomem[]

References buf, free, and ssl_nomem.

Referenced by initialize_SSL(), open_client_SSL(), pgtls_read(), and pgtls_write().

◆ SSLerrmessage()

static char * SSLerrmessage ( unsigned long  ecode)
static

Definition at line 1688 of file fe-secure-openssl.c.

1689 {
1690  const char *errreason;
1691  char *errbuf;
1692 
1693  errbuf = malloc(SSL_ERR_LEN);
1694  if (!errbuf)
1695  return ssl_nomem;
1696  if (ecode == 0)
1697  {
1698  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1699  return errbuf;
1700  }
1701  errreason = ERR_reason_error_string(ecode);
1702  if (errreason != NULL)
1703  {
1704  strlcpy(errbuf, errreason, SSL_ERR_LEN);
1705  return errbuf;
1706  }
1707  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
1708  return errbuf;
1709 }
#define SSL_ERR_LEN

References libpq_gettext, malloc, snprintf, SSL_ERR_LEN, ssl_nomem, and strlcpy().

Referenced by initialize_SSL(), open_client_SSL(), pgtls_read(), and pgtls_write().

◆ verify_cb()

static int verify_cb ( int  ok,
X509_STORE_CTX *  ctx 
)
static

Definition at line 451 of file fe-secure-openssl.c.

452 {
453  return ok;
454 }

Referenced by initialize_SSL().

Variable Documentation

◆ crypto_open_connections

long crypto_open_connections = 0
static

Definition at line 92 of file fe-secure-openssl.c.

Referenced by destroy_ssl_system(), pgtls_init(), and pgtls_init_library().

◆ my_bio_methods

BIO_METHOD* my_bio_methods
static

Definition at line 1823 of file fe-secure-openssl.c.

Referenced by my_BIO_s_socket().

◆ pq_init_crypto_lib

bool pq_init_crypto_lib = true
static

Definition at line 88 of file fe-secure-openssl.c.

Referenced by destroy_ssl_system(), pgtls_init(), and pgtls_init_library().

◆ pq_init_ssl_lib

bool pq_init_ssl_lib = true
static

Definition at line 87 of file fe-secure-openssl.c.

Referenced by pgtls_init(), and pgtls_init_library().

◆ PQsslKeyPassHook

◆ ssl_config_mutex

pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 95 of file fe-secure-openssl.c.

Referenced by destroy_ssl_system(), and pgtls_init().

◆ ssl_lib_initialized

bool ssl_lib_initialized = false
static

Definition at line 90 of file fe-secure-openssl.c.

Referenced by pgtls_init().

◆ ssl_nomem

char ssl_nomem[] = "out of memory allocating error description"
static

Definition at line 1683 of file fe-secure-openssl.c.

Referenced by SSLerrfree(), and SSLerrmessage().