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)
 
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)
 
bool be_tls_get_compression (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 691 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 692 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 526 of file be-secure-openssl.c.

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

Referenced by secure_close().

527 {
528  if (port->ssl)
529  {
530  SSL_shutdown(port->ssl);
531  SSL_free(port->ssl);
532  port->ssl = NULL;
533  port->ssl_in_use = false;
534  }
535 
536  if (port->peer)
537  {
538  X509_free(port->peer);
539  port->peer = NULL;
540  }
541 
542  if (port->peer_cn)
543  {
544  pfree(port->peer_cn);
545  port->peer_cn = NULL;
546  }
547 }
char * peer_cn
Definition: libpq-be.h:191
bool ssl_in_use
Definition: libpq-be.h:190
void pfree(void *pointer)
Definition: mcxt.c:1056

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

References SSL_context.

Referenced by secure_destroy().

354 {
355  if (SSL_context)
356  SSL_CTX_free(SSL_context);
357  SSL_context = NULL;
358  ssl_loaded_verify_locations = false;
359 }
static SSL_CTX * SSL_context

◆ be_tls_get_cipher()

const char* be_tls_get_cipher ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1135 {
1136  if (port->ssl)
1137  return SSL_get_cipher(port->ssl);
1138  else
1139  return NULL;
1140 }

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1103 {
1104  int bits;
1105 
1106  if (port->ssl)
1107  {
1108  SSL_get_cipher_bits(port->ssl, &bits);
1109  return bits;
1110  }
1111  else
1112  return 0;
1113 }

◆ be_tls_get_compression()

bool be_tls_get_compression ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1117 {
1118  if (port->ssl)
1119  return (SSL_get_current_compression(port->ssl) != NULL);
1120  else
1121  return false;
1122 }

◆ be_tls_get_peer_issuer_name()

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

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

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart().

1153 {
1154  if (port->peer)
1155  strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1156  else
1157  ptr[0] = '\0';
1158 }
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 1161 of file be-secure-openssl.c.

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

Referenced by pgstat_bestart().

1162 {
1163  if (port->peer)
1164  {
1165  ASN1_INTEGER *serial;
1166  BIGNUM *b;
1167  char *decimal;
1168 
1169  serial = X509_get_serialNumber(port->peer);
1170  b = ASN1_INTEGER_to_BN(serial, NULL);
1171  decimal = BN_bn2dec(b);
1172 
1173  BN_free(b);
1174  strlcpy(ptr, decimal, len);
1175  OPENSSL_free(decimal);
1176  }
1177  else
1178  ptr[0] = '\0';
1179 }
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 1143 of file be-secure-openssl.c.

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart().

1144 {
1145  if (port->peer)
1146  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1147  else
1148  ptr[0] = '\0';
1149 }
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 1125 of file be-secure-openssl.c.

Referenced by PerformAuthentication(), and pgstat_bestart().

1126 {
1127  if (port->ssl)
1128  return SSL_get_version(port->ssl);
1129  else
1130  return NULL;
1131 }

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

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

82 {
83  STACK_OF(X509_NAME) * root_cert_list = NULL;
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  * We use SSLv23_method() because it can negotiate use of the highest
103  * mutually supported protocol version, while alternatives like
104  * TLSv1_2_method() permit only one specific version. Note that we don't
105  * actually allow SSL v2 or v3, only TLS protocols (see below).
106  */
107  context = SSL_CTX_new(SSLv23_method());
108  if (!context)
109  {
110  ereport(isServerStart ? FATAL : LOG,
111  (errmsg("could not create SSL context: %s",
112  SSLerrmessage(ERR_get_error()))));
113  goto error;
114  }
115 
116  /*
117  * Disable OpenSSL's moving-write-buffer sanity check, because it causes
118  * unnecessary failures in nonblocking send cases.
119  */
120  SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
121 
122  /*
123  * Call init hook (usually to set password callback)
124  */
125  (*openssl_tls_init_hook) (context, isServerStart);
126 
127  /* used by the callback */
128  ssl_is_server_start = isServerStart;
129 
130  /*
131  * Load and verify server's certificate and private key
132  */
133  if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
134  {
135  ereport(isServerStart ? FATAL : LOG,
136  (errcode(ERRCODE_CONFIG_FILE_ERROR),
137  errmsg("could not load server certificate file \"%s\": %s",
138  ssl_cert_file, SSLerrmessage(ERR_get_error()))));
139  goto error;
140  }
141 
142  if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
143  goto error;
144 
145  /*
146  * OK, try to load the private key file.
147  */
149 
150  if (SSL_CTX_use_PrivateKey_file(context,
151  ssl_key_file,
152  SSL_FILETYPE_PEM) != 1)
153  {
155  ereport(isServerStart ? FATAL : LOG,
156  (errcode(ERRCODE_CONFIG_FILE_ERROR),
157  errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
158  ssl_key_file)));
159  else
160  ereport(isServerStart ? FATAL : LOG,
161  (errcode(ERRCODE_CONFIG_FILE_ERROR),
162  errmsg("could not load private key file \"%s\": %s",
163  ssl_key_file, SSLerrmessage(ERR_get_error()))));
164  goto error;
165  }
166 
167  if (SSL_CTX_check_private_key(context) != 1)
168  {
169  ereport(isServerStart ? FATAL : LOG,
170  (errcode(ERRCODE_CONFIG_FILE_ERROR),
171  errmsg("check of private key failed: %s",
172  SSLerrmessage(ERR_get_error()))));
173  goto error;
174  }
175 
177  {
179 
180  if (ssl_ver_min == -1)
181  {
182  ereport(isServerStart ? FATAL : LOG,
183  (errmsg("\"%s\" setting \"%s\" not supported by this build",
184  "ssl_min_protocol_version",
185  GetConfigOption("ssl_min_protocol_version",
186  false, false))));
187  goto error;
188  }
189 
190  if (!SSL_CTX_set_min_proto_version(context, ssl_ver_min))
191  {
192  ereport(isServerStart ? FATAL : LOG,
193  (errmsg("could not set minimum SSL protocol version")));
194  goto error;
195  }
196  }
197 
199  {
201 
202  if (ssl_ver_max == -1)
203  {
204  ereport(isServerStart ? FATAL : LOG,
205  (errmsg("\"%s\" setting \"%s\" not supported by this build",
206  "ssl_max_protocol_version",
207  GetConfigOption("ssl_max_protocol_version",
208  false, false))));
209  goto error;
210  }
211 
212  if (!SSL_CTX_set_max_proto_version(context, ssl_ver_max))
213  {
214  ereport(isServerStart ? FATAL : LOG,
215  (errmsg("could not set maximum SSL protocol version")));
216  goto error;
217  }
218  }
219 
220  /* Check compatibility of min/max protocols */
223  {
224  /*
225  * No need to check for invalid values (-1) for each protocol number
226  * as the code above would have already generated an error.
227  */
228  if (ssl_ver_min > ssl_ver_max)
229  {
230  ereport(isServerStart ? FATAL : LOG,
231  (errmsg("could not set SSL protocol version range"),
232  errdetail("\"%s\" cannot be higher than \"%s\"",
233  "ssl_min_protocol_version",
234  "ssl_max_protocol_version")));
235  goto error;
236  }
237  }
238 
239  /* disallow SSL session tickets */
240  SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
241 
242  /* disallow SSL session caching, too */
243  SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
244 
245  /* set up ephemeral DH and ECDH keys */
246  if (!initialize_dh(context, isServerStart))
247  goto error;
248  if (!initialize_ecdh(context, isServerStart))
249  goto error;
250 
251  /* set up the allowed cipher list */
252  if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
253  {
254  ereport(isServerStart ? FATAL : LOG,
255  (errcode(ERRCODE_CONFIG_FILE_ERROR),
256  errmsg("could not set the cipher list (no valid ciphers available)")));
257  goto error;
258  }
259 
260  /* Let server choose order */
262  SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
263 
264  /*
265  * Load CA store, so we can verify client certificates if needed.
266  */
267  if (ssl_ca_file[0])
268  {
269  if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
270  (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
271  {
272  ereport(isServerStart ? FATAL : LOG,
273  (errcode(ERRCODE_CONFIG_FILE_ERROR),
274  errmsg("could not load root certificate file \"%s\": %s",
275  ssl_ca_file, SSLerrmessage(ERR_get_error()))));
276  goto error;
277  }
278  }
279 
280  /*----------
281  * Load the Certificate Revocation List (CRL).
282  * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
283  *----------
284  */
285  if (ssl_crl_file[0])
286  {
287  X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
288 
289  if (cvstore)
290  {
291  /* Set the flags to check against the complete CRL chain */
292  if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
293  {
294  X509_STORE_set_flags(cvstore,
295  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
296  }
297  else
298  {
299  ereport(isServerStart ? FATAL : LOG,
300  (errcode(ERRCODE_CONFIG_FILE_ERROR),
301  errmsg("could not load SSL certificate revocation list file \"%s\": %s",
302  ssl_crl_file, SSLerrmessage(ERR_get_error()))));
303  goto error;
304  }
305  }
306  }
307 
308  if (ssl_ca_file[0])
309  {
310  /*
311  * Always ask for SSL client cert, but don't fail if it's not
312  * presented. We might fail such connections later, depending on what
313  * we find in pg_hba.conf.
314  */
315  SSL_CTX_set_verify(context,
316  (SSL_VERIFY_PEER |
317  SSL_VERIFY_CLIENT_ONCE),
318  verify_cb);
319 
320  /*
321  * Tell OpenSSL to send the list of root certs we trust to clients in
322  * CertificateRequests. This lets a client with a keystore select the
323  * appropriate client certificate to send to us.
324  */
325  SSL_CTX_set_client_CA_list(context, root_cert_list);
326  }
327 
328  /*
329  * Success! Replace any existing SSL_context.
330  */
331  if (SSL_context)
332  SSL_CTX_free(SSL_context);
333 
334  SSL_context = context;
335 
336  /*
337  * Set flag to remember whether CA store has been loaded into SSL_context.
338  */
339  if (ssl_ca_file[0])
340  ssl_loaded_verify_locations = true;
341  else
342  ssl_loaded_verify_locations = false;
343 
344  return 0;
345 
346 error:
347  if (context)
348  SSL_CTX_free(context);
349  return -1;
350 }
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:7730
int errcode(int sqlerrcode)
Definition: elog.c:610
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:62
#define FATAL
Definition: elog.h:52
int errdetail(const char *fmt,...)
Definition: elog.c:957
static bool SSL_initialized
char * SSLCipherSuites
Definition: be-secure.c:54
static int verify_cb(int, X509_STORE_CTX *)
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:144
int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
int ssl_max_protocol_version
Definition: be-secure.c:63
int errmsg(const char *fmt,...)
Definition: elog.c:824
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:60
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 362 of file be-secure-openssl.c.

References Assert, COMMERROR, ereport, errcode(), errcode_for_socket_access(), errmsg(), info_cb(), MemoryContextAlloc(), my_SSL_set_fd(), MyLatch, Port::noblock, Port::peer_cert_valid, Port::peer_cn, pfree(), Port::sock, SSL_context, Port::ssl_in_use, 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().

363 {
364  int r;
365  int err;
366  int waitfor;
367  unsigned long ecode;
368 
369  Assert(!port->ssl);
370  Assert(!port->peer);
371 
372  if (!SSL_context)
373  {
375  (errcode(ERRCODE_PROTOCOL_VIOLATION),
376  errmsg("could not initialize SSL connection: SSL context not set up")));
377  return -1;
378  }
379 
380  if (!(port->ssl = SSL_new(SSL_context)))
381  {
383  (errcode(ERRCODE_PROTOCOL_VIOLATION),
384  errmsg("could not initialize SSL connection: %s",
385  SSLerrmessage(ERR_get_error()))));
386  return -1;
387  }
388  if (!my_SSL_set_fd(port, port->sock))
389  {
391  (errcode(ERRCODE_PROTOCOL_VIOLATION),
392  errmsg("could not set SSL socket: %s",
393  SSLerrmessage(ERR_get_error()))));
394  return -1;
395  }
396  port->ssl_in_use = true;
397 
398 aloop:
399 
400  /*
401  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
402  * queue. In general, the current thread's error queue must be empty
403  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
404  * not work reliably. An extension may have failed to clear the
405  * per-thread error queue following another call to an OpenSSL I/O
406  * routine.
407  */
408  ERR_clear_error();
409  r = SSL_accept(port->ssl);
410  if (r <= 0)
411  {
412  err = SSL_get_error(port->ssl, r);
413 
414  /*
415  * Other clients of OpenSSL in the backend may fail to call
416  * ERR_get_error(), but we always do, so as to not cause problems for
417  * OpenSSL clients that don't call ERR_clear_error() defensively. Be
418  * sure that this happens by calling now. SSL_get_error() relies on
419  * the OpenSSL per-thread error queue being intact, so this is the
420  * earliest possible point ERR_get_error() may be called.
421  */
422  ecode = ERR_get_error();
423  switch (err)
424  {
425  case SSL_ERROR_WANT_READ:
426  case SSL_ERROR_WANT_WRITE:
427  /* not allowed during connection establishment */
428  Assert(!port->noblock);
429 
430  /*
431  * No need to care about timeouts/interrupts here. At this
432  * point authentication_timeout still employs
433  * StartupPacketTimeoutHandler() which directly exits.
434  */
435  if (err == SSL_ERROR_WANT_READ)
437  else
439 
440  (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
442  goto aloop;
443  case SSL_ERROR_SYSCALL:
444  if (r < 0)
447  errmsg("could not accept SSL connection: %m")));
448  else
450  (errcode(ERRCODE_PROTOCOL_VIOLATION),
451  errmsg("could not accept SSL connection: EOF detected")));
452  break;
453  case SSL_ERROR_SSL:
455  (errcode(ERRCODE_PROTOCOL_VIOLATION),
456  errmsg("could not accept SSL connection: %s",
457  SSLerrmessage(ecode))));
458  break;
459  case SSL_ERROR_ZERO_RETURN:
461  (errcode(ERRCODE_PROTOCOL_VIOLATION),
462  errmsg("could not accept SSL connection: EOF detected")));
463  break;
464  default:
466  (errcode(ERRCODE_PROTOCOL_VIOLATION),
467  errmsg("unrecognized SSL error code: %d",
468  err)));
469  break;
470  }
471  return -1;
472  }
473 
474  /* Get client certificate, if available. */
475  port->peer = SSL_get_peer_certificate(port->ssl);
476 
477  /* and extract the Common Name from it. */
478  port->peer_cn = NULL;
479  port->peer_cert_valid = false;
480  if (port->peer != NULL)
481  {
482  int len;
483 
484  len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
485  NID_commonName, NULL, 0);
486  if (len != -1)
487  {
488  char *peer_cn;
489 
490  peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
491  r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
492  NID_commonName, peer_cn, len + 1);
493  peer_cn[len] = '\0';
494  if (r != len)
495  {
496  /* shouldn't happen */
497  pfree(peer_cn);
498  return -1;
499  }
500 
501  /*
502  * Reject embedded NULLs in certificate common name to prevent
503  * attacks like CVE-2009-4034.
504  */
505  if (len != strlen(peer_cn))
506  {
508  (errcode(ERRCODE_PROTOCOL_VIOLATION),
509  errmsg("SSL certificate's common name contains embedded null")));
510  pfree(peer_cn);
511  return -1;
512  }
513 
514  port->peer_cn = peer_cn;
515  }
516  port->peer_cert_valid = true;
517  }
518 
519  /* set up debugging/info callback */
520  SSL_CTX_set_info_callback(SSL_context, info_cb);
521 
522  return 0;
523 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
char * peer_cn
Definition: libpq-be.h:191
bool peer_cert_valid
Definition: libpq-be.h:192
static void info_cb(const SSL *ssl, int type, int args)
int errcode(int sqlerrcode)
Definition: elog.c:610
bool ssl_in_use
Definition: libpq-be.h:190
#define WL_SOCKET_READABLE
Definition: latch.h:125
pgsocket sock
Definition: libpq-be.h:122
void pfree(void *pointer)
Definition: mcxt.c:1056
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:390
MemoryContext TopMemoryContext
Definition: mcxt.c:44
int errcode_for_socket_access(void)
Definition: elog.c:704
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:738
bool noblock
Definition: libpq-be.h:123
int errmsg(const char *fmt,...)
Definition: elog.c:824
static SSL_CTX * SSL_context
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:796
static const char * SSLerrmessage(unsigned long ecode)
struct Latch * MyLatch
Definition: globals.c:54
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:129

◆ be_tls_read()

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

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

551 {
552  ssize_t n;
553  int err;
554  unsigned long ecode;
555 
556  errno = 0;
557  ERR_clear_error();
558  n = SSL_read(port->ssl, ptr, len);
559  err = SSL_get_error(port->ssl, n);
560  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
561  switch (err)
562  {
563  case SSL_ERROR_NONE:
564  /* a-ok */
565  break;
566  case SSL_ERROR_WANT_READ:
567  *waitfor = WL_SOCKET_READABLE;
568  errno = EWOULDBLOCK;
569  n = -1;
570  break;
571  case SSL_ERROR_WANT_WRITE:
572  *waitfor = WL_SOCKET_WRITEABLE;
573  errno = EWOULDBLOCK;
574  n = -1;
575  break;
576  case SSL_ERROR_SYSCALL:
577  /* leave it to caller to ereport the value of errno */
578  if (n != -1)
579  {
580  errno = ECONNRESET;
581  n = -1;
582  }
583  break;
584  case SSL_ERROR_SSL:
586  (errcode(ERRCODE_PROTOCOL_VIOLATION),
587  errmsg("SSL error: %s", SSLerrmessage(ecode))));
588  errno = ECONNRESET;
589  n = -1;
590  break;
591  case SSL_ERROR_ZERO_RETURN:
592  /* connection was cleanly shut down by peer */
593  n = 0;
594  break;
595  default:
597  (errcode(ERRCODE_PROTOCOL_VIOLATION),
598  errmsg("unrecognized SSL error code: %d",
599  err)));
600  errno = ECONNRESET;
601  n = -1;
602  break;
603  }
604 
605  return n;
606 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
int errcode(int sqlerrcode)
Definition: elog.c:610
#define WL_SOCKET_READABLE
Definition: latch.h:125
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:144
#define ECONNRESET
Definition: win32_port.h:333
int errmsg(const char *fmt,...)
Definition: elog.c:824
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:329

◆ be_tls_write()

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

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

610 {
611  ssize_t n;
612  int err;
613  unsigned long ecode;
614 
615  errno = 0;
616  ERR_clear_error();
617  n = SSL_write(port->ssl, ptr, len);
618  err = SSL_get_error(port->ssl, n);
619  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
620  switch (err)
621  {
622  case SSL_ERROR_NONE:
623  /* a-ok */
624  break;
625  case SSL_ERROR_WANT_READ:
626  *waitfor = WL_SOCKET_READABLE;
627  errno = EWOULDBLOCK;
628  n = -1;
629  break;
630  case SSL_ERROR_WANT_WRITE:
631  *waitfor = WL_SOCKET_WRITEABLE;
632  errno = EWOULDBLOCK;
633  n = -1;
634  break;
635  case SSL_ERROR_SYSCALL:
636  /* leave it to caller to ereport the value of errno */
637  if (n != -1)
638  {
639  errno = ECONNRESET;
640  n = -1;
641  }
642  break;
643  case SSL_ERROR_SSL:
645  (errcode(ERRCODE_PROTOCOL_VIOLATION),
646  errmsg("SSL error: %s", SSLerrmessage(ecode))));
647  errno = ECONNRESET;
648  n = -1;
649  break;
650  case SSL_ERROR_ZERO_RETURN:
651 
652  /*
653  * the SSL connection was closed, leave it to the caller to
654  * ereport it
655  */
656  errno = ECONNRESET;
657  n = -1;
658  break;
659  default:
661  (errcode(ERRCODE_PROTOCOL_VIOLATION),
662  errmsg("unrecognized SSL error code: %d",
663  err)));
664  errno = ECONNRESET;
665  n = -1;
666  break;
667  }
668 
669  return n;
670 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
int errcode(int sqlerrcode)
Definition: elog.c:610
#define WL_SOCKET_READABLE
Definition: latch.h:125
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel,...)
Definition: elog.h:144
#define ECONNRESET
Definition: win32_port.h:333
int errmsg(const char *fmt,...)
Definition: elog.c:824
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:329

◆ default_openssl_tls_init()

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

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

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

1334 {
1335  if (isServerStart)
1336  {
1337  if (ssl_passphrase_command[0])
1338  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1339  }
1340  else
1341  {
1343  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1344  else
1345 
1346  /*
1347  * If reloading and no external command is configured, override
1348  * OpenSSL's default handling of passphrase-protected files,
1349  * because we don't want to prompt for a passphrase in an
1350  * already-running server.
1351  */
1352  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1353  }
1354 }
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:47
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
char * ssl_passphrase_command
Definition: be-secure.c:46
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 922 of file be-secure-openssl.c.

References Assert, and dummy_ssl_passwd_cb_called.

Referenced by default_openssl_tls_init().

923 {
924  /* Set flag to change the error message we'll report */
926  /* And return empty string */
927  Assert(size > 0);
928  buf[0] = '\0';
929  return 0;
930 }
static bool dummy_ssl_passwd_cb_called
static char * buf
Definition: pg_test_fsync.c:67
#define Assert(condition)
Definition: c.h:738

◆ info_cb()

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

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

References DEBUG4, ereport, and errmsg_internal().

Referenced by be_tls_open_server().

955 {
956  switch (type)
957  {
958  case SSL_CB_HANDSHAKE_START:
959  ereport(DEBUG4,
960  (errmsg_internal("SSL: handshake start")));
961  break;
962  case SSL_CB_HANDSHAKE_DONE:
963  ereport(DEBUG4,
964  (errmsg_internal("SSL: handshake done")));
965  break;
966  case SSL_CB_ACCEPT_LOOP:
967  ereport(DEBUG4,
968  (errmsg_internal("SSL: accept loop")));
969  break;
970  case SSL_CB_ACCEPT_EXIT:
971  ereport(DEBUG4,
972  (errmsg_internal("SSL: accept exit (%d)", args)));
973  break;
974  case SSL_CB_CONNECT_LOOP:
975  ereport(DEBUG4,
976  (errmsg_internal("SSL: connect loop")));
977  break;
978  case SSL_CB_CONNECT_EXIT:
979  ereport(DEBUG4,
980  (errmsg_internal("SSL: connect exit (%d)", args)));
981  break;
982  case SSL_CB_READ_ALERT:
983  ereport(DEBUG4,
984  (errmsg_internal("SSL: read alert (0x%04x)", args)));
985  break;
986  case SSL_CB_WRITE_ALERT:
987  ereport(DEBUG4,
988  (errmsg_internal("SSL: write alert (0x%04x)", args)));
989  break;
990  }
991 }
#define DEBUG4
Definition: elog.h:22
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg_internal(const char *fmt,...)
Definition: elog.c:911

◆ initialize_dh()

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

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

1008 {
1009  DH *dh = NULL;
1010 
1011  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1012 
1013  if (ssl_dh_params_file[0])
1014  dh = load_dh_file(ssl_dh_params_file, isServerStart);
1015  if (!dh)
1016  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1017  if (!dh)
1018  {
1019  ereport(isServerStart ? FATAL : LOG,
1020  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1021  errmsg("DH: could not load DH parameters")));
1022  return false;
1023  }
1024 
1025  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1026  {
1027  ereport(isServerStart ? FATAL : LOG,
1028  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1029  errmsg("DH: could not set DH parameters: %s",
1030  SSLerrmessage(ERR_get_error()))));
1031  DH_free(dh);
1032  return false;
1033  }
1034 
1035  DH_free(dh);
1036  return true;
1037 }
static DH * load_dh_file(char *filename, bool isServerStart)
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
static DH * load_dh_buffer(const char *, size_t)
#define ereport(elevel,...)
Definition: elog.h:144
char * ssl_dh_params_file
Definition: be-secure.c:45
int errmsg(const char *fmt,...)
Definition: elog.c:824
static const char * SSLerrmessage(unsigned long ecode)

◆ initialize_ecdh()

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

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

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

Referenced by be_tls_init().

1046 {
1047 #ifndef OPENSSL_NO_ECDH
1048  EC_KEY *ecdh;
1049  int nid;
1050 
1051  nid = OBJ_sn2nid(SSLECDHCurve);
1052  if (!nid)
1053  {
1054  ereport(isServerStart ? FATAL : LOG,
1055  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1056  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1057  return false;
1058  }
1059 
1060  ecdh = EC_KEY_new_by_curve_name(nid);
1061  if (!ecdh)
1062  {
1063  ereport(isServerStart ? FATAL : LOG,
1064  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1065  errmsg("ECDH: could not create key")));
1066  return false;
1067  }
1068 
1069  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1070  SSL_CTX_set_tmp_ecdh(context, ecdh);
1071  EC_KEY_free(ecdh);
1072 #endif
1073 
1074  return true;
1075 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
char * SSLECDHCurve
Definition: be-secure.c:57
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ load_dh_buffer()

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

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

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

Referenced by initialize_dh().

881 {
882  BIO *bio;
883  DH *dh = NULL;
884 
885  bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
886  if (bio == NULL)
887  return NULL;
888  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
889  if (dh == NULL)
890  ereport(DEBUG2,
891  (errmsg_internal("DH load buffer: %s",
892  SSLerrmessage(ERR_get_error()))));
893  BIO_free(bio);
894 
895  return dh;
896 }
#define DEBUG2
Definition: elog.h:24
#define unconstify(underlying_type, expr)
Definition: c.h:1206
#define ereport(elevel,...)
Definition: elog.h:144
int errmsg_internal(const char *fmt,...)
Definition: elog.c:911
static const char * SSLerrmessage(unsigned long ecode)

◆ load_dh_file()

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

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

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

Referenced by initialize_dh().

817 {
818  FILE *fp;
819  DH *dh = NULL;
820  int codes;
821 
822  /* attempt to open file. It's not an error if it doesn't exist. */
823  if ((fp = AllocateFile(filename, "r")) == NULL)
824  {
825  ereport(isServerStart ? FATAL : LOG,
827  errmsg("could not open DH parameters file \"%s\": %m",
828  filename)));
829  return NULL;
830  }
831 
832  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
833  FreeFile(fp);
834 
835  if (dh == NULL)
836  {
837  ereport(isServerStart ? FATAL : LOG,
838  (errcode(ERRCODE_CONFIG_FILE_ERROR),
839  errmsg("could not load DH parameters file: %s",
840  SSLerrmessage(ERR_get_error()))));
841  return NULL;
842  }
843 
844  /* make sure the DH parameters are usable */
845  if (DH_check(dh, &codes) == 0)
846  {
847  ereport(isServerStart ? FATAL : LOG,
848  (errcode(ERRCODE_CONFIG_FILE_ERROR),
849  errmsg("invalid DH parameters: %s",
850  SSLerrmessage(ERR_get_error()))));
851  return NULL;
852  }
853  if (codes & DH_CHECK_P_NOT_PRIME)
854  {
855  ereport(isServerStart ? FATAL : LOG,
856  (errcode(ERRCODE_CONFIG_FILE_ERROR),
857  errmsg("invalid DH parameters: p is not prime")));
858  return NULL;
859  }
860  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
861  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
862  {
863  ereport(isServerStart ? FATAL : LOG,
864  (errcode(ERRCODE_CONFIG_FILE_ERROR),
865  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
866  return NULL;
867  }
868 
869  return dh;
870 }
int errcode(int sqlerrcode)
Definition: elog.c:610
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
int errcode_for_file_access(void)
Definition: elog.c:633
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2320
#define ereport(elevel,...)
Definition: elog.h:144
int FreeFile(FILE *file)
Definition: fd.c:2519
static char * filename
Definition: pg_dumpall.c:90
int errmsg(const char *fmt,...)
Definition: elog.c:824
static const char * SSLerrmessage(unsigned long ecode)

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

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

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

Referenced by my_SSL_set_fd().

740 {
741  if (!my_bio_methods)
742  {
743  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
744 #ifdef HAVE_BIO_METH_NEW
745  int my_bio_index;
746 
747  my_bio_index = BIO_get_new_index();
748  if (my_bio_index == -1)
749  return NULL;
750  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
751  if (!my_bio_methods)
752  return NULL;
753  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
754  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
755  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
756  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
757  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
758  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
759  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
760  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
761  {
762  BIO_meth_free(my_bio_methods);
763  my_bio_methods = NULL;
764  return NULL;
765  }
766 #else
767  my_bio_methods = malloc(sizeof(BIO_METHOD));
768  if (!my_bio_methods)
769  return NULL;
770  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
771  my_bio_methods->bread = my_sock_read;
772  my_bio_methods->bwrite = my_sock_write;
773 #endif
774  }
775  return my_bio_methods;
776 }
#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 698 of file be-secure-openssl.c.

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

Referenced by my_BIO_s_socket().

699 {
700  int res = 0;
701 
702  if (buf != NULL)
703  {
704  res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
705  BIO_clear_retry_flags(h);
706  if (res <= 0)
707  {
708  /* If we were interrupted, tell caller to retry */
709  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
710  {
711  BIO_set_retry_read(h);
712  }
713  }
714  }
715 
716  return res;
717 }
#define EAGAIN
Definition: win32_port.h:321
#define BIO_get_data(bio)
Definition: libpq-be.h:120
static char * buf
Definition: pg_test_fsync.c:67
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:234
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323

◆ my_sock_write()

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

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

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

Referenced by my_BIO_s_socket().

721 {
722  int res = 0;
723 
724  res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
725  BIO_clear_retry_flags(h);
726  if (res <= 0)
727  {
728  /* If we were interrupted, tell caller to retry */
729  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
730  {
731  BIO_set_retry_write(h);
732  }
733  }
734 
735  return res;
736 }
#define EAGAIN
Definition: win32_port.h:321
#define BIO_get_data(bio)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:330
Definition: libpq-be.h:120
static char * buf
Definition: pg_test_fsync.c:67
#define EWOULDBLOCK
Definition: win32_port.h:329
#define EINTR
Definition: win32_port.h:323

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( Port port,
int  fd 
)
static

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

References BIO_set_data, and my_BIO_s_socket().

Referenced by be_tls_open_server().

781 {
782  int ret = 0;
783  BIO *bio;
784  BIO_METHOD *bio_method;
785 
786  bio_method = my_BIO_s_socket();
787  if (bio_method == NULL)
788  {
789  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
790  goto err;
791  }
792  bio = BIO_new(bio_method);
793 
794  if (bio == NULL)
795  {
796  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
797  goto err;
798  }
799  BIO_set_data(bio, port);
800 
801  BIO_set_fd(bio, fd, BIO_NOCLOSE);
802  SSL_set_bio(port->ssl, bio, bio);
803  ret = 1;
804 err:
805  return ret;
806 }
#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 902 of file be-secure-openssl.c.

References Assert, run_ssl_passphrase_command(), and ssl_is_server_start.

Referenced by default_openssl_tls_init().

903 {
904  /* same prompt as OpenSSL uses internally */
905  const char *prompt = "Enter PEM pass phrase:";
906 
907  Assert(rwflag == 0);
908 
909  return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
910 }
static char * buf
Definition: pg_test_fsync.c:67
static bool ssl_is_server_start
#define Assert(condition)
Definition: c.h:738
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 1300 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().

1301 {
1302  switch (v)
1303  {
1304  case PG_TLS_ANY:
1305  return 0;
1306  case PG_TLS1_VERSION:
1307  return TLS1_VERSION;
1308  case PG_TLS1_1_VERSION:
1309 #ifdef TLS1_1_VERSION
1310  return TLS1_1_VERSION;
1311 #else
1312  break;
1313 #endif
1314  case PG_TLS1_2_VERSION:
1315 #ifdef TLS1_2_VERSION
1316  return TLS1_2_VERSION;
1317 #else
1318  break;
1319 #endif
1320  case PG_TLS1_3_VERSION:
1321 #ifdef TLS1_3_VERSION
1322  return TLS1_3_VERSION;
1323 #else
1324  break;
1325 #endif
1326  }
1327 
1328  return -1;
1329 }

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

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

1088 {
1089  const char *errreason;
1090  static char errbuf[36];
1091 
1092  if (ecode == 0)
1093  return _("no SSL error reported");
1094  errreason = ERR_reason_error_string(ecode);
1095  if (errreason != NULL)
1096  return errreason;
1097  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1098  return errbuf;
1099 }
#define snprintf
Definition: port.h:193
#define _(x)
Definition: elog.c:88

◆ verify_cb()

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

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

Referenced by be_tls_init().

945 {
946  return ok;
947 }

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

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

References 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().

1243 {
1244  BIO *membuf = BIO_new(BIO_s_mem());
1245  int i,
1246  nid,
1247  count = X509_NAME_entry_count(name);
1248  X509_NAME_ENTRY *e;
1249  ASN1_STRING *v;
1250  const char *field_name;
1251  size_t size;
1252  char nullterm;
1253  char *sp;
1254  char *dp;
1255  char *result;
1256 
1257  (void) BIO_set_close(membuf, BIO_CLOSE);
1258  for (i = 0; i < count; i++)
1259  {
1260  e = X509_NAME_get_entry(name, i);
1261  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1262  v = X509_NAME_ENTRY_get_data(e);
1263  field_name = OBJ_nid2sn(nid);
1264  if (!field_name)
1265  field_name = OBJ_nid2ln(nid);
1266  BIO_printf(membuf, "/%s=", field_name);
1267  ASN1_STRING_print_ex(membuf, v,
1268  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1269  | ASN1_STRFLGS_UTF8_CONVERT));
1270  }
1271 
1272  /* ensure null termination of the BIO's content */
1273  nullterm = '\0';
1274  BIO_write(membuf, &nullterm, 1);
1275  size = BIO_get_mem_data(membuf, &sp);
1276  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1277 
1278  result = pstrdup(dp);
1279  if (dp != sp)
1280  pfree(dp);
1281  BIO_free(membuf);
1282 
1283  return result;
1284 }
char * pstrdup(const char *in)
Definition: mcxt.c:1186
void pfree(void *pointer)
Definition: mcxt.c:1056
const char * name
Definition: encode.c:555
e
Definition: preproc-init.c:82
int i
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:619

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 695 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().