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 <netinet/tcp.h>
#include <arpa/inet.h>
#include "common/string.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/builtins.h"
#include "utils/memutils.h"
#include "common/openssl.h"
#include <openssl/conf.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/x509v3.h>
Include dependency graph for be-secure-openssl.c:

Go to the source code of this file.

Macros

#define MAXLEN   71
 

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 *buffer, size_t len)
 
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 ok, X509_STORE_CTX *ctx)
 
static void info_cb (const SSL *ssl, int type, int args)
 
static int alpn_cb (SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *userdata)
 
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)
 
static char * prepare_cert_name (char *name)
 
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)
 
char * be_tls_get_certificate_hash (Port *port, 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 const char * cert_errdetail
 
static BIO_METHOD * my_bio_methods = NULL
 
static const unsigned char alpn_protos [] = PG_ALPN_PROTOCOL_VECTOR
 

Macro Definition Documentation

◆ MAXLEN

#define MAXLEN   71

Function Documentation

◆ alpn_cb()

static int alpn_cb ( SSL *  ssl,
const unsigned char **  out,
unsigned char *  outlen,
const unsigned char *  in,
unsigned int  inlen,
void *  userdata 
)
static

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

1318 {
1319  /*
1320  * Why does OpenSSL provide a helper function that requires a nonconst
1321  * vector when the callback is declared to take a const vector? What are
1322  * we to do with that?
1323  */
1324  int retval;
1325 
1326  Assert(userdata != NULL);
1327  Assert(out != NULL);
1328  Assert(outlen != NULL);
1329  Assert(in != NULL);
1330 
1331  retval = SSL_select_next_proto((unsigned char **) out, outlen,
1332  alpn_protos, sizeof(alpn_protos),
1333  in, inlen);
1334  if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
1335  return SSL_TLSEXT_ERR_NOACK; /* can't happen */
1336 
1337  if (retval == OPENSSL_NPN_NEGOTIATED)
1338  return SSL_TLSEXT_ERR_OK;
1339  else
1340  {
1341  /*
1342  * The client doesn't support our protocol. Reject the connection
1343  * with TLS "no_application_protocol" alert, per RFC 7301.
1344  */
1345  return SSL_TLSEXT_ERR_ALERT_FATAL;
1346  }
1347 }
static const unsigned char alpn_protos[]
#define Assert(condition)
Definition: c.h:858

References alpn_protos, and Assert.

Referenced by be_tls_open_server().

◆ be_tls_close()

void be_tls_close ( Port port)

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

721 {
722  if (port->ssl)
723  {
724  SSL_shutdown(port->ssl);
725  SSL_free(port->ssl);
726  port->ssl = NULL;
727  port->ssl_in_use = false;
728  }
729 
730  if (port->peer)
731  {
732  X509_free(port->peer);
733  port->peer = NULL;
734  }
735 
736  if (port->peer_cn)
737  {
738  pfree(port->peer_cn);
739  port->peer_cn = NULL;
740  }
741 
742  if (port->peer_dn)
743  {
744  pfree(port->peer_dn);
745  port->peer_dn = NULL;
746  }
747 }
void pfree(void *pointer)
Definition: mcxt.c:1520
static int port
Definition: pg_regress.c:116

References pfree(), and port.

Referenced by secure_close().

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

416 {
417  if (SSL_context)
418  SSL_CTX_free(SSL_context);
419  SSL_context = NULL;
420  ssl_loaded_verify_locations = false;
421 }
static SSL_CTX * SSL_context

References SSL_context.

Referenced by secure_destroy().

◆ be_tls_get_certificate_hash()

char* be_tls_get_certificate_hash ( Port port,
size_t *  len 
)

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

1544 {
1545  X509 *server_cert;
1546  char *cert_hash;
1547  const EVP_MD *algo_type = NULL;
1548  unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
1549  unsigned int hash_size;
1550  int algo_nid;
1551 
1552  *len = 0;
1553  server_cert = SSL_get_certificate(port->ssl);
1554  if (server_cert == NULL)
1555  return NULL;
1556 
1557  /*
1558  * Get the signature algorithm of the certificate to determine the hash
1559  * algorithm to use for the result. Prefer X509_get_signature_info(),
1560  * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
1561  */
1562 #if HAVE_X509_GET_SIGNATURE_INFO
1563  if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
1564 #else
1565  if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
1566  &algo_nid, NULL))
1567 #endif
1568  elog(ERROR, "could not determine server certificate signature algorithm");
1569 
1570  /*
1571  * The TLS server's certificate bytes need to be hashed with SHA-256 if
1572  * its signature algorithm is MD5 or SHA-1 as per RFC 5929
1573  * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
1574  * is used, the same hash as the signature algorithm is used.
1575  */
1576  switch (algo_nid)
1577  {
1578  case NID_md5:
1579  case NID_sha1:
1580  algo_type = EVP_sha256();
1581  break;
1582  default:
1583  algo_type = EVP_get_digestbynid(algo_nid);
1584  if (algo_type == NULL)
1585  elog(ERROR, "could not find digest for NID %s",
1586  OBJ_nid2sn(algo_nid));
1587  break;
1588  }
1589 
1590  /* generate and save the certificate hash */
1591  if (!X509_digest(server_cert, algo_type, hash, &hash_size))
1592  elog(ERROR, "could not generate server certificate hash");
1593 
1594  cert_hash = palloc(hash_size);
1595  memcpy(cert_hash, hash, hash_size);
1596  *len = hash_size;
1597 
1598  return cert_hash;
1599 }
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:224
void * palloc(Size size)
Definition: mcxt.c:1316
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715

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

Referenced by read_client_final_message().

◆ be_tls_get_cipher()

const char* be_tls_get_cipher ( Port port)

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

1496 {
1497  if (port->ssl)
1498  return SSL_get_cipher(port->ssl);
1499  else
1500  return NULL;
1501 }

References port.

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

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

1473 {
1474  int bits;
1475 
1476  if (port->ssl)
1477  {
1478  SSL_get_cipher_bits(port->ssl, &bits);
1479  return bits;
1480  }
1481  else
1482  return 0;
1483 }

References port.

Referenced by PerformAuthentication(), and pgstat_bestart().

◆ be_tls_get_peer_issuer_name()

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

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

1514 {
1515  if (port->peer)
1516  strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1517  else
1518  ptr[0] = '\0';
1519 }
static char * X509_NAME_to_cstring(X509_NAME *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

References len, port, strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_issuer_dn().

◆ be_tls_get_peer_serial()

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

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

1523 {
1524  if (port->peer)
1525  {
1526  ASN1_INTEGER *serial;
1527  BIGNUM *b;
1528  char *decimal;
1529 
1530  serial = X509_get_serialNumber(port->peer);
1531  b = ASN1_INTEGER_to_BN(serial, NULL);
1532  decimal = BN_bn2dec(b);
1533 
1534  BN_free(b);
1535  strlcpy(ptr, decimal, len);
1536  OPENSSL_free(decimal);
1537  }
1538  else
1539  ptr[0] = '\0';
1540 }
int b
Definition: isn.c:70

References b, len, port, and strlcpy().

Referenced by pgstat_bestart(), and ssl_client_serial().

◆ be_tls_get_peer_subject_name()

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

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

1505 {
1506  if (port->peer)
1507  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1508  else
1509  ptr[0] = '\0';
1510 }

References len, port, strlcpy(), and X509_NAME_to_cstring().

Referenced by pgstat_bestart(), and ssl_client_dn().

◆ be_tls_get_version()

const char* be_tls_get_version ( Port port)

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

1487 {
1488  if (port->ssl)
1489  return SSL_get_version(port->ssl);
1490  else
1491  return NULL;
1492 }

References port.

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

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

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

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

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

◆ be_tls_open_server()

int be_tls_open_server ( Port port)

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

425 {
426  int r;
427  int err;
428  int waitfor;
429  unsigned long ecode;
430  bool give_proto_hint;
431 
432  Assert(!port->ssl);
433  Assert(!port->peer);
434 
435  if (!SSL_context)
436  {
438  (errcode(ERRCODE_PROTOCOL_VIOLATION),
439  errmsg("could not initialize SSL connection: SSL context not set up")));
440  return -1;
441  }
442 
443  /* set up debugging/info callback */
444  SSL_CTX_set_info_callback(SSL_context, info_cb);
445 
446  /* enable ALPN */
447  SSL_CTX_set_alpn_select_cb(SSL_context, alpn_cb, port);
448 
449  if (!(port->ssl = SSL_new(SSL_context)))
450  {
452  (errcode(ERRCODE_PROTOCOL_VIOLATION),
453  errmsg("could not initialize SSL connection: %s",
454  SSLerrmessage(ERR_get_error()))));
455  return -1;
456  }
457  if (!my_SSL_set_fd(port, port->sock))
458  {
460  (errcode(ERRCODE_PROTOCOL_VIOLATION),
461  errmsg("could not set SSL socket: %s",
462  SSLerrmessage(ERR_get_error()))));
463  return -1;
464  }
465  port->ssl_in_use = true;
466 
467 aloop:
468 
469  /*
470  * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
471  * queue. In general, the current thread's error queue must be empty
472  * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
473  * not work reliably. An extension may have failed to clear the
474  * per-thread error queue following another call to an OpenSSL I/O
475  * routine.
476  */
477  errno = 0;
478  ERR_clear_error();
479  r = SSL_accept(port->ssl);
480  if (r <= 0)
481  {
482  err = SSL_get_error(port->ssl, r);
483 
484  /*
485  * Other clients of OpenSSL in the backend may fail to call
486  * ERR_get_error(), but we always do, so as to not cause problems for
487  * OpenSSL clients that don't call ERR_clear_error() defensively. Be
488  * sure that this happens by calling now. SSL_get_error() relies on
489  * the OpenSSL per-thread error queue being intact, so this is the
490  * earliest possible point ERR_get_error() may be called.
491  */
492  ecode = ERR_get_error();
493  switch (err)
494  {
495  case SSL_ERROR_WANT_READ:
496  case SSL_ERROR_WANT_WRITE:
497  /* not allowed during connection establishment */
498  Assert(!port->noblock);
499 
500  /*
501  * No need to care about timeouts/interrupts here. At this
502  * point authentication_timeout still employs
503  * StartupPacketTimeoutHandler() which directly exits.
504  */
505  if (err == SSL_ERROR_WANT_READ)
507  else
509 
510  (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
511  WAIT_EVENT_SSL_OPEN_SERVER);
512  goto aloop;
513  case SSL_ERROR_SYSCALL:
514  if (r < 0 && errno != 0)
517  errmsg("could not accept SSL connection: %m")));
518  else
520  (errcode(ERRCODE_PROTOCOL_VIOLATION),
521  errmsg("could not accept SSL connection: EOF detected")));
522  break;
523  case SSL_ERROR_SSL:
524  switch (ERR_GET_REASON(ecode))
525  {
526  /*
527  * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
528  * TLSV1_ALERT_PROTOCOL_VERSION have been observed
529  * when trying to communicate with an old OpenSSL
530  * library, or when the client and server specify
531  * disjoint protocol ranges. NO_PROTOCOLS_AVAILABLE
532  * occurs if there's a local misconfiguration (which
533  * can happen despite our checks, if openssl.cnf
534  * injects a limit we didn't account for). It's not
535  * very clear what would make OpenSSL return the other
536  * codes listed here, but a hint about protocol
537  * versions seems like it's appropriate for all.
538  */
539  case SSL_R_NO_PROTOCOLS_AVAILABLE:
540  case SSL_R_UNSUPPORTED_PROTOCOL:
541  case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
542  case SSL_R_UNKNOWN_PROTOCOL:
543  case SSL_R_UNKNOWN_SSL_VERSION:
544  case SSL_R_UNSUPPORTED_SSL_VERSION:
545  case SSL_R_WRONG_SSL_VERSION:
546  case SSL_R_WRONG_VERSION_NUMBER:
547  case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
548 #ifdef SSL_R_VERSION_TOO_HIGH
549  case SSL_R_VERSION_TOO_HIGH:
550 #endif
551 #ifdef SSL_R_VERSION_TOO_LOW
552  case SSL_R_VERSION_TOO_LOW:
553 #endif
554  give_proto_hint = true;
555  break;
556  default:
557  give_proto_hint = false;
558  break;
559  }
561  (errcode(ERRCODE_PROTOCOL_VIOLATION),
562  errmsg("could not accept SSL connection: %s",
563  SSLerrmessage(ecode)),
565  give_proto_hint ?
566  errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
569  MIN_OPENSSL_TLS_VERSION,
572  MAX_OPENSSL_TLS_VERSION) : 0));
573  cert_errdetail = NULL;
574  break;
575  case SSL_ERROR_ZERO_RETURN:
577  (errcode(ERRCODE_PROTOCOL_VIOLATION),
578  errmsg("could not accept SSL connection: EOF detected")));
579  break;
580  default:
582  (errcode(ERRCODE_PROTOCOL_VIOLATION),
583  errmsg("unrecognized SSL error code: %d",
584  err)));
585  break;
586  }
587  return -1;
588  }
589 
590  /* Get the protocol selected by ALPN */
591  port->alpn_used = false;
592  {
593  const unsigned char *selected;
594  unsigned int len;
595 
596  SSL_get0_alpn_selected(port->ssl, &selected, &len);
597 
598  /* If ALPN is used, check that we negotiated the expected protocol */
599  if (selected != NULL)
600  {
601  if (len == strlen(PG_ALPN_PROTOCOL) &&
602  memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) == 0)
603  {
604  port->alpn_used = true;
605  }
606  else
607  {
608  /* shouldn't happen */
610  (errcode(ERRCODE_PROTOCOL_VIOLATION),
611  errmsg("received SSL connection request with unexpected ALPN protocol")));
612  }
613  }
614  }
615 
616  /* Get client certificate, if available. */
617  port->peer = SSL_get_peer_certificate(port->ssl);
618 
619  /* and extract the Common Name and Distinguished Name from it. */
620  port->peer_cn = NULL;
621  port->peer_dn = NULL;
622  port->peer_cert_valid = false;
623  if (port->peer != NULL)
624  {
625  int len;
626  X509_NAME *x509name = X509_get_subject_name(port->peer);
627  char *peer_dn;
628  BIO *bio = NULL;
629  BUF_MEM *bio_buf = NULL;
630 
631  len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0);
632  if (len != -1)
633  {
634  char *peer_cn;
635 
636  peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
637  r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn,
638  len + 1);
639  peer_cn[len] = '\0';
640  if (r != len)
641  {
642  /* shouldn't happen */
643  pfree(peer_cn);
644  return -1;
645  }
646 
647  /*
648  * Reject embedded NULLs in certificate common name to prevent
649  * attacks like CVE-2009-4034.
650  */
651  if (len != strlen(peer_cn))
652  {
654  (errcode(ERRCODE_PROTOCOL_VIOLATION),
655  errmsg("SSL certificate's common name contains embedded null")));
656  pfree(peer_cn);
657  return -1;
658  }
659 
660  port->peer_cn = peer_cn;
661  }
662 
663  bio = BIO_new(BIO_s_mem());
664  if (!bio)
665  {
666  if (port->peer_cn != NULL)
667  {
668  pfree(port->peer_cn);
669  port->peer_cn = NULL;
670  }
671  return -1;
672  }
673 
674  /*
675  * RFC2253 is the closest thing to an accepted standard format for
676  * DNs. We have documented how to produce this format from a
677  * certificate. It uses commas instead of slashes for delimiters,
678  * which make regular expression matching a bit easier. Also note that
679  * it prints the Subject fields in reverse order.
680  */
681  if (X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253) == -1 ||
682  BIO_get_mem_ptr(bio, &bio_buf) <= 0)
683  {
684  BIO_free(bio);
685  if (port->peer_cn != NULL)
686  {
687  pfree(port->peer_cn);
688  port->peer_cn = NULL;
689  }
690  return -1;
691  }
692  peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
693  memcpy(peer_dn, bio_buf->data, bio_buf->length);
694  len = bio_buf->length;
695  BIO_free(bio);
696  peer_dn[len] = '\0';
697  if (len != strlen(peer_dn))
698  {
700  (errcode(ERRCODE_PROTOCOL_VIOLATION),
701  errmsg("SSL certificate's distinguished name contains embedded null")));
702  pfree(peer_dn);
703  if (port->peer_cn != NULL)
704  {
705  pfree(port->peer_cn);
706  port->peer_cn = NULL;
707  }
708  return -1;
709  }
710 
711  port->peer_dn = peer_dn;
712 
713  port->peer_cert_valid = true;
714  }
715 
716  return 0;
717 }
static const char * ssl_protocol_version_to_string(int v)
static const char * cert_errdetail
static void info_cb(const SSL *ssl, int type, int args)
static int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *userdata)
static int my_SSL_set_fd(Port *port, int fd)
int errcode_for_socket_access(void)
Definition: elog.c:953
int errdetail_internal(const char *fmt,...)
Definition: elog.c:1230
int errhint(const char *fmt,...)
Definition: elog.c:1317
#define COMMERROR
Definition: elog.h:33
void err(int eval, const char *fmt,...)
Definition: err.c:43
struct Latch * MyLatch
Definition: globals.c:60
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition: latch.c:565
#define WL_SOCKET_READABLE
Definition: latch.h:128
#define WL_EXIT_ON_PM_DEATH
Definition: latch.h:132
#define WL_SOCKET_WRITEABLE
Definition: latch.h:129
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition: mcxt.c:1180
#define PG_ALPN_PROTOCOL
Definition: pqcomm.h:159

References alpn_cb(), Assert, cert_errdetail, COMMERROR, ereport, err(), errcode(), errcode_for_socket_access(), errdetail_internal(), errhint(), errmsg(), info_cb(), len, MemoryContextAlloc(), my_SSL_set_fd(), MyLatch, pfree(), PG_ALPN_PROTOCOL, port, SSL_context, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_string(), SSLerrmessage(), TopMemoryContext, WaitLatchOrSocket(), WL_EXIT_ON_PM_DEATH, WL_SOCKET_READABLE, and WL_SOCKET_WRITEABLE.

Referenced by secure_open_server().

◆ be_tls_read()

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

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

751 {
752  ssize_t n;
753  int err;
754  unsigned long ecode;
755 
756  errno = 0;
757  ERR_clear_error();
758  n = SSL_read(port->ssl, ptr, len);
759  err = SSL_get_error(port->ssl, n);
760  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
761  switch (err)
762  {
763  case SSL_ERROR_NONE:
764  /* a-ok */
765  break;
766  case SSL_ERROR_WANT_READ:
767  *waitfor = WL_SOCKET_READABLE;
768  errno = EWOULDBLOCK;
769  n = -1;
770  break;
771  case SSL_ERROR_WANT_WRITE:
772  *waitfor = WL_SOCKET_WRITEABLE;
773  errno = EWOULDBLOCK;
774  n = -1;
775  break;
776  case SSL_ERROR_SYSCALL:
777  /* leave it to caller to ereport the value of errno */
778  if (n != -1 || errno == 0)
779  {
780  errno = ECONNRESET;
781  n = -1;
782  }
783  break;
784  case SSL_ERROR_SSL:
786  (errcode(ERRCODE_PROTOCOL_VIOLATION),
787  errmsg("SSL error: %s", SSLerrmessage(ecode))));
788  errno = ECONNRESET;
789  n = -1;
790  break;
791  case SSL_ERROR_ZERO_RETURN:
792  /* connection was cleanly shut down by peer */
793  n = 0;
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 EWOULDBLOCK
Definition: win32_port.h:380
#define ECONNRESET
Definition: win32_port.h:384

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

Referenced by secure_read().

◆ be_tls_write()

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

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

810 {
811  ssize_t n;
812  int err;
813  unsigned long ecode;
814 
815  errno = 0;
816  ERR_clear_error();
817  n = SSL_write(port->ssl, ptr, len);
818  err = SSL_get_error(port->ssl, n);
819  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
820  switch (err)
821  {
822  case SSL_ERROR_NONE:
823  /* a-ok */
824  break;
825  case SSL_ERROR_WANT_READ:
826  *waitfor = WL_SOCKET_READABLE;
827  errno = EWOULDBLOCK;
828  n = -1;
829  break;
830  case SSL_ERROR_WANT_WRITE:
831  *waitfor = WL_SOCKET_WRITEABLE;
832  errno = EWOULDBLOCK;
833  n = -1;
834  break;
835  case SSL_ERROR_SYSCALL:
836 
837  /*
838  * Leave it to caller to ereport the value of errno. However, if
839  * errno is still zero then assume it's a read EOF situation, and
840  * report ECONNRESET. (This seems possible because SSL_write can
841  * also do reads.)
842  */
843  if (n != -1 || errno == 0)
844  {
845  errno = ECONNRESET;
846  n = -1;
847  }
848  break;
849  case SSL_ERROR_SSL:
851  (errcode(ERRCODE_PROTOCOL_VIOLATION),
852  errmsg("SSL error: %s", SSLerrmessage(ecode))));
853  errno = ECONNRESET;
854  n = -1;
855  break;
856  case SSL_ERROR_ZERO_RETURN:
857 
858  /*
859  * the SSL connection was closed, leave it to the caller to
860  * ereport it
861  */
862  errno = ECONNRESET;
863  n = -1;
864  break;
865  default:
867  (errcode(ERRCODE_PROTOCOL_VIOLATION),
868  errmsg("unrecognized SSL error code: %d",
869  err)));
870  errno = ECONNRESET;
871  n = -1;
872  break;
873  }
874 
875  return n;
876 }

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

Referenced by secure_write().

◆ default_openssl_tls_init()

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

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

1736 {
1737  if (isServerStart)
1738  {
1739  if (ssl_passphrase_command[0])
1740  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1741  }
1742  else
1743  {
1745  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1746  else
1747 
1748  /*
1749  * If reloading and no external command is configured, override
1750  * OpenSSL's default handling of passphrase-protected files,
1751  * because we don't want to prompt for a passphrase in an
1752  * already-running server.
1753  */
1754  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1755  }
1756 }
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
char * ssl_passphrase_command
Definition: be-secure.c:42
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:43

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

◆ dummy_ssl_passwd_cb()

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

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

1126 {
1127  /* Set flag to change the error message we'll report */
1129  /* And return empty string */
1130  Assert(size > 0);
1131  buf[0] = '\0';
1132  return 0;
1133 }
static char * buf
Definition: pg_test_fsync.c:73
static pg_noinline void Size size
Definition: slab.c:607

References Assert, buf, dummy_ssl_passwd_cb_called, and size.

Referenced by default_openssl_tls_init().

◆ info_cb()

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

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

1262 {
1263  const char *desc;
1264 
1265  desc = SSL_state_string_long(ssl);
1266 
1267  switch (type)
1268  {
1269  case SSL_CB_HANDSHAKE_START:
1270  ereport(DEBUG4,
1271  (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1272  break;
1273  case SSL_CB_HANDSHAKE_DONE:
1274  ereport(DEBUG4,
1275  (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1276  break;
1277  case SSL_CB_ACCEPT_LOOP:
1278  ereport(DEBUG4,
1279  (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1280  break;
1281  case SSL_CB_ACCEPT_EXIT:
1282  ereport(DEBUG4,
1283  (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1284  break;
1285  case SSL_CB_CONNECT_LOOP:
1286  ereport(DEBUG4,
1287  (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1288  break;
1289  case SSL_CB_CONNECT_EXIT:
1290  ereport(DEBUG4,
1291  (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1292  break;
1293  case SSL_CB_READ_ALERT:
1294  ereport(DEBUG4,
1295  (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1296  break;
1297  case SSL_CB_WRITE_ALERT:
1298  ereport(DEBUG4,
1299  (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1300  break;
1301  }
1302 }
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define DEBUG4
Definition: elog.h:27
const char * type

References generate_unaccent_rules::args, DEBUG4, ereport, errmsg_internal(), and type.

Referenced by be_tls_open_server().

◆ initialize_dh()

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

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

1365 {
1366  DH *dh = NULL;
1367 
1368  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1369 
1370  if (ssl_dh_params_file[0])
1371  dh = load_dh_file(ssl_dh_params_file, isServerStart);
1372  if (!dh)
1373  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1374  if (!dh)
1375  {
1376  ereport(isServerStart ? FATAL : LOG,
1377  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1378  errmsg("DH: could not load DH parameters")));
1379  return false;
1380  }
1381 
1382  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1383  {
1384  ereport(isServerStart ? FATAL : LOG,
1385  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1386  errmsg("DH: could not set DH parameters: %s",
1387  SSLerrmessage(ERR_get_error()))));
1388  DH_free(dh);
1389  return false;
1390  }
1391 
1392  DH_free(dh);
1393  return true;
1394 }
static DH * load_dh_buffer(const char *buffer, size_t len)
static DH * load_dh_file(char *filename, bool isServerStart)
char * ssl_dh_params_file
Definition: be-secure.c:41

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

Referenced by be_tls_init().

◆ initialize_ecdh()

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

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

1403 {
1404 #ifndef OPENSSL_NO_ECDH
1405  EC_KEY *ecdh;
1406  int nid;
1407 
1408  nid = OBJ_sn2nid(SSLECDHCurve);
1409  if (!nid)
1410  {
1411  ereport(isServerStart ? FATAL : LOG,
1412  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1413  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1414  return false;
1415  }
1416 
1417  ecdh = EC_KEY_new_by_curve_name(nid);
1418  if (!ecdh)
1419  {
1420  ereport(isServerStart ? FATAL : LOG,
1421  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1422  errmsg("ECDH: could not create key")));
1423  return false;
1424  }
1425 
1426  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1427  SSL_CTX_set_tmp_ecdh(context, ecdh);
1428  EC_KEY_free(ecdh);
1429 #endif
1430 
1431  return true;
1432 }
char * SSLECDHCurve
Definition: be-secure.c:53

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

Referenced by be_tls_init().

◆ load_dh_buffer()

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

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

1084 {
1085  BIO *bio;
1086  DH *dh = NULL;
1087 
1088  bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
1089  if (bio == NULL)
1090  return NULL;
1091  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1092  if (dh == NULL)
1093  ereport(DEBUG2,
1094  (errmsg_internal("DH load buffer: %s",
1095  SSLerrmessage(ERR_get_error()))));
1096  BIO_free(bio);
1097 
1098  return dh;
1099 }
#define unconstify(underlying_type, expr)
Definition: c.h:1245
#define DEBUG2
Definition: elog.h:29

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

Referenced by initialize_dh().

◆ load_dh_file()

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

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

1017 {
1018  FILE *fp;
1019  DH *dh = NULL;
1020  int codes;
1021 
1022  /* attempt to open file. It's not an error if it doesn't exist. */
1023  if ((fp = AllocateFile(filename, "r")) == NULL)
1024  {
1025  ereport(isServerStart ? FATAL : LOG,
1027  errmsg("could not open DH parameters file \"%s\": %m",
1028  filename)));
1029  return NULL;
1030  }
1031 
1032  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
1033  FreeFile(fp);
1034 
1035  if (dh == NULL)
1036  {
1037  ereport(isServerStart ? FATAL : LOG,
1038  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1039  errmsg("could not load DH parameters file: %s",
1040  SSLerrmessage(ERR_get_error()))));
1041  return NULL;
1042  }
1043 
1044  /* make sure the DH parameters are usable */
1045  if (DH_check(dh, &codes) == 0)
1046  {
1047  ereport(isServerStart ? FATAL : LOG,
1048  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1049  errmsg("invalid DH parameters: %s",
1050  SSLerrmessage(ERR_get_error()))));
1051  DH_free(dh);
1052  return NULL;
1053  }
1054  if (codes & DH_CHECK_P_NOT_PRIME)
1055  {
1056  ereport(isServerStart ? FATAL : LOG,
1057  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1058  errmsg("invalid DH parameters: p is not prime")));
1059  DH_free(dh);
1060  return NULL;
1061  }
1062  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
1063  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
1064  {
1065  ereport(isServerStart ? FATAL : LOG,
1066  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1067  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1068  DH_free(dh);
1069  return NULL;
1070  }
1071 
1072  return dh;
1073 }
int errcode_for_file_access(void)
Definition: elog.c:880
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2583
int FreeFile(FILE *file)
Definition: fd.c:2781
static char * filename
Definition: pg_dumpall.c:119

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

Referenced by initialize_dh().

◆ my_BIO_s_socket()

static BIO_METHOD * my_BIO_s_socket ( void  )
static

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

939 {
940  if (!my_bio_methods)
941  {
942  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
943 #ifdef HAVE_BIO_METH_NEW
944  int my_bio_index;
945 
946  my_bio_index = BIO_get_new_index();
947  if (my_bio_index == -1)
948  return NULL;
949  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
950  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
951  if (!my_bio_methods)
952  return NULL;
953  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
954  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
955  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
956  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
957  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
958  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
959  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
960  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
961  {
962  BIO_meth_free(my_bio_methods);
963  my_bio_methods = NULL;
964  return NULL;
965  }
966 #else
967  my_bio_methods = malloc(sizeof(BIO_METHOD));
968  if (!my_bio_methods)
969  return NULL;
970  memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
971  my_bio_methods->bread = my_sock_read;
972  my_bio_methods->bwrite = my_sock_write;
973 #endif
974  }
975  return my_bio_methods;
976 }
static BIO_METHOD * my_bio_methods
static int my_sock_write(BIO *h, const char *buf, int size)
static int my_sock_read(BIO *h, char *buf, int size)
#define malloc(a)
Definition: header.h:50

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

Referenced by my_SSL_set_fd().

◆ my_sock_read()

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

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

898 {
899  int res = 0;
900 
901  if (buf != NULL)
902  {
903  res = secure_raw_read(((Port *) BIO_get_app_data(h)), buf, size);
904  BIO_clear_retry_flags(h);
905  if (res <= 0)
906  {
907  /* If we were interrupted, tell caller to retry */
908  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
909  {
910  BIO_set_retry_read(h);
911  }
912  }
913  }
914 
915  return res;
916 }
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:264
Definition: libpq-be.h:133
#define EINTR
Definition: win32_port.h:374
#define EAGAIN
Definition: win32_port.h:372

References buf, EAGAIN, EINTR, EWOULDBLOCK, res, secure_raw_read(), and size.

Referenced by my_BIO_s_socket().

◆ my_sock_write()

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

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

920 {
921  int res = 0;
922 
923  res = secure_raw_write(((Port *) BIO_get_app_data(h)), buf, size);
924  BIO_clear_retry_flags(h);
925  if (res <= 0)
926  {
927  /* If we were interrupted, tell caller to retry */
928  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
929  {
930  BIO_set_retry_write(h);
931  }
932  }
933 
934  return res;
935 }
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:373

References buf, EAGAIN, EINTR, EWOULDBLOCK, res, secure_raw_write(), and size.

Referenced by my_BIO_s_socket().

◆ my_SSL_set_fd()

static int my_SSL_set_fd ( Port port,
int  fd 
)
static

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

981 {
982  int ret = 0;
983  BIO *bio;
984  BIO_METHOD *bio_method;
985 
986  bio_method = my_BIO_s_socket();
987  if (bio_method == NULL)
988  {
989  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
990  goto err;
991  }
992  bio = BIO_new(bio_method);
993 
994  if (bio == NULL)
995  {
996  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
997  goto err;
998  }
999  BIO_set_app_data(bio, port);
1000 
1001  BIO_set_fd(bio, fd, BIO_NOCLOSE);
1002  SSL_set_bio(port->ssl, bio, bio);
1003  ret = 1;
1004 err:
1005  return ret;
1006 }
static BIO_METHOD * my_BIO_s_socket(void)
static int fd(const char *x, int i)
Definition: preproc-init.c:105

References err(), fd(), my_BIO_s_socket(), and port.

Referenced by be_tls_open_server().

◆ prepare_cert_name()

static char* prepare_cert_name ( char *  name)
static

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

1143 {
1144  size_t namelen = strlen(name);
1145  char *truncated = name;
1146 
1147  /*
1148  * Common Names are 64 chars max, so for a common case where the CN is the
1149  * last field, we can still print the longest possible CN with a
1150  * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
1151  * characters.
1152  */
1153 #define MAXLEN 71
1154 
1155  if (namelen > MAXLEN)
1156  {
1157  /*
1158  * Keep the end of the name, not the beginning, since the most
1159  * specific field is likely to give users the most information.
1160  */
1161  truncated = name + namelen - MAXLEN;
1162  truncated[0] = truncated[1] = truncated[2] = '.';
1163  namelen = MAXLEN;
1164  }
1165 
1166 #undef MAXLEN
1167 
1168  return pg_clean_ascii(truncated, 0);
1169 }
#define MAXLEN
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition: string.c:86
const char * name

References MAXLEN, name, and pg_clean_ascii().

Referenced by verify_cb().

◆ ssl_external_passwd_cb()

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

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

1106 {
1107  /* same prompt as OpenSSL uses internally */
1108  const char *prompt = "Enter PEM pass phrase:";
1109 
1110  Assert(rwflag == 0);
1111 
1113 }
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)

References Assert, buf, run_ssl_passphrase_command(), size, and ssl_is_server_start.

Referenced by default_openssl_tls_init().

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( int  v)
static

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

1680 {
1681  switch (v)
1682  {
1683  case PG_TLS_ANY:
1684  return 0;
1685  case PG_TLS1_VERSION:
1686  return TLS1_VERSION;
1687  case PG_TLS1_1_VERSION:
1688 #ifdef TLS1_1_VERSION
1689  return TLS1_1_VERSION;
1690 #else
1691  break;
1692 #endif
1693  case PG_TLS1_2_VERSION:
1694 #ifdef TLS1_2_VERSION
1695  return TLS1_2_VERSION;
1696 #else
1697  break;
1698 #endif
1699  case PG_TLS1_3_VERSION:
1700 #ifdef TLS1_3_VERSION
1701  return TLS1_3_VERSION;
1702 #else
1703  break;
1704 #endif
1705  }
1706 
1707  return -1;
1708 }
@ PG_TLS1_VERSION
Definition: libpq.h:129
@ PG_TLS1_3_VERSION
Definition: libpq.h:132
@ PG_TLS1_1_VERSION
Definition: libpq.h:130
@ PG_TLS1_2_VERSION
Definition: libpq.h:131
@ PG_TLS_ANY
Definition: libpq.h:128

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

◆ ssl_protocol_version_to_string()

static const char * ssl_protocol_version_to_string ( int  v)
static

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

1715 {
1716  switch (v)
1717  {
1718  case PG_TLS_ANY:
1719  return "any";
1720  case PG_TLS1_VERSION:
1721  return "TLSv1";
1722  case PG_TLS1_1_VERSION:
1723  return "TLSv1.1";
1724  case PG_TLS1_2_VERSION:
1725  return "TLSv1.2";
1726  case PG_TLS1_3_VERSION:
1727  return "TLSv1.3";
1728  }
1729 
1730  return "(unrecognized)";
1731 }

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

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

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

1445 {
1446  const char *errreason;
1447  static char errbuf[36];
1448 
1449  if (ecode == 0)
1450  return _("no SSL error reported");
1451  errreason = ERR_reason_error_string(ecode);
1452  if (errreason != NULL)
1453  return errreason;
1454 
1455  /*
1456  * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to
1457  * map system errno values. We can cover that shortcoming with this bit
1458  * of code. Older OpenSSL versions don't have the ERR_SYSTEM_ERROR macro,
1459  * but that's okay because they don't have the shortcoming either.
1460  */
1461 #ifdef ERR_SYSTEM_ERROR
1462  if (ERR_SYSTEM_ERROR(ecode))
1463  return strerror(ERR_GET_REASON(ecode));
1464 #endif
1465 
1466  /* No choice but to report the numeric ecode */
1467  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1468  return errbuf;
1469 }
#define _(x)
Definition: elog.c:90
#define strerror
Definition: port.h:251
#define snprintf
Definition: port.h:238

References _, snprintf, and strerror.

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

◆ verify_cb()

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

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

1183 {
1184  int depth;
1185  int errcode;
1186  const char *errstring;
1188  X509 *cert;
1189 
1190  if (ok)
1191  {
1192  /* Nothing to do for the successful case. */
1193  return ok;
1194  }
1195 
1196  /* Pull all the information we have on the verification failure. */
1197  depth = X509_STORE_CTX_get_error_depth(ctx);
1198  errcode = X509_STORE_CTX_get_error(ctx);
1199  errstring = X509_verify_cert_error_string(errcode);
1200 
1201  initStringInfo(&str);
1203  _("Client certificate verification failed at depth %d: %s."),
1204  depth, errstring);
1205 
1206  cert = X509_STORE_CTX_get_current_cert(ctx);
1207  if (cert)
1208  {
1209  char *subject,
1210  *issuer;
1211  char *sub_prepared,
1212  *iss_prepared;
1213  char *serialno;
1214  ASN1_INTEGER *sn;
1215  BIGNUM *b;
1216 
1217  /*
1218  * Get the Subject and Issuer for logging, but don't let maliciously
1219  * huge certs flood the logs, and don't reflect non-ASCII bytes into
1220  * it either.
1221  */
1222  subject = X509_NAME_to_cstring(X509_get_subject_name(cert));
1223  sub_prepared = prepare_cert_name(subject);
1224  pfree(subject);
1225 
1226  issuer = X509_NAME_to_cstring(X509_get_issuer_name(cert));
1227  iss_prepared = prepare_cert_name(issuer);
1228  pfree(issuer);
1229 
1230  /*
1231  * Pull the serial number, too, in case a Subject is still ambiguous.
1232  * This mirrors be_tls_get_peer_serial().
1233  */
1234  sn = X509_get_serialNumber(cert);
1235  b = ASN1_INTEGER_to_BN(sn, NULL);
1236  serialno = BN_bn2dec(b);
1237 
1238  appendStringInfoChar(&str, '\n');
1240  _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1241  sub_prepared, serialno ? serialno : _("unknown"),
1242  iss_prepared);
1243 
1244  BN_free(b);
1245  OPENSSL_free(serialno);
1246  pfree(iss_prepared);
1247  pfree(sub_prepared);
1248  }
1249 
1250  /* Store our detail message to be logged later. */
1251  cert_errdetail = str.data;
1252 
1253  return ok;
1254 }
static char * prepare_cert_name(char *name)
const char * str
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:97
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:194
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59

References _, appendStringInfo(), appendStringInfoChar(), b, cert_errdetail, errcode(), initStringInfo(), pfree(), prepare_cert_name(), str, and X509_NAME_to_cstring().

Referenced by be_tls_init().

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

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

1607 {
1608  BIO *membuf = BIO_new(BIO_s_mem());
1609  int i,
1610  nid,
1611  count = X509_NAME_entry_count(name);
1612  X509_NAME_ENTRY *e;
1613  ASN1_STRING *v;
1614  const char *field_name;
1615  size_t size;
1616  char nullterm;
1617  char *sp;
1618  char *dp;
1619  char *result;
1620 
1621  if (membuf == NULL)
1622  ereport(ERROR,
1623  (errcode(ERRCODE_OUT_OF_MEMORY),
1624  errmsg("could not create BIO")));
1625 
1626  (void) BIO_set_close(membuf, BIO_CLOSE);
1627  for (i = 0; i < count; i++)
1628  {
1629  e = X509_NAME_get_entry(name, i);
1630  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1631  if (nid == NID_undef)
1632  ereport(ERROR,
1633  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1634  errmsg("could not get NID for ASN1_OBJECT object")));
1635  v = X509_NAME_ENTRY_get_data(e);
1636  field_name = OBJ_nid2sn(nid);
1637  if (field_name == NULL)
1638  field_name = OBJ_nid2ln(nid);
1639  if (field_name == NULL)
1640  ereport(ERROR,
1641  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1642  errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1643  BIO_printf(membuf, "/%s=", field_name);
1644  ASN1_STRING_print_ex(membuf, v,
1645  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1646  | ASN1_STRFLGS_UTF8_CONVERT));
1647  }
1648 
1649  /* ensure null termination of the BIO's content */
1650  nullterm = '\0';
1651  BIO_write(membuf, &nullterm, 1);
1652  size = BIO_get_mem_data(membuf, &sp);
1653  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1654 
1655  result = pstrdup(dp);
1656  if (dp != sp)
1657  pfree(dp);
1658  if (BIO_free(membuf) != 1)
1659  elog(ERROR, "could not free OpenSSL BIO structure");
1660 
1661  return result;
1662 }
int i
Definition: isn.c:73
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:676
char * pstrdup(const char *in)
Definition: mcxt.c:1695
@ PG_UTF8
Definition: pg_wchar.h:232
e
Definition: preproc-init.c:82

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

Referenced by be_tls_get_peer_issuer_name(), be_tls_get_peer_subject_name(), and verify_cb().

Variable Documentation

◆ alpn_protos

const unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR
static

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

Referenced by alpn_cb().

◆ cert_errdetail

const char* cert_errdetail
static

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

Referenced by be_tls_open_server(), and verify_cb().

◆ dummy_ssl_passwd_cb_called

bool dummy_ssl_passwd_cb_called = false
static

Definition at line 84 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 894 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 57 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 83 of file be-secure-openssl.c.

Referenced by be_tls_init().

◆ ssl_is_server_start

bool ssl_is_server_start
static

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

Referenced by be_tls_init(), and ssl_external_passwd_cb().