PostgreSQL Source Code  git master
be-secure-openssl.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <openssl/ssl.h>
#include <openssl/dh.h>
#include <openssl/conf.h>
#include <openssl/ec.h>
#include "common/openssl.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "tcop/tcopprot.h"
#include "utils/memutils.h"
Include dependency graph for be-secure-openssl.c:

Go to the source code of this file.

Macros

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

Functions

static void default_openssl_tls_init (SSL_CTX *context, bool isServerStart)
 
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 (Port *port, int fd)
 
static DH * load_dh_file (char *filename, bool isServerStart)
 
static DH * load_dh_buffer (const char *, size_t)
 
static int ssl_external_passwd_cb (char *buf, int size, int rwflag, void *userdata)
 
static int dummy_ssl_passwd_cb (char *buf, int size, int rwflag, void *userdata)
 
static int verify_cb (int, X509_STORE_CTX *)
 
static void info_cb (const SSL *ssl, int type, int args)
 
static bool initialize_dh (SSL_CTX *context, bool isServerStart)
 
static bool initialize_ecdh (SSL_CTX *context, bool isServerStart)
 
static const char * SSLerrmessage (unsigned long ecode)
 
static char * X509_NAME_to_cstring (X509_NAME *name)
 
static int ssl_protocol_version_to_openssl (int v)
 
static const char * ssl_protocol_version_to_string (int v)
 
int be_tls_init (bool isServerStart)
 
void be_tls_destroy (void)
 
int be_tls_open_server (Port *port)
 
void be_tls_close (Port *port)
 
ssize_t be_tls_read (Port *port, void *ptr, size_t len, int *waitfor)
 
ssize_t be_tls_write (Port *port, void *ptr, size_t len, int *waitfor)
 
int be_tls_get_cipher_bits (Port *port)
 
const char * be_tls_get_version (Port *port)
 
const char * be_tls_get_cipher (Port *port)
 
void be_tls_get_peer_subject_name (Port *port, char *ptr, size_t len)
 
void be_tls_get_peer_issuer_name (Port *port, char *ptr, size_t len)
 
void be_tls_get_peer_serial (Port *port, char *ptr, size_t len)
 

Variables

openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init
 
static SSL_CTX * SSL_context = NULL
 
static bool SSL_initialized = false
 
static bool dummy_ssl_passwd_cb_called = false
 
static bool ssl_is_server_start
 
static BIO_METHOD * my_bio_methods = NULL
 

Macro Definition Documentation

◆ BIO_get_data

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

Definition at line 817 of file be-secure-openssl.c.

Referenced by my_sock_read(), and my_sock_write().

◆ BIO_set_data

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

Definition at line 818 of file be-secure-openssl.c.

Referenced by my_SSL_set_fd().

Function Documentation

◆ be_tls_close()

void be_tls_close ( Port port)

Definition at line 646 of file be-secure-openssl.c.

References Port::peer_cn, Port::peer_dn, pfree(), and Port::ssl_in_use.

Referenced by secure_close().

647 {
648  if (port->ssl)
649  {
650  SSL_shutdown(port->ssl);
651  SSL_free(port->ssl);
652  port->ssl = NULL;
653  port->ssl_in_use = false;
654  }
655 
656  if (port->peer)
657  {
658  X509_free(port->peer);
659  port->peer = NULL;
660  }
661 
662  if (port->peer_cn)
663  {
664  pfree(port->peer_cn);
665  port->peer_cn = NULL;
666  }
667 
668  if (port->peer_dn)
669  {
670  pfree(port->peer_dn);
671  port->peer_dn = NULL;
672  }
673 }
char * peer_dn
Definition: libpq-be.h:211
char * peer_cn
Definition: libpq-be.h:210
bool ssl_in_use
Definition: libpq-be.h:209
void pfree(void *pointer)
Definition: mcxt.c:1169

◆ be_tls_destroy()

void be_tls_destroy ( void  )

Definition at line 384 of file be-secure-openssl.c.

References SSL_context.

Referenced by secure_destroy().

385 {
386  if (SSL_context)
387  SSL_CTX_free(SSL_context);
388  SSL_context = NULL;
389  ssl_loaded_verify_locations = false;
390 }
static SSL_CTX * SSL_context

◆ be_tls_get_cipher()

const char* be_tls_get_cipher ( Port port)

Definition at line 1258 of file be-secure-openssl.c.

Referenced by PerformAuthentication(), pgstat_bestart(), and ssl_cipher().

1259 {
1260  if (port->ssl)
1261  return SSL_get_cipher(port->ssl);
1262  else
1263  return NULL;
1264 }

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

Definition at line 1235 of file be-secure-openssl.c.

Referenced by PerformAuthentication(), and pgstat_bestart().

1236 {
1237  int bits;
1238 
1239  if (port->ssl)
1240  {
1241  SSL_get_cipher_bits(port->ssl, &bits);
1242  return bits;
1243  }
1244  else
1245  return 0;
1246 }

◆ be_tls_get_peer_issuer_name()

void be_tls_get_peer_issuer_name ( Port port,
char *  ptr,
size_t  len 
)

Definition at line 1276 of file be-secure-openssl.c.

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_issuer_dn().

1277 {
1278  if (port->peer)
1279  strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1280  else
1281  ptr[0] = '\0';
1282 }
static char * X509_NAME_to_cstring(X509_NAME *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

◆ be_tls_get_peer_serial()

void be_tls_get_peer_serial ( Port port,
char *  ptr,
size_t  len 
)

Definition at line 1285 of file be-secure-openssl.c.

References elog, ERROR, hash(), palloc(), port, and strlcpy().

Referenced by pgstat_bestart(), and ssl_client_serial().

1286 {
1287  if (port->peer)
1288  {
1289  ASN1_INTEGER *serial;
1290  BIGNUM *b;
1291  char *decimal;
1292 
1293  serial = X509_get_serialNumber(port->peer);
1294  b = ASN1_INTEGER_to_BN(serial, NULL);
1295  decimal = BN_bn2dec(b);
1296 
1297  BN_free(b);
1298  strlcpy(ptr, decimal, len);
1299  OPENSSL_free(decimal);
1300  }
1301  else
1302  ptr[0] = '\0';
1303 }
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

◆ be_tls_get_peer_subject_name()

void be_tls_get_peer_subject_name ( Port port,
char *  ptr,
size_t  len 
)

Definition at line 1267 of file be-secure-openssl.c.

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_client_dn().

1268 {
1269  if (port->peer)
1270  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1271  else
1272  ptr[0] = '\0';
1273 }
static char * X509_NAME_to_cstring(X509_NAME *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

◆ be_tls_get_version()

const char* be_tls_get_version ( Port port)

Definition at line 1249 of file be-secure-openssl.c.

Referenced by PerformAuthentication(), pgstat_bestart(), and ssl_version().

1250 {
1251  if (port->ssl)
1252  return SSL_get_version(port->ssl);
1253  else
1254  return NULL;
1255 }

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

Definition at line 82 of file be-secure-openssl.c.

References check_ssl_key_file_permissions(), dummy_ssl_passwd_cb_called, ereport, errcode(), errdetail(), errmsg(), error(), FATAL, GetConfigOption(), initialize_dh(), initialize_ecdh(), LOG, ssl_ca_file, ssl_cert_file, SSL_context, ssl_crl_dir, ssl_crl_file, SSL_CTX_set_max_proto_version(), SSL_CTX_set_min_proto_version(), SSL_initialized, ssl_is_server_start, ssl_key_file, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_openssl(), SSLCipherSuites, SSLerrmessage(), SSLPreferServerCiphers, and verify_cb().

Referenced by secure_initialize().

83 {
84  SSL_CTX *context;
85  int ssl_ver_min = -1;
86  int ssl_ver_max = -1;
87 
88  /* This stuff need be done only once. */
89  if (!SSL_initialized)
90  {
91 #ifdef HAVE_OPENSSL_INIT_SSL
92  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
93 #else
94  OPENSSL_config(NULL);
95  SSL_library_init();
96  SSL_load_error_strings();
97 #endif
98  SSL_initialized = true;
99  }
100 
101  /*
102  * Create a new SSL context into which we'll load all the configuration
103  * settings. If we fail partway through, we can avoid memory leakage by
104  * freeing this context; we don't install it as active until the end.
105  *
106  * We use SSLv23_method() because it can negotiate use of the highest
107  * mutually supported protocol version, while alternatives like
108  * TLSv1_2_method() permit only one specific version. Note that we don't
109  * actually allow SSL v2 or v3, only TLS protocols (see below).
110  */
111  context = SSL_CTX_new(SSLv23_method());
112  if (!context)
113  {
114  ereport(isServerStart ? FATAL : LOG,
115  (errmsg("could not create SSL context: %s",
116  SSLerrmessage(ERR_get_error()))));
117  goto error;
118  }
119 
120  /*
121  * Disable OpenSSL's moving-write-buffer sanity check, because it causes
122  * unnecessary failures in nonblocking send cases.
123  */
124  SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
125 
126  /*
127  * Call init hook (usually to set password callback)
128  */
129  (*openssl_tls_init_hook) (context, isServerStart);
130 
131  /* used by the callback */
132  ssl_is_server_start = isServerStart;
133 
134  /*
135  * Load and verify server's certificate and private key
136  */
137  if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
138  {
139  ereport(isServerStart ? FATAL : LOG,
140  (errcode(ERRCODE_CONFIG_FILE_ERROR),
141  errmsg("could not load server certificate file \"%s\": %s",
142  ssl_cert_file, SSLerrmessage(ERR_get_error()))));
143  goto error;
144  }
145 
146  if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
147  goto error;
148 
149  /*
150  * OK, try to load the private key file.
151  */
153 
154  if (SSL_CTX_use_PrivateKey_file(context,
155  ssl_key_file,
156  SSL_FILETYPE_PEM) != 1)
157  {
159  ereport(isServerStart ? FATAL : LOG,
160  (errcode(ERRCODE_CONFIG_FILE_ERROR),
161  errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
162  ssl_key_file)));
163  else
164  ereport(isServerStart ? FATAL : LOG,
165  (errcode(ERRCODE_CONFIG_FILE_ERROR),
166  errmsg("could not load private key file \"%s\": %s",
167  ssl_key_file, SSLerrmessage(ERR_get_error()))));
168  goto error;
169  }
170 
171  if (SSL_CTX_check_private_key(context) != 1)
172  {
173  ereport(isServerStart ? FATAL : LOG,
174  (errcode(ERRCODE_CONFIG_FILE_ERROR),
175  errmsg("check of private key failed: %s",
176  SSLerrmessage(ERR_get_error()))));
177  goto error;
178  }
179 
181  {
183 
184  if (ssl_ver_min == -1)
185  {
186  ereport(isServerStart ? FATAL : LOG,
187  /*- translator: first %s is a GUC option name, second %s is its value */
188  (errmsg("\"%s\" setting \"%s\" not supported by this build",
189  "ssl_min_protocol_version",
190  GetConfigOption("ssl_min_protocol_version",
191  false, false))));
192  goto error;
193  }
194 
195  if (!SSL_CTX_set_min_proto_version(context, ssl_ver_min))
196  {
197  ereport(isServerStart ? FATAL : LOG,
198  (errmsg("could not set minimum SSL protocol version")));
199  goto error;
200  }
201  }
202 
204  {
206 
207  if (ssl_ver_max == -1)
208  {
209  ereport(isServerStart ? FATAL : LOG,
210  /*- translator: first %s is a GUC option name, second %s is its value */
211  (errmsg("\"%s\" setting \"%s\" not supported by this build",
212  "ssl_max_protocol_version",
213  GetConfigOption("ssl_max_protocol_version",
214  false, false))));
215  goto error;
216  }
217 
218  if (!SSL_CTX_set_max_proto_version(context, ssl_ver_max))
219  {
220  ereport(isServerStart ? FATAL : LOG,
221  (errmsg("could not set maximum SSL protocol version")));
222  goto error;
223  }
224  }
225 
226  /* Check compatibility of min/max protocols */
229  {
230  /*
231  * No need to check for invalid values (-1) for each protocol number
232  * as the code above would have already generated an error.
233  */
234  if (ssl_ver_min > ssl_ver_max)
235  {
236  ereport(isServerStart ? FATAL : LOG,
237  (errmsg("could not set SSL protocol version range"),
238  errdetail("\"%s\" cannot be higher than \"%s\"",
239  "ssl_min_protocol_version",
240  "ssl_max_protocol_version")));
241  goto error;
242  }
243  }
244 
245  /* disallow SSL session tickets */
246  SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
247 
248  /* disallow SSL session caching, too */
249  SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
250 
251  /* disallow SSL compression */
252  SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
253 
254  /* set up ephemeral DH and ECDH keys */
255  if (!initialize_dh(context, isServerStart))
256  goto error;
257  if (!initialize_ecdh(context, isServerStart))
258  goto error;
259 
260  /* set up the allowed cipher list */
261  if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
262  {
263  ereport(isServerStart ? FATAL : LOG,
264  (errcode(ERRCODE_CONFIG_FILE_ERROR),
265  errmsg("could not set the cipher list (no valid ciphers available)")));
266  goto error;
267  }
268 
269  /* Let server choose order */
271  SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
272 
273  /*
274  * Load CA store, so we can verify client certificates if needed.
275  */
276  if (ssl_ca_file[0])
277  {
278  STACK_OF(X509_NAME) * root_cert_list;
279 
280  if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
281  (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
282  {
283  ereport(isServerStart ? FATAL : LOG,
284  (errcode(ERRCODE_CONFIG_FILE_ERROR),
285  errmsg("could not load root certificate file \"%s\": %s",
286  ssl_ca_file, SSLerrmessage(ERR_get_error()))));
287  goto error;
288  }
289 
290  /*
291  * Tell OpenSSL to send the list of root certs we trust to clients in
292  * CertificateRequests. This lets a client with a keystore select the
293  * appropriate client certificate to send to us. Also, this ensures
294  * that the SSL context will "own" the root_cert_list and remember to
295  * free it when no longer needed.
296  */
297  SSL_CTX_set_client_CA_list(context, root_cert_list);
298 
299  /*
300  * Always ask for SSL client cert, but don't fail if it's not
301  * presented. We might fail such connections later, depending on what
302  * we find in pg_hba.conf.
303  */
304  SSL_CTX_set_verify(context,
305  (SSL_VERIFY_PEER |
306  SSL_VERIFY_CLIENT_ONCE),
307  verify_cb);
308  }
309 
310  /*----------
311  * Load the Certificate Revocation List (CRL).
312  * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
313  *----------
314  */
315  if (ssl_crl_file[0] || ssl_crl_dir[0])
316  {
317  X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
318 
319  if (cvstore)
320  {
321  /* Set the flags to check against the complete CRL chain */
322  if (X509_STORE_load_locations(cvstore,
323  ssl_crl_file[0] ? ssl_crl_file : NULL,
324  ssl_crl_dir[0] ? ssl_crl_dir : NULL)
325  == 1)
326  {
327  X509_STORE_set_flags(cvstore,
328  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
329  }
330  else if (ssl_crl_dir[0] == 0)
331  {
332  ereport(isServerStart ? FATAL : LOG,
333  (errcode(ERRCODE_CONFIG_FILE_ERROR),
334  errmsg("could not load SSL certificate revocation list file \"%s\": %s",
335  ssl_crl_file, SSLerrmessage(ERR_get_error()))));
336  goto error;
337  }
338  else if (ssl_crl_file[0] == 0)
339  {
340  ereport(isServerStart ? FATAL : LOG,
341  (errcode(ERRCODE_CONFIG_FILE_ERROR),
342  errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
343  ssl_crl_dir, SSLerrmessage(ERR_get_error()))));
344  goto error;
345  }
346  else
347  {
348  ereport(isServerStart ? FATAL : LOG,
349  (errcode(ERRCODE_CONFIG_FILE_ERROR),
350  errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
352  SSLerrmessage(ERR_get_error()))));
353  goto error;
354  }
355  }
356  }
357 
358  /*
359  * Success! Replace any existing SSL_context.
360  */
361  if (SSL_context)
362  SSL_CTX_free(SSL_context);
363 
364  SSL_context = context;
365 
366  /*
367  * Set flag to remember whether CA store has been loaded into SSL_context.
368  */
369  if (ssl_ca_file[0])
370  ssl_loaded_verify_locations = true;
371  else
372  ssl_loaded_verify_locations = false;
373 
374  return 0;
375 
376  /* Clean up by releasing working context. */
377 error:
378  if (context)
379  SSL_CTX_free(context);
380  return -1;
381 }
static int ssl_protocol_version_to_openssl(int v)
static void error(void)
Definition: sql-dyntest.c:147
static bool dummy_ssl_passwd_cb_called
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
Definition: guc.c:8074
int errcode(int sqlerrcode)
Definition: elog.c:698
char * ssl_cert_file
Definition: be-secure.c:41
static bool initialize_ecdh(SSL_CTX *context, bool isServerStart)
#define LOG
Definition: elog.h:26
char * ssl_crl_file
Definition: be-secure.c:44
int ssl_min_protocol_version
Definition: be-secure.c:63
#define FATAL
Definition: elog.h:49
int errdetail(const char *fmt,...)
Definition: elog.c:1042
static bool SSL_initialized
char * SSLCipherSuites
Definition: be-secure.c:55
static int verify_cb(int, X509_STORE_CTX *)
char * ssl_crl_dir
Definition: be-secure.c:45
static bool ssl_is_server_start
static bool initialize_dh(SSL_CTX *context, bool isServerStart)
char * ssl_ca_file
Definition: be-secure.c:43
#define ereport(elevel,...)
Definition: elog.h:157
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
int ssl_max_protocol_version
Definition: be-secure.c:64
int errmsg(const char *fmt,...)
Definition: elog.c:909
static SSL_CTX * SSL_context
static const char * SSLerrmessage(unsigned long ecode)
int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
char * ssl_key_file
Definition: be-secure.c:42
bool SSLPreferServerCiphers
Definition: be-secure.c:61
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)

◆ be_tls_open_server()

int be_tls_open_server ( Port port)

Definition at line 393 of file be-secure-openssl.c.

References Assert, COMMERROR, ereport, errcode(), errcode_for_socket_access(), errhint(), errmsg(), info_cb(), MemoryContextAlloc(), my_SSL_set_fd(), MyLatch, Port::noblock, Port::peer_cert_valid, Port::peer_cn, Port::peer_dn, pfree(), Port::sock, SSL_context, Port::ssl_in_use, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_string(), SSLerrmessage(), TopMemoryContext, WAIT_EVENT_SSL_OPEN_SERVER, WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_open_server().

394 {
395  int r;
396  int err;
397  int waitfor;
398  unsigned long ecode;
399  bool give_proto_hint;
400 
401  Assert(!port->ssl);
402  Assert(!port->peer);
403 
404  if (!SSL_context)
405  {
407  (errcode(ERRCODE_PROTOCOL_VIOLATION),
408  errmsg("could not initialize SSL connection: SSL context not set up")));
409  return -1;
410  }
411 
412  /* set up debugging/info callback */
413  SSL_CTX_set_info_callback(SSL_context, info_cb);
414 
415  if (!(port->ssl = SSL_new(SSL_context)))
416  {
418  (errcode(ERRCODE_PROTOCOL_VIOLATION),
419  errmsg("could not initialize SSL connection: %s",
420  SSLerrmessage(ERR_get_error()))));
421  return -1;
422  }
423  if (!my_SSL_set_fd(port, port->sock))
424  {
426  (errcode(ERRCODE_PROTOCOL_VIOLATION),
427  errmsg("could not set SSL socket: %s",
428  SSLerrmessage(ERR_get_error()))));
429  return -1;
430  }
431  port->ssl_in_use = true;
432 
433 aloop:
434 
435  /*
436  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
437  * queue. In general, the current thread's error queue must be empty
438  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
439  * not work reliably. An extension may have failed to clear the
440  * per-thread error queue following another call to an OpenSSL I/O
441  * routine.
442  */
443  ERR_clear_error();
444  r = SSL_accept(port->ssl);
445  if (r <= 0)
446  {
447  err = SSL_get_error(port->ssl, r);
448 
449  /*
450  * Other clients of OpenSSL in the backend may fail to call
451  * ERR_get_error(), but we always do, so as to not cause problems for
452  * OpenSSL clients that don't call ERR_clear_error() defensively. Be
453  * sure that this happens by calling now. SSL_get_error() relies on
454  * the OpenSSL per-thread error queue being intact, so this is the
455  * earliest possible point ERR_get_error() may be called.
456  */
457  ecode = ERR_get_error();
458  switch (err)
459  {
460  case SSL_ERROR_WANT_READ:
461  case SSL_ERROR_WANT_WRITE:
462  /* not allowed during connection establishment */
463  Assert(!port->noblock);
464 
465  /*
466  * No need to care about timeouts/interrupts here. At this
467  * point authentication_timeout still employs
468  * StartupPacketTimeoutHandler() which directly exits.
469  */
470  if (err == SSL_ERROR_WANT_READ)
472  else
474 
475  (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
477  goto aloop;
478  case SSL_ERROR_SYSCALL:
479  if (r < 0)
482  errmsg("could not accept SSL connection: %m")));
483  else
485  (errcode(ERRCODE_PROTOCOL_VIOLATION),
486  errmsg("could not accept SSL connection: EOF detected")));
487  break;
488  case SSL_ERROR_SSL:
489  switch (ERR_GET_REASON(ecode))
490  {
491  /*
492  * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
493  * TLSV1_ALERT_PROTOCOL_VERSION have been observed
494  * when trying to communicate with an old OpenSSL
495  * library, or when the client and server specify
496  * disjoint protocol ranges. NO_PROTOCOLS_AVAILABLE
497  * occurs if there's a local misconfiguration (which
498  * can happen despite our checks, if openssl.cnf
499  * injects a limit we didn't account for). It's not
500  * very clear what would make OpenSSL return the other
501  * codes listed here, but a hint about protocol
502  * versions seems like it's appropriate for all.
503  */
504  case SSL_R_NO_PROTOCOLS_AVAILABLE:
505  case SSL_R_UNSUPPORTED_PROTOCOL:
506  case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
507  case SSL_R_UNKNOWN_PROTOCOL:
508  case SSL_R_UNKNOWN_SSL_VERSION:
509  case SSL_R_UNSUPPORTED_SSL_VERSION:
510  case SSL_R_WRONG_SSL_VERSION:
511  case SSL_R_WRONG_VERSION_NUMBER:
512  case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
513 #ifdef SSL_R_VERSION_TOO_HIGH
514  case SSL_R_VERSION_TOO_HIGH:
515  case SSL_R_VERSION_TOO_LOW:
516 #endif
517  give_proto_hint = true;
518  break;
519  default:
520  give_proto_hint = false;
521  break;
522  }
524  (errcode(ERRCODE_PROTOCOL_VIOLATION),
525  errmsg("could not accept SSL connection: %s",
526  SSLerrmessage(ecode)),
527  give_proto_hint ?
528  errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
531  MIN_OPENSSL_TLS_VERSION,
534  MAX_OPENSSL_TLS_VERSION) : 0));
535  break;
536  case SSL_ERROR_ZERO_RETURN:
538  (errcode(ERRCODE_PROTOCOL_VIOLATION),
539  errmsg("could not accept SSL connection: EOF detected")));
540  break;
541  default:
543  (errcode(ERRCODE_PROTOCOL_VIOLATION),
544  errmsg("unrecognized SSL error code: %d",
545  err)));
546  break;
547  }
548  return -1;
549  }
550 
551  /* Get client certificate, if available. */
552  port->peer = SSL_get_peer_certificate(port->ssl);
553 
554  /* and extract the Common Name and Distinguished Name from it. */
555  port->peer_cn = NULL;
556  port->peer_dn = NULL;
557  port->peer_cert_valid = false;
558  if (port->peer != NULL)
559  {
560  int len;
561  X509_NAME *x509name = X509_get_subject_name(port->peer);
562  char *peer_dn;
563  BIO *bio = NULL;
564  BUF_MEM *bio_buf = NULL;
565 
566  len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0);
567  if (len != -1)
568  {
569  char *peer_cn;
570 
571  peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
572  r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn,
573  len + 1);
574  peer_cn[len] = '\0';
575  if (r != len)
576  {
577  /* shouldn't happen */
578  pfree(peer_cn);
579  return -1;
580  }
581 
582  /*
583  * Reject embedded NULLs in certificate common name to prevent
584  * attacks like CVE-2009-4034.
585  */
586  if (len != strlen(peer_cn))
587  {
589  (errcode(ERRCODE_PROTOCOL_VIOLATION),
590  errmsg("SSL certificate's common name contains embedded null")));
591  pfree(peer_cn);
592  return -1;
593  }
594 
595  port->peer_cn = peer_cn;
596  }
597 
598  bio = BIO_new(BIO_s_mem());
599  if (!bio)
600  {
601  pfree(port->peer_cn);
602  port->peer_cn = NULL;
603  return -1;
604  }
605 
606  /*
607  * RFC2253 is the closest thing to an accepted standard format for
608  * DNs. We have documented how to produce this format from a
609  * certificate. It uses commas instead of slashes for delimiters,
610  * which make regular expression matching a bit easier. Also note that
611  * it prints the Subject fields in reverse order.
612  */
613  X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253);
614  if (BIO_get_mem_ptr(bio, &bio_buf) <= 0)
615  {
616  BIO_free(bio);
617  pfree(port->peer_cn);
618  port->peer_cn = NULL;
619  return -1;
620  }
621  peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
622  memcpy(peer_dn, bio_buf->data, bio_buf->length);
623  len = bio_buf->length;
624  BIO_free(bio);
625  peer_dn[len] = '\0';
626  if (len != strlen(peer_dn))
627  {
629  (errcode(ERRCODE_PROTOCOL_VIOLATION),
630  errmsg("SSL certificate's distinguished name contains embedded null")));
631  pfree(peer_dn);
632  pfree(port->peer_cn);
633  port->peer_cn = NULL;
634  return -1;
635  }
636 
637  port->peer_dn = peer_dn;
638 
639  port->peer_cert_valid = true;
640  }
641 
642  return 0;
643 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:127
int errhint(const char *fmt,...)
Definition: elog.c:1156
char * peer_dn
Definition: libpq-be.h:211
char * peer_cn
Definition: libpq-be.h:210
bool peer_cert_valid
Definition: libpq-be.h:212
static void info_cb(const SSL *ssl, int type, int args)
int errcode(int sqlerrcode)
Definition: elog.c:698
bool ssl_in_use
Definition: libpq-be.h:209
#define WL_SOCKET_READABLE
Definition: latch.h:126
pgsocket sock
Definition: libpq-be.h:127
int ssl_min_protocol_version
Definition: be-secure.c:63
void pfree(void *pointer)
Definition: mcxt.c:1169
static int my_SSL_set_fd(Port *port, int fd)
#define COMMERROR
Definition: elog.h:30
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:500
MemoryContext TopMemoryContext
Definition: mcxt.c:48
int errcode_for_socket_access(void)
Definition: elog.c:792
#define ereport(elevel,...)
Definition: elog.h:157
#define Assert(condition)
Definition: c.h:804
bool noblock
Definition: libpq-be.h:128
int ssl_max_protocol_version
Definition: be-secure.c:64
int errmsg(const char *fmt,...)
Definition: elog.c:909
static SSL_CTX * SSL_context
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:863
static const char * SSLerrmessage(unsigned long ecode)
struct Latch * MyLatch
Definition: globals.c:57
static const char * ssl_protocol_version_to_string(int v)
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:130

◆ be_tls_read()

ssize_t be_tls_read ( Port port,
void *  ptr,
size_t  len,
int *  waitfor 
)

Definition at line 676 of file be-secure-openssl.c.

References COMMERROR, ECONNRESET, ereport, errcode(), errmsg(), EWOULDBLOCK, SSLerrmessage(), WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_read().

677 {
678  ssize_t n;
679  int err;
680  unsigned long ecode;
681 
682  errno = 0;
683  ERR_clear_error();
684  n = SSL_read(port->ssl, ptr, len);
685  err = SSL_get_error(port->ssl, n);
686  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
687  switch (err)
688  {
689  case SSL_ERROR_NONE:
690  /* a-ok */
691  break;
692  case SSL_ERROR_WANT_READ:
693  *waitfor = WL_SOCKET_READABLE;
694  errno = EWOULDBLOCK;
695  n = -1;
696  break;
697  case SSL_ERROR_WANT_WRITE:
698  *waitfor = WL_SOCKET_WRITEABLE;
699  errno = EWOULDBLOCK;
700  n = -1;
701  break;
702  case SSL_ERROR_SYSCALL:
703  /* leave it to caller to ereport the value of errno */
704  if (n != -1)
705  {
706  errno = ECONNRESET;
707  n = -1;
708  }
709  break;
710  case SSL_ERROR_SSL:
712  (errcode(ERRCODE_PROTOCOL_VIOLATION),
713  errmsg("SSL error: %s", SSLerrmessage(ecode))));
714  errno = ECONNRESET;
715  n = -1;
716  break;
717  case SSL_ERROR_ZERO_RETURN:
718  /* connection was cleanly shut down by peer */
719  n = 0;
720  break;
721  default:
723  (errcode(ERRCODE_PROTOCOL_VIOLATION),
724  errmsg("unrecognized SSL error code: %d",
725  err)));
726  errno = ECONNRESET;
727  n = -1;
728  break;
729  }
730 
731  return n;
732 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:127
int errcode(int sqlerrcode)
Definition: elog.c:698
#define WL_SOCKET_READABLE
Definition: latch.h:126
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:157
#define ECONNRESET
Definition: win32_port.h:353
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:349

◆ be_tls_write()

ssize_t be_tls_write ( Port port,
void *  ptr,
size_t  len,
int *  waitfor 
)

Definition at line 735 of file be-secure-openssl.c.

References COMMERROR, ECONNRESET, ereport, errcode(), errmsg(), EWOULDBLOCK, SSLerrmessage(), WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_write().

736 {
737  ssize_t n;
738  int err;
739  unsigned long ecode;
740 
741  errno = 0;
742  ERR_clear_error();
743  n = SSL_write(port->ssl, ptr, len);
744  err = SSL_get_error(port->ssl, n);
745  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
746  switch (err)
747  {
748  case SSL_ERROR_NONE:
749  /* a-ok */
750  break;
751  case SSL_ERROR_WANT_READ:
752  *waitfor = WL_SOCKET_READABLE;
753  errno = EWOULDBLOCK;
754  n = -1;
755  break;
756  case SSL_ERROR_WANT_WRITE:
757  *waitfor = WL_SOCKET_WRITEABLE;
758  errno = EWOULDBLOCK;
759  n = -1;
760  break;
761  case SSL_ERROR_SYSCALL:
762  /* leave it to caller to ereport the value of errno */
763  if (n != -1)
764  {
765  errno = ECONNRESET;
766  n = -1;
767  }
768  break;
769  case SSL_ERROR_SSL:
771  (errcode(ERRCODE_PROTOCOL_VIOLATION),
772  errmsg("SSL error: %s", SSLerrmessage(ecode))));
773  errno = ECONNRESET;
774  n = -1;
775  break;
776  case SSL_ERROR_ZERO_RETURN:
777 
778  /*
779  * the SSL connection was closed, leave it to the caller to
780  * ereport it
781  */
782  errno = ECONNRESET;
783  n = -1;
784  break;
785  default:
787  (errcode(ERRCODE_PROTOCOL_VIOLATION),
788  errmsg("unrecognized SSL error code: %d",
789  err)));
790  errno = ECONNRESET;
791  n = -1;
792  break;
793  }
794 
795  return n;
796 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:127
int errcode(int sqlerrcode)
Definition: elog.c:698
#define WL_SOCKET_READABLE
Definition: latch.h:126
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:157
#define ECONNRESET
Definition: win32_port.h:353
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:349

◆ default_openssl_tls_init()

static void default_openssl_tls_init ( SSL_CTX *  context,
bool  isServerStart 
)
static

Definition at line 1494 of file be-secure-openssl.c.

References dummy_ssl_passwd_cb(), ssl_external_passwd_cb(), ssl_passphrase_command, and ssl_passphrase_command_supports_reload.

1495 {
1496  if (isServerStart)
1497  {
1498  if (ssl_passphrase_command[0])
1499  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1500  }
1501  else
1502  {
1504  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1505  else
1506 
1507  /*
1508  * If reloading and no external command is configured, override
1509  * OpenSSL's default handling of passphrase-protected files,
1510  * because we don't want to prompt for a passphrase in an
1511  * already-running server.
1512  */
1513  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1514  }
1515 }
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:48
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
char * ssl_passphrase_command
Definition: be-secure.c:47
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)

◆ dummy_ssl_passwd_cb()

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

Definition at line 1051 of file be-secure-openssl.c.

References Assert, and dummy_ssl_passwd_cb_called.

Referenced by default_openssl_tls_init().

1052 {
1053  /* Set flag to change the error message we'll report */
1055  /* And return empty string */
1056  Assert(size > 0);
1057  buf[0] = '\0';
1058  return 0;
1059 }
static bool dummy_ssl_passwd_cb_called
static char * buf
Definition: pg_test_fsync.c:68
#define Assert(condition)
Definition: c.h:804

◆ info_cb()

static void info_cb ( const SSL *  ssl,
int  type,
int  args 
)
static

Definition at line 1083 of file be-secure-openssl.c.

References DEBUG4, ereport, and errmsg_internal().

Referenced by be_tls_open_server().

1084 {
1085  const char *desc;
1086 
1087  desc = SSL_state_string_long(ssl);
1088 
1089  switch (type)
1090  {
1091  case SSL_CB_HANDSHAKE_START:
1092  ereport(DEBUG4,
1093  (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1094  break;
1095  case SSL_CB_HANDSHAKE_DONE:
1096  ereport(DEBUG4,
1097  (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1098  break;
1099  case SSL_CB_ACCEPT_LOOP:
1100  ereport(DEBUG4,
1101  (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1102  break;
1103  case SSL_CB_ACCEPT_EXIT:
1104  ereport(DEBUG4,
1105  (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1106  break;
1107  case SSL_CB_CONNECT_LOOP:
1108  ereport(DEBUG4,
1109  (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1110  break;
1111  case SSL_CB_CONNECT_EXIT:
1112  ereport(DEBUG4,
1113  (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1114  break;
1115  case SSL_CB_READ_ALERT:
1116  ereport(DEBUG4,
1117  (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1118  break;
1119  case SSL_CB_WRITE_ALERT:
1120  ereport(DEBUG4,
1121  (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1122  break;
1123  }
1124 }
#define DEBUG4
Definition: elog.h:22
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996

◆ initialize_dh()

static bool initialize_dh ( SSL_CTX *  context,
bool  isServerStart 
)
static

Definition at line 1140 of file be-secure-openssl.c.

References ereport, errcode(), errmsg(), FATAL, load_dh_buffer(), load_dh_file(), LOG, ssl_dh_params_file, and SSLerrmessage().

Referenced by be_tls_init().

1141 {
1142  DH *dh = NULL;
1143 
1144  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1145 
1146  if (ssl_dh_params_file[0])
1147  dh = load_dh_file(ssl_dh_params_file, isServerStart);
1148  if (!dh)
1149  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1150  if (!dh)
1151  {
1152  ereport(isServerStart ? FATAL : LOG,
1153  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1154  errmsg("DH: could not load DH parameters")));
1155  return false;
1156  }
1157 
1158  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1159  {
1160  ereport(isServerStart ? FATAL : LOG,
1161  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1162  errmsg("DH: could not set DH parameters: %s",
1163  SSLerrmessage(ERR_get_error()))));
1164  DH_free(dh);
1165  return false;
1166  }
1167 
1168  DH_free(dh);
1169  return true;
1170 }
static DH * load_dh_file(char *filename, bool isServerStart)
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:49
static DH * load_dh_buffer(const char *, size_t)
#define ereport(elevel,...)
Definition: elog.h:157
char * ssl_dh_params_file
Definition: be-secure.c:46
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)

◆ initialize_ecdh()

static bool initialize_ecdh ( SSL_CTX *  context,
bool  isServerStart 
)
static

Definition at line 1178 of file be-secure-openssl.c.

References ereport, errcode(), errmsg(), FATAL, LOG, and SSLECDHCurve.

Referenced by be_tls_init().

1179 {
1180 #ifndef OPENSSL_NO_ECDH
1181  EC_KEY *ecdh;
1182  int nid;
1183 
1184  nid = OBJ_sn2nid(SSLECDHCurve);
1185  if (!nid)
1186  {
1187  ereport(isServerStart ? FATAL : LOG,
1188  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1189  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1190  return false;
1191  }
1192 
1193  ecdh = EC_KEY_new_by_curve_name(nid);
1194  if (!ecdh)
1195  {
1196  ereport(isServerStart ? FATAL : LOG,
1197  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1198  errmsg("ECDH: could not create key")));
1199  return false;
1200  }
1201 
1202  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1203  SSL_CTX_set_tmp_ecdh(context, ecdh);
1204  EC_KEY_free(ecdh);
1205 #endif
1206 
1207  return true;
1208 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:49
char * SSLECDHCurve
Definition: be-secure.c:58
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg(const char *fmt,...)
Definition: elog.c:909

◆ load_dh_buffer()

static DH * load_dh_buffer ( const char *  buffer,
size_t  len 
)
static

Definition at line 1009 of file be-secure-openssl.c.

References DEBUG2, ereport, errmsg_internal(), SSLerrmessage(), and unconstify.

Referenced by initialize_dh().

1010 {
1011  BIO *bio;
1012  DH *dh = NULL;
1013 
1014  bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
1015  if (bio == NULL)
1016  return NULL;
1017  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1018  if (dh == NULL)
1019  ereport(DEBUG2,
1020  (errmsg_internal("DH load buffer: %s",
1021  SSLerrmessage(ERR_get_error()))));
1022  BIO_free(bio);
1023 
1024  return dh;
1025 }
#define DEBUG2
Definition: elog.h:24
#define unconstify(underlying_type, expr)
Definition: c.h:1243
#define ereport(elevel,...)
Definition: elog.h:157
int errmsg_internal(const char *fmt,...)
Definition: elog.c:996
static const char * SSLerrmessage(unsigned long ecode)

◆ load_dh_file()

static DH * load_dh_file ( char *  filename,
bool  isServerStart 
)
static

Definition at line 942 of file be-secure-openssl.c.

References AllocateFile(), ereport, errcode(), errcode_for_file_access(), errmsg(), FATAL, FreeFile(), LOG, and SSLerrmessage().

Referenced by initialize_dh().

943 {
944  FILE *fp;
945  DH *dh = NULL;
946  int codes;
947 
948  /* attempt to open file. It's not an error if it doesn't exist. */
949  if ((fp = AllocateFile(filename, "r")) == NULL)
950  {
951  ereport(isServerStart ? FATAL : LOG,
953  errmsg("could not open DH parameters file \"%s\": %m",
954  filename)));
955  return NULL;
956  }
957 
958  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
959  FreeFile(fp);
960 
961  if (dh == NULL)
962  {
963  ereport(isServerStart ? FATAL : LOG,
964  (errcode(ERRCODE_CONFIG_FILE_ERROR),
965  errmsg("could not load DH parameters file: %s",
966  SSLerrmessage(ERR_get_error()))));
967  return NULL;
968  }
969 
970  /* make sure the DH parameters are usable */
971  if (DH_check(dh, &codes) == 0)
972  {
973  ereport(isServerStart ? FATAL : LOG,
974  (errcode(ERRCODE_CONFIG_FILE_ERROR),
975  errmsg("invalid DH parameters: %s",
976  SSLerrmessage(ERR_get_error()))));
977  DH_free(dh);
978  return NULL;
979  }
980  if (codes & DH_CHECK_P_NOT_PRIME)
981  {
982  ereport(isServerStart ? FATAL : LOG,
983  (errcode(ERRCODE_CONFIG_FILE_ERROR),
984  errmsg("invalid DH parameters: p is not prime")));
985  DH_free(dh);
986  return NULL;
987  }
988  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
989  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
990  {
991  ereport(isServerStart ? FATAL : LOG,
992  (errcode(ERRCODE_CONFIG_FILE_ERROR),
993  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
994  DH_free(dh);
995  return NULL;
996  }
997 
998  return dh;
999 }
int errcode(int sqlerrcode)
Definition: elog.c:698
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:49
int errcode_for_file_access(void)
Definition: elog.c:721
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2373
#define ereport(elevel,...)
Definition: elog.h:157
int FreeFile(FILE *file)
Definition: fd.c:2572
static char * filename
Definition: pg_dumpall.c:91
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

Definition at line 865 of file be-secure-openssl.c.

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

Referenced by my_SSL_set_fd().

866 {
867  if (!my_bio_methods)
868  {
869  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
870 #ifdef HAVE_BIO_METH_NEW
871  int my_bio_index;
872 
873  my_bio_index = BIO_get_new_index();
874  if (my_bio_index == -1)
875  return NULL;
876  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
877  if (!my_bio_methods)
878  return NULL;
879  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
880  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
881  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
882  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
883  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
884  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
885  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
886  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
887  {
888  BIO_meth_free(my_bio_methods);
889  my_bio_methods = NULL;
890  return NULL;
891  }
892 #else
893  my_bio_methods = malloc(sizeof(BIO_METHOD));
894  if (!my_bio_methods)
895  return NULL;
896  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
897  my_bio_methods->bread = my_sock_read;
898  my_bio_methods->bwrite = my_sock_write;
899 #endif
900  }
901  return my_bio_methods;
902 }
#define malloc(a)
Definition: header.h:50
static BIO_METHOD * my_bio_methods
static int my_sock_read(BIO *h, char *buf, int size)
static int my_sock_write(BIO *h, const char *buf, int size)

◆ my_sock_read()

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

Definition at line 824 of file be-secure-openssl.c.

References BIO_get_data, EAGAIN, EINTR, EWOULDBLOCK, and secure_raw_read().

Referenced by my_BIO_s_socket().

825 {
826  int res = 0;
827 
828  if (buf != NULL)
829  {
830  res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
831  BIO_clear_retry_flags(h);
832  if (res <= 0)
833  {
834  /* If we were interrupted, tell caller to retry */
835  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
836  {
837  BIO_set_retry_read(h);
838  }
839  }
840  }
841 
842  return res;
843 }
#define EAGAIN
Definition: win32_port.h:341
#define BIO_get_data(bio)
Definition: libpq-be.h:125
static char * buf
Definition: pg_test_fsync.c:68
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:236
#define EWOULDBLOCK
Definition: win32_port.h:349
#define EINTR
Definition: win32_port.h:343

◆ my_sock_write()

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

Definition at line 846 of file be-secure-openssl.c.

References BIO_get_data, EAGAIN, EINTR, EWOULDBLOCK, and secure_raw_write().

Referenced by my_BIO_s_socket().

847 {
848  int res = 0;
849 
850  res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
851  BIO_clear_retry_flags(h);
852  if (res <= 0)
853  {
854  /* If we were interrupted, tell caller to retry */
855  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
856  {
857  BIO_set_retry_write(h);
858  }
859  }
860 
861  return res;
862 }
#define EAGAIN
Definition: win32_port.h:341
#define BIO_get_data(bio)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:332
Definition: libpq-be.h:125
static char * buf
Definition: pg_test_fsync.c:68
#define EWOULDBLOCK
Definition: win32_port.h:349
#define EINTR
Definition: win32_port.h:343

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( Port port,
int  fd 
)
static

Definition at line 906 of file be-secure-openssl.c.

References BIO_set_data, and my_BIO_s_socket().

Referenced by be_tls_open_server().

907 {
908  int ret = 0;
909  BIO *bio;
910  BIO_METHOD *bio_method;
911 
912  bio_method = my_BIO_s_socket();
913  if (bio_method == NULL)
914  {
915  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
916  goto err;
917  }
918  bio = BIO_new(bio_method);
919 
920  if (bio == NULL)
921  {
922  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
923  goto err;
924  }
925  BIO_set_data(bio, port);
926 
927  BIO_set_fd(bio, fd, BIO_NOCLOSE);
928  SSL_set_bio(port->ssl, bio, bio);
929  ret = 1;
930 err:
931  return ret;
932 }
#define BIO_set_data(bio, data)
static BIO_METHOD * my_BIO_s_socket(void)
static int fd(const char *x, int i)
Definition: preproc-init.c:105

◆ ssl_external_passwd_cb()

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

Definition at line 1031 of file be-secure-openssl.c.

References Assert, run_ssl_passphrase_command(), and ssl_is_server_start.

Referenced by default_openssl_tls_init().

1032 {
1033  /* same prompt as OpenSSL uses internally */
1034  const char *prompt = "Enter PEM pass phrase:";
1035 
1036  Assert(rwflag == 0);
1037 
1038  return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
1039 }
static char * buf
Definition: pg_test_fsync.c:68
static bool ssl_is_server_start
#define Assert(condition)
Definition: c.h:804
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( int  v)
static

Definition at line 1438 of file be-secure-openssl.c.

References PG_TLS1_1_VERSION, PG_TLS1_2_VERSION, PG_TLS1_3_VERSION, PG_TLS1_VERSION, and PG_TLS_ANY.

Referenced by be_tls_init().

1439 {
1440  switch (v)
1441  {
1442  case PG_TLS_ANY:
1443  return 0;
1444  case PG_TLS1_VERSION:
1445  return TLS1_VERSION;
1446  case PG_TLS1_1_VERSION:
1447 #ifdef TLS1_1_VERSION
1448  return TLS1_1_VERSION;
1449 #else
1450  break;
1451 #endif
1452  case PG_TLS1_2_VERSION:
1453 #ifdef TLS1_2_VERSION
1454  return TLS1_2_VERSION;
1455 #else
1456  break;
1457 #endif
1458  case PG_TLS1_3_VERSION:
1459 #ifdef TLS1_3_VERSION
1460  return TLS1_3_VERSION;
1461 #else
1462  break;
1463 #endif
1464  }
1465 
1466  return -1;
1467 }

◆ ssl_protocol_version_to_string()

static const char * ssl_protocol_version_to_string ( int  v)
static

Definition at line 1473 of file be-secure-openssl.c.

References PG_TLS1_1_VERSION, PG_TLS1_2_VERSION, PG_TLS1_3_VERSION, PG_TLS1_VERSION, and PG_TLS_ANY.

Referenced by be_tls_open_server().

1474 {
1475  switch (v)
1476  {
1477  case PG_TLS_ANY:
1478  return "any";
1479  case PG_TLS1_VERSION:
1480  return "TLSv1";
1481  case PG_TLS1_1_VERSION:
1482  return "TLSv1.1";
1483  case PG_TLS1_2_VERSION:
1484  return "TLSv1.2";
1485  case PG_TLS1_3_VERSION:
1486  return "TLSv1.3";
1487  }
1488 
1489  return "(unrecognized)";
1490 }

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

Definition at line 1220 of file be-secure-openssl.c.

References _, and snprintf.

Referenced by be_tls_init(), be_tls_open_server(), be_tls_read(), be_tls_write(), initialize_dh(), load_dh_buffer(), and load_dh_file().

1221 {
1222  const char *errreason;
1223  static char errbuf[36];
1224 
1225  if (ecode == 0)
1226  return _("no SSL error reported");
1227  errreason = ERR_reason_error_string(ecode);
1228  if (errreason != NULL)
1229  return errreason;
1230  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1231  return errbuf;
1232 }
#define snprintf
Definition: port.h:216
#define _(x)
Definition: elog.c:89

◆ verify_cb()

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

Definition at line 1073 of file be-secure-openssl.c.

Referenced by be_tls_init().

1074 {
1075  return ok;
1076 }

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

Definition at line 1366 of file be-secure-openssl.c.

References elog, ereport, errcode(), errmsg(), ERROR, i, pfree(), pg_any_to_server(), PG_UTF8, and pstrdup().

Referenced by be_tls_get_peer_issuer_name(), and be_tls_get_peer_subject_name().

1367 {
1368  BIO *membuf = BIO_new(BIO_s_mem());
1369  int i,
1370  nid,
1371  count = X509_NAME_entry_count(name);
1372  X509_NAME_ENTRY *e;
1373  ASN1_STRING *v;
1374  const char *field_name;
1375  size_t size;
1376  char nullterm;
1377  char *sp;
1378  char *dp;
1379  char *result;
1380 
1381  if (membuf == NULL)
1382  ereport(ERROR,
1383  (errcode(ERRCODE_OUT_OF_MEMORY),
1384  errmsg("failed to create BIO")));
1385 
1386  (void) BIO_set_close(membuf, BIO_CLOSE);
1387  for (i = 0; i < count; i++)
1388  {
1389  e = X509_NAME_get_entry(name, i);
1390  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1391  if (nid == NID_undef)
1392  ereport(ERROR,
1393  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1394  errmsg("could not get NID for ASN1_OBJECT object")));
1395  v = X509_NAME_ENTRY_get_data(e);
1396  field_name = OBJ_nid2sn(nid);
1397  if (field_name == NULL)
1398  field_name = OBJ_nid2ln(nid);
1399  if (field_name == NULL)
1400  ereport(ERROR,
1401  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1402  errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1403  BIO_printf(membuf, "/%s=", field_name);
1404  ASN1_STRING_print_ex(membuf, v,
1405  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1406  | ASN1_STRFLGS_UTF8_CONVERT));
1407  }
1408 
1409  /* ensure null termination of the BIO's content */
1410  nullterm = '\0';
1411  BIO_write(membuf, &nullterm, 1);
1412  size = BIO_get_mem_data(membuf, &sp);
1413  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1414 
1415  result = pstrdup(dp);
1416  if (dp != sp)
1417  pfree(dp);
1418  if (BIO_free(membuf) != 1)
1419  elog(ERROR, "could not free OpenSSL BIO structure");
1420 
1421  return result;
1422 }
char * pstrdup(const char *in)
Definition: mcxt.c:1299
int errcode(int sqlerrcode)
Definition: elog.c:698
void pfree(void *pointer)
Definition: mcxt.c:1169
#define ERROR
Definition: elog.h:46
#define ereport(elevel,...)
Definition: elog.h:157
const char * name
Definition: encode.c:515
e
Definition: preproc-init.c:82
int errmsg(const char *fmt,...)
Definition: elog.c:909
#define elog(elevel,...)
Definition: elog.h:232
int i
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:676

Variable Documentation

◆ dummy_ssl_passwd_cb_called

bool dummy_ssl_passwd_cb_called = false
static

Definition at line 71 of file be-secure-openssl.c.

Referenced by be_tls_init(), and dummy_ssl_passwd_cb().

◆ my_bio_methods

BIO_METHOD* my_bio_methods = NULL
static

Definition at line 821 of file be-secure-openssl.c.

Referenced by my_BIO_s_socket().

◆ openssl_tls_init_hook

openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init

Definition at line 50 of file be-secure-openssl.c.

Referenced by _PG_init().

◆ SSL_context

SSL_CTX* SSL_context = NULL
static

◆ SSL_initialized

bool SSL_initialized = false
static

Definition at line 70 of file be-secure-openssl.c.

Referenced by be_tls_init().

◆ ssl_is_server_start

bool ssl_is_server_start
static

Definition at line 72 of file be-secure-openssl.c.

Referenced by be_tls_init(), and ssl_external_passwd_cb().