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 827 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 828 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 656 of file be-secure-openssl.c.

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

Referenced by secure_close().

657 {
658  if (port->ssl)
659  {
660  SSL_shutdown(port->ssl);
661  SSL_free(port->ssl);
662  port->ssl = NULL;
663  port->ssl_in_use = false;
664  }
665 
666  if (port->peer)
667  {
668  X509_free(port->peer);
669  port->peer = NULL;
670  }
671 
672  if (port->peer_cn)
673  {
674  pfree(port->peer_cn);
675  port->peer_cn = NULL;
676  }
677 
678  if (port->peer_dn)
679  {
680  pfree(port->peer_dn);
681  port->peer_dn = NULL;
682  }
683 }
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 394 of file be-secure-openssl.c.

References SSL_context.

Referenced by secure_destroy().

395 {
396  if (SSL_context)
397  SSL_CTX_free(SSL_context);
398  SSL_context = NULL;
399  ssl_loaded_verify_locations = false;
400 }
static SSL_CTX * SSL_context

◆ be_tls_get_cipher()

const char* be_tls_get_cipher ( Port port)

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

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

1270 {
1271  if (port->ssl)
1272  return SSL_get_cipher(port->ssl);
1273  else
1274  return NULL;
1275 }

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1247 {
1248  int bits;
1249 
1250  if (port->ssl)
1251  {
1252  SSL_get_cipher_bits(port->ssl, &bits);
1253  return bits;
1254  }
1255  else
1256  return 0;
1257 }

◆ be_tls_get_peer_issuer_name()

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

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

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_issuer_dn().

1288 {
1289  if (port->peer)
1290  strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1291  else
1292  ptr[0] = '\0';
1293 }
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 1296 of file be-secure-openssl.c.

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

Referenced by pgstat_bestart(), and ssl_client_serial().

1297 {
1298  if (port->peer)
1299  {
1300  ASN1_INTEGER *serial;
1301  BIGNUM *b;
1302  char *decimal;
1303 
1304  serial = X509_get_serialNumber(port->peer);
1305  b = ASN1_INTEGER_to_BN(serial, NULL);
1306  decimal = BN_bn2dec(b);
1307 
1308  BN_free(b);
1309  strlcpy(ptr, decimal, len);
1310  OPENSSL_free(decimal);
1311  }
1312  else
1313  ptr[0] = '\0';
1314 }
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 1278 of file be-secure-openssl.c.

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_client_dn().

1279 {
1280  if (port->peer)
1281  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1282  else
1283  ptr[0] = '\0';
1284 }
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 1260 of file be-secure-openssl.c.

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

1261 {
1262  if (port->ssl)
1263  return SSL_get_version(port->ssl);
1264  else
1265  return NULL;
1266 }

◆ 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 #ifdef SSL_OP_NO_RENEGOTIATION
255 
256  /*
257  * Disallow SSL renegotiation, option available since 1.1.0h. This
258  * concerns only TLSv1.2 and older protocol versions, as TLSv1.3 has no
259  * support for renegotiation.
260  */
261  SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
262 #endif
263 
264  /* set up ephemeral DH and ECDH keys */
265  if (!initialize_dh(context, isServerStart))
266  goto error;
267  if (!initialize_ecdh(context, isServerStart))
268  goto error;
269 
270  /* set up the allowed cipher list */
271  if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
272  {
273  ereport(isServerStart ? FATAL : LOG,
274  (errcode(ERRCODE_CONFIG_FILE_ERROR),
275  errmsg("could not set the cipher list (no valid ciphers available)")));
276  goto error;
277  }
278 
279  /* Let server choose order */
281  SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
282 
283  /*
284  * Load CA store, so we can verify client certificates if needed.
285  */
286  if (ssl_ca_file[0])
287  {
288  STACK_OF(X509_NAME) * root_cert_list;
289 
290  if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
291  (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
292  {
293  ereport(isServerStart ? FATAL : LOG,
294  (errcode(ERRCODE_CONFIG_FILE_ERROR),
295  errmsg("could not load root certificate file \"%s\": %s",
296  ssl_ca_file, SSLerrmessage(ERR_get_error()))));
297  goto error;
298  }
299 
300  /*
301  * Tell OpenSSL to send the list of root certs we trust to clients in
302  * CertificateRequests. This lets a client with a keystore select the
303  * appropriate client certificate to send to us. Also, this ensures
304  * that the SSL context will "own" the root_cert_list and remember to
305  * free it when no longer needed.
306  */
307  SSL_CTX_set_client_CA_list(context, root_cert_list);
308 
309  /*
310  * Always ask for SSL client cert, but don't fail if it's not
311  * presented. We might fail such connections later, depending on what
312  * we find in pg_hba.conf.
313  */
314  SSL_CTX_set_verify(context,
315  (SSL_VERIFY_PEER |
316  SSL_VERIFY_CLIENT_ONCE),
317  verify_cb);
318  }
319 
320  /*----------
321  * Load the Certificate Revocation List (CRL).
322  * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
323  *----------
324  */
325  if (ssl_crl_file[0] || ssl_crl_dir[0])
326  {
327  X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
328 
329  if (cvstore)
330  {
331  /* Set the flags to check against the complete CRL chain */
332  if (X509_STORE_load_locations(cvstore,
333  ssl_crl_file[0] ? ssl_crl_file : NULL,
334  ssl_crl_dir[0] ? ssl_crl_dir : NULL)
335  == 1)
336  {
337  X509_STORE_set_flags(cvstore,
338  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
339  }
340  else if (ssl_crl_dir[0] == 0)
341  {
342  ereport(isServerStart ? FATAL : LOG,
343  (errcode(ERRCODE_CONFIG_FILE_ERROR),
344  errmsg("could not load SSL certificate revocation list file \"%s\": %s",
345  ssl_crl_file, SSLerrmessage(ERR_get_error()))));
346  goto error;
347  }
348  else if (ssl_crl_file[0] == 0)
349  {
350  ereport(isServerStart ? FATAL : LOG,
351  (errcode(ERRCODE_CONFIG_FILE_ERROR),
352  errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
353  ssl_crl_dir, SSLerrmessage(ERR_get_error()))));
354  goto error;
355  }
356  else
357  {
358  ereport(isServerStart ? FATAL : LOG,
359  (errcode(ERRCODE_CONFIG_FILE_ERROR),
360  errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
362  SSLerrmessage(ERR_get_error()))));
363  goto error;
364  }
365  }
366  }
367 
368  /*
369  * Success! Replace any existing SSL_context.
370  */
371  if (SSL_context)
372  SSL_CTX_free(SSL_context);
373 
374  SSL_context = context;
375 
376  /*
377  * Set flag to remember whether CA store has been loaded into SSL_context.
378  */
379  if (ssl_ca_file[0])
380  ssl_loaded_verify_locations = true;
381  else
382  ssl_loaded_verify_locations = false;
383 
384  return 0;
385 
386  /* Clean up by releasing working context. */
387 error:
388  if (context)
389  SSL_CTX_free(context);
390  return -1;
391 }
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:8147
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 403 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().

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

687 {
688  ssize_t n;
689  int err;
690  unsigned long ecode;
691 
692  errno = 0;
693  ERR_clear_error();
694  n = SSL_read(port->ssl, ptr, len);
695  err = SSL_get_error(port->ssl, n);
696  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
697  switch (err)
698  {
699  case SSL_ERROR_NONE:
700  /* a-ok */
701  break;
702  case SSL_ERROR_WANT_READ:
703  *waitfor = WL_SOCKET_READABLE;
704  errno = EWOULDBLOCK;
705  n = -1;
706  break;
707  case SSL_ERROR_WANT_WRITE:
708  *waitfor = WL_SOCKET_WRITEABLE;
709  errno = EWOULDBLOCK;
710  n = -1;
711  break;
712  case SSL_ERROR_SYSCALL:
713  /* leave it to caller to ereport the value of errno */
714  if (n != -1)
715  {
716  errno = ECONNRESET;
717  n = -1;
718  }
719  break;
720  case SSL_ERROR_SSL:
722  (errcode(ERRCODE_PROTOCOL_VIOLATION),
723  errmsg("SSL error: %s", SSLerrmessage(ecode))));
724  errno = ECONNRESET;
725  n = -1;
726  break;
727  case SSL_ERROR_ZERO_RETURN:
728  /* connection was cleanly shut down by peer */
729  n = 0;
730  break;
731  default:
733  (errcode(ERRCODE_PROTOCOL_VIOLATION),
734  errmsg("unrecognized SSL error code: %d",
735  err)));
736  errno = ECONNRESET;
737  n = -1;
738  break;
739  }
740 
741  return n;
742 }
#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:361
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:357

◆ be_tls_write()

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

Definition at line 745 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().

746 {
747  ssize_t n;
748  int err;
749  unsigned long ecode;
750 
751  errno = 0;
752  ERR_clear_error();
753  n = SSL_write(port->ssl, ptr, len);
754  err = SSL_get_error(port->ssl, n);
755  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
756  switch (err)
757  {
758  case SSL_ERROR_NONE:
759  /* a-ok */
760  break;
761  case SSL_ERROR_WANT_READ:
762  *waitfor = WL_SOCKET_READABLE;
763  errno = EWOULDBLOCK;
764  n = -1;
765  break;
766  case SSL_ERROR_WANT_WRITE:
767  *waitfor = WL_SOCKET_WRITEABLE;
768  errno = EWOULDBLOCK;
769  n = -1;
770  break;
771  case SSL_ERROR_SYSCALL:
772  /* leave it to caller to ereport the value of errno */
773  if (n != -1)
774  {
775  errno = ECONNRESET;
776  n = -1;
777  }
778  break;
779  case SSL_ERROR_SSL:
781  (errcode(ERRCODE_PROTOCOL_VIOLATION),
782  errmsg("SSL error: %s", SSLerrmessage(ecode))));
783  errno = ECONNRESET;
784  n = -1;
785  break;
786  case SSL_ERROR_ZERO_RETURN:
787 
788  /*
789  * the SSL connection was closed, leave it to the caller to
790  * ereport it
791  */
792  errno = ECONNRESET;
793  n = -1;
794  break;
795  default:
797  (errcode(ERRCODE_PROTOCOL_VIOLATION),
798  errmsg("unrecognized SSL error code: %d",
799  err)));
800  errno = ECONNRESET;
801  n = -1;
802  break;
803  }
804 
805  return n;
806 }
#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:361
int errmsg(const char *fmt,...)
Definition: elog.c:909
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:357

◆ default_openssl_tls_init()

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

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

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

1506 {
1507  if (isServerStart)
1508  {
1509  if (ssl_passphrase_command[0])
1510  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1511  }
1512  else
1513  {
1515  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1516  else
1517 
1518  /*
1519  * If reloading and no external command is configured, override
1520  * OpenSSL's default handling of passphrase-protected files,
1521  * because we don't want to prompt for a passphrase in an
1522  * already-running server.
1523  */
1524  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1525  }
1526 }
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 1062 of file be-secure-openssl.c.

References Assert, and dummy_ssl_passwd_cb_called.

Referenced by default_openssl_tls_init().

1063 {
1064  /* Set flag to change the error message we'll report */
1066  /* And return empty string */
1067  Assert(size > 0);
1068  buf[0] = '\0';
1069  return 0;
1070 }
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 1094 of file be-secure-openssl.c.

References DEBUG4, ereport, and errmsg_internal().

Referenced by be_tls_open_server().

1095 {
1096  const char *desc;
1097 
1098  desc = SSL_state_string_long(ssl);
1099 
1100  switch (type)
1101  {
1102  case SSL_CB_HANDSHAKE_START:
1103  ereport(DEBUG4,
1104  (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1105  break;
1106  case SSL_CB_HANDSHAKE_DONE:
1107  ereport(DEBUG4,
1108  (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1109  break;
1110  case SSL_CB_ACCEPT_LOOP:
1111  ereport(DEBUG4,
1112  (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1113  break;
1114  case SSL_CB_ACCEPT_EXIT:
1115  ereport(DEBUG4,
1116  (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1117  break;
1118  case SSL_CB_CONNECT_LOOP:
1119  ereport(DEBUG4,
1120  (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1121  break;
1122  case SSL_CB_CONNECT_EXIT:
1123  ereport(DEBUG4,
1124  (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1125  break;
1126  case SSL_CB_READ_ALERT:
1127  ereport(DEBUG4,
1128  (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1129  break;
1130  case SSL_CB_WRITE_ALERT:
1131  ereport(DEBUG4,
1132  (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1133  break;
1134  }
1135 }
#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 1151 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().

1152 {
1153  DH *dh = NULL;
1154 
1155  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1156 
1157  if (ssl_dh_params_file[0])
1158  dh = load_dh_file(ssl_dh_params_file, isServerStart);
1159  if (!dh)
1160  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1161  if (!dh)
1162  {
1163  ereport(isServerStart ? FATAL : LOG,
1164  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1165  errmsg("DH: could not load DH parameters")));
1166  return false;
1167  }
1168 
1169  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1170  {
1171  ereport(isServerStart ? FATAL : LOG,
1172  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1173  errmsg("DH: could not set DH parameters: %s",
1174  SSLerrmessage(ERR_get_error()))));
1175  DH_free(dh);
1176  return false;
1177  }
1178 
1179  DH_free(dh);
1180  return true;
1181 }
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 1189 of file be-secure-openssl.c.

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

Referenced by be_tls_init().

1190 {
1191 #ifndef OPENSSL_NO_ECDH
1192  EC_KEY *ecdh;
1193  int nid;
1194 
1195  nid = OBJ_sn2nid(SSLECDHCurve);
1196  if (!nid)
1197  {
1198  ereport(isServerStart ? FATAL : LOG,
1199  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1200  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1201  return false;
1202  }
1203 
1204  ecdh = EC_KEY_new_by_curve_name(nid);
1205  if (!ecdh)
1206  {
1207  ereport(isServerStart ? FATAL : LOG,
1208  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1209  errmsg("ECDH: could not create key")));
1210  return false;
1211  }
1212 
1213  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1214  SSL_CTX_set_tmp_ecdh(context, ecdh);
1215  EC_KEY_free(ecdh);
1216 #endif
1217 
1218  return true;
1219 }
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 1020 of file be-secure-openssl.c.

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

Referenced by initialize_dh().

1021 {
1022  BIO *bio;
1023  DH *dh = NULL;
1024 
1025  bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
1026  if (bio == NULL)
1027  return NULL;
1028  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1029  if (dh == NULL)
1030  ereport(DEBUG2,
1031  (errmsg_internal("DH load buffer: %s",
1032  SSLerrmessage(ERR_get_error()))));
1033  BIO_free(bio);
1034 
1035  return dh;
1036 }
#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 953 of file be-secure-openssl.c.

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

Referenced by initialize_dh().

954 {
955  FILE *fp;
956  DH *dh = NULL;
957  int codes;
958 
959  /* attempt to open file. It's not an error if it doesn't exist. */
960  if ((fp = AllocateFile(filename, "r")) == NULL)
961  {
962  ereport(isServerStart ? FATAL : LOG,
964  errmsg("could not open DH parameters file \"%s\": %m",
965  filename)));
966  return NULL;
967  }
968 
969  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
970  FreeFile(fp);
971 
972  if (dh == NULL)
973  {
974  ereport(isServerStart ? FATAL : LOG,
975  (errcode(ERRCODE_CONFIG_FILE_ERROR),
976  errmsg("could not load DH parameters file: %s",
977  SSLerrmessage(ERR_get_error()))));
978  return NULL;
979  }
980 
981  /* make sure the DH parameters are usable */
982  if (DH_check(dh, &codes) == 0)
983  {
984  ereport(isServerStart ? FATAL : LOG,
985  (errcode(ERRCODE_CONFIG_FILE_ERROR),
986  errmsg("invalid DH parameters: %s",
987  SSLerrmessage(ERR_get_error()))));
988  DH_free(dh);
989  return NULL;
990  }
991  if (codes & DH_CHECK_P_NOT_PRIME)
992  {
993  ereport(isServerStart ? FATAL : LOG,
994  (errcode(ERRCODE_CONFIG_FILE_ERROR),
995  errmsg("invalid DH parameters: p is not prime")));
996  DH_free(dh);
997  return NULL;
998  }
999  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
1000  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
1001  {
1002  ereport(isServerStart ? FATAL : LOG,
1003  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1004  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1005  DH_free(dh);
1006  return NULL;
1007  }
1008 
1009  return dh;
1010 }
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:2460
#define ereport(elevel,...)
Definition: elog.h:157
int FreeFile(FILE *file)
Definition: fd.c:2659
static char * filename
Definition: pg_dumpall.c:92
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 875 of file be-secure-openssl.c.

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

Referenced by my_SSL_set_fd().

876 {
877  if (!my_bio_methods)
878  {
879  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
880 #ifdef HAVE_BIO_METH_NEW
881  int my_bio_index;
882 
883  my_bio_index = BIO_get_new_index();
884  if (my_bio_index == -1)
885  return NULL;
886  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
887  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
888  if (!my_bio_methods)
889  return NULL;
890  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
891  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
892  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
893  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
894  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
895  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
896  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
897  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
898  {
899  BIO_meth_free(my_bio_methods);
900  my_bio_methods = NULL;
901  return NULL;
902  }
903 #else
904  my_bio_methods = malloc(sizeof(BIO_METHOD));
905  if (!my_bio_methods)
906  return NULL;
907  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
908  my_bio_methods->bread = my_sock_read;
909  my_bio_methods->bwrite = my_sock_write;
910 #endif
911  }
912  return my_bio_methods;
913 }
#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 834 of file be-secure-openssl.c.

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

Referenced by my_BIO_s_socket().

835 {
836  int res = 0;
837 
838  if (buf != NULL)
839  {
840  res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
841  BIO_clear_retry_flags(h);
842  if (res <= 0)
843  {
844  /* If we were interrupted, tell caller to retry */
845  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
846  {
847  BIO_set_retry_read(h);
848  }
849  }
850  }
851 
852  return res;
853 }
#define EAGAIN
Definition: win32_port.h:349
#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:357
#define EINTR
Definition: win32_port.h:351

◆ my_sock_write()

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

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

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

Referenced by my_BIO_s_socket().

857 {
858  int res = 0;
859 
860  res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
861  BIO_clear_retry_flags(h);
862  if (res <= 0)
863  {
864  /* If we were interrupted, tell caller to retry */
865  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
866  {
867  BIO_set_retry_write(h);
868  }
869  }
870 
871  return res;
872 }
#define EAGAIN
Definition: win32_port.h:349
#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:357
#define EINTR
Definition: win32_port.h:351

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( Port port,
int  fd 
)
static

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

References BIO_set_data, and my_BIO_s_socket().

Referenced by be_tls_open_server().

918 {
919  int ret = 0;
920  BIO *bio;
921  BIO_METHOD *bio_method;
922 
923  bio_method = my_BIO_s_socket();
924  if (bio_method == NULL)
925  {
926  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
927  goto err;
928  }
929  bio = BIO_new(bio_method);
930 
931  if (bio == NULL)
932  {
933  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
934  goto err;
935  }
936  BIO_set_data(bio, port);
937 
938  BIO_set_fd(bio, fd, BIO_NOCLOSE);
939  SSL_set_bio(port->ssl, bio, bio);
940  ret = 1;
941 err:
942  return ret;
943 }
#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 1042 of file be-secure-openssl.c.

References Assert, run_ssl_passphrase_command(), and ssl_is_server_start.

Referenced by default_openssl_tls_init().

1043 {
1044  /* same prompt as OpenSSL uses internally */
1045  const char *prompt = "Enter PEM pass phrase:";
1046 
1047  Assert(rwflag == 0);
1048 
1049  return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
1050 }
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 1449 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().

1450 {
1451  switch (v)
1452  {
1453  case PG_TLS_ANY:
1454  return 0;
1455  case PG_TLS1_VERSION:
1456  return TLS1_VERSION;
1457  case PG_TLS1_1_VERSION:
1458 #ifdef TLS1_1_VERSION
1459  return TLS1_1_VERSION;
1460 #else
1461  break;
1462 #endif
1463  case PG_TLS1_2_VERSION:
1464 #ifdef TLS1_2_VERSION
1465  return TLS1_2_VERSION;
1466 #else
1467  break;
1468 #endif
1469  case PG_TLS1_3_VERSION:
1470 #ifdef TLS1_3_VERSION
1471  return TLS1_3_VERSION;
1472 #else
1473  break;
1474 #endif
1475  }
1476 
1477  return -1;
1478 }

◆ ssl_protocol_version_to_string()

static const char * ssl_protocol_version_to_string ( int  v)
static

Definition at line 1484 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().

1485 {
1486  switch (v)
1487  {
1488  case PG_TLS_ANY:
1489  return "any";
1490  case PG_TLS1_VERSION:
1491  return "TLSv1";
1492  case PG_TLS1_1_VERSION:
1493  return "TLSv1.1";
1494  case PG_TLS1_2_VERSION:
1495  return "TLSv1.2";
1496  case PG_TLS1_3_VERSION:
1497  return "TLSv1.3";
1498  }
1499 
1500  return "(unrecognized)";
1501 }

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

Definition at line 1231 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().

1232 {
1233  const char *errreason;
1234  static char errbuf[36];
1235 
1236  if (ecode == 0)
1237  return _("no SSL error reported");
1238  errreason = ERR_reason_error_string(ecode);
1239  if (errreason != NULL)
1240  return errreason;
1241  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1242  return errbuf;
1243 }
#define snprintf
Definition: port.h:217
#define _(x)
Definition: elog.c:89

◆ verify_cb()

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

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

Referenced by be_tls_init().

1085 {
1086  return ok;
1087 }

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

Definition at line 1377 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().

1378 {
1379  BIO *membuf = BIO_new(BIO_s_mem());
1380  int i,
1381  nid,
1382  count = X509_NAME_entry_count(name);
1383  X509_NAME_ENTRY *e;
1384  ASN1_STRING *v;
1385  const char *field_name;
1386  size_t size;
1387  char nullterm;
1388  char *sp;
1389  char *dp;
1390  char *result;
1391 
1392  if (membuf == NULL)
1393  ereport(ERROR,
1394  (errcode(ERRCODE_OUT_OF_MEMORY),
1395  errmsg("could not create BIO")));
1396 
1397  (void) BIO_set_close(membuf, BIO_CLOSE);
1398  for (i = 0; i < count; i++)
1399  {
1400  e = X509_NAME_get_entry(name, i);
1401  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1402  if (nid == NID_undef)
1403  ereport(ERROR,
1404  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1405  errmsg("could not get NID for ASN1_OBJECT object")));
1406  v = X509_NAME_ENTRY_get_data(e);
1407  field_name = OBJ_nid2sn(nid);
1408  if (field_name == NULL)
1409  field_name = OBJ_nid2ln(nid);
1410  if (field_name == NULL)
1411  ereport(ERROR,
1412  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1413  errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1414  BIO_printf(membuf, "/%s=", field_name);
1415  ASN1_STRING_print_ex(membuf, v,
1416  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1417  | ASN1_STRFLGS_UTF8_CONVERT));
1418  }
1419 
1420  /* ensure null termination of the BIO's content */
1421  nullterm = '\0';
1422  BIO_write(membuf, &nullterm, 1);
1423  size = BIO_get_mem_data(membuf, &sp);
1424  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1425 
1426  result = pstrdup(dp);
1427  if (dp != sp)
1428  pfree(dp);
1429  if (BIO_free(membuf) != 1)
1430  elog(ERROR, "could not free OpenSSL BIO structure");
1431 
1432  return result;
1433 }
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:561
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 831 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().