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/bn.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 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 1302 of file be-secure-openssl.c.

1308 {
1309  /*
1310  * Why does OpenSSL provide a helper function that requires a nonconst
1311  * vector when the callback is declared to take a const vector? What are
1312  * we to do with that?
1313  */
1314  int retval;
1315 
1316  Assert(userdata != NULL);
1317  Assert(out != NULL);
1318  Assert(outlen != NULL);
1319  Assert(in != NULL);
1320 
1321  retval = SSL_select_next_proto((unsigned char **) out, outlen,
1322  alpn_protos, sizeof(alpn_protos),
1323  in, inlen);
1324  if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
1325  return SSL_TLSEXT_ERR_NOACK; /* can't happen */
1326 
1327  if (retval == OPENSSL_NPN_NEGOTIATED)
1328  return SSL_TLSEXT_ERR_OK;
1329  else
1330  {
1331  /*
1332  * The client doesn't support our protocol. Reject the connection
1333  * with TLS "no_application_protocol" alert, per RFC 7301.
1334  */
1335  return SSL_TLSEXT_ERR_ALERT_FATAL;
1336  }
1337 }
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 719 of file be-secure-openssl.c.

720 {
721  if (port->ssl)
722  {
723  SSL_shutdown(port->ssl);
724  SSL_free(port->ssl);
725  port->ssl = NULL;
726  port->ssl_in_use = false;
727  }
728 
729  if (port->peer)
730  {
731  X509_free(port->peer);
732  port->peer = NULL;
733  }
734 
735  if (port->peer_cn)
736  {
737  pfree(port->peer_cn);
738  port->peer_cn = NULL;
739  }
740 
741  if (port->peer_dn)
742  {
743  pfree(port->peer_dn);
744  port->peer_dn = NULL;
745  }
746 }
void pfree(void *pointer)
Definition: mcxt.c:1521
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 414 of file be-secure-openssl.c.

415 {
416  if (SSL_context)
417  SSL_CTX_free(SSL_context);
418  SSL_context = NULL;
419  ssl_loaded_verify_locations = false;
420 }
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 1534 of file be-secure-openssl.c.

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

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

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 1463 of file be-secure-openssl.c.

1464 {
1465  int bits;
1466 
1467  if (port->ssl)
1468  {
1469  SSL_get_cipher_bits(port->ssl, &bits);
1470  return bits;
1471  }
1472  else
1473  return 0;
1474 }

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 1504 of file be-secure-openssl.c.

1505 {
1506  if (port->peer)
1507  strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1508  else
1509  ptr[0] = '\0';
1510 }
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 1513 of file be-secure-openssl.c.

1514 {
1515  if (port->peer)
1516  {
1517  ASN1_INTEGER *serial;
1518  BIGNUM *b;
1519  char *decimal;
1520 
1521  serial = X509_get_serialNumber(port->peer);
1522  b = ASN1_INTEGER_to_BN(serial, NULL);
1523  decimal = BN_bn2dec(b);
1524 
1525  BN_free(b);
1526  strlcpy(ptr, decimal, len);
1527  OPENSSL_free(decimal);
1528  }
1529  else
1530  ptr[0] = '\0';
1531 }
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 1495 of file be-secure-openssl.c.

1496 {
1497  if (port->peer)
1498  strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1499  else
1500  ptr[0] = '\0';
1501 }

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 1477 of file be-secure-openssl.c.

1478 {
1479  if (port->ssl)
1480  return SSL_get_version(port->ssl);
1481  else
1482  return NULL;
1483 }

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

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

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 749 of file be-secure-openssl.c.

750 {
751  ssize_t n;
752  int err;
753  unsigned long ecode;
754 
755  errno = 0;
756  ERR_clear_error();
757  n = SSL_read(port->ssl, ptr, len);
758  err = SSL_get_error(port->ssl, n);
759  ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
760  switch (err)
761  {
762  case SSL_ERROR_NONE:
763  /* a-ok */
764  break;
765  case SSL_ERROR_WANT_READ:
766  *waitfor = WL_SOCKET_READABLE;
767  errno = EWOULDBLOCK;
768  n = -1;
769  break;
770  case SSL_ERROR_WANT_WRITE:
771  *waitfor = WL_SOCKET_WRITEABLE;
772  errno = EWOULDBLOCK;
773  n = -1;
774  break;
775  case SSL_ERROR_SYSCALL:
776  /* leave it to caller to ereport the value of errno */
777  if (n != -1 || errno == 0)
778  {
779  errno = ECONNRESET;
780  n = -1;
781  }
782  break;
783  case SSL_ERROR_SSL:
785  (errcode(ERRCODE_PROTOCOL_VIOLATION),
786  errmsg("SSL error: %s", SSLerrmessage(ecode))));
787  errno = ECONNRESET;
788  n = -1;
789  break;
790  case SSL_ERROR_ZERO_RETURN:
791  /* connection was cleanly shut down by peer */
792  n = 0;
793  break;
794  default:
796  (errcode(ERRCODE_PROTOCOL_VIOLATION),
797  errmsg("unrecognized SSL error code: %d",
798  err)));
799  errno = ECONNRESET;
800  n = -1;
801  break;
802  }
803 
804  return n;
805 }
#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 808 of file be-secure-openssl.c.

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

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 1726 of file be-secure-openssl.c.

1727 {
1728  if (isServerStart)
1729  {
1730  if (ssl_passphrase_command[0])
1731  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1732  }
1733  else
1734  {
1736  SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1737  else
1738 
1739  /*
1740  * If reloading and no external command is configured, override
1741  * OpenSSL's default handling of passphrase-protected files,
1742  * because we don't want to prompt for a passphrase in an
1743  * already-running server.
1744  */
1745  SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1746  }
1747 }
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:43
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:44

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 1115 of file be-secure-openssl.c.

1116 {
1117  /* Set flag to change the error message we'll report */
1119  /* And return empty string */
1120  Assert(size > 0);
1121  buf[0] = '\0';
1122  return 0;
1123 }
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 1251 of file be-secure-openssl.c.

1252 {
1253  const char *desc;
1254 
1255  desc = SSL_state_string_long(ssl);
1256 
1257  switch (type)
1258  {
1259  case SSL_CB_HANDSHAKE_START:
1260  ereport(DEBUG4,
1261  (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1262  break;
1263  case SSL_CB_HANDSHAKE_DONE:
1264  ereport(DEBUG4,
1265  (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1266  break;
1267  case SSL_CB_ACCEPT_LOOP:
1268  ereport(DEBUG4,
1269  (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1270  break;
1271  case SSL_CB_ACCEPT_EXIT:
1272  ereport(DEBUG4,
1273  (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1274  break;
1275  case SSL_CB_CONNECT_LOOP:
1276  ereport(DEBUG4,
1277  (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1278  break;
1279  case SSL_CB_CONNECT_EXIT:
1280  ereport(DEBUG4,
1281  (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1282  break;
1283  case SSL_CB_READ_ALERT:
1284  ereport(DEBUG4,
1285  (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1286  break;
1287  case SSL_CB_WRITE_ALERT:
1288  ereport(DEBUG4,
1289  (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1290  break;
1291  }
1292 }
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 1354 of file be-secure-openssl.c.

1355 {
1356  DH *dh = NULL;
1357 
1358  SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1359 
1360  if (ssl_dh_params_file[0])
1361  dh = load_dh_file(ssl_dh_params_file, isServerStart);
1362  if (!dh)
1363  dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1364  if (!dh)
1365  {
1366  ereport(isServerStart ? FATAL : LOG,
1367  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1368  errmsg("DH: could not load DH parameters")));
1369  return false;
1370  }
1371 
1372  if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1373  {
1374  ereport(isServerStart ? FATAL : LOG,
1375  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1376  errmsg("DH: could not set DH parameters: %s",
1377  SSLerrmessage(ERR_get_error()))));
1378  DH_free(dh);
1379  return false;
1380  }
1381 
1382  DH_free(dh);
1383  return true;
1384 }
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:42

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 1392 of file be-secure-openssl.c.

1393 {
1394 #ifndef OPENSSL_NO_ECDH
1395  EC_KEY *ecdh;
1396  int nid;
1397 
1398  nid = OBJ_sn2nid(SSLECDHCurve);
1399  if (!nid)
1400  {
1401  ereport(isServerStart ? FATAL : LOG,
1402  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1403  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
1404  return false;
1405  }
1406 
1407  ecdh = EC_KEY_new_by_curve_name(nid);
1408  if (!ecdh)
1409  {
1410  ereport(isServerStart ? FATAL : LOG,
1411  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1412  errmsg("ECDH: could not create key")));
1413  return false;
1414  }
1415 
1416  SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
1417  SSL_CTX_set_tmp_ecdh(context, ecdh);
1418  EC_KEY_free(ecdh);
1419 #endif
1420 
1421  return true;
1422 }
char * SSLECDHCurve
Definition: be-secure.c:54

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 1073 of file be-secure-openssl.c.

1074 {
1075  BIO *bio;
1076  DH *dh = NULL;
1077 
1078  bio = BIO_new_mem_buf(buffer, len);
1079  if (bio == NULL)
1080  return NULL;
1081  dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1082  if (dh == NULL)
1083  ereport(DEBUG2,
1084  (errmsg_internal("DH load buffer: %s",
1085  SSLerrmessage(ERR_get_error()))));
1086  BIO_free(bio);
1087 
1088  return dh;
1089 }
#define DEBUG2
Definition: elog.h:29

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

Referenced by initialize_dh().

◆ load_dh_file()

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

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

1007 {
1008  FILE *fp;
1009  DH *dh = NULL;
1010  int codes;
1011 
1012  /* attempt to open file. It's not an error if it doesn't exist. */
1013  if ((fp = AllocateFile(filename, "r")) == NULL)
1014  {
1015  ereport(isServerStart ? FATAL : LOG,
1017  errmsg("could not open DH parameters file \"%s\": %m",
1018  filename)));
1019  return NULL;
1020  }
1021 
1022  dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
1023  FreeFile(fp);
1024 
1025  if (dh == NULL)
1026  {
1027  ereport(isServerStart ? FATAL : LOG,
1028  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1029  errmsg("could not load DH parameters file: %s",
1030  SSLerrmessage(ERR_get_error()))));
1031  return NULL;
1032  }
1033 
1034  /* make sure the DH parameters are usable */
1035  if (DH_check(dh, &codes) == 0)
1036  {
1037  ereport(isServerStart ? FATAL : LOG,
1038  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1039  errmsg("invalid DH parameters: %s",
1040  SSLerrmessage(ERR_get_error()))));
1041  DH_free(dh);
1042  return NULL;
1043  }
1044  if (codes & DH_CHECK_P_NOT_PRIME)
1045  {
1046  ereport(isServerStart ? FATAL : LOG,
1047  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1048  errmsg("invalid DH parameters: p is not prime")));
1049  DH_free(dh);
1050  return NULL;
1051  }
1052  if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
1053  (codes & DH_CHECK_P_NOT_SAFE_PRIME))
1054  {
1055  ereport(isServerStart ? FATAL : LOG,
1056  (errcode(ERRCODE_CONFIG_FILE_ERROR),
1057  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1058  DH_free(dh);
1059  return NULL;
1060  }
1061 
1062  return dh;
1063 }
int errcode_for_file_access(void)
Definition: elog.c:876
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2606
int FreeFile(FILE *file)
Definition: fd.c:2804
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 937 of file be-secure-openssl.c.

938 {
939  if (!my_bio_methods)
940  {
941  BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
942  int my_bio_index;
943 
944  my_bio_index = BIO_get_new_index();
945  if (my_bio_index == -1)
946  return NULL;
947  my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
948  my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
949  if (!my_bio_methods)
950  return NULL;
951  if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
952  !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
953  !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
954  !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
955  !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
956  !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
957  !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
958  !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
959  {
960  BIO_meth_free(my_bio_methods);
961  my_bio_methods = NULL;
962  return NULL;
963  }
964  }
965  return my_bio_methods;
966 }
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)

References 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 896 of file be-secure-openssl.c.

897 {
898  int res = 0;
899 
900  if (buf != NULL)
901  {
902  res = secure_raw_read(((Port *) BIO_get_app_data(h)), buf, size);
903  BIO_clear_retry_flags(h);
904  if (res <= 0)
905  {
906  /* If we were interrupted, tell caller to retry */
907  if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
908  {
909  BIO_set_retry_read(h);
910  }
911  }
912  }
913 
914  return res;
915 }
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:267
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 918 of file be-secure-openssl.c.

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

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 970 of file be-secure-openssl.c.

971 {
972  int ret = 0;
973  BIO *bio;
974  BIO_METHOD *bio_method;
975 
976  bio_method = my_BIO_s_socket();
977  if (bio_method == NULL)
978  {
979  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
980  goto err;
981  }
982  bio = BIO_new(bio_method);
983 
984  if (bio == NULL)
985  {
986  SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
987  goto err;
988  }
989  BIO_set_app_data(bio, port);
990 
991  BIO_set_fd(bio, fd, BIO_NOCLOSE);
992  SSL_set_bio(port->ssl, bio, bio);
993  ret = 1;
994 err:
995  return ret;
996 }
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 1132 of file be-secure-openssl.c.

1133 {
1134  size_t namelen = strlen(name);
1135  char *truncated = name;
1136 
1137  /*
1138  * Common Names are 64 chars max, so for a common case where the CN is the
1139  * last field, we can still print the longest possible CN with a
1140  * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
1141  * characters.
1142  */
1143 #define MAXLEN 71
1144 
1145  if (namelen > MAXLEN)
1146  {
1147  /*
1148  * Keep the end of the name, not the beginning, since the most
1149  * specific field is likely to give users the most information.
1150  */
1151  truncated = name + namelen - MAXLEN;
1152  truncated[0] = truncated[1] = truncated[2] = '.';
1153  namelen = MAXLEN;
1154  }
1155 
1156 #undef MAXLEN
1157 
1158  return pg_clean_ascii(truncated, 0);
1159 }
#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 1095 of file be-secure-openssl.c.

1096 {
1097  /* same prompt as OpenSSL uses internally */
1098  const char *prompt = "Enter PEM pass phrase:";
1099 
1100  Assert(rwflag == 0);
1101 
1103 }
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 1670 of file be-secure-openssl.c.

1671 {
1672  switch (v)
1673  {
1674  case PG_TLS_ANY:
1675  return 0;
1676  case PG_TLS1_VERSION:
1677  return TLS1_VERSION;
1678  case PG_TLS1_1_VERSION:
1679 #ifdef TLS1_1_VERSION
1680  return TLS1_1_VERSION;
1681 #else
1682  break;
1683 #endif
1684  case PG_TLS1_2_VERSION:
1685 #ifdef TLS1_2_VERSION
1686  return TLS1_2_VERSION;
1687 #else
1688  break;
1689 #endif
1690  case PG_TLS1_3_VERSION:
1691 #ifdef TLS1_3_VERSION
1692  return TLS1_3_VERSION;
1693 #else
1694  break;
1695 #endif
1696  }
1697 
1698  return -1;
1699 }
@ 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 1705 of file be-secure-openssl.c.

1706 {
1707  switch (v)
1708  {
1709  case PG_TLS_ANY:
1710  return "any";
1711  case PG_TLS1_VERSION:
1712  return "TLSv1";
1713  case PG_TLS1_1_VERSION:
1714  return "TLSv1.1";
1715  case PG_TLS1_2_VERSION:
1716  return "TLSv1.2";
1717  case PG_TLS1_3_VERSION:
1718  return "TLSv1.3";
1719  }
1720 
1721  return "(unrecognized)";
1722 }

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 1434 of file be-secure-openssl.c.

1435 {
1436  const char *errreason;
1437  static char errbuf[36];
1438 
1439  if (ecode == 0)
1440  return _("no SSL error reported");
1441  errreason = ERR_reason_error_string(ecode);
1442  if (errreason != NULL)
1443  return errreason;
1444 
1445  /*
1446  * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
1447  * errno values anymore. (See OpenSSL source code for the explanation.)
1448  * We can cover that shortcoming with this bit of code. Older OpenSSL
1449  * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
1450  * they don't have the shortcoming either.
1451  */
1452 #ifdef ERR_SYSTEM_ERROR
1453  if (ERR_SYSTEM_ERROR(ecode))
1454  return strerror(ERR_GET_REASON(ecode));
1455 #endif
1456 
1457  /* No choice but to report the numeric ecode */
1458  snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1459  return errbuf;
1460 }
#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 1172 of file be-secure-openssl.c.

1173 {
1174  int depth;
1175  int errcode;
1176  const char *errstring;
1178  X509 *cert;
1179 
1180  if (ok)
1181  {
1182  /* Nothing to do for the successful case. */
1183  return ok;
1184  }
1185 
1186  /* Pull all the information we have on the verification failure. */
1187  depth = X509_STORE_CTX_get_error_depth(ctx);
1188  errcode = X509_STORE_CTX_get_error(ctx);
1189  errstring = X509_verify_cert_error_string(errcode);
1190 
1191  initStringInfo(&str);
1193  _("Client certificate verification failed at depth %d: %s."),
1194  depth, errstring);
1195 
1196  cert = X509_STORE_CTX_get_current_cert(ctx);
1197  if (cert)
1198  {
1199  char *subject,
1200  *issuer;
1201  char *sub_prepared,
1202  *iss_prepared;
1203  char *serialno;
1204  ASN1_INTEGER *sn;
1205  BIGNUM *b;
1206 
1207  /*
1208  * Get the Subject and Issuer for logging, but don't let maliciously
1209  * huge certs flood the logs, and don't reflect non-ASCII bytes into
1210  * it either.
1211  */
1212  subject = X509_NAME_to_cstring(X509_get_subject_name(cert));
1213  sub_prepared = prepare_cert_name(subject);
1214  pfree(subject);
1215 
1216  issuer = X509_NAME_to_cstring(X509_get_issuer_name(cert));
1217  iss_prepared = prepare_cert_name(issuer);
1218  pfree(issuer);
1219 
1220  /*
1221  * Pull the serial number, too, in case a Subject is still ambiguous.
1222  * This mirrors be_tls_get_peer_serial().
1223  */
1224  sn = X509_get_serialNumber(cert);
1225  b = ASN1_INTEGER_to_BN(sn, NULL);
1226  serialno = BN_bn2dec(b);
1227 
1228  appendStringInfoChar(&str, '\n');
1230  _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1231  sub_prepared, serialno ? serialno : _("unknown"),
1232  iss_prepared);
1233 
1234  BN_free(b);
1235  OPENSSL_free(serialno);
1236  pfree(iss_prepared);
1237  pfree(sub_prepared);
1238  }
1239 
1240  /* Store our detail message to be logged later. */
1241  cert_errdetail = str.data;
1242 
1243  return ok;
1244 }
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 1597 of file be-secure-openssl.c.

1598 {
1599  BIO *membuf = BIO_new(BIO_s_mem());
1600  int i,
1601  nid,
1602  count = X509_NAME_entry_count(name);
1603  X509_NAME_ENTRY *e;
1604  ASN1_STRING *v;
1605  const char *field_name;
1606  size_t size;
1607  char nullterm;
1608  char *sp;
1609  char *dp;
1610  char *result;
1611 
1612  if (membuf == NULL)
1613  ereport(ERROR,
1614  (errcode(ERRCODE_OUT_OF_MEMORY),
1615  errmsg("could not create BIO")));
1616 
1617  (void) BIO_set_close(membuf, BIO_CLOSE);
1618  for (i = 0; i < count; i++)
1619  {
1620  e = X509_NAME_get_entry(name, i);
1621  nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1622  if (nid == NID_undef)
1623  ereport(ERROR,
1624  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1625  errmsg("could not get NID for ASN1_OBJECT object")));
1626  v = X509_NAME_ENTRY_get_data(e);
1627  field_name = OBJ_nid2sn(nid);
1628  if (field_name == NULL)
1629  field_name = OBJ_nid2ln(nid);
1630  if (field_name == NULL)
1631  ereport(ERROR,
1632  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1633  errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1634  BIO_printf(membuf, "/%s=", field_name);
1635  ASN1_STRING_print_ex(membuf, v,
1636  ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1637  | ASN1_STRFLGS_UTF8_CONVERT));
1638  }
1639 
1640  /* ensure null termination of the BIO's content */
1641  nullterm = '\0';
1642  BIO_write(membuf, &nullterm, 1);
1643  size = BIO_get_mem_data(membuf, &sp);
1644  dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1645 
1646  result = pstrdup(dp);
1647  if (dp != sp)
1648  pfree(dp);
1649  if (BIO_free(membuf) != 1)
1650  elog(ERROR, "could not free OpenSSL BIO structure");
1651 
1652  return result;
1653 }
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:1696
@ 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 1295 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 893 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 58 of file be-secure-openssl.c.

Referenced by _PG_init().

◆ SSL_context

SSL_CTX* SSL_context = NULL
static

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