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 unsigned char alpn_protos [] = PG_ALPN_PROTOCOL_VECTOR
 
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 1693 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 898 of file fe-secure-openssl.c.

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

1927 {
1928  BIO_METHOD *res;
1929 
1931  return NULL;
1932 
1933  res = my_bio_methods;
1934 
1935  if (!my_bio_methods)
1936  {
1937  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
1938 #ifdef HAVE_BIO_METH_NEW
1939  int my_bio_index;
1940 
1941  my_bio_index = BIO_get_new_index();
1942  if (my_bio_index == -1)
1943  goto err;
1944  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
1945  res = BIO_meth_new(my_bio_index, "libpq socket");
1946  if (!res)
1947  goto err;
1948 
1949  /*
1950  * As of this writing, these functions never fail. But check anyway,
1951  * like OpenSSL's own examples do.
1952  */
1953  if (!BIO_meth_set_write(res, my_sock_write) ||
1954  !BIO_meth_set_read(res, my_sock_read) ||
1955  !BIO_meth_set_gets(res, BIO_meth_get_gets(biom)) ||
1956  !BIO_meth_set_puts(res, BIO_meth_get_puts(biom)) ||
1957  !BIO_meth_set_ctrl(res, BIO_meth_get_ctrl(biom)) ||
1958  !BIO_meth_set_create(res, BIO_meth_get_create(biom)) ||
1959  !BIO_meth_set_destroy(res, BIO_meth_get_destroy(biom)) ||
1960  !BIO_meth_set_callback_ctrl(res, BIO_meth_get_callback_ctrl(biom)))
1961  {
1962  goto err;
1963  }
1964 #else
1965  res = malloc(sizeof(BIO_METHOD));
1966  if (!res)
1967  goto err;
1968  memcpy(res, biom, sizeof(BIO_METHOD));
1969  res->bread = my_sock_read;
1970  res->bwrite = my_sock_write;
1971 #endif
1972  }
1973 
1974  my_bio_methods = res;
1976  return res;
1977 
1978 err:
1979 #ifdef HAVE_BIO_METH_NEW
1980  if (res)
1981  BIO_meth_free(res);
1982 #else
1983  if (res)
1984  free(res);
1985 #endif
1987  return NULL;
1988 }
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 1862 of file fe-secure-openssl.c.

1863 {
1864  PGconn *conn = (PGconn *) BIO_get_app_data(h);
1865  int res;
1866 
1868  BIO_clear_retry_flags(h);
1869  if (res < 0)
1870  {
1871  /* If we were interrupted, tell caller to retry */
1872  switch (SOCK_ERRNO)
1873  {
1874 #ifdef EAGAIN
1875  case EAGAIN:
1876 #endif
1877 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1878  case EWOULDBLOCK:
1879 #endif
1880  case EINTR:
1881  BIO_set_retry_read(h);
1882  break;
1883 
1884  default:
1885  break;
1886  }
1887  }
1888 
1889  if (res > 0)
1890  conn->ssl_handshake_started = true;
1891 
1892  return res;
1893 }
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:208
#define SOCK_ERRNO
Definition: libpq-int.h:934
static pg_noinline void Size size
Definition: slab.c:607
bool ssl_handshake_started
Definition: libpq-int.h:569
#define EINTR
Definition: win32_port.h:374
#define EWOULDBLOCK
Definition: win32_port.h:380
#define EAGAIN
Definition: win32_port.h:372

References buf, conn, EAGAIN, EINTR, EWOULDBLOCK, pqsecure_raw_read(), res, size, SOCK_ERRNO, and pg_conn::ssl_handshake_started.

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

1897 {
1898  int res;
1899 
1900  res = pqsecure_raw_write((PGconn *) BIO_get_app_data(h), buf, size);
1901  BIO_clear_retry_flags(h);
1902  if (res < 0)
1903  {
1904  /* If we were interrupted, tell caller to retry */
1905  switch (SOCK_ERRNO)
1906  {
1907 #ifdef EAGAIN
1908  case EAGAIN:
1909 #endif
1910 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1911  case EWOULDBLOCK:
1912 #endif
1913  case EINTR:
1914  BIO_set_retry_write(h);
1915  break;
1916 
1917  default:
1918  break;
1919  }
1920  }
1921 
1922  return res;
1923 }
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, size, 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 1992 of file fe-secure-openssl.c.

1993 {
1994  int ret = 0;
1995  BIO *bio;
1996  BIO_METHOD *bio_method;
1997 
1998  bio_method = my_BIO_s_socket();
1999  if (bio_method == NULL)
2000  {
2001  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
2002  goto err;
2003  }
2004  bio = BIO_new(bio_method);
2005  if (bio == NULL)
2006  {
2007  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
2008  goto err;
2009  }
2010  BIO_set_app_data(bio, conn);
2011 
2012  SSL_set_bio(conn->ssl, bio, bio);
2013  BIO_set_fd(bio, fd, BIO_NOCLOSE);
2014  ret = 1;
2015 err:
2016  return ret;
2017 }
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 1480 of file fe-secure-openssl.c.

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

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

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

References conn, destroy_ssl_system(), pg_conn::ssl_handshake_started, 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:635
#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 }
#define Assert(condition)
Definition: c.h:858
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)
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 2025 of file fe-secure-openssl.c.

2026 {
2027  if (conn && conn->sslpassword)
2028  {
2029  if (strlen(conn->sslpassword) + 1 > size)
2030  fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
2031  strncpy(buf, conn->sslpassword, size);
2032  buf[size - 1] = '\0';
2033  return strlen(buf);
2034  }
2035  else
2036  {
2037  buf[0] = '\0';
2038  return 0;
2039  }
2040 }
#define libpq_gettext(x)
Definition: libpq-int.h:913
#define fprintf
Definition: port.h:242

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

Referenced by PQssl_passwd_cb().

◆ PQgetssl()

void* PQgetssl ( PGconn conn)

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

1751 {
1752  if (!conn)
1753  return NULL;
1754  return conn->ssl;
1755 }

References conn.

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

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

2044 {
2045  return PQsslKeyPassHook;
2046 }

References PQsslKeyPassHook.

◆ PQsetSSLKeyPassHook_OpenSSL()

void PQsetSSLKeyPassHook_OpenSSL ( PQsslKeyPassHook_OpenSSL_type  hook)

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

2050 {
2051  PQsslKeyPassHook = hook;
2052 }

References PQsslKeyPassHook.

◆ PQssl_passwd_cb()

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

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

2061 {
2062  PGconn *conn = userdata;
2063 
2064  if (PQsslKeyPassHook)
2065  return PQsslKeyPassHook(buf, size, conn);
2066  else
2068 }
int PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)

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

Referenced by initialize_SSL().

◆ PQsslAttribute()

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

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

1796 {
1797  if (!conn)
1798  {
1799  /* PQsslAttribute(NULL, "library") reports the default SSL library */
1800  if (strcmp(attribute_name, "library") == 0)
1801  return "OpenSSL";
1802  return NULL;
1803  }
1804 
1805  /* All attributes read as NULL for a non-encrypted connection */
1806  if (conn->ssl == NULL)
1807  return NULL;
1808 
1809  if (strcmp(attribute_name, "library") == 0)
1810  return "OpenSSL";
1811 
1812  if (strcmp(attribute_name, "key_bits") == 0)
1813  {
1814  static char sslbits_str[12];
1815  int sslbits;
1816 
1817  SSL_get_cipher_bits(conn->ssl, &sslbits);
1818  snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
1819  return sslbits_str;
1820  }
1821 
1822  if (strcmp(attribute_name, "cipher") == 0)
1823  return SSL_get_cipher(conn->ssl);
1824 
1825  if (strcmp(attribute_name, "compression") == 0)
1826  return SSL_get_current_compression(conn->ssl) ? "on" : "off";
1827 
1828  if (strcmp(attribute_name, "protocol") == 0)
1829  return SSL_get_version(conn->ssl);
1830 
1831  if (strcmp(attribute_name, "alpn") == 0)
1832  {
1833  const unsigned char *data;
1834  unsigned int len;
1835  static char alpn_str[256]; /* alpn doesn't support longer than 255
1836  * bytes */
1837 
1838  SSL_get0_alpn_selected(conn->ssl, &data, &len);
1839  if (data == NULL || len == 0 || len > sizeof(alpn_str) - 1)
1840  return NULL;
1841  memcpy(alpn_str, data, len);
1842  alpn_str[len] = 0;
1843  return alpn_str;
1844  }
1845 
1846  return NULL; /* unknown attribute */
1847 }
const void * data

References conn, data, len, and snprintf.

Referenced by print_ssl_library(), and printSSLInfo().

◆ PQsslAttributeNames()

const char* const* PQsslAttributeNames ( PGconn conn)

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

1769 {
1770  static const char *const openssl_attrs[] = {
1771  "library",
1772  "key_bits",
1773  "cipher",
1774  "compression",
1775  "protocol",
1776  "alpn",
1777  NULL
1778  };
1779  static const char *const empty_attrs[] = {NULL};
1780 
1781  if (!conn)
1782  {
1783  /* Return attributes of default SSL library */
1784  return openssl_attrs;
1785  }
1786 
1787  /* No attrs for unencrypted connection */
1788  if (conn->ssl == NULL)
1789  return empty_attrs;
1790 
1791  return openssl_attrs;
1792 }

References conn.

◆ PQsslStruct()

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

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

1759 {
1760  if (!conn)
1761  return NULL;
1762  if (strcmp(struct_name, "OpenSSL") == 0)
1763  return conn->ssl;
1764  return NULL;
1765 }

References conn.

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( const char *  protocol)
static

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

2082 {
2083  if (pg_strcasecmp("TLSv1", protocol) == 0)
2084  return TLS1_VERSION;
2085 
2086 #ifdef TLS1_1_VERSION
2087  if (pg_strcasecmp("TLSv1.1", protocol) == 0)
2088  return TLS1_1_VERSION;
2089 #endif
2090 
2091 #ifdef TLS1_2_VERSION
2092  if (pg_strcasecmp("TLSv1.2", protocol) == 0)
2093  return TLS1_2_VERSION;
2094 #endif
2095 
2096 #ifdef TLS1_3_VERSION
2097  if (pg_strcasecmp("TLSv1.3", protocol) == 0)
2098  return TLS1_3_VERSION;
2099 #endif
2100 
2101  return -1;
2102 }
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 1736 of file fe-secure-openssl.c.

1737 {
1738  if (buf != ssl_nomem)
1739  free(buf);
1740 }
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 1696 of file fe-secure-openssl.c.

1697 {
1698  const char *errreason;
1699  char *errbuf;
1700 
1701  errbuf = malloc(SSL_ERR_LEN);
1702  if (!errbuf)
1703  return ssl_nomem;
1704  if (ecode == 0)
1705  {
1706  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1707  return errbuf;
1708  }
1709  errreason = ERR_reason_error_string(ecode);
1710  if (errreason != NULL)
1711  {
1712  strlcpy(errbuf, errreason, SSL_ERR_LEN);
1713  return errbuf;
1714  }
1715 
1716  /*
1717  * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to
1718  * map system errno values. We can cover that shortcoming with this bit
1719  * of code. Older OpenSSL versions don't have the ERR_SYSTEM_ERROR macro,
1720  * but that's okay because they don't have the shortcoming either.
1721  */
1722 #ifdef ERR_SYSTEM_ERROR
1723  if (ERR_SYSTEM_ERROR(ecode))
1724  {
1725  strlcpy(errbuf, strerror(ERR_GET_REASON(ecode)), SSL_ERR_LEN);
1726  return errbuf;
1727  }
1728 #endif
1729 
1730  /* No choice but to report the numeric ecode */
1731  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
1732  return errbuf;
1733 }
#define SSL_ERR_LEN
#define strerror
Definition: port.h:251

References libpq_gettext, malloc, snprintf, SSL_ERR_LEN, ssl_nomem, strerror, 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

◆ alpn_protos

unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR
static

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

Referenced by initialize_SSL().

◆ 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 1859 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 1691 of file fe-secure-openssl.c.

Referenced by SSLerrfree(), and SSLerrmessage().