PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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/hashfn.h"
#include "common/string.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "utils/wait_event.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 "lib/simplehash.h"
Include dependency graph for be-secure-openssl.c:

Go to the source code of this file.

Data Structures

struct  HostCacheEntry
 
struct  hosts
 
struct  CallbackErr
 

Macros

#define SH_PREFIX   host_cache
 
#define SH_ELEMENT_TYPE   HostCacheEntry
 
#define SH_KEY_TYPE   const char *
 
#define SH_KEY   hostname
 
#define SH_HASH_KEY(tb, key)   host_cache_pointer(key)
 
#define SH_EQUAL(tb, a, b)   (pg_strcasecmp(a, b) == 0)
 
#define SH_SCOPE   static inline
 
#define SH_DECLARE
 
#define SH_DEFINE
 
#define MAXLEN   71
 

Functions

static uint32 host_cache_pointer (const char *key)
 
static void default_openssl_tls_init (SSL_CTX *context, bool isServerStart)
 
static int port_bio_read (BIO *h, char *buf, int size)
 
static int port_bio_write (BIO *h, const char *buf, int size)
 
static BIO_METHODport_bio_method (void)
 
static int ssl_set_port_bio (Port *port)
 
static DHload_dh_file (char *filename, bool isServerStart)
 
static DHload_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 charSSLerrmessageExt (unsigned long ecode, const char *replacement)
 
static const charSSLerrmessage (unsigned long ecode)
 
static bool init_host_context (HostsLine *host, bool isServerStart)
 
static void host_context_cleanup_cb (void *arg)
 
static charX509_NAME_to_cstring (const X509_NAME *name)
 
static int ssl_protocol_version_to_openssl (int v)
 
static const charssl_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, const void *ptr, size_t len, int *waitfor)
 
static long port_bio_ctrl (BIO *h, int cmd, long num, void *ptr)
 
static charprepare_cert_name (char *name)
 
int be_tls_get_cipher_bits (Port *port)
 
const charbe_tls_get_version (Port *port)
 
const charbe_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)
 
charbe_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_CTXSSL_context = NULL
 
static MemoryContext SSL_hosts_memcxt = NULL
 
static struct hostsSSL_hosts
 
static bool dummy_ssl_passwd_cb_called = false
 
static bool ssl_is_server_start
 
static BIO_METHODport_bio_method_ptr = NULL
 
static const unsigned char alpn_protos [] = PG_ALPN_PROTOCOL_VECTOR
 

Macro Definition Documentation

◆ MAXLEN

#define MAXLEN   71

◆ SH_DECLARE

#define SH_DECLARE

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

◆ SH_DEFINE

#define SH_DEFINE

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

◆ SH_ELEMENT_TYPE

#define SH_ELEMENT_TYPE   HostCacheEntry

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

◆ SH_EQUAL

#define SH_EQUAL (   tb,
  a,
  b 
)    (pg_strcasecmp(a, b) == 0)

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

◆ SH_HASH_KEY

#define SH_HASH_KEY (   tb,
  key 
)    host_cache_pointer(key)

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

◆ SH_KEY

#define SH_KEY   hostname

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

◆ SH_KEY_TYPE

#define SH_KEY_TYPE   const char *

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

◆ SH_PREFIX

#define SH_PREFIX   host_cache

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

◆ SH_SCOPE

#define SH_SCOPE   static inline

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

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

1782{
1783 /*
1784 * Why does OpenSSL provide a helper function that requires a nonconst
1785 * vector when the callback is declared to take a const vector? What are
1786 * we to do with that?
1787 */
1788 int retval;
1789
1790 Assert(userdata != NULL);
1791 Assert(out != NULL);
1792 Assert(outlen != NULL);
1793 Assert(in != NULL);
1794
1795 retval = SSL_select_next_proto((unsigned char **) out, outlen,
1796 alpn_protos, sizeof(alpn_protos),
1797 in, inlen);
1798 if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
1799 return SSL_TLSEXT_ERR_NOACK; /* can't happen */
1800
1801 if (retval == OPENSSL_NPN_NEGOTIATED)
1802 return SSL_TLSEXT_ERR_OK;
1803 else
1804 {
1805 /*
1806 * The client doesn't support our protocol. Reject the connection
1807 * with TLS "no_application_protocol" alert, per RFC 7301.
1808 */
1810 }
1811}
static const unsigned char alpn_protos[]
#define Assert(condition)
Definition c.h:943
static int fb(int x)

References alpn_protos, Assert, and fb().

Referenced by be_tls_open_server().

◆ be_tls_close()

void be_tls_close ( Port port)

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

1167{
1168 if (port->ssl)
1169 {
1170 SSL_shutdown(port->ssl);
1171 SSL_free(port->ssl);
1172 port->ssl = NULL;
1173 port->ssl_in_use = false;
1174 }
1175
1176 if (port->peer)
1177 {
1178 X509_free(port->peer);
1179 port->peer = NULL;
1180 }
1181
1182 if (port->peer_cn)
1183 {
1184 pfree(port->peer_cn);
1185 port->peer_cn = NULL;
1186 }
1187
1188 if (port->peer_dn)
1189 {
1190 pfree(port->peer_dn);
1191 port->peer_dn = NULL;
1192 }
1193}
void pfree(void *pointer)
Definition mcxt.c:1619
static int port
Definition pg_regress.c:117

References fb(), pfree(), and port.

Referenced by secure_close().

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

824{
825 if (SSL_context)
829}
static SSL_CTX * SSL_context

References fb(), and 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 2269 of file be-secure-openssl.c.

2270{
2272 char *cert_hash;
2273 const EVP_MD *algo_type = NULL;
2274 unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
2275 unsigned int hash_size;
2276 int algo_nid;
2277
2278 *len = 0;
2280 if (server_cert == NULL)
2281 return NULL;
2282
2283 /*
2284 * Get the signature algorithm of the certificate to determine the hash
2285 * algorithm to use for the result. Prefer X509_get_signature_info(),
2286 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
2287 */
2288#if HAVE_X509_GET_SIGNATURE_INFO
2290#else
2292 &algo_nid, NULL))
2293#endif
2294 elog(ERROR, "could not determine server certificate signature algorithm");
2295
2296 /*
2297 * The TLS server's certificate bytes need to be hashed with SHA-256 if
2298 * its signature algorithm is MD5 or SHA-1 as per RFC 5929
2299 * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
2300 * is used, the same hash as the signature algorithm is used.
2301 */
2302 switch (algo_nid)
2303 {
2304 case NID_md5:
2305 case NID_sha1:
2307 break;
2308 default:
2310 if (algo_type == NULL)
2311 elog(ERROR, "could not find digest for NID %s",
2313 break;
2314 }
2315
2316 /* generate and save the certificate hash */
2318 elog(ERROR, "could not generate server certificate hash");
2319
2322 *len = hash_size;
2323
2324 return cert_hash;
2325}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
void * palloc(Size size)
Definition mcxt.c:1390
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition rege_dfa.c:724

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

Referenced by read_client_final_message().

◆ be_tls_get_cipher()

const char * be_tls_get_cipher ( Port port)

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

2222{
2223 if (port->ssl)
2224 return SSL_get_cipher(port->ssl);
2225 else
2226 return NULL;
2227}

References fb(), and port.

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

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

2199{
2200 int bits;
2201
2202 if (port->ssl)
2203 {
2204 SSL_get_cipher_bits(port->ssl, &bits);
2205 return bits;
2206 }
2207 else
2208 return 0;
2209}

References fb(), and port.

Referenced by PerformAuthentication(), and pgstat_bestart_security().

◆ be_tls_get_peer_issuer_name()

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

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

2240{
2241 if (port->peer)
2243 else
2244 ptr[0] = '\0';
2245}
static char * X509_NAME_to_cstring(const X509_NAME *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45

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

Referenced by pgstat_bestart_security(), 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 2248 of file be-secure-openssl.c.

2249{
2250 if (port->peer)
2251 {
2253 BIGNUM *b;
2254 char *decimal;
2255
2258 decimal = BN_bn2dec(b);
2259
2260 BN_free(b);
2261 strlcpy(ptr, decimal, len);
2263 }
2264 else
2265 ptr[0] = '\0';
2266}
int b
Definition isn.c:74

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

Referenced by pgstat_bestart_security(), 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 2230 of file be-secure-openssl.c.

2231{
2232 if (port->peer)
2234 else
2235 ptr[0] = '\0';
2236}

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

Referenced by pgstat_bestart_security(), and ssl_client_dn().

◆ be_tls_get_version()

const char * be_tls_get_version ( Port port)

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

2213{
2214 if (port->ssl)
2215 return SSL_get_version(port->ssl);
2216 else
2217 return NULL;
2218}

References fb(), and port.

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

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

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

150{
151 List *pg_hosts = NIL;
152 ListCell *line;
156 char *err_msg = NULL;
158 struct hosts *new_hosts;
159 SSL_CTX *context = NULL;
160 int ssl_ver_min = -1;
161 int ssl_ver_max = -1;
163
164 /*
165 * Since we don't know which host we're using until the ClientHello is
166 * sent, ssl_loaded_verify_locations *always* starts out as false. The
167 * only place it's set to true is in sni_clienthello_cb().
168 */
170
172 "hosts file parser context",
175
176 /* Allocate a tentative replacement for SSL_hosts. */
178
179 /*
180 * Register a reset callback for the memory context which is responsible
181 * for freeing OpenSSL managed allocations upon context deletion. The
182 * callback is allocated here to make sure it gets cleaned up along with
183 * the memory context it's registered for.
184 */
189
190 /*
191 * If ssl_sni is enabled, attempt to load and parse TLS configuration from
192 * the pg_hosts.conf file with the set of hosts returned as a list. If
193 * there are hosts configured they take precedence over the configuration
194 * in postgresql.conf. Make sure to allocate the parsed rows in their own
195 * memory context so that we can delete them easily in case parsing fails.
196 * If ssl_sni is disabled then set the state accordingly to make sure we
197 * instead parse the config from postgresql.conf.
198 *
199 * The reason for not doing everything in this if-else conditional is that
200 * we want to use the same processing of postgresql.conf for when ssl_sni
201 * is off as well as when it's on but the hosts file is missing etc. Thus
202 * we set res to the state and continue with a new conditional instead of
203 * duplicating logic and risk it diverging over time.
204 */
205 if (ssl_sni)
206 {
207 /*
208 * The GUC check hook should have already blocked this but to be on
209 * the safe side we double-check here.
210 */
211#ifndef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
214 errmsg("ssl_sni is not supported with LibreSSL"));
215 goto error;
216#endif
217
218 /* Attempt to load configuration from pg_hosts.conf */
219 res = load_hosts(&pg_hosts, &err_msg);
220
221 /*
222 * pg_hosts.conf is not required to contain configuration, but if it
223 * does we error out in case it fails to load rather than continue to
224 * try the postgresql.conf configuration to avoid silently falling
225 * back on an undesired configuration.
226 */
227 if (res == HOSTSFILE_LOAD_FAILED)
228 {
231 errmsg("could not load \"%s\": %s", "pg_hosts.conf",
232 err_msg ? err_msg : "unknown error"));
233 goto error;
234 }
235 }
236 else
237 res = HOSTSFILE_DISABLED;
238
239 /*
240 * Loading and parsing the hosts file was successful, create configs for
241 * each host entry and add to the list of hosts to be checked during
242 * login.
243 */
244 if (res == HOSTSFILE_LOAD_OK)
245 {
247
248 foreach(line, pg_hosts)
249 {
250 HostsLine *host = lfirst(line);
251
253 goto error;
254
255 /*
256 * The hostname in the config will be set to NULL for the default
257 * host as well as in configs used for non-SNI connections. Lists
258 * of hostnames in pg_hosts.conf are not allowed to contain the
259 * default '*' entry or a '/no_sni/' entry and this is checked
260 * during parsing. Thus we can inspect the head of the hostnames
261 * list for these since they will never be anywhere else.
262 */
263 if (strcmp(linitial(host->hostnames), "*") == 0)
264 {
265 if (new_hosts->default_host)
266 {
269 errmsg("multiple default hosts specified"),
270 errcontext("line %d of configuration file \"%s\"",
271 host->linenumber, host->sourcefile));
272 goto error;
273 }
274
275 new_hosts->default_host = host;
276 }
277 else if (strcmp(linitial(host->hostnames), "/no_sni/") == 0)
278 {
279 if (new_hosts->no_sni)
280 {
283 errmsg("multiple no_sni hosts specified"),
284 errcontext("line %d of configuration file \"%s\"",
285 host->linenumber, host->sourcefile));
286 goto error;
287 }
288
289 new_hosts->no_sni = host;
290 }
291 else
292 {
293 /* Check the hostnames for duplicates */
294 if (!host_cache)
296
297 foreach_ptr(char, hostname, host->hostnames)
298 {
299 HostCacheEntry *entry;
300 bool found;
301
302 entry = host_cache_insert(host_cache, hostname, &found);
303 if (found)
304 {
307 errmsg("multiple entries for host \"%s\" specified",
308 hostname),
309 errcontext("line %d of configuration file \"%s\"",
310 host->linenumber, host->sourcefile));
311 goto error;
312 }
313 else
314 entry->hostname = pstrdup(hostname);
315 }
316
317 /*
318 * At this point we know we have a configuration with a list
319 * of distinct 1..n hostnames for literal string matching with
320 * the SNI extension from the user.
321 */
322 new_hosts->sni = lappend(new_hosts->sni, host);
323 }
324 }
325 }
326
327 /*
328 * If SNI is disabled, then we load configuration from postgresql.conf. If
329 * SNI is enabled but the pg_hosts.conf file doesn't exist, or is empty,
330 * then we also load the config from postgresql.conf.
331 */
332 else if (res == HOSTSFILE_DISABLED || res == HOSTSFILE_EMPTY || res == HOSTSFILE_MISSING)
333 {
334 HostsLine *pgconf = palloc0(sizeof(HostsLine));
335
336#ifdef USE_ASSERT_CHECKING
337 if (res == HOSTSFILE_DISABLED)
338 Assert(ssl_sni == false);
339#endif
340
341 pgconf->ssl_cert = ssl_cert_file;
342 pgconf->ssl_key = ssl_key_file;
343 pgconf->ssl_ca = ssl_ca_file;
344 pgconf->ssl_passphrase_cmd = ssl_passphrase_command;
345 pgconf->ssl_passphrase_reload = ssl_passphrase_command_supports_reload;
346
348 goto error;
349
350 /*
351 * If postgresql.conf is used to configure SSL then by definition it
352 * will be the default context as we don't have per-host config.
353 */
354 new_hosts->default_host = pgconf;
355 }
356
357 /*
358 * Make sure we have at least one configuration loaded to use, without
359 * that we cannot drive a connection so exit.
360 */
361 if (new_hosts->sni == NIL && !new_hosts->default_host && !new_hosts->no_sni)
362 {
365 errmsg("no SSL configurations loaded"),
366 /*- translator: The two %s contain filenames */
367 errhint("If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"",
368 "pg_hosts.conf", "postgresql.conf"));
369 goto error;
370 }
371
372#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
373
374 /*
375 * Create a new SSL context into which we'll load all the configuration
376 * settings. If we fail partway through, we can avoid memory leakage by
377 * freeing this context; we don't install it as active until the end.
378 *
379 * We use SSLv23_method() because it can negotiate use of the highest
380 * mutually supported protocol version, while alternatives like
381 * TLSv1_2_method() permit only one specific version. Note that we don't
382 * actually allow SSL v2 or v3, only TLS protocols (see below).
383 */
384 context = SSL_CTX_new(SSLv23_method());
385 if (!context)
386 {
388 (errmsg("could not create SSL context: %s",
390 goto error;
391 }
392#else
393
394 /*
395 * If the client hello callback isn't supported we want to use the default
396 * context as the one to drive the handshake so avoid creating a new one
397 * and use the already existing default one instead.
398 */
399 context = new_hosts->default_host->ssl_ctx;
400
401 /*
402 * Since we don't allocate a new SSL_CTX here like we do when SNI has been
403 * enabled we need to bump the reference count on context to avoid double
404 * free of the context when using the same cleanup logic across the cases.
405 */
406 SSL_CTX_up_ref(context);
407#endif
408
409 /*
410 * Disable OpenSSL's moving-write-buffer sanity check, because it causes
411 * unnecessary failures in nonblocking send cases.
412 */
414
416 {
418
419 if (ssl_ver_min == -1)
420 {
422 /*- translator: first %s is a GUC option name, second %s is its value */
423 (errmsg("\"%s\" setting \"%s\" not supported by this build",
424 "ssl_min_protocol_version",
425 GetConfigOption("ssl_min_protocol_version",
426 false, false))));
427 goto error;
428 }
429
431 {
433 (errmsg("could not set minimum SSL protocol version")));
434 goto error;
435 }
436 }
437
439 {
441
442 if (ssl_ver_max == -1)
443 {
445 /*- translator: first %s is a GUC option name, second %s is its value */
446 (errmsg("\"%s\" setting \"%s\" not supported by this build",
447 "ssl_max_protocol_version",
448 GetConfigOption("ssl_max_protocol_version",
449 false, false))));
450 goto error;
451 }
452
454 {
456 (errmsg("could not set maximum SSL protocol version")));
457 goto error;
458 }
459 }
460
461 /* Check compatibility of min/max protocols */
464 {
465 /*
466 * No need to check for invalid values (-1) for each protocol number
467 * as the code above would have already generated an error.
468 */
470 {
473 errmsg("could not set SSL protocol version range"),
474 errdetail("\"%s\" cannot be higher than \"%s\"",
475 "ssl_min_protocol_version",
476 "ssl_max_protocol_version")));
477 goto error;
478 }
479 }
480
481 /*
482 * Disallow SSL session tickets. OpenSSL use both stateful and stateless
483 * tickets for TLSv1.3, and stateless ticket for TLSv1.2. SSL_OP_NO_TICKET
484 * is available since 0.9.8f but only turns off stateless tickets. In
485 * order to turn off stateful tickets we need SSL_CTX_set_num_tickets,
486 * which is available since OpenSSL 1.1.1. LibreSSL 3.5.4 (from OpenBSD
487 * 7.1) introduced this API for compatibility, but doesn't support session
488 * tickets at all so it's a no-op there.
489 */
490#ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
491 SSL_CTX_set_num_tickets(context, 0);
492#endif
494
495 /* disallow SSL session caching, too */
497
498 /* disallow SSL compression */
500
501 /*
502 * Disallow SSL renegotiation. This concerns only TLSv1.2 and older
503 * protocol versions, as TLSv1.3 has no support for renegotiation.
504 * SSL_OP_NO_RENEGOTIATION is available in OpenSSL since 1.1.0h (via a
505 * backport from 1.1.1). SSL_OP_NO_CLIENT_RENEGOTIATION is available in
506 * LibreSSL since 2.5.1 disallowing all client-initiated renegotiation
507 * (this is usually on by default).
508 */
509#ifdef SSL_OP_NO_RENEGOTIATION
511#endif
512#ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
514#endif
515
516 /* set up ephemeral DH and ECDH keys */
517 if (!initialize_dh(context, isServerStart))
518 goto error;
519 if (!initialize_ecdh(context, isServerStart))
520 goto error;
521
522 /* set up the allowed cipher list for TLSv1.2 and below */
523 if (SSL_CTX_set_cipher_list(context, SSLCipherList) != 1)
524 {
527 errmsg("could not set the TLSv1.2 cipher list (no valid ciphers available)")));
528 goto error;
529 }
530
531 /*
532 * Set up the allowed cipher suites for TLSv1.3. If the GUC is an empty
533 * string we leave the allowed suites to be the OpenSSL default value.
534 */
535 if (SSLCipherSuites[0])
536 {
537 /* set up the allowed cipher suites */
538 if (SSL_CTX_set_ciphersuites(context, SSLCipherSuites) != 1)
539 {
542 errmsg("could not set the TLSv1.3 cipher suites (no valid ciphers available)")));
543 goto error;
544 }
545 }
546
547 /* Let server choose order */
550
551 /*
552 * Success! Replace any existing SSL_context and host configurations.
553 */
554 if (SSL_context)
555 {
558 }
559
561
564
567 SSL_context = context;
568
569 return 0;
570
571 /*
572 * Clean up by releasing working SSL contexts as well as allocations
573 * performed during parsing. Since all our allocations are done in a
574 * local memory context all we need to do is delete it.
575 */
576error:
577 if (context)
578 SSL_CTX_free(context);
579
582 return -1;
583}
HostsFileLoadResult load_hosts(List **hosts, char **err_msg)
static bool init_host_context(HostsLine *host, 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 void host_context_cleanup_cb(void *arg)
static MemoryContext SSL_hosts_memcxt
static struct hosts * SSL_hosts
static bool initialize_ecdh(SSL_CTX *context, bool isServerStart)
int ssl_min_protocol_version
Definition be-secure.c:61
char * ssl_cert_file
Definition be-secure.c:38
bool SSLPreferServerCiphers
Definition be-secure.c:59
bool ssl_sni
Definition be-secure.c:65
int ssl_max_protocol_version
Definition be-secure.c:62
char * ssl_passphrase_command
Definition be-secure.c:44
bool ssl_passphrase_command_supports_reload
Definition be-secure.c:45
char * SSLCipherSuites
Definition be-secure.c:52
char * SSLCipherList
Definition be-secure.c:53
char * ssl_key_file
Definition be-secure.c:39
char * ssl_ca_file
Definition be-secure.c:40
int errcode(int sqlerrcode)
Definition elog.c:875
#define LOG
Definition elog.h:32
#define errcontext
Definition elog.h:200
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:42
#define ereport(elevel,...)
Definition elog.h:152
#define palloc0_object(type)
Definition fe_memutils.h:90
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
Definition guc.c:4257
#define false
HostsFileLoadResult
Definition libpq.h:160
@ HOSTSFILE_MISSING
Definition libpq.h:164
@ HOSTSFILE_LOAD_OK
Definition libpq.h:161
@ HOSTSFILE_EMPTY
Definition libpq.h:163
@ HOSTSFILE_DISABLED
Definition libpq.h:165
@ HOSTSFILE_LOAD_FAILED
Definition libpq.h:162
List * lappend(List *list, void *datum)
Definition list.c:339
char * pstrdup(const char *in)
Definition mcxt.c:1910
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
Definition mcxt.c:585
void * palloc0(Size size)
Definition mcxt.c:1420
MemoryContext CurrentMemoryContext
Definition mcxt.c:161
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:475
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_SMALL_SIZES
Definition memutils.h:170
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
#define linitial(l)
Definition pg_list.h:178
static char * hostname
Definition pg_regress.c:116
static void error(void)
const char * hostname
List * hostnames
Definition hba.h:155
Definition pg_list.h:54

References ALLOCSET_SMALL_SIZES, AllocSetContextCreate, Assert, CurrentMemoryContext, ereport, errcode(), errcontext, errdetail(), errhint(), errmsg, error(), FATAL, fb(), foreach_ptr, GetConfigOption(), host_context_cleanup_cb(), HostCacheEntry::hostname, hostname, HostsLine::hostnames, HOSTSFILE_DISABLED, HOSTSFILE_EMPTY, HOSTSFILE_LOAD_FAILED, HOSTSFILE_LOAD_OK, HOSTSFILE_MISSING, init_host_context(), initialize_dh(), initialize_ecdh(), lappend(), lfirst, HostsLine::linenumber, linitial, load_hosts(), LOG, MemoryContextDelete(), MemoryContextRegisterResetCallback(), MemoryContextSwitchTo(), NIL, palloc0(), palloc0_object, pstrdup(), HostsLine::sourcefile, ssl_ca_file, ssl_cert_file, SSL_context, SSL_hosts, SSL_hosts_memcxt, ssl_key_file, ssl_max_protocol_version, ssl_min_protocol_version, ssl_passphrase_command, ssl_passphrase_command_supports_reload, ssl_protocol_version_to_openssl(), ssl_sni, SSLCipherList, SSLCipherSuites, SSLerrmessage(), and SSLPreferServerCiphers.

Referenced by secure_initialize().

◆ be_tls_open_server()

int be_tls_open_server ( Port port)

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

833{
834 int r;
835 int err;
836 int waitfor;
837 unsigned long ecode;
838 bool give_proto_hint;
839 static struct CallbackErr err_context;
840
841 Assert(!port->ssl);
842 Assert(!port->peer);
843
844 if (!SSL_context)
845 {
848 errmsg("could not initialize SSL connection: SSL context not set up")));
849 return -1;
850 }
851
852 /* set up debugging/info callback */
854
855 /* enable ALPN */
857
858 if (!(port->ssl = SSL_new(SSL_context)))
859 {
862 errmsg("could not initialize SSL connection: %s",
864 return -1;
865 }
867 {
870 errmsg("could not set SSL socket: %s",
872 return -1;
873 }
874
875 /*
876 * If the underlying TLS library supports the client hello callback we use
877 * that in order to support host based configuration using the SNI TLS
878 * extension. If the user has disabled SNI via the ssl_sni GUC we still
879 * make use of the callback in order to have consistent handling of
880 * OpenSSL contexts, except in that case the callback will install the
881 * default configuration regardless of the hostname sent by the user in
882 * the handshake.
883 *
884 * In case the TLS library does not support the client hello callback, as
885 * of this writing LibreSSL does not, we need to install the client cert
886 * verification callback here (if the user configured a CA) since we
887 * cannot use the OpenSSL context update functionality.
888 */
889#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
891#else
893 {
894 /*
895 * Always ask for SSL client cert, but don't fail if it's not
896 * presented. We might fail such connections later, depending on what
897 * we find in pg_hba.conf.
898 */
899 SSL_set_verify(port->ssl,
901 verify_cb);
902
904 }
905#endif
906
907 err_context.cert_errdetail = NULL;
909
910 port->ssl_in_use = true;
911
912aloop:
913
914 /*
915 * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
916 * queue. In general, the current thread's error queue must be empty
917 * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
918 * not work reliably. An extension may have failed to clear the
919 * per-thread error queue following another call to an OpenSSL I/O
920 * routine.
921 */
922 errno = 0;
924 r = SSL_accept(port->ssl);
925 if (r <= 0)
926 {
927 err = SSL_get_error(port->ssl, r);
928
929 /*
930 * Other clients of OpenSSL in the backend may fail to call
931 * ERR_get_error(), but we always do, so as to not cause problems for
932 * OpenSSL clients that don't call ERR_clear_error() defensively. Be
933 * sure that this happens by calling now. SSL_get_error() relies on
934 * the OpenSSL per-thread error queue being intact, so this is the
935 * earliest possible point ERR_get_error() may be called.
936 */
938 switch (err)
939 {
942 /* not allowed during connection establishment */
943 Assert(!port->noblock);
944
945 /*
946 * No need to care about timeouts/interrupts here. At this
947 * point authentication_timeout still employs
948 * StartupPacketTimeoutHandler() which directly exits.
949 */
952 else
954
957 goto aloop;
959 if (r < 0 && errno != 0)
962 errmsg("could not accept SSL connection: %m")));
963 else
966 errmsg("could not accept SSL connection: EOF detected")));
967 break;
968 case SSL_ERROR_SSL:
969 switch (ERR_GET_REASON(ecode))
970 {
971 /*
972 * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
973 * TLSV1_ALERT_PROTOCOL_VERSION have been observed
974 * when trying to communicate with an old OpenSSL
975 * library, or when the client and server specify
976 * disjoint protocol ranges. NO_PROTOCOLS_AVAILABLE
977 * occurs if there's a local misconfiguration (which
978 * can happen despite our checks, if openssl.cnf
979 * injects a limit we didn't account for). It's not
980 * very clear what would make OpenSSL return the other
981 * codes listed here, but a hint about protocol
982 * versions seems like it's appropriate for all.
983 */
993#ifdef SSL_R_VERSION_TOO_HIGH
995#endif
996#ifdef SSL_R_VERSION_TOO_LOW
998#endif
999 give_proto_hint = true;
1000 break;
1001 default:
1002 give_proto_hint = false;
1003 break;
1004 }
1007 errmsg("could not accept SSL connection: %s",
1009 err_context.cert_errdetail ? errdetail_internal("%s", err_context.cert_errdetail) : 0,
1011 errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
1018 if (err_context.cert_errdetail)
1019 pfree(err_context.cert_errdetail);
1020 break;
1024 errmsg("could not accept SSL connection: EOF detected")));
1025 break;
1026 default:
1029 errmsg("unrecognized SSL error code: %d",
1030 err)));
1031 break;
1032 }
1033 return -1;
1034 }
1035
1036 /* Get the protocol selected by ALPN */
1037 port->alpn_used = false;
1038 {
1039 const unsigned char *selected;
1040 unsigned int len;
1041
1042 SSL_get0_alpn_selected(port->ssl, &selected, &len);
1043
1044 /* If ALPN is used, check that we negotiated the expected protocol */
1045 if (selected != NULL)
1046 {
1047 if (len == strlen(PG_ALPN_PROTOCOL) &&
1049 {
1050 port->alpn_used = true;
1051 }
1052 else
1053 {
1054 /* shouldn't happen */
1057 errmsg("received SSL connection request with unexpected ALPN protocol")));
1058 }
1059 }
1060 }
1061
1062 /* Get client certificate, if available. */
1063 port->peer = SSL_get_peer_certificate(port->ssl);
1064
1065 /* and extract the Common Name and Distinguished Name from it. */
1066 port->peer_cn = NULL;
1067 port->peer_dn = NULL;
1068 port->peer_cert_valid = false;
1069 if (port->peer != NULL)
1070 {
1071 int len;
1073 char *peer_dn;
1074 BIO *bio = NULL;
1075 BUF_MEM *bio_buf = NULL;
1076
1078 if (len != -1)
1079 {
1080 char *peer_cn;
1081
1082 peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
1084 len + 1);
1085 peer_cn[len] = '\0';
1086 if (r != len)
1087 {
1088 /* shouldn't happen */
1089 pfree(peer_cn);
1090 return -1;
1091 }
1092
1093 /*
1094 * Reject embedded NULLs in certificate common name to prevent
1095 * attacks like CVE-2009-4034.
1096 */
1097 if (len != strlen(peer_cn))
1098 {
1101 errmsg("SSL certificate's common name contains embedded null")));
1102 pfree(peer_cn);
1103 return -1;
1104 }
1105
1106 port->peer_cn = peer_cn;
1107 }
1108
1109 bio = BIO_new(BIO_s_mem());
1110 if (!bio)
1111 {
1112 if (port->peer_cn != NULL)
1113 {
1114 pfree(port->peer_cn);
1115 port->peer_cn = NULL;
1116 }
1117 return -1;
1118 }
1119
1120 /*
1121 * RFC2253 is the closest thing to an accepted standard format for
1122 * DNs. We have documented how to produce this format from a
1123 * certificate. It uses commas instead of slashes for delimiters,
1124 * which make regular expression matching a bit easier. Also note that
1125 * it prints the Subject fields in reverse order.
1126 */
1128 BIO_get_mem_ptr(bio, &bio_buf) <= 0)
1129 {
1130 BIO_free(bio);
1131 if (port->peer_cn != NULL)
1132 {
1133 pfree(port->peer_cn);
1134 port->peer_cn = NULL;
1135 }
1136 return -1;
1137 }
1138 peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
1139 memcpy(peer_dn, bio_buf->data, bio_buf->length);
1140 len = bio_buf->length;
1141 BIO_free(bio);
1142 peer_dn[len] = '\0';
1143 if (len != strlen(peer_dn))
1144 {
1147 errmsg("SSL certificate's distinguished name contains embedded null")));
1148 pfree(peer_dn);
1149 if (port->peer_cn != NULL)
1150 {
1151 pfree(port->peer_cn);
1152 port->peer_cn = NULL;
1153 }
1154 return -1;
1155 }
1156
1157 port->peer_dn = peer_dn;
1158
1159 port->peer_cert_valid = true;
1160 }
1161
1162 return 0;
1163}
static const char * ssl_protocol_version_to_string(int v)
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 ssl_set_port_bio(Port *port)
static int verify_cb(int ok, X509_STORE_CTX *ctx)
#define unconstify(underlying_type, expr)
Definition c.h:1325
int errcode_for_socket_access(void)
Definition elog.c:977
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
#define COMMERROR
Definition elog.h:34
void err(int eval, const char *fmt,...)
Definition err.c:43
#define ERRCODE_PROTOCOL_VIOLATION
Definition fe-connect.c:96
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
Definition latch.c:223
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1235
MemoryContext TopMemoryContext
Definition mcxt.c:167
#define PG_ALPN_PROTOCOL
Definition pqcomm.h:189
char * ssl_ca
Definition hba.h:160
HostsLine * default_host
#define WL_SOCKET_READABLE
#define WL_EXIT_ON_PM_DEATH
#define WL_SOCKET_WRITEABLE

References alpn_cb(), Assert, COMMERROR, hosts::default_host, ereport, err(), errcode(), errcode_for_socket_access(), ERRCODE_PROTOCOL_VIOLATION, errdetail_internal(), errhint(), errmsg, fb(), info_cb(), len, memcpy(), MemoryContextAlloc(), pfree(), PG_ALPN_PROTOCOL, port, HostsLine::ssl_ca, SSL_context, SSL_hosts, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_string(), ssl_set_port_bio(), SSLerrmessage(), TopMemoryContext, unconstify, verify_cb(), 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 1196 of file be-secure-openssl.c.

1197{
1198 ssize_t n;
1199 int err;
1200 unsigned long ecode;
1201
1202 errno = 0;
1204 n = SSL_read(port->ssl, ptr, len);
1205 err = SSL_get_error(port->ssl, n);
1206 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
1207 switch (err)
1208 {
1209 case SSL_ERROR_NONE:
1210 /* a-ok */
1211 break;
1215 n = -1;
1216 break;
1220 n = -1;
1221 break;
1222 case SSL_ERROR_SYSCALL:
1223 /* leave it to caller to ereport the value of errno */
1224 if (n != -1 || errno == 0)
1225 {
1226 errno = ECONNRESET;
1227 n = -1;
1228 }
1229 break;
1230 case SSL_ERROR_SSL:
1233 errmsg("SSL error: %s", SSLerrmessage(ecode))));
1234 errno = ECONNRESET;
1235 n = -1;
1236 break;
1238 /* connection was cleanly shut down by peer */
1239 n = 0;
1240 break;
1241 default:
1244 errmsg("unrecognized SSL error code: %d",
1245 err)));
1246 errno = ECONNRESET;
1247 n = -1;
1248 break;
1249 }
1250
1251 return n;
1252}
#define EWOULDBLOCK
Definition win32_port.h:367
#define ECONNRESET
Definition win32_port.h:371

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

Referenced by secure_read().

◆ be_tls_write()

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

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

1256{
1257 ssize_t n;
1258 int err;
1259 unsigned long ecode;
1260
1261 errno = 0;
1263 n = SSL_write(port->ssl, ptr, len);
1264 err = SSL_get_error(port->ssl, n);
1265 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
1266 switch (err)
1267 {
1268 case SSL_ERROR_NONE:
1269 /* a-ok */
1270 break;
1274 n = -1;
1275 break;
1279 n = -1;
1280 break;
1281 case SSL_ERROR_SYSCALL:
1282
1283 /*
1284 * Leave it to caller to ereport the value of errno. However, if
1285 * errno is still zero then assume it's a read EOF situation, and
1286 * report ECONNRESET. (This seems possible because SSL_write can
1287 * also do reads.)
1288 */
1289 if (n != -1 || errno == 0)
1290 {
1291 errno = ECONNRESET;
1292 n = -1;
1293 }
1294 break;
1295 case SSL_ERROR_SSL:
1298 errmsg("SSL error: %s", SSLerrmessage(ecode))));
1299 errno = ECONNRESET;
1300 n = -1;
1301 break;
1303
1304 /*
1305 * the SSL connection was closed, leave it to the caller to
1306 * ereport it
1307 */
1308 errno = ECONNRESET;
1309 n = -1;
1310 break;
1311 default:
1314 errmsg("unrecognized SSL error code: %d",
1315 err)));
1316 errno = ECONNRESET;
1317 n = -1;
1318 break;
1319 }
1320
1321 return n;
1322}

References COMMERROR, ECONNRESET, ereport, err(), errcode(), ERRCODE_PROTOCOL_VIOLATION, errmsg, EWOULDBLOCK, fb(), 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 2475 of file be-secure-openssl.c.

2476{
2477 if (isServerStart)
2478 {
2480 {
2483 }
2484 }
2485 else
2486 {
2488 {
2491 }
2492 else
2493
2494 /*
2495 * If reloading and no external command is configured, override
2496 * OpenSSL's default handling of passphrase-protected files,
2497 * because we don't want to prompt for a passphrase in an
2498 * already-running server.
2499 */
2501 }
2502}
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)

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

Referenced by init_host_context().

◆ dummy_ssl_passwd_cb()

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

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

1581{
1582 /* Set flag to change the error message we'll report */
1584 /* And return empty string */
1585 Assert(size > 0);
1586 buf[0] = '\0';
1587 return 0;
1588}
static bool dummy_ssl_passwd_cb_called
static char buf[DEFAULT_XLOG_SEG_SIZE]

References Assert, buf, and dummy_ssl_passwd_cb_called.

Referenced by default_openssl_tls_init(), and init_host_context().

◆ host_cache_pointer()

static uint32 host_cache_pointer ( const char key)
static

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

2461{
2462 uint32 hash;
2463 char *lkey = pstrdup(key);
2464 int len = strlen(key);
2465
2466 for (int i = 0; i < len; i++)
2467 lkey[i] = pg_tolower(lkey[i]);
2468
2469 hash = string_hash((const void *) lkey, len);
2470 pfree(lkey);
2471 return hash;
2472}
uint32_t uint32
Definition c.h:624
uint32 string_hash(const void *key, Size keysize)
Definition hashfn.c:660
int i
Definition isn.c:77
unsigned char pg_tolower(unsigned char ch)

References fb(), hash(), i, len, pfree(), pg_tolower(), pstrdup(), and string_hash().

◆ host_context_cleanup_cb()

static void host_context_cleanup_cb ( void arg)
static

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

595{
596 struct hosts *hosts = arg;
597
599 {
600 if (host->ssl_ctx != NULL)
601 SSL_CTX_free(host->ssl_ctx);
602 }
603
604 if (hosts->no_sni && hosts->no_sni->ssl_ctx)
606
609}
Datum arg
Definition elog.c:1323
void * ssl_ctx
Definition hba.h:165
HostsLine * no_sni

References arg, hosts::default_host, fb(), foreach_ptr, hosts::no_sni, hosts::sni, and HostsLine::ssl_ctx.

Referenced by be_tls_init().

◆ info_cb()

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

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

1726{
1727 const char *desc;
1728
1729 desc = SSL_state_string_long(ssl);
1730
1731 switch (type)
1732 {
1735 (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1736 break;
1739 (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1740 break;
1741 case SSL_CB_ACCEPT_LOOP:
1743 (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1744 break;
1745 case SSL_CB_ACCEPT_EXIT:
1747 (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1748 break;
1751 (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1752 break;
1755 (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1756 break;
1757 case SSL_CB_READ_ALERT:
1759 (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1760 break;
1761 case SSL_CB_WRITE_ALERT:
1763 (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1764 break;
1765 }
1766}
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG4
Definition elog.h:28
const char * type

References DEBUG4, ereport, errmsg_internal(), fb(), and type.

Referenced by be_tls_open_server().

◆ init_host_context()

static bool init_host_context ( HostsLine host,
bool  isServerStart 
)
static

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

613{
615 static bool init_warned = false;
616
617 if (!ctx)
618 {
620 (errmsg("could not create SSL context: %s",
622 goto error;
623 }
624
625 /*
626 * Call init hook (usually to set password callback) in case SNI hasn't
627 * been enabled. If SNI is enabled the hook won't operate on the actual
628 * TLS context used so it cannot function properly; we warn if one has
629 * been installed.
630 *
631 * If SNI is enabled, we set password callback based what was configured.
632 */
633 if (!ssl_sni)
634 (*openssl_tls_init_hook) (ctx, isServerStart);
635 else
636 {
638 {
641 errmsg("SNI is enabled; installed TLS init hook will be ignored"),
642 /*- translator: first %s is a GUC, second %s contains a filename */
643 errhint("TLS init hooks are incompatible with SNI. "
644 "Set \"%s\" to \"off\" to make use of the hook "
645 "that is currently installed, or remove the hook "
646 "and use per-host passphrase commands in \"%s\".",
647 "ssl_sni", "pg_hosts.conf"));
648 init_warned = true;
649 }
650
651 /*
652 * Set up the password callback, if configured.
653 */
654 if (isServerStart)
655 {
656 if (host->ssl_passphrase_cmd && host->ssl_passphrase_cmd[0])
657 {
660 }
661 }
662 else
663 {
664 /*
665 * If ssl_passphrase_reload is true then ssl_passphrase_cmd cannot
666 * be NULL due to their parsing order, but just in case and to
667 * self-document the code we replicate the nullness checks.
668 */
669 if (host->ssl_passphrase_reload &&
670 (host->ssl_passphrase_cmd && host->ssl_passphrase_cmd[0]))
671 {
674 }
675 else
676 {
677 /*
678 * If reloading and no external command is configured,
679 * override OpenSSL's default handling of passphrase-protected
680 * files, because we don't want to prompt for a passphrase in
681 * an already-running server.
682 */
684 }
685 }
686 }
687
688 /*
689 * Load and verify server's certificate and private key
690 */
691 if (SSL_CTX_use_certificate_chain_file(ctx, host->ssl_cert) != 1)
692 {
695 errmsg("could not load server certificate file \"%s\": %s",
697 goto error;
698 }
699
701 goto error;
702
703
704 /* used by the callback */
706
707 /*
708 * OK, try to load the private key file.
709 */
711
713 host->ssl_key,
714 SSL_FILETYPE_PEM) != 1)
715 {
719 errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
720 host->ssl_key)));
721 else
724 errmsg("could not load private key file \"%s\": %s",
726 goto error;
727 }
728
729 if (SSL_CTX_check_private_key(ctx) != 1)
730 {
733 errmsg("check of private key failed: %s",
735 goto error;
736 }
737
738 /*
739 * Load CA store, so we can verify client certificates if needed.
740 */
741 if (host->ssl_ca && host->ssl_ca[0])
742 {
744
745 if (SSL_CTX_load_verify_locations(ctx, host->ssl_ca, NULL) != 1 ||
747 {
750 errmsg("could not load root certificate file \"%s\": %s",
751 host->ssl_ca, SSLerrmessage(ERR_get_error()))));
752 goto error;
753 }
754
755 /*
756 * Tell OpenSSL to send the list of root certs we trust to clients in
757 * CertificateRequests. This lets a client with a keystore select the
758 * appropriate client certificate to send to us. Also, this ensures
759 * that the SSL context will "own" the root_cert_list and remember to
760 * free it when no longer needed.
761 */
763 }
764
765 /*----------
766 * Load the Certificate Revocation List (CRL).
767 * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
768 *----------
769 */
770 if (ssl_crl_file[0] || ssl_crl_dir[0])
771 {
773
774 if (cvstore)
775 {
776 /* Set the flags to check against the complete CRL chain */
780 == 1)
781 {
784 }
785 else if (ssl_crl_dir[0] == 0)
786 {
789 errmsg("could not load SSL certificate revocation list file \"%s\": %s",
791 goto error;
792 }
793 else if (ssl_crl_file[0] == 0)
794 {
797 errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
799 goto error;
800 }
801 else
802 {
805 errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
808 goto error;
809 }
810 }
811 }
812
813 host->ssl_ctx = ctx;
814 return true;
815
816error:
817 if (ctx)
818 SSL_CTX_free(ctx);
819 return false;
820}
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
openssl_tls_init_hook_typ openssl_tls_init_hook
static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
static bool ssl_is_server_start
char * ssl_crl_dir
Definition be-secure.c:42
char * ssl_crl_file
Definition be-secure.c:41
#define WARNING
Definition elog.h:37
char * ssl_passphrase_cmd
Definition hba.h:161
char * ssl_key
Definition hba.h:156
bool ssl_passphrase_reload
Definition hba.h:162
char * ssl_cert
Definition hba.h:157

References check_ssl_key_file_permissions(), default_openssl_tls_init(), dummy_ssl_passwd_cb(), dummy_ssl_passwd_cb_called, ereport, errcode(), errhint(), errmsg, error(), FATAL, fb(), LOG, openssl_tls_init_hook, HostsLine::ssl_ca, HostsLine::ssl_cert, ssl_crl_dir, ssl_crl_file, HostsLine::ssl_ctx, ssl_external_passwd_cb(), ssl_is_server_start, HostsLine::ssl_key, HostsLine::ssl_passphrase_cmd, HostsLine::ssl_passphrase_reload, ssl_sni, SSLerrmessage(), and WARNING.

Referenced by be_tls_init().

◆ initialize_dh()

static bool initialize_dh ( SSL_CTX context,
bool  isServerStart 
)
static

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

2077{
2078 DH *dh = NULL;
2079
2081
2082 if (ssl_dh_params_file[0])
2084 if (!dh)
2086 if (!dh)
2087 {
2090 errmsg("DH: could not load DH parameters")));
2091 return false;
2092 }
2093
2094 if (SSL_CTX_set_tmp_dh(context, dh) != 1)
2095 {
2098 errmsg("DH: could not set DH parameters: %s",
2100 DH_free(dh);
2101 return false;
2102 }
2103
2104 DH_free(dh);
2105 return true;
2106}
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:43

References ereport, errcode(), errmsg, FATAL, fb(), 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 2114 of file be-secure-openssl.c.

2115{
2116 if (SSL_CTX_set1_groups_list(context, SSLECDHCurve) != 1)
2117 {
2118 /*
2119 * OpenSSL 3.3.0 introduced proper error messages for group parsing
2120 * errors, earlier versions returns "no SSL error reported" which is
2121 * far from helpful. For older versions, we replace with a better
2122 * error message. Injecting the error into the OpenSSL error queue
2123 * need APIs from OpenSSL 3.0.
2124 */
2127 errmsg("could not set group names specified in ssl_groups: %s",
2129 _("No valid groups found"))),
2130 errhint("Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL."));
2131 return false;
2132 }
2133
2134 return true;
2135}
static const char * SSLerrmessageExt(unsigned long ecode, const char *replacement)
char * SSLECDHCurve
Definition be-secure.c:56
#define _(x)
Definition elog.c:96

References _, ereport, errcode(), errhint(), errmsg, FATAL, fb(), LOG, SSLECDHCurve, and SSLerrmessageExt().

Referenced by be_tls_init().

◆ load_dh_buffer()

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

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

1538{
1539 BIO *bio;
1540 DH *dh = NULL;
1541
1542 bio = BIO_new_mem_buf(buffer, len);
1543 if (bio == NULL)
1544 return NULL;
1546 if (dh == NULL)
1548 (errmsg_internal("DH load buffer: %s",
1550 BIO_free(bio);
1551
1552 return dh;
1553}
#define DEBUG2
Definition elog.h:30

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

Referenced by initialize_dh().

◆ load_dh_file()

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

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

1471{
1472 FILE *fp;
1473 DH *dh = NULL;
1474 int codes;
1475
1476 /* attempt to open file. It's not an error if it doesn't exist. */
1477 if ((fp = AllocateFile(filename, "r")) == NULL)
1478 {
1481 errmsg("could not open DH parameters file \"%s\": %m",
1482 filename)));
1483 return NULL;
1484 }
1485
1487 FreeFile(fp);
1488
1489 if (dh == NULL)
1490 {
1493 errmsg("could not load DH parameters file: %s",
1495 return NULL;
1496 }
1497
1498 /* make sure the DH parameters are usable */
1499 if (DH_check(dh, &codes) == 0)
1500 {
1503 errmsg("invalid DH parameters: %s",
1505 DH_free(dh);
1506 return NULL;
1507 }
1509 {
1512 errmsg("invalid DH parameters: p is not prime")));
1513 DH_free(dh);
1514 return NULL;
1515 }
1518 {
1521 errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1522 DH_free(dh);
1523 return NULL;
1524 }
1525
1526 return dh;
1527}
int errcode_for_file_access(void)
Definition elog.c:898
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
static char * filename
Definition pg_dumpall.c:133

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

Referenced by initialize_dh().

◆ port_bio_ctrl()

static long port_bio_ctrl ( BIO h,
int  cmd,
long  num,
void ptr 
)
static

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

1387{
1388 long res;
1389 Port *port = (Port *) BIO_get_data(h);
1390
1391 switch (cmd)
1392 {
1393 case BIO_CTRL_EOF:
1394
1395 /*
1396 * This should not be needed. port_bio_read already has a way to
1397 * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
1398 * backwards-incompatible change and now expects EOF via BIO_ctrl.
1399 * See https://github.com/openssl/openssl/issues/8208
1400 */
1401 res = port->last_read_was_eof;
1402 break;
1403 case BIO_CTRL_FLUSH:
1404 /* libssl expects all BIOs to support BIO_flush. */
1405 res = 1;
1406 break;
1407 default:
1408 res = 0;
1409 break;
1410 }
1411
1412 return res;
1413}
bool last_read_was_eof
Definition libpq-be.h:213

References fb(), Port::last_read_was_eof, and port.

Referenced by port_bio_method().

◆ port_bio_method()

static BIO_METHOD * port_bio_method ( void  )
static

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

1417{
1419 {
1420 int my_bio_index;
1421
1423 if (my_bio_index == -1)
1424 return NULL;
1426 port_bio_method_ptr = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
1428 return NULL;
1432 {
1435 return NULL;
1436 }
1437 }
1438 return port_bio_method_ptr;
1439}
static long port_bio_ctrl(BIO *h, int cmd, long num, void *ptr)
static BIO_METHOD * port_bio_method_ptr
static int port_bio_read(BIO *h, char *buf, int size)
static int port_bio_write(BIO *h, const char *buf, int size)

References fb(), port_bio_ctrl(), port_bio_method_ptr, port_bio_read(), and port_bio_write().

Referenced by ssl_set_port_bio().

◆ port_bio_read()

static int port_bio_read ( BIO h,
char buf,
int  size 
)
static

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

1344{
1345 int res = 0;
1346 Port *port = (Port *) BIO_get_data(h);
1347
1348 if (buf != NULL)
1349 {
1350 res = secure_raw_read(port, buf, size);
1352 port->last_read_was_eof = res == 0;
1353 if (res <= 0)
1354 {
1355 /* If we were interrupted, tell caller to retry */
1356 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
1357 {
1359 }
1360 }
1361 }
1362
1363 return res;
1364}
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition be-secure.c:272
#define EINTR
Definition win32_port.h:361
#define EAGAIN
Definition win32_port.h:359

References buf, EAGAIN, EINTR, EWOULDBLOCK, fb(), port, and secure_raw_read().

Referenced by port_bio_method().

◆ port_bio_write()

static int port_bio_write ( BIO h,
const char buf,
int  size 
)
static

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

1368{
1369 int res = 0;
1370
1371 res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
1373 if (res <= 0)
1374 {
1375 /* If we were interrupted, tell caller to retry */
1376 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
1377 {
1379 }
1380 }
1381
1382 return res;
1383}
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition be-secure.c:381

References buf, EAGAIN, EINTR, EWOULDBLOCK, fb(), and secure_raw_write().

Referenced by port_bio_method().

◆ prepare_cert_name()

static char * prepare_cert_name ( char name)
static

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

1598{
1599 size_t namelen = strlen(name);
1600 char *truncated = name;
1601
1602 /*
1603 * Common Names are 64 chars max, so for a common case where the CN is the
1604 * last field, we can still print the longest possible CN with a
1605 * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
1606 * characters.
1607 */
1608#define MAXLEN 71
1609
1610 if (namelen > MAXLEN)
1611 {
1612 /*
1613 * Keep the end of the name, not the beginning, since the most
1614 * specific field is likely to give users the most information.
1615 */
1616 truncated = name + namelen - MAXLEN;
1617 truncated[0] = truncated[1] = truncated[2] = '.';
1618 namelen = MAXLEN;
1619 }
1620
1621#undef MAXLEN
1622
1623 return pg_clean_ascii(truncated, 0);
1624}
#define MAXLEN
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition string.c:85
const char * name

References fb(), 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 1559 of file be-secure-openssl.c.

1560{
1561 /* same prompt as OpenSSL uses internally */
1562 const char *prompt = "Enter PEM pass phrase:";
1563 const char *cmd = userdata;
1564
1565 Assert(rwflag == 0);
1566
1568}
int run_ssl_passphrase_command(const char *cmd, const char *prompt, bool is_server_start, char *buf, int size)

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

Referenced by default_openssl_tls_init(), and init_host_context().

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( int  v)
static

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

2406{
2407 switch (v)
2408 {
2409 case PG_TLS_ANY:
2410 return 0;
2411 case PG_TLS1_VERSION:
2412 return TLS1_VERSION;
2413 case PG_TLS1_1_VERSION:
2414#ifdef TLS1_1_VERSION
2415 return TLS1_1_VERSION;
2416#else
2417 break;
2418#endif
2419 case PG_TLS1_2_VERSION:
2420#ifdef TLS1_2_VERSION
2421 return TLS1_2_VERSION;
2422#else
2423 break;
2424#endif
2425 case PG_TLS1_3_VERSION:
2426#ifdef TLS1_3_VERSION
2427 return TLS1_3_VERSION;
2428#else
2429 break;
2430#endif
2431 }
2432
2433 return -1;
2434}
@ PG_TLS1_VERSION
Definition libpq.h:153
@ PG_TLS1_3_VERSION
Definition libpq.h:156
@ PG_TLS1_1_VERSION
Definition libpq.h:154
@ PG_TLS1_2_VERSION
Definition libpq.h:155
@ PG_TLS_ANY
Definition libpq.h:152

References fb(), 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 2440 of file be-secure-openssl.c.

2441{
2442 switch (v)
2443 {
2444 case PG_TLS_ANY:
2445 return "any";
2446 case PG_TLS1_VERSION:
2447 return "TLSv1";
2448 case PG_TLS1_1_VERSION:
2449 return "TLSv1.1";
2450 case PG_TLS1_2_VERSION:
2451 return "TLSv1.2";
2452 case PG_TLS1_3_VERSION:
2453 return "TLSv1.3";
2454 }
2455
2456 return "(unrecognized)";
2457}

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

◆ ssl_set_port_bio()

static int ssl_set_port_bio ( Port port)
static

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

1443{
1444 BIO *bio;
1446
1448 if (bio_method == NULL)
1449 return 0;
1450
1452 if (bio == NULL)
1453 return 0;
1454
1456 BIO_set_init(bio, 1);
1457
1458 SSL_set_bio(port->ssl, bio, bio);
1459 return 1;
1460}
static BIO_METHOD * port_bio_method(void)

References fb(), port, and port_bio_method().

Referenced by be_tls_open_server().

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

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

2170{
2171 const char *errreason;
2172 static char errbuf[36];
2173
2174 if (ecode == 0)
2175 return _("no SSL error reported");
2176 errreason = ERR_reason_error_string(ecode);
2177 if (errreason != NULL)
2178 return errreason;
2179
2180 /*
2181 * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
2182 * errno values anymore. (See OpenSSL source code for the explanation.)
2183 * We can cover that shortcoming with this bit of code. Older OpenSSL
2184 * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
2185 * they don't have the shortcoming either.
2186 */
2187#ifdef ERR_SYSTEM_ERROR
2189 return strerror(ERR_GET_REASON(ecode));
2190#endif
2191
2192 /* No choice but to report the numeric ecode */
2193 snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
2194 return errbuf;
2195}
#define strerror
Definition port.h:274
#define snprintf
Definition port.h:261

References _, fb(), snprintf, and strerror.

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

◆ SSLerrmessageExt()

static const char * SSLerrmessageExt ( unsigned long  ecode,
const char replacement 
)
static

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

2152{
2153 if (ecode == 0)
2154 return replacement;
2155 else
2156 return SSLerrmessage(ecode);
2157}

References fb(), and SSLerrmessage().

Referenced by initialize_ecdh().

◆ verify_cb()

static int verify_cb ( int  ok,
X509_STORE_CTX ctx 
)
static

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

1638{
1639 int depth;
1640 int errcode;
1641 const char *errstring;
1643 X509 *cert;
1644 SSL *ssl;
1645 struct CallbackErr *cb_err;
1646
1647 if (ok)
1648 {
1649 /* Nothing to do for the successful case. */
1650 return ok;
1651 }
1652
1653 /* Pull all the information we have on the verification failure. */
1654 depth = X509_STORE_CTX_get_error_depth(ctx);
1657
1658 /*
1659 * Extract the current SSL and CallbackErr object to use for passing error
1660 * detail back from the callback.
1661 */
1663 cb_err = (struct CallbackErr *) SSL_get_ex_data(ssl, 0);
1664
1667 _("Client certificate verification failed at depth %d: %s."),
1668 depth, errstring);
1669
1671 if (cert)
1672 {
1673 char *subject,
1674 *issuer;
1675 char *sub_prepared,
1676 *iss_prepared;
1677 char *serialno;
1678 ASN1_INTEGER *sn;
1679 BIGNUM *b;
1680
1681 /*
1682 * Get the Subject and Issuer for logging, but don't let maliciously
1683 * huge certs flood the logs, and don't reflect non-ASCII bytes into
1684 * it either.
1685 */
1688 pfree(subject);
1689
1692 pfree(issuer);
1693
1694 /*
1695 * Pull the serial number, too, in case a Subject is still ambiguous.
1696 * This mirrors be_tls_get_peer_serial().
1697 */
1699 b = ASN1_INTEGER_to_BN(sn, NULL);
1700 serialno = BN_bn2dec(b);
1701
1702 appendStringInfoChar(&str, '\n');
1704 _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1705 sub_prepared, serialno ? serialno : _("unknown"),
1706 iss_prepared);
1707
1708 BN_free(b);
1712 }
1713
1714 /* Store our detail message to be logged later. */
1715 cb_err->cert_errdetail = str.data;
1716
1717 return ok;
1718}
static char * prepare_cert_name(char *name)
const char * str
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242
void initStringInfo(StringInfo str)
Definition stringinfo.c:97

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

Referenced by be_tls_open_server().

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( const X509_NAME name)
static

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

2333{
2335 int i,
2336 nid,
2337 count = X509_NAME_entry_count(name);
2338 const X509_NAME_ENTRY *e;
2339 const ASN1_STRING *v;
2340 const char *field_name;
2341 size_t size;
2342 char nullterm;
2343 char *sp;
2344 char *dp;
2345 char *result;
2346
2347 if (membuf == NULL)
2348 ereport(ERROR,
2350 errmsg("could not create BIO")));
2351
2353 for (i = 0; i < count; i++)
2354 {
2357 if (nid == NID_undef)
2358 ereport(ERROR,
2360 errmsg("could not get NID for ASN1_OBJECT object")));
2363 if (field_name == NULL)
2365 if (field_name == NULL)
2366 ereport(ERROR,
2368 errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
2369 BIO_printf(membuf, "/%s=", field_name);
2373 }
2374
2375 /* ensure null termination of the BIO's content */
2376 nullterm = '\0';
2378 size = BIO_get_mem_data(membuf, &sp);
2379 dp = pg_any_to_server(sp, size - 1, PG_UTF8);
2380
2381 result = pstrdup(dp);
2382 if (dp != sp)
2383 pfree(dp);
2384 if (BIO_free(membuf) != 1)
2385 elog(ERROR, "could not free OpenSSL BIO structure");
2386
2387 return result;
2388}
uint32 result
#define PG_UTF8
Definition mbprint.c:43
char * pg_any_to_server(const char *s, int len, int encoding)
Definition mbutils.c:687
e

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

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

Referenced by alpn_cb().

◆ dummy_ssl_passwd_cb_called

bool dummy_ssl_passwd_cb_called = false
static

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

Referenced by dummy_ssl_passwd_cb(), and init_host_context().

◆ openssl_tls_init_hook

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

Referenced by _PG_init(), and init_host_context().

◆ port_bio_method_ptr

BIO_METHOD* port_bio_method_ptr = NULL
static

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

Referenced by port_bio_method().

◆ SSL_context

SSL_CTX* SSL_context = NULL
static

◆ SSL_hosts

struct hosts * SSL_hosts
static

Referenced by be_tls_init(), and be_tls_open_server().

◆ SSL_hosts_memcxt

MemoryContext SSL_hosts_memcxt = NULL
static

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

Referenced by be_tls_init().

◆ ssl_is_server_start

bool ssl_is_server_start
static

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

Referenced by init_host_context(), and ssl_external_passwd_cb().