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 <arpa/inet.h>
#include <sys/stat.h>
#include "common/openssl.h"
#include <openssl/conf.h>
#include <openssl/x509v3.h>
Include dependency graph for fe-secure-openssl.c:

Go to the source code of this file.

Macros

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

Functions

static int verify_cb (int ok, X509_STORE_CTX *ctx)
 
static int openssl_verify_peer_name_matches_certificate_name (PGconn *conn, ASN1_STRING *name, char **store_name)
 
static void destroy_ssl_system (void)
 
static int initialize_SSL (PGconn *conn)
 
static PostgresPollingStatusType open_client_SSL (PGconn *)
 
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)
 
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 PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL
 
static char ssl_nomem [] = "out of memory allocating error description"
 
static BIO_METHOD * my_bio_methods
 

Macro Definition Documentation

◆ BIO_get_data

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

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

◆ BIO_set_data

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

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

◆ SSL_ERR_LEN

#define SSL_ERR_LEN   128

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

Function Documentation

◆ destroy_ssl_system()

static void destroy_ssl_system ( void  )
static

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

754 {
755 #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
756  /* Mutex is created in pgtls_init() */
757  if (pthread_mutex_lock(&ssl_config_mutex))
758  return;
759 
760  if (pq_init_crypto_lib && crypto_open_connections > 0)
761  --crypto_open_connections;
762 
763  if (pq_init_crypto_lib && crypto_open_connections == 0)
764  {
765  /*
766  * No connections left, unregister libcrypto callbacks, if no one
767  * registered different ones in the meantime.
768  */
769  if (CRYPTO_get_locking_callback() == pq_lockingcallback)
770  CRYPTO_set_locking_callback(NULL);
771  if (CRYPTO_get_id_callback() == pq_threadidcallback)
772  CRYPTO_set_id_callback(NULL);
773 
774  /*
775  * We don't free the lock array. If we get another connection in this
776  * process, we will just re-use them with the existing mutexes.
777  *
778  * This means we leak a little memory on repeated load/unload of the
779  * library.
780  */
781  }
782 
783  pthread_mutex_unlock(&ssl_config_mutex);
784 #endif
785 }
static bool pq_init_crypto_lib
int pthread_mutex_unlock(pthread_mutex_t *mp)
Definition: pthread-win32.c:54
int pthread_mutex_lock(pthread_mutex_t *mp)
Definition: pthread-win32.c:45

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

Referenced by pgtls_close().

◆ initialize_SSL()

static int initialize_SSL ( PGconn conn)
static

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

795 {
796  SSL_CTX *SSL_context;
797  struct stat buf;
798  char homedir[MAXPGPATH];
799  char fnbuf[MAXPGPATH];
800  char sebuf[PG_STRERROR_R_BUFLEN];
801  bool have_homedir;
802  bool have_cert;
803  bool have_rootcert;
804  EVP_PKEY *pkey = NULL;
805 
806  /*
807  * We'll need the home directory if any of the relevant parameters are
808  * defaulted. If pqGetHomeDirectory fails, act as though none of the
809  * files could be found.
810  */
811  if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
812  !(conn->sslkey && strlen(conn->sslkey) > 0) ||
813  !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
814  !((conn->sslcrl && strlen(conn->sslcrl) > 0) ||
815  (conn->sslcrldir && strlen(conn->sslcrldir) > 0)))
816  have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
817  else /* won't need it */
818  have_homedir = false;
819 
820  /*
821  * Create a new SSL_CTX object.
822  *
823  * We used to share a single SSL_CTX between all connections, but it was
824  * complicated if connections used different certificates. So now we
825  * create a separate context for each connection, and accept the overhead.
826  */
827  SSL_context = SSL_CTX_new(SSLv23_method());
828  if (!SSL_context)
829  {
830  char *err = SSLerrmessage(ERR_get_error());
831 
833  libpq_gettext("could not create SSL context: %s\n"),
834  err);
835  SSLerrfree(err);
836  return -1;
837  }
838 
839  /*
840  * Delegate the client cert password prompt to the libpq wrapper callback
841  * if any is defined.
842  *
843  * If the application hasn't installed its own and the sslpassword
844  * parameter is non-null, we install ours now to make sure we supply
845  * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin.
846  *
847  * This will replace OpenSSL's default PEM_def_callback (which prompts on
848  * stdin), but we're only setting it for this SSL context so it's
849  * harmless.
850  */
851  if (PQsslKeyPassHook
852  || (conn->sslpassword && strlen(conn->sslpassword) > 0))
853  {
854  SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb);
855  SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn);
856  }
857 
858  /* Disable old protocol versions */
859  SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
860 
861  /* Set the minimum and maximum protocol versions if necessary */
863  strlen(conn->ssl_min_protocol_version) != 0)
864  {
865  int ssl_min_ver;
866 
868 
869  if (ssl_min_ver == -1)
870  {
872  libpq_gettext("invalid value \"%s\" for minimum SSL protocol version\n"),
874  SSL_CTX_free(SSL_context);
875  return -1;
876  }
877 
878  if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver))
879  {
880  char *err = SSLerrmessage(ERR_get_error());
881 
883  libpq_gettext("could not set minimum SSL protocol version: %s\n"),
884  err);
885  SSLerrfree(err);
886  SSL_CTX_free(SSL_context);
887  return -1;
888  }
889  }
890 
892  strlen(conn->ssl_max_protocol_version) != 0)
893  {
894  int ssl_max_ver;
895 
897 
898  if (ssl_max_ver == -1)
899  {
901  libpq_gettext("invalid value \"%s\" for maximum SSL protocol version\n"),
903  SSL_CTX_free(SSL_context);
904  return -1;
905  }
906 
907  if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver))
908  {
909  char *err = SSLerrmessage(ERR_get_error());
910 
912  libpq_gettext("could not set maximum SSL protocol version: %s\n"),
913  err);
914  SSLerrfree(err);
915  SSL_CTX_free(SSL_context);
916  return -1;
917  }
918  }
919 
920  /*
921  * Disable OpenSSL's moving-write-buffer sanity check, because it causes
922  * unnecessary failures in nonblocking send cases.
923  */
924  SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
925 
926  /*
927  * If the root cert file exists, load it so we can perform certificate
928  * verification. If sslmode is "verify-full" we will also do further
929  * verification after the connection has been completed.
930  */
931  if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
932  strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
933  else if (have_homedir)
934  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
935  else
936  fnbuf[0] = '\0';
937 
938  if (fnbuf[0] != '\0' &&
939  stat(fnbuf, &buf) == 0)
940  {
941  X509_STORE *cvstore;
942 
943  if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
944  {
945  char *err = SSLerrmessage(ERR_get_error());
946 
948  libpq_gettext("could not read root certificate file \"%s\": %s\n"),
949  fnbuf, err);
950  SSLerrfree(err);
951  SSL_CTX_free(SSL_context);
952  return -1;
953  }
954 
955  if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
956  {
957  char *fname = NULL;
958  char *dname = NULL;
959 
960  if (conn->sslcrl && strlen(conn->sslcrl) > 0)
961  fname = conn->sslcrl;
962  if (conn->sslcrldir && strlen(conn->sslcrldir) > 0)
963  dname = conn->sslcrldir;
964 
965  /* defaults to use the default CRL file */
966  if (!fname && !dname && have_homedir)
967  {
968  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
969  fname = fnbuf;
970  }
971 
972  /* Set the flags to check against the complete CRL chain */
973  if ((fname || dname) &&
974  X509_STORE_load_locations(cvstore, fname, dname) == 1)
975  {
976  X509_STORE_set_flags(cvstore,
977  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
978  }
979 
980  /* if not found, silently ignore; we do not require CRL */
981  ERR_clear_error();
982  }
983  have_rootcert = true;
984  }
985  else
986  {
987  /*
988  * stat() failed; assume root file doesn't exist. If sslmode is
989  * verify-ca or verify-full, this is an error. Otherwise, continue
990  * without performing any server cert verification.
991  */
992  if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
993  {
994  /*
995  * The only way to reach here with an empty filename is if
996  * pqGetHomeDirectory failed. That's a sufficiently unusual case
997  * that it seems worth having a specialized error message for it.
998  */
999  if (fnbuf[0] == '\0')
1001  libpq_gettext("could not get home directory to locate root certificate file\n"
1002  "Either provide the file or change sslmode to disable server certificate verification.\n"));
1003  else
1005  libpq_gettext("root certificate file \"%s\" does not exist\n"
1006  "Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
1007  SSL_CTX_free(SSL_context);
1008  return -1;
1009  }
1010  have_rootcert = false;
1011  }
1012 
1013  /* Read the client certificate file */
1014  if (conn->sslcert && strlen(conn->sslcert) > 0)
1015  strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
1016  else if (have_homedir)
1017  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
1018  else
1019  fnbuf[0] = '\0';
1020 
1021  if (fnbuf[0] == '\0')
1022  {
1023  /* no home directory, proceed without a client cert */
1024  have_cert = false;
1025  }
1026  else if (stat(fnbuf, &buf) != 0)
1027  {
1028  /*
1029  * If file is not present, just go on without a client cert; server
1030  * might or might not accept the connection. Any other error,
1031  * however, is grounds for complaint.
1032  */
1033  if (errno != ENOENT && errno != ENOTDIR)
1034  {
1036  libpq_gettext("could not open certificate file \"%s\": %s\n"),
1037  fnbuf, strerror_r(errno, sebuf, sizeof(sebuf)));
1038  SSL_CTX_free(SSL_context);
1039  return -1;
1040  }
1041  have_cert = false;
1042  }
1043  else
1044  {
1045  /*
1046  * Cert file exists, so load it. Since OpenSSL doesn't provide the
1047  * equivalent of "SSL_use_certificate_chain_file", we have to load it
1048  * into the SSL context, rather than the SSL object.
1049  */
1050  if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
1051  {
1052  char *err = SSLerrmessage(ERR_get_error());
1053 
1055  libpq_gettext("could not read certificate file \"%s\": %s\n"),
1056  fnbuf, err);
1057  SSLerrfree(err);
1058  SSL_CTX_free(SSL_context);
1059  return -1;
1060  }
1061 
1062  /* need to load the associated private key, too */
1063  have_cert = true;
1064  }
1065 
1066  /*
1067  * The SSL context is now loaded with the correct root and client
1068  * certificates. Create a connection-specific SSL object. The private key
1069  * is loaded directly into the SSL object. (We could load the private key
1070  * into the context, too, but we have done it this way historically, and
1071  * it doesn't really matter.)
1072  */
1073  if (!(conn->ssl = SSL_new(SSL_context)) ||
1074  !SSL_set_app_data(conn->ssl, conn) ||
1076  {
1077  char *err = SSLerrmessage(ERR_get_error());
1078 
1080  libpq_gettext("could not establish SSL connection: %s\n"),
1081  err);
1082  SSLerrfree(err);
1083  SSL_CTX_free(SSL_context);
1084  return -1;
1085  }
1086  conn->ssl_in_use = true;
1087 
1088  /*
1089  * SSL contexts are reference counted by OpenSSL. We can free it as soon
1090  * as we have created the SSL object, and it will stick around for as long
1091  * as it's actually needed.
1092  */
1093  SSL_CTX_free(SSL_context);
1094  SSL_context = NULL;
1095 
1096  /*
1097  * Set Server Name Indication (SNI), if enabled by connection parameters.
1098  * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
1099  * or IPv6).
1100  */
1101  if (conn->sslsni && conn->sslsni[0] == '1')
1102  {
1103  const char *host = conn->connhost[conn->whichhost].host;
1104 
1105  if (host && host[0] &&
1106  !(strspn(host, "0123456789.") == strlen(host) ||
1107  strchr(host, ':')))
1108  {
1109  if (SSL_set_tlsext_host_name(conn->ssl, host) != 1)
1110  {
1111  char *err = SSLerrmessage(ERR_get_error());
1112 
1114  libpq_gettext("could not set SSL Server Name Indication (SNI): %s\n"),
1115  err);
1116  SSLerrfree(err);
1117  return -1;
1118  }
1119  }
1120  }
1121 
1122  /*
1123  * Read the SSL key. If a key is specified, treat it as an engine:key
1124  * combination if there is colon present - we don't support files with
1125  * colon in the name. The exception is if the second character is a colon,
1126  * in which case it can be a Windows filename with drive specification.
1127  */
1128  if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0)
1129  {
1130 #ifdef USE_SSL_ENGINE
1131  if (strchr(conn->sslkey, ':')
1132 #ifdef WIN32
1133  && conn->sslkey[1] != ':'
1134 #endif
1135  )
1136  {
1137  /* Colon, but not in second character, treat as engine:key */
1138  char *engine_str = strdup(conn->sslkey);
1139  char *engine_colon;
1140 
1141  if (engine_str == NULL)
1142  {
1144  libpq_gettext("out of memory\n"));
1145  return -1;
1146  }
1147 
1148  /* cannot return NULL because we already checked before strdup */
1149  engine_colon = strchr(engine_str, ':');
1150 
1151  *engine_colon = '\0'; /* engine_str now has engine name */
1152  engine_colon++; /* engine_colon now has key name */
1153 
1154  conn->engine = ENGINE_by_id(engine_str);
1155  if (conn->engine == NULL)
1156  {
1157  char *err = SSLerrmessage(ERR_get_error());
1158 
1160  libpq_gettext("could not load SSL engine \"%s\": %s\n"),
1161  engine_str, err);
1162  SSLerrfree(err);
1163  free(engine_str);
1164  return -1;
1165  }
1166 
1167  if (ENGINE_init(conn->engine) == 0)
1168  {
1169  char *err = SSLerrmessage(ERR_get_error());
1170 
1172  libpq_gettext("could not initialize SSL engine \"%s\": %s\n"),
1173  engine_str, err);
1174  SSLerrfree(err);
1175  ENGINE_free(conn->engine);
1176  conn->engine = NULL;
1177  free(engine_str);
1178  return -1;
1179  }
1180 
1181  pkey = ENGINE_load_private_key(conn->engine, engine_colon,
1182  NULL, NULL);
1183  if (pkey == NULL)
1184  {
1185  char *err = SSLerrmessage(ERR_get_error());
1186 
1188  libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
1189  engine_colon, engine_str, err);
1190  SSLerrfree(err);
1191  ENGINE_finish(conn->engine);
1192  ENGINE_free(conn->engine);
1193  conn->engine = NULL;
1194  free(engine_str);
1195  return -1;
1196  }
1197  if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
1198  {
1199  char *err = SSLerrmessage(ERR_get_error());
1200 
1202  libpq_gettext("could not load private SSL key \"%s\" from engine \"%s\": %s\n"),
1203  engine_colon, engine_str, err);
1204  SSLerrfree(err);
1205  ENGINE_finish(conn->engine);
1206  ENGINE_free(conn->engine);
1207  conn->engine = NULL;
1208  free(engine_str);
1209  return -1;
1210  }
1211 
1212  free(engine_str);
1213 
1214  fnbuf[0] = '\0'; /* indicate we're not going to load from a
1215  * file */
1216  }
1217  else
1218 #endif /* USE_SSL_ENGINE */
1219  {
1220  /* PGSSLKEY is not an engine, treat it as a filename */
1221  strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
1222  }
1223  }
1224  else if (have_homedir)
1225  {
1226  /* No PGSSLKEY specified, load default file */
1227  snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
1228  }
1229  else
1230  fnbuf[0] = '\0';
1231 
1232  if (have_cert && fnbuf[0] != '\0')
1233  {
1234  /* read the client key from file */
1235 
1236  if (stat(fnbuf, &buf) != 0)
1237  {
1238  if (errno == ENOENT)
1240  libpq_gettext("certificate present, but not private key file \"%s\"\n"),
1241  fnbuf);
1242  else
1244  libpq_gettext("could not stat private key file \"%s\": %m\n"),
1245  fnbuf);
1246  return -1;
1247  }
1248 #ifndef WIN32
1249  if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
1250  {
1252  libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
1253  fnbuf);
1254  return -1;
1255  }
1256 #endif
1257 
1258  if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
1259  {
1260  char *err = SSLerrmessage(ERR_get_error());
1261 
1262  /*
1263  * We'll try to load the file in DER (binary ASN.1) format, and if
1264  * that fails too, report the original error. This could mask
1265  * issues where there's something wrong with a DER-format cert,
1266  * but we'd have to duplicate openssl's format detection to be
1267  * smarter than this. We can't just probe for a leading -----BEGIN
1268  * because PEM can have leading non-matching lines and blanks.
1269  * OpenSSL doesn't expose its get_name(...) and its PEM routines
1270  * don't differentiate between failure modes in enough detail to
1271  * let us tell the difference between "not PEM, try DER" and
1272  * "wrong password".
1273  */
1274  if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1)
1275  {
1277  libpq_gettext("could not load private key file \"%s\": %s\n"),
1278  fnbuf, err);
1279  SSLerrfree(err);
1280  return -1;
1281  }
1282 
1283  SSLerrfree(err);
1284 
1285  }
1286  }
1287 
1288  /* verify that the cert and key go together */
1289  if (have_cert &&
1290  SSL_check_private_key(conn->ssl) != 1)
1291  {
1292  char *err = SSLerrmessage(ERR_get_error());
1293 
1295  libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
1296  fnbuf, err);
1297  SSLerrfree(err);
1298  return -1;
1299  }
1300 
1301  /*
1302  * If a root cert was loaded, also set our certificate verification
1303  * callback.
1304  */
1305  if (have_rootcert)
1306  SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
1307 
1308  /*
1309  * Set compression option if necessary.
1310  */
1311  if (conn->sslcompression && conn->sslcompression[0] == '0')
1312  SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1313  else
1314  SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1315 
1316  return 0;
1317 }
static SSL_CTX * SSL_context
bool pqGetHomeDirectory(char *buf, int bufsize)
Definition: fe-connect.c:7413
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 libpq_gettext(x)
Definition: libpq-int.h:848
#define MAXPGPATH
static char * buf
Definition: pg_test_fsync.c:70
#define PG_STRERROR_R_BUFLEN
Definition: port.h:243
#define snprintf
Definition: port.h:225
#define strerror_r
Definition: port.h:242
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
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:335
char * sslrootcert
Definition: libpq-int.h:384
char * sslcompression
Definition: libpq-int.h:380
pgsocket sock
Definition: libpq-int.h:444
char * sslcrldir
Definition: libpq-int.h:386
char * sslcrl
Definition: libpq-int.h:385
char * ssl_max_protocol_version
Definition: libpq-int.h:394
char * sslcert
Definition: libpq-int.h:382
char * sslpassword
Definition: libpq-int.h:383
char * sslmode
Definition: libpq-int.h:379
char * ssl_min_protocol_version
Definition: libpq-int.h:393
PQExpBufferData errorMessage
Definition: libpq-int.h:571
char * sslkey
Definition: libpq-int.h:381
int whichhost
Definition: libpq-int.h:426
char * sslsni
Definition: libpq-int.h:387
pg_conn_host * connhost
Definition: libpq-int.h:427
bool ssl_in_use
Definition: libpq-int.h:508
#define stat
Definition: win32_port.h:283
#define S_IRWXG
Definition: win32_port.h:309
#define S_IRWXO
Definition: win32_port.h:321
#define S_ISREG(m)
Definition: win32_port.h:327

References appendPQExpBuffer(), appendPQExpBufferStr(), buf, conn, pg_conn::connhost, pg_conn::errorMessage, free, pg_conn_host::host, libpq_gettext, MAXPGPATH, my_SSL_set_fd(), PG_STRERROR_R_BUFLEN, pqGetHomeDirectory(), PQssl_passwd_cb(), PQsslKeyPassHook, S_IRWXG, S_IRWXO, S_ISREG, 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::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().

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

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

1710 {
1711  if (!my_bio_methods)
1712  {
1713  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
1714 #ifdef HAVE_BIO_METH_NEW
1715  int my_bio_index;
1716 
1717  my_bio_index = BIO_get_new_index();
1718  if (my_bio_index == -1)
1719  return NULL;
1720  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
1721  my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
1722  if (!my_bio_methods)
1723  return NULL;
1724 
1725  /*
1726  * As of this writing, these functions never fail. But check anyway,
1727  * like OpenSSL's own examples do.
1728  */
1729  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
1730  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
1731  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
1732  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
1733  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
1734  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
1735  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
1736  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
1737  {
1738  BIO_meth_free(my_bio_methods);
1739  my_bio_methods = NULL;
1740  return NULL;
1741  }
1742 #else
1743  my_bio_methods = malloc(sizeof(BIO_METHOD));
1744  if (!my_bio_methods)
1745  return NULL;
1746  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
1747  my_bio_methods->bread = my_sock_read;
1748  my_bio_methods->bwrite = my_sock_write;
1749 #endif
1750  }
1751  return my_bio_methods;
1752 }
static BIO_METHOD * my_bio_methods
static int my_sock_write(BIO *h, const char *buf, int size)
static int my_sock_read(BIO *h, char *buf, int size)
#define malloc(a)
Definition: header.h:50

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

Referenced by my_SSL_set_fd().

◆ my_sock_read()

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

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

1650 {
1651  int res;
1652 
1653  res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
1654  BIO_clear_retry_flags(h);
1655  if (res < 0)
1656  {
1657  /* If we were interrupted, tell caller to retry */
1658  switch (SOCK_ERRNO)
1659  {
1660 #ifdef EAGAIN
1661  case EAGAIN:
1662 #endif
1663 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1664  case EWOULDBLOCK:
1665 #endif
1666  case EINTR:
1667  BIO_set_retry_read(h);
1668  break;
1669 
1670  default:
1671  break;
1672  }
1673  }
1674 
1675  return res;
1676 }
#define BIO_get_data(bio)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
Definition: fe-secure.c:232
#define SOCK_ERRNO
Definition: libpq-int.h:861
#define EINTR
Definition: win32_port.h:351
#define EWOULDBLOCK
Definition: win32_port.h:357
#define EAGAIN
Definition: win32_port.h:349

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

Referenced by my_BIO_s_socket().

◆ my_sock_write()

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

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

1680 {
1681  int res;
1682 
1683  res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
1684  BIO_clear_retry_flags(h);
1685  if (res <= 0)
1686  {
1687  /* If we were interrupted, tell caller to retry */
1688  switch (SOCK_ERRNO)
1689  {
1690 #ifdef EAGAIN
1691  case EAGAIN:
1692 #endif
1693 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1694  case EWOULDBLOCK:
1695 #endif
1696  case EINTR:
1697  BIO_set_retry_write(h);
1698  break;
1699 
1700  default:
1701  break;
1702  }
1703  }
1704 
1705  return res;
1706 }
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
Definition: fe-secure.c:314

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

Referenced by my_BIO_s_socket().

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( PGconn conn,
int  fd 
)
static

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

1757 {
1758  int ret = 0;
1759  BIO *bio;
1760  BIO_METHOD *bio_method;
1761 
1762  bio_method = my_BIO_s_socket();
1763  if (bio_method == NULL)
1764  {
1765  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
1766  goto err;
1767  }
1768  bio = BIO_new(bio_method);
1769  if (bio == NULL)
1770  {
1771  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
1772  goto err;
1773  }
1774  BIO_set_data(bio, conn);
1775 
1776  SSL_set_bio(conn->ssl, bio, bio);
1777  BIO_set_fd(bio, fd, BIO_NOCLOSE);
1778  ret = 1;
1779 err:
1780  return ret;
1781 }
static BIO_METHOD * my_BIO_s_socket(void)
#define BIO_set_data(bio, data)
static int fd(const char *x, int i)
Definition: preproc-init.c:105

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

Referenced by initialize_SSL().

◆ open_client_SSL()

static PostgresPollingStatusType open_client_SSL ( PGconn conn)
static

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

1324 {
1325  int r;
1326 
1327  ERR_clear_error();
1328  r = SSL_connect(conn->ssl);
1329  if (r <= 0)
1330  {
1331  int err = SSL_get_error(conn->ssl, r);
1332  unsigned long ecode;
1333 
1334  ecode = ERR_get_error();
1335  switch (err)
1336  {
1337  case SSL_ERROR_WANT_READ:
1338  return PGRES_POLLING_READING;
1339 
1340  case SSL_ERROR_WANT_WRITE:
1341  return PGRES_POLLING_WRITING;
1342 
1343  case SSL_ERROR_SYSCALL:
1344  {
1345  char sebuf[PG_STRERROR_R_BUFLEN];
1346 
1347  if (r == -1)
1349  libpq_gettext("SSL SYSCALL error: %s\n"),
1350  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1351  else
1353  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
1354  pgtls_close(conn);
1355  return PGRES_POLLING_FAILED;
1356  }
1357  case SSL_ERROR_SSL:
1358  {
1359  char *err = SSLerrmessage(ecode);
1360 
1362  libpq_gettext("SSL error: %s\n"),
1363  err);
1364  SSLerrfree(err);
1365  switch (ERR_GET_REASON(ecode))
1366  {
1367  /*
1368  * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
1369  * TLSV1_ALERT_PROTOCOL_VERSION have been observed
1370  * when trying to communicate with an old OpenSSL
1371  * library, or when the client and server specify
1372  * disjoint protocol ranges.
1373  * NO_PROTOCOLS_AVAILABLE occurs if there's a
1374  * local misconfiguration (which can happen
1375  * despite our checks, if openssl.cnf injects a
1376  * limit we didn't account for). It's not very
1377  * clear what would make OpenSSL return the other
1378  * codes listed here, but a hint about protocol
1379  * versions seems like it's appropriate for all.
1380  */
1381  case SSL_R_NO_PROTOCOLS_AVAILABLE:
1382  case SSL_R_UNSUPPORTED_PROTOCOL:
1383  case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
1384  case SSL_R_UNKNOWN_PROTOCOL:
1385  case SSL_R_UNKNOWN_SSL_VERSION:
1386  case SSL_R_UNSUPPORTED_SSL_VERSION:
1387  case SSL_R_WRONG_SSL_VERSION:
1388  case SSL_R_WRONG_VERSION_NUMBER:
1389  case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
1390 #ifdef SSL_R_VERSION_TOO_HIGH
1391  case SSL_R_VERSION_TOO_HIGH:
1392  case SSL_R_VERSION_TOO_LOW:
1393 #endif
1395  libpq_gettext("This may indicate that the server does not support any SSL protocol version between %s and %s.\n"),
1398  MIN_OPENSSL_TLS_VERSION,
1401  MAX_OPENSSL_TLS_VERSION);
1402  break;
1403  default:
1404  break;
1405  }
1406  pgtls_close(conn);
1407  return PGRES_POLLING_FAILED;
1408  }
1409 
1410  default:
1412  libpq_gettext("unrecognized SSL error code: %d\n"),
1413  err);
1414  pgtls_close(conn);
1415  return PGRES_POLLING_FAILED;
1416  }
1417  }
1418 
1419  /*
1420  * We already checked the server certificate in initialize_SSL() using
1421  * SSL_CTX_set_verify(), if root.crt exists.
1422  */
1423 
1424  /* get server certificate */
1425  conn->peer = SSL_get_peer_certificate(conn->ssl);
1426  if (conn->peer == NULL)
1427  {
1428  char *err = SSLerrmessage(ERR_get_error());
1429 
1431  libpq_gettext("certificate could not be obtained: %s\n"),
1432  err);
1433  SSLerrfree(err);
1434  pgtls_close(conn);
1435  return PGRES_POLLING_FAILED;
1436  }
1437 
1439  {
1440  pgtls_close(conn);
1441  return PGRES_POLLING_FAILED;
1442  }
1443 
1444  /* SSL handshake is complete */
1445  return PGRES_POLLING_OK;
1446 }
bool pq_verify_peer_name_matches_certificate(PGconn *conn)
void pgtls_close(PGconn *conn)
@ PGRES_POLLING_OK
Definition: libpq-fe.h:87
@ PGRES_POLLING_READING
Definition: libpq-fe.h:85
@ PGRES_POLLING_WRITING
Definition: libpq-fe.h:86
@ PGRES_POLLING_FAILED
Definition: libpq-fe.h:84
#define SOCK_STRERROR
Definition: libpq-int.h:862

References appendPQExpBuffer(), appendPQExpBufferStr(), conn, pg_conn::errorMessage, libpq_gettext, 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_STRERROR, pg_conn::ssl_max_protocol_version, pg_conn::ssl_min_protocol_version, SSLerrfree(), and SSLerrmessage().

Referenced by pgtls_open_client().

◆ openssl_verify_peer_name_matches_certificate_name()

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

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

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

References appendPQExpBufferStr(), conn, pg_conn::errorMessage, len, libpq_gettext, 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 1449 of file fe-secure-openssl.c.

1450 {
1451  bool destroy_needed = false;
1452 
1453  if (conn->ssl_in_use)
1454  {
1455  if (conn->ssl)
1456  {
1457  /*
1458  * We can't destroy everything SSL-related here due to the
1459  * possible later calls to OpenSSL routines which may need our
1460  * thread callbacks, so set a flag here and check at the end.
1461  */
1462 
1463  SSL_shutdown(conn->ssl);
1464  SSL_free(conn->ssl);
1465  conn->ssl = NULL;
1466  conn->ssl_in_use = false;
1467 
1468  destroy_needed = true;
1469  }
1470 
1471  if (conn->peer)
1472  {
1473  X509_free(conn->peer);
1474  conn->peer = NULL;
1475  }
1476 
1477 #ifdef USE_SSL_ENGINE
1478  if (conn->engine)
1479  {
1480  ENGINE_finish(conn->engine);
1481  ENGINE_free(conn->engine);
1482  conn->engine = NULL;
1483  }
1484 #endif
1485  }
1486  else
1487  {
1488  /*
1489  * In the non-SSL case, just remove the crypto callbacks if the
1490  * connection has then loaded. This code path has no dependency on
1491  * any pending SSL calls.
1492  */
1493  if (conn->crypto_loaded)
1494  destroy_needed = true;
1495  }
1496 
1497  /*
1498  * This will remove our crypto locking hooks if this is the last
1499  * connection using libcrypto which means we must wait to call it until
1500  * after all the potential SSL calls have been made, otherwise we can end
1501  * up with a race condition and possible deadlocks.
1502  *
1503  * See comments above destroy_ssl_system().
1504  */
1505  if (destroy_needed)
1506  {
1508  conn->crypto_loaded = false;
1509  }
1510 }
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_init()

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

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

650 {
651 #ifdef ENABLE_THREAD_SAFETY
652 #ifdef WIN32
653  /* Also see similar code in fe-connect.c, default_threadlock() */
654  if (ssl_config_mutex == NULL)
655  {
656  while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
657  /* loop, another thread own the lock */ ;
658  if (ssl_config_mutex == NULL)
659  {
660  if (pthread_mutex_init(&ssl_config_mutex, NULL))
661  return -1;
662  }
663  InterlockedExchange(&win32_ssl_create_mutex, 0);
664  }
665 #endif
666  if (pthread_mutex_lock(&ssl_config_mutex))
667  return -1;
668 
669 #ifdef HAVE_CRYPTO_LOCK
670  if (pq_init_crypto_lib)
671  {
672  /*
673  * If necessary, set up an array to hold locks for libcrypto.
674  * libcrypto will tell us how big to make this array.
675  */
676  if (pq_lockarray == NULL)
677  {
678  int i;
679 
680  pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
681  if (!pq_lockarray)
682  {
683  pthread_mutex_unlock(&ssl_config_mutex);
684  return -1;
685  }
686  for (i = 0; i < CRYPTO_num_locks(); i++)
687  {
688  if (pthread_mutex_init(&pq_lockarray[i], NULL))
689  {
690  free(pq_lockarray);
691  pq_lockarray = NULL;
692  pthread_mutex_unlock(&ssl_config_mutex);
693  return -1;
694  }
695  }
696  }
697 
698  if (do_crypto && !conn->crypto_loaded)
699  {
700  if (crypto_open_connections++ == 0)
701  {
702  /*
703  * These are only required for threaded libcrypto
704  * applications, but make sure we don't stomp on them if
705  * they're already set.
706  */
707  if (CRYPTO_get_id_callback() == NULL)
708  CRYPTO_set_id_callback(pq_threadidcallback);
709  if (CRYPTO_get_locking_callback() == NULL)
710  CRYPTO_set_locking_callback(pq_lockingcallback);
711  }
712 
713  conn->crypto_loaded = true;
714  }
715  }
716 #endif /* HAVE_CRYPTO_LOCK */
717 #endif /* ENABLE_THREAD_SAFETY */
718 
719  if (!ssl_lib_initialized && do_ssl)
720  {
721  if (pq_init_ssl_lib)
722  {
723 #ifdef HAVE_OPENSSL_INIT_SSL
724  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
725 #else
726  OPENSSL_config(NULL);
727  SSL_library_init();
728  SSL_load_error_strings();
729 #endif
730  }
731  ssl_lib_initialized = true;
732  }
733 
734 #ifdef ENABLE_THREAD_SAFETY
735  pthread_mutex_unlock(&ssl_config_mutex);
736 #endif
737  return 0;
738 }
static bool ssl_lib_initialized
static bool pq_init_ssl_lib
int i
Definition: isn.c:73
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
Definition: pthread-win32.c:35
CRITICAL_SECTION * pthread_mutex_t
Definition: pthread-win32.h:8

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

Referenced by pqsecure_initialize().

◆ pgtls_init_library()

void pgtls_init_library ( bool  do_ssl,
int  do_crypto 
)

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

113 {
114 #ifdef ENABLE_THREAD_SAFETY
115 
116  /*
117  * Disallow changing the flags while we have open connections, else we'd
118  * get completely confused.
119  */
120  if (crypto_open_connections != 0)
121  return;
122 #endif
123 
124  pq_init_ssl_lib = do_ssl;
125  pq_init_crypto_lib = do_crypto;
126 }

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

130 {
131  /* First time through? */
132  if (conn->ssl == NULL)
133  {
134  /*
135  * Create a connection-specific SSL object, and load client
136  * certificate, private key, and trusted CA certs.
137  */
138  if (initialize_SSL(conn) != 0)
139  {
140  /* initialize_SSL already put a message in conn->errorMessage */
141  pgtls_close(conn);
142  return PGRES_POLLING_FAILED;
143  }
144  }
145 
146  /* Begin or continue the actual handshake */
147  return open_client_SSL(conn);
148 }
static PostgresPollingStatusType open_client_SSL(PGconn *)
static int initialize_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 151 of file fe-secure-openssl.c.

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

References appendPQExpBuffer(), appendPQExpBufferStr(), conn, ECONNRESET, pg_conn::errorMessage, len, libpq_gettext, 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 274 of file fe-secure-openssl.c.

275 {
276  return SSL_pending(conn->ssl) > 0;
277 }

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

521 {
522  STACK_OF(GENERAL_NAME) * peer_san;
523  int i;
524  int rc = 0;
525 
526  /*
527  * First, get the Subject Alternative Names (SANs) from the certificate,
528  * and compare them against the originally given hostname.
529  */
530  peer_san = (STACK_OF(GENERAL_NAME) *)
531  X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
532 
533  if (peer_san)
534  {
535  int san_len = sk_GENERAL_NAME_num(peer_san);
536 
537  for (i = 0; i < san_len; i++)
538  {
539  const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
540 
541  if (name->type == GEN_DNS)
542  {
543  char *alt_name;
544 
545  (*names_examined)++;
547  name->d.dNSName,
548  &alt_name);
549 
550  if (alt_name)
551  {
552  if (!*first_name)
553  *first_name = alt_name;
554  else
555  free(alt_name);
556  }
557  }
558  if (rc != 0)
559  break;
560  }
561  sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
562  }
563 
564  /*
565  * If there is no subjectAltName extension of type dNSName, check the
566  * Common Name.
567  *
568  * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
569  * dNSName is present, the CN must be ignored.)
570  */
571  if (*names_examined == 0)
572  {
573  X509_NAME *subject_name;
574 
575  subject_name = X509_get_subject_name(conn->peer);
576  if (subject_name != NULL)
577  {
578  int cn_index;
579 
580  cn_index = X509_NAME_get_index_by_NID(subject_name,
581  NID_commonName, -1);
582  if (cn_index >= 0)
583  {
584  (*names_examined)++;
586  X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
587  first_name);
588  }
589  }
590  }
591 
592  return rc;
593 }
const char * name
Definition: encode.c:561
static int openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name, char **store_name)

References conn, free, i, name, and openssl_verify_peer_name_matches_certificate_name().

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

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

References appendPQExpBuffer(), appendPQExpBufferStr(), conn, ECONNRESET, pg_conn::errorMessage, len, libpq_gettext, 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 1789 of file fe-secure-openssl.c.

1790 {
1791  if (conn->sslpassword)
1792  {
1793  if (strlen(conn->sslpassword) + 1 > size)
1794  fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
1795  strncpy(buf, conn->sslpassword, size);
1796  buf[size - 1] = '\0';
1797  return strlen(buf);
1798  }
1799  else
1800  {
1801  buf[0] = '\0';
1802  return 0;
1803  }
1804 }
#define fprintf
Definition: port.h:229

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

Referenced by PQssl_passwd_cb().

◆ PQgetssl()

void* PQgetssl ( PGconn conn)

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

1566 {
1567  if (!conn)
1568  return NULL;
1569  return conn->ssl;
1570 }

References conn.

◆ PQgetSSLKeyPassHook_OpenSSL()

PQsslKeyPassHook_OpenSSL_type PQgetSSLKeyPassHook_OpenSSL ( void  )

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

1808 {
1809  return PQsslKeyPassHook;
1810 }

References PQsslKeyPassHook.

◆ PQsetSSLKeyPassHook_OpenSSL()

void PQsetSSLKeyPassHook_OpenSSL ( PQsslKeyPassHook_OpenSSL_type  hook)

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

1814 {
1815  PQsslKeyPassHook = hook;
1816 }

References PQsslKeyPassHook.

◆ PQssl_passwd_cb()

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

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

1825 {
1826  PGconn *conn = userdata;
1827 
1828  if (PQsslKeyPassHook)
1829  return PQsslKeyPassHook(buf, size, conn);
1830  else
1831  return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
1832 }
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 1598 of file fe-secure-openssl.c.

1599 {
1600  if (!conn)
1601  return NULL;
1602  if (conn->ssl == NULL)
1603  return NULL;
1604 
1605  if (strcmp(attribute_name, "library") == 0)
1606  return "OpenSSL";
1607 
1608  if (strcmp(attribute_name, "key_bits") == 0)
1609  {
1610  static char sslbits_str[12];
1611  int sslbits;
1612 
1613  SSL_get_cipher_bits(conn->ssl, &sslbits);
1614  snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
1615  return sslbits_str;
1616  }
1617 
1618  if (strcmp(attribute_name, "cipher") == 0)
1619  return SSL_get_cipher(conn->ssl);
1620 
1621  if (strcmp(attribute_name, "compression") == 0)
1622  return SSL_get_current_compression(conn->ssl) ? "on" : "off";
1623 
1624  if (strcmp(attribute_name, "protocol") == 0)
1625  return SSL_get_version(conn->ssl);
1626 
1627  return NULL; /* unknown attribute */
1628 }

References conn, and snprintf.

Referenced by printSSLInfo().

◆ PQsslAttributeNames()

const char* const* PQsslAttributeNames ( PGconn conn)

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

1584 {
1585  static const char *const result[] = {
1586  "library",
1587  "key_bits",
1588  "cipher",
1589  "compression",
1590  "protocol",
1591  NULL
1592  };
1593 
1594  return result;
1595 }

◆ PQsslStruct()

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

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

1574 {
1575  if (!conn)
1576  return NULL;
1577  if (strcmp(struct_name, "OpenSSL") == 0)
1578  return conn->ssl;
1579  return NULL;
1580 }

References conn.

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( const char *  protocol)
static

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

1846 {
1847  if (pg_strcasecmp("TLSv1", protocol) == 0)
1848  return TLS1_VERSION;
1849 
1850 #ifdef TLS1_1_VERSION
1851  if (pg_strcasecmp("TLSv1.1", protocol) == 0)
1852  return TLS1_1_VERSION;
1853 #endif
1854 
1855 #ifdef TLS1_2_VERSION
1856  if (pg_strcasecmp("TLSv1.2", protocol) == 0)
1857  return TLS1_2_VERSION;
1858 #endif
1859 
1860 #ifdef TLS1_3_VERSION
1861  if (pg_strcasecmp("TLSv1.3", protocol) == 0)
1862  return TLS1_3_VERSION;
1863 #endif
1864 
1865  return -1;
1866 }
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 1551 of file fe-secure-openssl.c.

1552 {
1553  if (buf != ssl_nomem)
1554  free(buf);
1555 }
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 1527 of file fe-secure-openssl.c.

1528 {
1529  const char *errreason;
1530  char *errbuf;
1531 
1532  errbuf = malloc(SSL_ERR_LEN);
1533  if (!errbuf)
1534  return ssl_nomem;
1535  if (ecode == 0)
1536  {
1537  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1538  return errbuf;
1539  }
1540  errreason = ERR_reason_error_string(ecode);
1541  if (errreason != NULL)
1542  {
1543  strlcpy(errbuf, errreason, SSL_ERR_LEN);
1544  return errbuf;
1545  }
1546  snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
1547  return errbuf;
1548 }
#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 472 of file fe-secure-openssl.c.

473 {
474  return ok;
475 }

Referenced by initialize_SSL().

Variable Documentation

◆ my_bio_methods

BIO_METHOD* my_bio_methods
static

Definition at line 1646 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 89 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 88 of file fe-secure-openssl.c.

Referenced by pgtls_init(), and pgtls_init_library().

◆ PQsslKeyPassHook

◆ ssl_lib_initialized

bool ssl_lib_initialized = false
static

Definition at line 91 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 1522 of file fe-secure-openssl.c.

Referenced by SSLerrfree(), and SSLerrmessage().