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 "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 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)
 
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_peerdn_name (Port *port, char *ptr, size_t len)
 
char * be_tls_get_peer_finished (Port *port, size_t *len)
 
char * be_tls_get_certificate_hash (Port *port, size_t *len)
 

Variables

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 652 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 653 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 487 of file be-secure-openssl.c.

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

Referenced by secure_close().

488 {
489  if (port->ssl)
490  {
491  SSL_shutdown(port->ssl);
492  SSL_free(port->ssl);
493  port->ssl = NULL;
494  port->ssl_in_use = false;
495  }
496 
497  if (port->peer)
498  {
499  X509_free(port->peer);
500  port->peer = NULL;
501  }
502 
503  if (port->peer_cn)
504  {
505  pfree(port->peer_cn);
506  port->peer_cn = NULL;
507  }
508 }
char * peer_cn
Definition: libpq-be.h:182
bool ssl_in_use
Definition: libpq-be.h:181
void pfree(void *pointer)
Definition: mcxt.c:1031

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

References SSL_context, and ssl_loaded_verify_locations.

Referenced by secure_destroy().

315 {
316  if (SSL_context)
317  SSL_CTX_free(SSL_context);
318  SSL_context = NULL;
320 }
bool ssl_loaded_verify_locations
static SSL_CTX * SSL_context

◆ be_tls_get_certificate_hash()

char* be_tls_get_certificate_hash ( Port port,
size_t *  len 
)

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

References elog, ereport, errcode(), errmsg(), ERROR, hash(), and palloc().

Referenced by read_client_final_message().

1128 {
1129 #ifdef HAVE_X509_GET_SIGNATURE_NID
1130  X509 *server_cert;
1131  char *cert_hash;
1132  const EVP_MD *algo_type = NULL;
1133  unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
1134  unsigned int hash_size;
1135  int algo_nid;
1136 
1137  *len = 0;
1138  server_cert = SSL_get_certificate(port->ssl);
1139  if (server_cert == NULL)
1140  return NULL;
1141 
1142  /*
1143  * Get the signature algorithm of the certificate to determine the hash
1144  * algorithm to use for the result.
1145  */
1146  if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
1147  &algo_nid, NULL))
1148  elog(ERROR, "could not determine server certificate signature algorithm");
1149 
1150  /*
1151  * The TLS server's certificate bytes need to be hashed with SHA-256 if
1152  * its signature algorithm is MD5 or SHA-1 as per RFC 5929
1153  * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
1154  * is used, the same hash as the signature algorithm is used.
1155  */
1156  switch (algo_nid)
1157  {
1158  case NID_md5:
1159  case NID_sha1:
1160  algo_type = EVP_sha256();
1161  break;
1162  default:
1163  algo_type = EVP_get_digestbynid(algo_nid);
1164  if (algo_type == NULL)
1165  elog(ERROR, "could not find digest for NID %s",
1166  OBJ_nid2sn(algo_nid));
1167  break;
1168  }
1169 
1170  /* generate and save the certificate hash */
1171  if (!X509_digest(server_cert, algo_type, hash, &hash_size))
1172  elog(ERROR, "could not generate server certificate hash");
1173 
1174  cert_hash = palloc(hash_size);
1175  memcpy(cert_hash, hash, hash_size);
1176  *len = hash_size;
1177 
1178  return cert_hash;
1179 #else
1180  ereport(ERROR,
1181  (errcode(ERRCODE_PROTOCOL_VIOLATION),
1182  errmsg("channel binding type \"tls-server-end-point\" is not supported by this build")));
1183  return NULL;
1184 #endif
1185 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void * palloc(Size size)
Definition: mcxt.c:924
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define elog
Definition: elog.h:219
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:541

◆ be_tls_get_cipher()

const char* be_tls_get_cipher ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1092 {
1093  if (port->ssl)
1094  return SSL_get_cipher(port->ssl);
1095  else
1096  return NULL;
1097 }

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

Referenced by PerformAuthentication(), and pgstat_bestart().

1060 {
1061  int bits;
1062 
1063  if (port->ssl)
1064  {
1065  SSL_get_cipher_bits(port->ssl, &bits);
1066  return bits;
1067  }
1068  else
1069  return 0;
1070 }

◆ be_tls_get_compression()

bool be_tls_get_compression ( Port port)

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

References SSL_get_current_compression.

Referenced by PerformAuthentication(), and pgstat_bestart().

1074 {
1075  if (port->ssl)
1076  return (SSL_get_current_compression(port->ssl) != NULL);
1077  else
1078  return false;
1079 }
#define SSL_get_current_compression(x)
Definition: port.h:400

◆ be_tls_get_peer_finished()

char* be_tls_get_peer_finished ( Port port,
size_t *  len 
)

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

References palloc().

Referenced by read_client_final_message().

1110 {
1111  char dummy[1];
1112  char *result;
1113 
1114  /*
1115  * OpenSSL does not offer an API to directly get the length of the
1116  * expected TLS Finished message, so just do a dummy call to grab this
1117  * information to allow caller to do an allocation with a correct size.
1118  */
1119  *len = SSL_get_peer_finished(port->ssl, dummy, sizeof(dummy));
1120  result = palloc(*len);
1121  (void) SSL_get_peer_finished(port->ssl, result, *len);
1122 
1123  return result;
1124 }
void * palloc(Size size)
Definition: mcxt.c:924

◆ be_tls_get_peerdn_name()

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

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

References strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart().

1101 {
1102  if (port->peer)
1103  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1104  else
1105  ptr[0] = '\0';
1106 }
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 1082 of file be-secure-openssl.c.

Referenced by PerformAuthentication(), and pgstat_bestart().

1083 {
1084  if (port->ssl)
1085  return SSL_get_version(port->ssl);
1086  else
1087  return NULL;
1088 }

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

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

References check_ssl_key_file_permissions(), dummy_ssl_passwd_cb(), dummy_ssl_passwd_cb_called, ereport, errcode(), errdetail(), errmsg(), error(), FATAL, initialize_dh(), initialize_ecdh(), LOG, ssl_ca_file, ssl_cert_file, SSL_context, ssl_crl_file, ssl_external_passwd_cb(), SSL_initialized, ssl_is_server_start, ssl_key_file, ssl_loaded_verify_locations, ssl_passphrase_command, ssl_passphrase_command_supports_reload, SSLCipherSuites, SSLerrmessage(), SSLPreferServerCiphers, and verify_cb().

Referenced by secure_initialize().

77 {
78  STACK_OF(X509_NAME) *root_cert_list = NULL;
79  SSL_CTX *context;
80 
81  /* This stuff need be done only once. */
82  if (!SSL_initialized)
83  {
84 #ifdef HAVE_OPENSSL_INIT_SSL
85  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
86 #else
87  OPENSSL_config(NULL);
88  SSL_library_init();
89  SSL_load_error_strings();
90 #endif
91  SSL_initialized = true;
92  }
93 
94  /*
95  * We use SSLv23_method() because it can negotiate use of the highest
96  * mutually supported protocol version, while alternatives like
97  * TLSv1_2_method() permit only one specific version. Note that we don't
98  * actually allow SSL v2 or v3, only TLS protocols (see below).
99  */
100  context = SSL_CTX_new(SSLv23_method());
101  if (!context)
102  {
103  ereport(isServerStart ? FATAL : LOG,
104  (errmsg("could not create SSL context: %s",
105  SSLerrmessage(ERR_get_error()))));
106  goto error;
107  }
108 
109  /*
110  * Disable OpenSSL's moving-write-buffer sanity check, because it causes
111  * unnecessary failures in nonblocking send cases.
112  */
113  SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
114 
115  /*
116  * Set password callback
117  */
118  if (isServerStart)
119  {
120  if (ssl_passphrase_command[0])
121  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
122  }
123  else
124  {
126  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
127  else
128 
129  /*
130  * If reloading and no external command is configured, override
131  * OpenSSL's default handling of passphrase-protected files,
132  * because we don't want to prompt for a passphrase in an
133  * already-running server.
134  */
135  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
136  }
137  /* used by the callback */
138  ssl_is_server_start = isServerStart;
139 
140  /*
141  * Load and verify server's certificate and private key
142  */
143  if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
144  {
145  ereport(isServerStart ? FATAL : LOG,
146  (errcode(ERRCODE_CONFIG_FILE_ERROR),
147  errmsg("could not load server certificate file \"%s\": %s",
148  ssl_cert_file, SSLerrmessage(ERR_get_error()))));
149  goto error;
150  }
151 
152  if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
153  goto error;
154 
155  /*
156  * OK, try to load the private key file.
157  */
159 
160  if (SSL_CTX_use_PrivateKey_file(context,
161  ssl_key_file,
162  SSL_FILETYPE_PEM) != 1)
163  {
165  ereport(isServerStart ? FATAL : LOG,
166  (errcode(ERRCODE_CONFIG_FILE_ERROR),
167  errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
168  ssl_key_file)));
169  else
170  ereport(isServerStart ? FATAL : LOG,
171  (errcode(ERRCODE_CONFIG_FILE_ERROR),
172  errmsg("could not load private key file \"%s\": %s",
173  ssl_key_file, SSLerrmessage(ERR_get_error()))));
174  goto error;
175  }
176 
177  if (SSL_CTX_check_private_key(context) != 1)
178  {
179  ereport(isServerStart ? FATAL : LOG,
180  (errcode(ERRCODE_CONFIG_FILE_ERROR),
181  errmsg("check of private key failed: %s",
182  SSLerrmessage(ERR_get_error()))));
183  goto error;
184  }
185 
186  /* disallow SSL v2/v3 */
187  SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
188 
189  /* disallow SSL session tickets */
190 #ifdef SSL_OP_NO_TICKET /* added in openssl 0.9.8f */
191  SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
192 #endif
193 
194  /* disallow SSL session caching, too */
195  SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
196 
197  /* set up ephemeral DH and ECDH keys */
198  if (!initialize_dh(context, isServerStart))
199  goto error;
200  if (!initialize_ecdh(context, isServerStart))
201  goto error;
202 
203  /* set up the allowed cipher list */
204  if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
205  {
206  ereport(isServerStart ? FATAL : LOG,
207  (errcode(ERRCODE_CONFIG_FILE_ERROR),
208  errmsg("could not set the cipher list (no valid ciphers available)")));
209  goto error;
210  }
211 
212  /* Let server choose order */
214  SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
215 
216  /*
217  * Load CA store, so we can verify client certificates if needed.
218  */
219  if (ssl_ca_file[0])
220  {
221  if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
222  (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
223  {
224  ereport(isServerStart ? FATAL : LOG,
225  (errcode(ERRCODE_CONFIG_FILE_ERROR),
226  errmsg("could not load root certificate file \"%s\": %s",
227  ssl_ca_file, SSLerrmessage(ERR_get_error()))));
228  goto error;
229  }
230  }
231 
232  /*----------
233  * Load the Certificate Revocation List (CRL).
234  * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
235  *----------
236  */
237  if (ssl_crl_file[0])
238  {
239  X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
240 
241  if (cvstore)
242  {
243  /* Set the flags to check against the complete CRL chain */
244  if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
245  {
246  /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
247 #ifdef X509_V_FLAG_CRL_CHECK
248  X509_STORE_set_flags(cvstore,
249  X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
250 #else
251  ereport(LOG,
252  (errcode(ERRCODE_CONFIG_FILE_ERROR),
253  errmsg("SSL certificate revocation list file \"%s\" ignored",
254  ssl_crl_file),
255  errdetail("SSL library does not support certificate revocation lists.")));
256 #endif
257  }
258  else
259  {
260  ereport(isServerStart ? FATAL : LOG,
261  (errcode(ERRCODE_CONFIG_FILE_ERROR),
262  errmsg("could not load SSL certificate revocation list file \"%s\": %s",
263  ssl_crl_file, SSLerrmessage(ERR_get_error()))));
264  goto error;
265  }
266  }
267  }
268 
269  if (ssl_ca_file[0])
270  {
271  /*
272  * Always ask for SSL client cert, but don't fail if it's not
273  * presented. We might fail such connections later, depending on what
274  * we find in pg_hba.conf.
275  */
276  SSL_CTX_set_verify(context,
277  (SSL_VERIFY_PEER |
278  SSL_VERIFY_CLIENT_ONCE),
279  verify_cb);
280 
281  /*
282  * Tell OpenSSL to send the list of root certs we trust to clients in
283  * CertificateRequests. This lets a client with a keystore select the
284  * appropriate client certificate to send to us.
285  */
286  SSL_CTX_set_client_CA_list(context, root_cert_list);
287  }
288 
289  /*
290  * Success! Replace any existing SSL_context.
291  */
292  if (SSL_context)
293  SSL_CTX_free(SSL_context);
294 
295  SSL_context = context;
296 
297  /*
298  * Set flag to remember whether CA store has been loaded into SSL_context.
299  */
300  if (ssl_ca_file[0])
302  else
304 
305  return 0;
306 
307 error:
308  if (context)
309  SSL_CTX_free(context);
310  return -1;
311 }
static void error(void)
Definition: sql-dyntest.c:147
static bool dummy_ssl_passwd_cb_called
bool ssl_loaded_verify_locations
int errcode(int sqlerrcode)
Definition: elog.c:575
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
#define FATAL
Definition: elog.h:52
int errdetail(const char *fmt,...)
Definition: elog.c:873
static bool SSL_initialized
char * SSLCipherSuites
Definition: be-secure.c:54
static int verify_cb(int, X509_STORE_CTX *)
#define ereport(elevel, rest)
Definition: elog.h:122
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)
static bool ssl_is_server_start
static bool initialize_dh(SSL_CTX *context, bool isServerStart)
char * ssl_ca_file
Definition: be-secure.c:43
int errmsg(const char *fmt,...)
Definition: elog.c:797
static SSL_CTX * SSL_context
static const char * SSLerrmessage(unsigned long ecode)
char * ssl_passphrase_command
Definition: be-secure.c:46
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
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 323 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_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_open_server().

324 {
325  int r;
326  int err;
327  int waitfor;
328  unsigned long ecode;
329 
330  Assert(!port->ssl);
331  Assert(!port->peer);
332 
333  if (!SSL_context)
334  {
336  (errcode(ERRCODE_PROTOCOL_VIOLATION),
337  errmsg("could not initialize SSL connection: SSL context not set up")));
338  return -1;
339  }
340 
341  if (!(port->ssl = SSL_new(SSL_context)))
342  {
344  (errcode(ERRCODE_PROTOCOL_VIOLATION),
345  errmsg("could not initialize SSL connection: %s",
346  SSLerrmessage(ERR_get_error()))));
347  return -1;
348  }
349  if (!my_SSL_set_fd(port, port->sock))
350  {
352  (errcode(ERRCODE_PROTOCOL_VIOLATION),
353  errmsg("could not set SSL socket: %s",
354  SSLerrmessage(ERR_get_error()))));
355  return -1;
356  }
357  port->ssl_in_use = true;
358 
359 aloop:
360 
361  /*
362  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
363  * queue. In general, the current thread's error queue must be empty
364  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
365  * not work reliably. An extension may have failed to clear the
366  * per-thread error queue following another call to an OpenSSL I/O
367  * routine.
368  */
369  ERR_clear_error();
370  r = SSL_accept(port->ssl);
371  if (r <= 0)
372  {
373  err = SSL_get_error(port->ssl, r);
374 
375  /*
376  * Other clients of OpenSSL in the backend may fail to call
377  * ERR_get_error(), but we always do, so as to not cause problems for
378  * OpenSSL clients that don't call ERR_clear_error() defensively. Be
379  * sure that this happens by calling now. SSL_get_error() relies on
380  * the OpenSSL per-thread error queue being intact, so this is the
381  * earliest possible point ERR_get_error() may be called.
382  */
383  ecode = ERR_get_error();
384  switch (err)
385  {
386  case SSL_ERROR_WANT_READ:
387  case SSL_ERROR_WANT_WRITE:
388  /* not allowed during connection establishment */
389  Assert(!port->noblock);
390 
391  /*
392  * No need to care about timeouts/interrupts here. At this
393  * point authentication_timeout still employs
394  * StartupPacketTimeoutHandler() which directly exits.
395  */
396  if (err == SSL_ERROR_WANT_READ)
397  waitfor = WL_SOCKET_READABLE;
398  else
399  waitfor = WL_SOCKET_WRITEABLE;
400 
401  WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
403  goto aloop;
404  case SSL_ERROR_SYSCALL:
405  if (r < 0)
408  errmsg("could not accept SSL connection: %m")));
409  else
411  (errcode(ERRCODE_PROTOCOL_VIOLATION),
412  errmsg("could not accept SSL connection: EOF detected")));
413  break;
414  case SSL_ERROR_SSL:
416  (errcode(ERRCODE_PROTOCOL_VIOLATION),
417  errmsg("could not accept SSL connection: %s",
418  SSLerrmessage(ecode))));
419  break;
420  case SSL_ERROR_ZERO_RETURN:
422  (errcode(ERRCODE_PROTOCOL_VIOLATION),
423  errmsg("could not accept SSL connection: EOF detected")));
424  break;
425  default:
427  (errcode(ERRCODE_PROTOCOL_VIOLATION),
428  errmsg("unrecognized SSL error code: %d",
429  err)));
430  break;
431  }
432  return -1;
433  }
434 
435  /* Get client certificate, if available. */
436  port->peer = SSL_get_peer_certificate(port->ssl);
437 
438  /* and extract the Common Name from it. */
439  port->peer_cn = NULL;
440  port->peer_cert_valid = false;
441  if (port->peer != NULL)
442  {
443  int len;
444 
445  len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
446  NID_commonName, NULL, 0);
447  if (len != -1)
448  {
449  char *peer_cn;
450 
451  peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
452  r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
453  NID_commonName, peer_cn, len + 1);
454  peer_cn[len] = '\0';
455  if (r != len)
456  {
457  /* shouldn't happen */
458  pfree(peer_cn);
459  return -1;
460  }
461 
462  /*
463  * Reject embedded NULLs in certificate common name to prevent
464  * attacks like CVE-2009-4034.
465  */
466  if (len != strlen(peer_cn))
467  {
469  (errcode(ERRCODE_PROTOCOL_VIOLATION),
470  errmsg("SSL certificate's common name contains embedded null")));
471  pfree(peer_cn);
472  return -1;
473  }
474 
475  port->peer_cn = peer_cn;
476  }
477  port->peer_cert_valid = true;
478  }
479 
480  /* set up debugging/info callback */
481  SSL_CTX_set_info_callback(SSL_context, info_cb);
482 
483  return 0;
484 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
char * peer_cn
Definition: libpq-be.h:182
bool peer_cert_valid
Definition: libpq-be.h:183
static void info_cb(const SSL *ssl, int type, int args)
int errcode(int sqlerrcode)
Definition: elog.c:575
bool ssl_in_use
Definition: libpq-be.h:181
#define WL_SOCKET_READABLE
Definition: latch.h:125
pgsocket sock
Definition: libpq-be.h:118
void pfree(void *pointer)
Definition: mcxt.c:1031
static int my_SSL_set_fd(Port *port, int fd)
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel, rest)
Definition: elog.h:122
MemoryContext TopMemoryContext
Definition: mcxt.c:44
int errcode_for_socket_access(void)
Definition: elog.c:669
#define Assert(condition)
Definition: c.h:699
int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:356
bool noblock
Definition: libpq-be.h:119
int errmsg(const char *fmt,...)
Definition: elog.c:797
static SSL_CTX * SSL_context
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:771
static const char * SSLerrmessage(unsigned long ecode)
struct Latch * MyLatch
Definition: globals.c:53

◆ be_tls_read()

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

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

512 {
513  ssize_t n;
514  int err;
515  unsigned long ecode;
516 
517  errno = 0;
518  ERR_clear_error();
519  n = SSL_read(port->ssl, ptr, len);
520  err = SSL_get_error(port->ssl, n);
521  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
522  switch (err)
523  {
524  case SSL_ERROR_NONE:
525  /* a-ok */
526  break;
527  case SSL_ERROR_WANT_READ:
528  *waitfor = WL_SOCKET_READABLE;
529  errno = EWOULDBLOCK;
530  n = -1;
531  break;
532  case SSL_ERROR_WANT_WRITE:
533  *waitfor = WL_SOCKET_WRITEABLE;
534  errno = EWOULDBLOCK;
535  n = -1;
536  break;
537  case SSL_ERROR_SYSCALL:
538  /* leave it to caller to ereport the value of errno */
539  if (n != -1)
540  {
541  errno = ECONNRESET;
542  n = -1;
543  }
544  break;
545  case SSL_ERROR_SSL:
547  (errcode(ERRCODE_PROTOCOL_VIOLATION),
548  errmsg("SSL error: %s", SSLerrmessage(ecode))));
549  errno = ECONNRESET;
550  n = -1;
551  break;
552  case SSL_ERROR_ZERO_RETURN:
553  /* connection was cleanly shut down by peer */
554  n = 0;
555  break;
556  default:
558  (errcode(ERRCODE_PROTOCOL_VIOLATION),
559  errmsg("unrecognized SSL error code: %d",
560  err)));
561  errno = ECONNRESET;
562  n = -1;
563  break;
564  }
565 
566  return n;
567 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
int errcode(int sqlerrcode)
Definition: elog.c:575
#define WL_SOCKET_READABLE
Definition: latch.h:125
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel, rest)
Definition: elog.h:122
#define ECONNRESET
Definition: win32_port.h:344
int errmsg(const char *fmt,...)
Definition: elog.c:797
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:340

◆ be_tls_write()

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

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

571 {
572  ssize_t n;
573  int err;
574  unsigned long ecode;
575 
576  errno = 0;
577  ERR_clear_error();
578  n = SSL_write(port->ssl, ptr, len);
579  err = SSL_get_error(port->ssl, n);
580  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
581  switch (err)
582  {
583  case SSL_ERROR_NONE:
584  /* a-ok */
585  break;
586  case SSL_ERROR_WANT_READ:
587  *waitfor = WL_SOCKET_READABLE;
588  errno = EWOULDBLOCK;
589  n = -1;
590  break;
591  case SSL_ERROR_WANT_WRITE:
592  *waitfor = WL_SOCKET_WRITEABLE;
593  errno = EWOULDBLOCK;
594  n = -1;
595  break;
596  case SSL_ERROR_SYSCALL:
597  /* leave it to caller to ereport the value of errno */
598  if (n != -1)
599  {
600  errno = ECONNRESET;
601  n = -1;
602  }
603  break;
604  case SSL_ERROR_SSL:
606  (errcode(ERRCODE_PROTOCOL_VIOLATION),
607  errmsg("SSL error: %s", SSLerrmessage(ecode))));
608  errno = ECONNRESET;
609  n = -1;
610  break;
611  case SSL_ERROR_ZERO_RETURN:
612 
613  /*
614  * the SSL connection was closed, leave it to the caller to
615  * ereport it
616  */
617  errno = ECONNRESET;
618  n = -1;
619  break;
620  default:
622  (errcode(ERRCODE_PROTOCOL_VIOLATION),
623  errmsg("unrecognized SSL error code: %d",
624  err)));
625  errno = ECONNRESET;
626  n = -1;
627  break;
628  }
629 
630  return n;
631 }
#define WL_SOCKET_WRITEABLE
Definition: latch.h:126
int errcode(int sqlerrcode)
Definition: elog.c:575
#define WL_SOCKET_READABLE
Definition: latch.h:125
#define COMMERROR
Definition: elog.h:30
#define ereport(elevel, rest)
Definition: elog.h:122
#define ECONNRESET
Definition: win32_port.h:344
int errmsg(const char *fmt,...)
Definition: elog.c:797
static const char * SSLerrmessage(unsigned long ecode)
#define EWOULDBLOCK
Definition: win32_port.h:340

◆ dummy_ssl_passwd_cb()

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

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

References Assert, and dummy_ssl_passwd_cb_called.

Referenced by be_tls_init().

883 {
884  /* Set flag to change the error message we'll report */
886  /* And return empty string */
887  Assert(size > 0);
888  buf[0] = '\0';
889  return 0;
890 }
static bool dummy_ssl_passwd_cb_called
static char * buf
Definition: pg_test_fsync.c:67
#define Assert(condition)
Definition: c.h:699

◆ info_cb()

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

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

References DEBUG4, ereport, and errmsg_internal().

Referenced by be_tls_open_server().

915 {
916  switch (type)
917  {
918  case SSL_CB_HANDSHAKE_START:
919  ereport(DEBUG4,
920  (errmsg_internal("SSL: handshake start")));
921  break;
922  case SSL_CB_HANDSHAKE_DONE:
923  ereport(DEBUG4,
924  (errmsg_internal("SSL: handshake done")));
925  break;
926  case SSL_CB_ACCEPT_LOOP:
927  ereport(DEBUG4,
928  (errmsg_internal("SSL: accept loop")));
929  break;
930  case SSL_CB_ACCEPT_EXIT:
931  ereport(DEBUG4,
932  (errmsg_internal("SSL: accept exit (%d)", args)));
933  break;
934  case SSL_CB_CONNECT_LOOP:
935  ereport(DEBUG4,
936  (errmsg_internal("SSL: connect loop")));
937  break;
938  case SSL_CB_CONNECT_EXIT:
939  ereport(DEBUG4,
940  (errmsg_internal("SSL: connect exit (%d)", args)));
941  break;
942  case SSL_CB_READ_ALERT:
943  ereport(DEBUG4,
944  (errmsg_internal("SSL: read alert (0x%04x)", args)));
945  break;
946  case SSL_CB_WRITE_ALERT:
947  ereport(DEBUG4,
948  (errmsg_internal("SSL: write alert (0x%04x)", args)));
949  break;
950  }
951 }
#define DEBUG4
Definition: elog.h:22
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg_internal(const char *fmt,...)
Definition: elog.c:827

◆ initialize_dh()

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

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

968 {
969  DH *dh = NULL;
970 
971  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
972 
973  if (ssl_dh_params_file[0])
974  dh = load_dh_file(ssl_dh_params_file, isServerStart);
975  if (!dh)
976  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
977  if (!dh)
978  {
979  ereport(isServerStart ? FATAL : LOG,
980  (errcode(ERRCODE_CONFIG_FILE_ERROR),
981  (errmsg("DH: could not load DH parameters"))));
982  return false;
983  }
984 
985  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
986  {
987  ereport(isServerStart ? FATAL : LOG,
988  (errcode(ERRCODE_CONFIG_FILE_ERROR),
989  (errmsg("DH: could not set DH parameters: %s",
990  SSLerrmessage(ERR_get_error())))));
991  return false;
992  }
993  return true;
994 }
static DH * load_dh_file(char *filename, bool isServerStart)
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
static DH * load_dh_buffer(const char *, size_t)
#define ereport(elevel, rest)
Definition: elog.h:122
char * ssl_dh_params_file
Definition: be-secure.c:45
int errmsg(const char *fmt,...)
Definition: elog.c:797
static const char * SSLerrmessage(unsigned long ecode)

◆ initialize_ecdh()

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

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

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

Referenced by be_tls_init().

1003 {
1004 #ifndef OPENSSL_NO_ECDH
1005  EC_KEY *ecdh;
1006  int nid;
1007 
1008  nid = OBJ_sn2nid(SSLECDHCurve);
1009  if (!nid)
1010  {
1011  ereport(isServerStart ? FATAL : LOG,
1012  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1013  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1014  return false;
1015  }
1016 
1017  ecdh = EC_KEY_new_by_curve_name(nid);
1018  if (!ecdh)
1019  {
1020  ereport(isServerStart ? FATAL : LOG,
1021  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1022  errmsg("ECDH: could not create key")));
1023  return false;
1024  }
1025 
1026  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1027  SSL_CTX_set_tmp_ecdh(context, ecdh);
1028  EC_KEY_free(ecdh);
1029 #endif
1030 
1031  return true;
1032 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
char * SSLECDHCurve
Definition: be-secure.c:57
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ load_dh_buffer()

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

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

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

Referenced by initialize_dh().

841 {
842  BIO *bio;
843  DH *dh = NULL;
844 
845  bio = BIO_new_mem_buf((char *) buffer, len);
846  if (bio == NULL)
847  return NULL;
848  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
849  if (dh == NULL)
850  ereport(DEBUG2,
851  (errmsg_internal("DH load buffer: %s",
852  SSLerrmessage(ERR_get_error()))));
853  BIO_free(bio);
854 
855  return dh;
856 }
#define DEBUG2
Definition: elog.h:24
#define ereport(elevel, rest)
Definition: elog.h:122
int errmsg_internal(const char *fmt,...)
Definition: elog.c:827
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:215
static const char * SSLerrmessage(unsigned long ecode)

◆ load_dh_file()

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

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

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

Referenced by initialize_dh().

778 {
779  FILE *fp;
780  DH *dh = NULL;
781  int codes;
782 
783  /* attempt to open file. It's not an error if it doesn't exist. */
784  if ((fp = AllocateFile(filename, "r")) == NULL)
785  {
786  ereport(isServerStart ? FATAL : LOG,
788  errmsg("could not open DH parameters file \"%s\": %m",
789  filename)));
790  return NULL;
791  }
792 
793  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
794  FreeFile(fp);
795 
796  if (dh == NULL)
797  {
798  ereport(isServerStart ? FATAL : LOG,
799  (errcode(ERRCODE_CONFIG_FILE_ERROR),
800  errmsg("could not load DH parameters file: %s",
801  SSLerrmessage(ERR_get_error()))));
802  return NULL;
803  }
804 
805  /* make sure the DH parameters are usable */
806  if (DH_check(dh, &codes) == 0)
807  {
808  ereport(isServerStart ? FATAL : LOG,
809  (errcode(ERRCODE_CONFIG_FILE_ERROR),
810  errmsg("invalid DH parameters: %s",
811  SSLerrmessage(ERR_get_error()))));
812  return NULL;
813  }
814  if (codes & DH_CHECK_P_NOT_PRIME)
815  {
816  ereport(isServerStart ? FATAL : LOG,
817  (errcode(ERRCODE_CONFIG_FILE_ERROR),
818  errmsg("invalid DH parameters: p is not prime")));
819  return NULL;
820  }
821  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
822  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
823  {
824  ereport(isServerStart ? FATAL : LOG,
825  (errcode(ERRCODE_CONFIG_FILE_ERROR),
826  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
827  return NULL;
828  }
829 
830  return dh;
831 }
int errcode(int sqlerrcode)
Definition: elog.c:575
#define LOG
Definition: elog.h:26
#define FATAL
Definition: elog.h:52
int errcode_for_file_access(void)
Definition: elog.c:598
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2336
#define ereport(elevel, rest)
Definition: elog.h:122
int FreeFile(FILE *file)
Definition: fd.c:2528
static char * filename
Definition: pg_dumpall.c:87
int errmsg(const char *fmt,...)
Definition: elog.c:797
static const char * SSLerrmessage(unsigned long ecode)

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

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

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

Referenced by my_SSL_set_fd().

701 {
702  if (!my_bio_methods)
703  {
704  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
705 #ifdef HAVE_BIO_METH_NEW
706  int my_bio_index;
707 
708  my_bio_index = BIO_get_new_index();
709  if (my_bio_index == -1)
710  return NULL;
711  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
712  if (!my_bio_methods)
713  return NULL;
714  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
715  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
716  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
717  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
718  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
719  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
720  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
721  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
722  {
723  BIO_meth_free(my_bio_methods);
724  my_bio_methods = NULL;
725  return NULL;
726  }
727 #else
728  my_bio_methods = malloc(sizeof(BIO_METHOD));
729  if (!my_bio_methods)
730  return NULL;
731  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
732  my_bio_methods->bread = my_sock_read;
733  my_bio_methods->bwrite = my_sock_write;
734 #endif
735  }
736  return my_bio_methods;
737 }
#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 659 of file be-secure-openssl.c.

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

Referenced by my_BIO_s_socket().

660 {
661  int res = 0;
662 
663  if (buf != NULL)
664  {
665  res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
666  BIO_clear_retry_flags(h);
667  if (res <= 0)
668  {
669  /* If we were interrupted, tell caller to retry */
670  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
671  {
672  BIO_set_retry_read(h);
673  }
674  }
675  }
676 
677  return res;
678 }
#define EAGAIN
Definition: win32_port.h:332
#define BIO_get_data(bio)
Definition: libpq-be.h:116
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:221
#define EWOULDBLOCK
Definition: win32_port.h:340
#define EINTR
Definition: win32_port.h:334

◆ my_sock_write()

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

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

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

Referenced by my_BIO_s_socket().

682 {
683  int res = 0;
684 
685  res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
686  BIO_clear_retry_flags(h);
687  if (res <= 0)
688  {
689  /* If we were interrupted, tell caller to retry */
690  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
691  {
692  BIO_set_retry_write(h);
693  }
694  }
695 
696  return res;
697 }
#define EAGAIN
Definition: win32_port.h:332
#define BIO_get_data(bio)
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:307
Definition: libpq-be.h:116
static char * buf
Definition: pg_test_fsync.c:67
#define EWOULDBLOCK
Definition: win32_port.h:340
#define EINTR
Definition: win32_port.h:334

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( Port port,
int  fd 
)
static

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

References BIO_set_data, and my_BIO_s_socket().

Referenced by be_tls_open_server().

742 {
743  int ret = 0;
744  BIO *bio;
745  BIO_METHOD *bio_method;
746 
747  bio_method = my_BIO_s_socket();
748  if (bio_method == NULL)
749  {
750  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
751  goto err;
752  }
753  bio = BIO_new(bio_method);
754 
755  if (bio == NULL)
756  {
757  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
758  goto err;
759  }
760  BIO_set_data(bio, port);
761 
762  BIO_set_fd(bio, fd, BIO_NOCLOSE);
763  SSL_set_bio(port->ssl, bio, bio);
764  ret = 1;
765 err:
766  return ret;
767 }
#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 862 of file be-secure-openssl.c.

References Assert, run_ssl_passphrase_command(), and ssl_is_server_start.

Referenced by be_tls_init().

863 {
864  /* same prompt as OpenSSL uses internally */
865  const char *prompt = "Enter PEM pass phrase:";
866 
867  Assert(rwflag == 0);
868 
869  return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
870 }
static char * buf
Definition: pg_test_fsync.c:67
static bool ssl_is_server_start
#define Assert(condition)
Definition: c.h:699
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

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

1045 {
1046  const char *errreason;
1047  static char errbuf[36];
1048 
1049  if (ecode == 0)
1050  return _("no SSL error reported");
1051  errreason = ERR_reason_error_string(ecode);
1052  if (errreason != NULL)
1053  return errreason;
1054  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1055  return errbuf;
1056 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define _(x)
Definition: elog.c:84

◆ verify_cb()

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

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

Referenced by be_tls_init().

905 {
906  return ok;
907 }

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

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

References i, pfree(), pg_any_to_server(), PG_UTF8, and pstrdup().

Referenced by be_tls_get_peerdn_name().

1193 {
1194  BIO *membuf = BIO_new(BIO_s_mem());
1195  int i,
1196  nid,
1197  count = X509_NAME_entry_count(name);
1198  X509_NAME_ENTRY *e;
1199  ASN1_STRING *v;
1200  const char *field_name;
1201  size_t size;
1202  char nullterm;
1203  char *sp;
1204  char *dp;
1205  char *result;
1206 
1207  (void) BIO_set_close(membuf, BIO_CLOSE);
1208  for (i = 0; i < count; i++)
1209  {
1210  e = X509_NAME_get_entry(name, i);
1211  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1212  v = X509_NAME_ENTRY_get_data(e);
1213  field_name = OBJ_nid2sn(nid);
1214  if (!field_name)
1215  field_name = OBJ_nid2ln(nid);
1216  BIO_printf(membuf, "/%s=", field_name);
1217  ASN1_STRING_print_ex(membuf, v,
1218  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1219  | ASN1_STRFLGS_UTF8_CONVERT));
1220  }
1221 
1222  /* ensure null termination of the BIO's content */
1223  nullterm = '\0';
1224  BIO_write(membuf, &nullterm, 1);
1225  size = BIO_get_mem_data(membuf, &sp);
1226  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1227 
1228  result = pstrdup(dp);
1229  if (dp != sp)
1230  pfree(dp);
1231  BIO_free(membuf);
1232 
1233  return result;
1234 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
void pfree(void *pointer)
Definition: mcxt.c:1031
const char * name
Definition: encode.c:521
e
Definition: preproc-init.c:82
int i
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:561

Variable Documentation

◆ dummy_ssl_passwd_cb_called

bool dummy_ssl_passwd_cb_called = false
static

Definition at line 67 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 656 of file be-secure-openssl.c.

Referenced by my_BIO_s_socket().

◆ SSL_context

SSL_CTX* SSL_context = NULL
static

◆ SSL_initialized

bool SSL_initialized = false
static

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

Referenced by be_tls_init().

◆ ssl_is_server_start

bool ssl_is_server_start
static

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

Referenced by be_tls_init(), and ssl_external_passwd_cb().