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
 

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

◆ SSL_ERR_LEN

#define SSL_ERR_LEN   128

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

Function Documentation

◆ destroy_ssl_system()

static void destroy_ssl_system ( void  )
static

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

856 {
857 #if defined(HAVE_CRYPTO_LOCK)
859  return;
860 
863 
865  {
866  /*
867  * No connections left, unregister libcrypto callbacks, if no one
868  * registered different ones in the meantime.
869  */
870  if (CRYPTO_get_locking_callback() == pq_lockingcallback)
871  CRYPTO_set_locking_callback(NULL);
872  if (CRYPTO_get_id_callback() == pq_threadidcallback)
873  CRYPTO_set_id_callback(NULL);
874 
875  /*
876  * We don't free the lock array. If we get another connection in this
877  * process, we will just re-use them with the existing mutexes.
878  *
879  * This means we leak a little memory on repeated load/unload of the
880  * library.
881  */
882  }
883 
885 #endif
886 }
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:60
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:42

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 895 of file fe-secure-openssl.c.

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

555 {
556  struct in_addr dummy4;
557 #ifdef HAVE_INET_PTON
558  struct in6_addr dummy6;
559 #endif
560 
561  return inet_aton(host, &dummy4)
562 #ifdef HAVE_INET_PTON
563  || (inet_pton(AF_INET6, host, &dummy6) == 1)
564 #endif
565  ;
566 }
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 1869 of file fe-secure-openssl.c.

1870 {
1871  BIO_METHOD *res;
1872 
1874  return NULL;
1875 
1876  res = my_bio_methods;
1877 
1878  if (!my_bio_methods)
1879  {
1880  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
1881 #ifdef HAVE_BIO_METH_NEW
1882  int my_bio_index;
1883 
1884  my_bio_index = BIO_get_new_index();
1885  if (my_bio_index == -1)
1886  goto err;
1887  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
1888  res = BIO_meth_new(my_bio_index, "libpq socket");
1889  if (!res)
1890  goto err;
1891 
1892  /*
1893  * As of this writing, these functions never fail. But check anyway,
1894  * like OpenSSL's own examples do.
1895  */
1896  if (!BIO_meth_set_write(res, my_sock_write) ||
1897  !BIO_meth_set_read(res, my_sock_read) ||
1898  !BIO_meth_set_gets(res, BIO_meth_get_gets(biom)) ||
1899  !BIO_meth_set_puts(res, BIO_meth_get_puts(biom)) ||
1900  !BIO_meth_set_ctrl(res, BIO_meth_get_ctrl(biom)) ||
1901  !BIO_meth_set_create(res, BIO_meth_get_create(biom)) ||
1902  !BIO_meth_set_destroy(res, BIO_meth_get_destroy(biom)) ||
1903  !BIO_meth_set_callback_ctrl(res, BIO_meth_get_callback_ctrl(biom)))
1904  {
1905  goto err;
1906  }
1907 #else
1908  res = malloc(sizeof(BIO_METHOD));
1909  if (!res)
1910  goto err;
1911  memcpy(res, biom, sizeof(BIO_METHOD));
1912  res->bread = my_sock_read;
1913  res->bwrite = my_sock_write;
1914 #endif
1915  }
1916 
1917  my_bio_methods = res;
1919  return res;
1920 
1921 err:
1922 #ifdef HAVE_BIO_METH_NEW
1923  if (res)
1924  BIO_meth_free(res);
1925 #else
1926  if (res)
1927  free(res);
1928 #endif
1930  return NULL;
1931 }
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 err(), free, malloc, my_bio_methods, my_sock_read(), my_sock_write(), pthread_mutex_lock(), pthread_mutex_unlock(), res, and ssl_config_mutex.

Referenced by my_SSL_set_fd().

◆ my_sock_read()

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

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

1810 {
1811  int res;
1812 
1813  res = pqsecure_raw_read((PGconn *) BIO_get_app_data(h), buf, size);
1814  BIO_clear_retry_flags(h);
1815  if (res < 0)
1816  {
1817  /* If we were interrupted, tell caller to retry */
1818  switch (SOCK_ERRNO)
1819  {
1820 #ifdef EAGAIN
1821  case EAGAIN:
1822 #endif
1823 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1824  case EWOULDBLOCK:
1825 #endif
1826  case EINTR:
1827  BIO_set_retry_read(h);
1828  break;
1829 
1830  default:
1831  break;
1832  }
1833  }
1834 
1835  return res;
1836 }
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:208
#define SOCK_ERRNO
Definition: libpq-int.h:933
#define EINTR
Definition: win32_port.h:374
#define EWOULDBLOCK
Definition: win32_port.h:380
#define EAGAIN
Definition: win32_port.h:372

References 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 1839 of file fe-secure-openssl.c.

1840 {
1841  int res;
1842 
1843  res = pqsecure_raw_write((PGconn *) BIO_get_app_data(h), buf, size);
1844  BIO_clear_retry_flags(h);
1845  if (res < 0)
1846  {
1847  /* If we were interrupted, tell caller to retry */
1848  switch (SOCK_ERRNO)
1849  {
1850 #ifdef EAGAIN
1851  case EAGAIN:
1852 #endif
1853 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1854  case EWOULDBLOCK:
1855 #endif
1856  case EINTR:
1857  BIO_set_retry_write(h);
1858  break;
1859 
1860  default:
1861  break;
1862  }
1863  }
1864 
1865  return res;
1866 }
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:331

References 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 1935 of file fe-secure-openssl.c.

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

References 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 1461 of file fe-secure-openssl.c.

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

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 525 of file fe-secure-openssl.c.

528 {
529  int len;
530  const unsigned char *addrdata;
531 
532  /* Should not happen... */
533  if (addr_entry == NULL)
534  {
535  libpq_append_conn_error(conn, "SSL certificate's address entry is missing");
536  return -1;
537  }
538 
539  /*
540  * GEN_IPADD is an OCTET STRING containing an IP address in network byte
541  * order.
542  */
543 #ifdef HAVE_ASN1_STRING_GET0_DATA
544  addrdata = ASN1_STRING_get0_data(addr_entry);
545 #else
546  addrdata = ASN1_STRING_data(addr_entry);
547 #endif
548  len = ASN1_STRING_length(addr_entry);
549 
550  return pq_verify_peer_name_matches_certificate_ip(conn, addrdata, len, store_name);
551 }
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 492 of file fe-secure-openssl.c.

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

1598 {
1599  bool destroy_needed = false;
1600 
1601  if (conn->ssl_in_use)
1602  {
1603  if (conn->ssl)
1604  {
1605  /*
1606  * We can't destroy everything SSL-related here due to the
1607  * possible later calls to OpenSSL routines which may need our
1608  * thread callbacks, so set a flag here and check at the end.
1609  */
1610 
1611  SSL_shutdown(conn->ssl);
1612  SSL_free(conn->ssl);
1613  conn->ssl = NULL;
1614  conn->ssl_in_use = false;
1615 
1616  destroy_needed = true;
1617  }
1618 
1619  if (conn->peer)
1620  {
1621  X509_free(conn->peer);
1622  conn->peer = NULL;
1623  }
1624 
1625 #ifdef USE_SSL_ENGINE
1626  if (conn->engine)
1627  {
1628  ENGINE_finish(conn->engine);
1629  ENGINE_free(conn->engine);
1630  conn->engine = NULL;
1631  }
1632 #endif
1633  }
1634  else
1635  {
1636  /*
1637  * In the non-SSL case, just remove the crypto callbacks if the
1638  * connection has then loaded. This code path has no dependency on
1639  * any pending SSL calls.
1640  */
1641  if (conn->crypto_loaded)
1642  destroy_needed = true;
1643  }
1644 
1645  /*
1646  * This will remove our crypto locking hooks if this is the last
1647  * connection using libcrypto which means we must wait to call it until
1648  * after all the potential SSL calls have been made, otherwise we can end
1649  * up with a race condition and possible deadlocks.
1650  *
1651  * See comments above destroy_ssl_system().
1652  */
1653  if (destroy_needed)
1654  {
1656  conn->crypto_loaded = false;
1657  }
1658 }
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 362 of file fe-secure-openssl.c.

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

770 {
772  return -1;
773 
774 #ifdef HAVE_CRYPTO_LOCK
775  if (pq_init_crypto_lib)
776  {
777  /*
778  * If necessary, set up an array to hold locks for libcrypto.
779  * libcrypto will tell us how big to make this array.
780  */
781  if (pq_lockarray == NULL)
782  {
783  int i;
784 
785  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
786  if (!pq_lockarray)
787  {
789  return -1;
790  }
791  for (i = 0; i < CRYPTO_num_locks(); i++)
792  {
793  if (pthread_mutex_init(&pq_lockarray[i], NULL))
794  {
795  free(pq_lockarray);
796  pq_lockarray = NULL;
798  return -1;
799  }
800  }
801  }
802 
803  if (do_crypto && !conn->crypto_loaded)
804  {
805  if (crypto_open_connections++ == 0)
806  {
807  /*
808  * These are only required for threaded libcrypto
809  * applications, but make sure we don't stomp on them if
810  * they're already set.
811  */
812  if (CRYPTO_get_id_callback() == NULL)
813  CRYPTO_set_id_callback(pq_threadidcallback);
814  if (CRYPTO_get_locking_callback() == NULL)
815  CRYPTO_set_locking_callback(pq_lockingcallback);
816  }
817 
818  conn->crypto_loaded = true;
819  }
820  }
821 #endif /* HAVE_CRYPTO_LOCK */
822 
823  if (!ssl_lib_initialized && do_ssl)
824  {
825  if (pq_init_ssl_lib)
826  {
827 #ifdef HAVE_OPENSSL_INIT_SSL
828  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
829 #else
830  OPENSSL_config(NULL);
831  SSL_library_init();
832  SSL_load_error_strings();
833 #endif
834  }
835  ssl_lib_initialized = true;
836  }
837 
839  return 0;
840 }
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

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 104 of file fe-secure-openssl.c.

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

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 118 of file fe-secure-openssl.c.

119 {
120  /* First time through? */
121  if (conn->ssl == NULL)
122  {
123  /*
124  * Create a connection-specific SSL object, and load client
125  * certificate, private key, and trusted CA certs.
126  */
127  if (initialize_SSL(conn) != 0)
128  {
129  /* initialize_SSL already put a message in conn->errorMessage */
130  pgtls_close(conn);
131  return PGRES_POLLING_FAILED;
132  }
133  }
134 
135  /* Begin or continue the actual handshake */
136  return open_client_SSL(conn);
137 }
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 140 of file fe-secure-openssl.c.

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

257 {
258  return SSL_pending(conn->ssl) > 0;
259 }

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 574 of file fe-secure-openssl.c.

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

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

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 1968 of file fe-secure-openssl.c.

1969 {
1970  if (conn && conn->sslpassword)
1971  {
1972  if (strlen(conn->sslpassword) + 1 > size)
1973  fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
1974  strncpy(buf, conn->sslpassword, size);
1975  buf[size - 1] = '\0';
1976  return strlen(buf);
1977  }
1978  else
1979  {
1980  buf[0] = '\0';
1981  return 0;
1982  }
1983 }
#define libpq_gettext(x)
Definition: libpq-int.h:912
#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 1713 of file fe-secure-openssl.c.

1714 {
1715  if (!conn)
1716  return NULL;
1717  return conn->ssl;
1718 }

References conn.

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

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

1987 {
1988  return PQsslKeyPassHook;
1989 }

References PQsslKeyPassHook.

◆ PQsetSSLKeyPassHook_OpenSSL()

void PQsetSSLKeyPassHook_OpenSSL ( PQsslKeyPassHook_OpenSSL_type  hook)

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

1993 {
1994  PQsslKeyPassHook = hook;
1995 }

References PQsslKeyPassHook.

◆ PQssl_passwd_cb()

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

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

2004 {
2005  PGconn *conn = userdata;
2006 
2007  if (PQsslKeyPassHook)
2008  return PQsslKeyPassHook(buf, size, conn);
2009  else
2010  return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
2011 }
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 1757 of file fe-secure-openssl.c.

1758 {
1759  if (!conn)
1760  {
1761  /* PQsslAttribute(NULL, "library") reports the default SSL library */
1762  if (strcmp(attribute_name, "library") == 0)
1763  return "OpenSSL";
1764  return NULL;
1765  }
1766 
1767  /* All attributes read as NULL for a non-encrypted connection */
1768  if (conn->ssl == NULL)
1769  return NULL;
1770 
1771  if (strcmp(attribute_name, "library") == 0)
1772  return "OpenSSL";
1773 
1774  if (strcmp(attribute_name, "key_bits") == 0)
1775  {
1776  static char sslbits_str[12];
1777  int sslbits;
1778 
1779  SSL_get_cipher_bits(conn->ssl, &sslbits);
1780  snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
1781  return sslbits_str;
1782  }
1783 
1784  if (strcmp(attribute_name, "cipher") == 0)
1785  return SSL_get_cipher(conn->ssl);
1786 
1787  if (strcmp(attribute_name, "compression") == 0)
1788  return SSL_get_current_compression(conn->ssl) ? "on" : "off";
1789 
1790  if (strcmp(attribute_name, "protocol") == 0)
1791  return SSL_get_version(conn->ssl);
1792 
1793  return NULL; /* unknown attribute */
1794 }

References conn, and snprintf.

Referenced by print_ssl_library(), and printSSLInfo().

◆ PQsslAttributeNames()

const char* const* PQsslAttributeNames ( PGconn conn)

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

1732 {
1733  static const char *const openssl_attrs[] = {
1734  "library",
1735  "key_bits",
1736  "cipher",
1737  "compression",
1738  "protocol",
1739  NULL
1740  };
1741  static const char *const empty_attrs[] = {NULL};
1742 
1743  if (!conn)
1744  {
1745  /* Return attributes of default SSL library */
1746  return openssl_attrs;
1747  }
1748 
1749  /* No attrs for unencrypted connection */
1750  if (conn->ssl == NULL)
1751  return empty_attrs;
1752 
1753  return openssl_attrs;
1754 }

References conn.

◆ PQsslStruct()

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

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

1722 {
1723  if (!conn)
1724  return NULL;
1725  if (strcmp(struct_name, "OpenSSL") == 0)
1726  return conn->ssl;
1727  return NULL;
1728 }

References conn.

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( const char *  protocol)
static

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

2025 {
2026  if (pg_strcasecmp("TLSv1", protocol) == 0)
2027  return TLS1_VERSION;
2028 
2029 #ifdef TLS1_1_VERSION
2030  if (pg_strcasecmp("TLSv1.1", protocol) == 0)
2031  return TLS1_1_VERSION;
2032 #endif
2033 
2034 #ifdef TLS1_2_VERSION
2035  if (pg_strcasecmp("TLSv1.2", protocol) == 0)
2036  return TLS1_2_VERSION;
2037 #endif
2038 
2039 #ifdef TLS1_3_VERSION
2040  if (pg_strcasecmp("TLSv1.3", protocol) == 0)
2041  return TLS1_3_VERSION;
2042 #endif
2043 
2044  return -1;
2045 }
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 1699 of file fe-secure-openssl.c.

1700 {
1701  if (buf != ssl_nomem)
1702  free(buf);
1703 }
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 1675 of file fe-secure-openssl.c.

1676 {
1677  const char *errreason;
1678  char *errbuf;
1679 
1680  errbuf = malloc(SSL_ERR_LEN);
1681  if (!errbuf)
1682  return ssl_nomem;
1683  if (ecode == 0)
1684  {
1685  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1686  return errbuf;
1687  }
1688  errreason = ERR_reason_error_string(ecode);
1689  if (errreason != NULL)
1690  {
1691  strlcpy(errbuf, errreason, SSL_ERR_LEN);
1692  return errbuf;
1693  }
1694  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
1695  return errbuf;
1696 }
#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 452 of file fe-secure-openssl.c.

453 {
454  return ok;
455 }

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 1806 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 94 of file fe-secure-openssl.c.

Referenced by destroy_ssl_system(), my_BIO_s_socket(), 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 1670 of file fe-secure-openssl.c.

Referenced by SSLerrfree(), and SSLerrmessage().