48#include <openssl/bn.h>
49#include <openssl/conf.h>
50#include <openssl/dh.h>
51#ifndef OPENSSL_NO_ECDH
52#include <openssl/ec.h>
54#include <openssl/x509v3.h>
67#define SH_PREFIX host_cache
68#define SH_ELEMENT_TYPE HostCacheEntry
69#define SH_KEY_TYPE const char *
70#define SH_KEY hostname
71#define SH_HASH_KEY(tb, key) host_cache_pointer(key)
72#define SH_EQUAL(tb, a, b) (pg_strcasecmp(a, b) == 0)
73#define SH_SCOPE static inline
94 const unsigned char **out,
95 unsigned char *outlen,
96 const unsigned char *in,
105#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
158 char *err_msg =
NULL;
174 "hosts file parser context",
213#ifndef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
216 errmsg(
"ssl_sni is not supported with LibreSSL"));
233 errmsg(
"could not load \"%s\": %s",
"pg_hosts.conf",
234 err_msg ? err_msg :
"unknown error"));
271 errmsg(
"multiple default hosts specified"),
272 errcontext(
"line %d of configuration file \"%s\"",
285 errmsg(
"multiple no_sni hosts specified"),
286 errcontext(
"line %d of configuration file \"%s\"",
309 errmsg(
"multiple entries for host \"%s\" specified",
311 errcontext(
"line %d of configuration file \"%s\"",
338#ifdef USE_ASSERT_CHECKING
367 errmsg(
"no SSL configurations loaded"),
369 errhint(
"If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"",
370 "pg_hosts.conf",
"postgresql.conf"));
374#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
390 (
errmsg(
"could not create SSL context: %s",
401 context =
new_hosts->default_host->ssl_ctx;
425 (
errmsg(
"\"%s\" setting \"%s\" not supported by this build",
426 "ssl_min_protocol_version",
435 (
errmsg(
"could not set minimum SSL protocol version")));
448 (
errmsg(
"\"%s\" setting \"%s\" not supported by this build",
449 "ssl_max_protocol_version",
458 (
errmsg(
"could not set maximum SSL protocol version")));
475 errmsg(
"could not set SSL protocol version range"),
476 errdetail(
"\"%s\" cannot be higher than \"%s\"",
477 "ssl_min_protocol_version",
478 "ssl_max_protocol_version")));
492#ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
511#ifdef SSL_OP_NO_RENEGOTIATION
514#ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
529 errmsg(
"could not set the TLSv1.2 cipher list (no valid ciphers available)")));
544 errmsg(
"could not set the TLSv1.3 cipher suites (no valid ciphers available)")));
602 if (host->ssl_ctx !=
NULL)
622 (
errmsg(
"could not create SSL context: %s",
643 errmsg(
"SNI is enabled; installed TLS init hook will be ignored"),
645 errhint(
"TLS init hooks are incompatible with SNI. "
646 "Set \"%s\" to \"off\" to make use of the hook "
647 "that is currently installed, or remove the hook "
648 "and use per-host passphrase commands in \"%s\".",
649 "ssl_sni",
"pg_hosts.conf"));
697 errmsg(
"could not load server certificate file \"%s\": %s",
721 errmsg(
"private key file \"%s\" cannot be reloaded because it requires a passphrase",
726 errmsg(
"could not load private key file \"%s\": %s",
735 errmsg(
"check of private key failed: %s",
752 errmsg(
"could not load root certificate file \"%s\": %s",
791 errmsg(
"could not load SSL certificate revocation list file \"%s\": %s",
799 errmsg(
"could not load SSL certificate revocation list directory \"%s\": %s",
807 errmsg(
"could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
850 errmsg(
"could not initialize SSL connection: SSL context not set up")));
864 errmsg(
"could not initialize SSL connection: %s",
872 errmsg(
"could not set SSL socket: %s",
891#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
912 port->ssl_in_use =
true;
961 if (r < 0 &&
errno != 0)
964 errmsg(
"could not accept SSL connection: %m")));
968 errmsg(
"could not accept SSL connection: EOF detected")));
995#ifdef SSL_R_VERSION_TOO_HIGH
998#ifdef SSL_R_VERSION_TOO_LOW
1009 errmsg(
"could not accept SSL connection: %s",
1013 errhint(
"This may indicate that the client does not support any SSL protocol version between %s and %s.",
1026 errmsg(
"could not accept SSL connection: EOF detected")));
1031 errmsg(
"unrecognized SSL error code: %d",
1039 port->alpn_used =
false;
1041 const unsigned char *selected;
1047 if (selected !=
NULL)
1052 port->alpn_used =
true;
1059 errmsg(
"received SSL connection request with unexpected ALPN protocol")));
1070 port->peer_cert_valid =
false;
1087 peer_cn[
len] =
'\0';
1103 errmsg(
"SSL certificate's common name contains embedded null")));
1108 port->peer_cn = peer_cn;
1144 peer_dn[
len] =
'\0';
1149 errmsg(
"SSL certificate's distinguished name contains embedded null")));
1159 port->peer_dn = peer_dn;
1161 port->peer_cert_valid =
true;
1175 port->ssl_in_use =
false;
1202 unsigned long ecode;
1226 if (n != -1 ||
errno == 0)
1246 errmsg(
"unrecognized SSL error code: %d",
1261 unsigned long ecode;
1291 if (n != -1 ||
errno == 0)
1316 errmsg(
"unrecognized SSL error code: %d",
1354 port->last_read_was_eof = res == 0;
1483 errmsg(
"could not open DH parameters file \"%s\": %m",
1495 errmsg(
"could not load DH parameters file: %s",
1505 errmsg(
"invalid DH parameters: %s",
1514 errmsg(
"invalid DH parameters: p is not prime")));
1523 errmsg(
"invalid DH parameters: neither suitable generator or safe prime")));
1564 const char *
prompt =
"Enter PEM pass phrase:";
1602 char *truncated =
name;
1619 truncated[0] = truncated[1] = truncated[2] =
'.';
1669 _(
"Client certificate verification failed at depth %d: %s."),
1706 _(
"Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1779 const unsigned char **out,
1780 unsigned char *outlen,
1781 const unsigned char *in,
1815#ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
1922 const unsigned char *
tlsext;
1942 if (
len + 2 != left)
2032 errmsg(
"no hostname provided in callback, and no fallback configured")));
2056 errmsg(
"failed to switch to SSL configuration for host, terminating connection"));
2092 errmsg(
"DH: could not load DH parameters")));
2100 errmsg(
"DH: could not set DH parameters: %s",
2118#ifndef OPENSSL_NO_ECDH
2130 errmsg(
"could not set group names specified in ssl_groups: %s",
2132 _(
"No valid groups found"))),
2133 errhint(
"Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL."));
2175 const char *errreason;
2176 static char errbuf[36];
2179 return _(
"no SSL error reported");
2181 if (errreason !=
NULL)
2191#ifdef ERR_SYSTEM_ERROR
2197 snprintf(errbuf,
sizeof(errbuf),
_(
"SSL error code %lu"),
ecode);
2292#if HAVE_X509_GET_SIGNATURE_INFO
2298 elog(
ERROR,
"could not determine server certificate signature algorithm");
2315 elog(
ERROR,
"could not find digest for NID %s",
2322 elog(
ERROR,
"could not generate server certificate hash");
2354 errmsg(
"could not create BIO")));
2357 for (
i = 0;
i < count;
i++)
2364 errmsg(
"could not get NID for ASN1_OBJECT object")));
2372 errmsg(
"could not convert NID %d to an ASN1_OBJECT structure",
nid)));
2389 elog(
ERROR,
"could not free OpenSSL BIO structure");
2418#ifdef TLS1_1_VERSION
2424#ifdef TLS1_2_VERSION
2430#ifdef TLS1_3_VERSION
2460 return "(unrecognized)";
2470 for (
int i = 0;
i <
len;
i++)
bool check_ssl_key_file_permissions(const char *ssl_key_file, bool isServerStart)
int load_hosts(List **hosts, char **err_msg)
int run_ssl_passphrase_command(const char *cmd, const char *prompt, bool is_server_start, char *buf, int size)
const char * be_tls_get_version(Port *port)
static bool init_host_context(HostsLine *host, bool isServerStart)
static const char * ssl_protocol_version_to_string(int v)
static void info_cb(const SSL *ssl, int type, int args)
static const char * SSLerrmessage(unsigned long ecode)
ssize_t be_tls_write(Port *port, const void *ptr, size_t len, int *waitfor)
void be_tls_destroy(void)
int be_tls_init(bool isServerStart)
static long port_bio_ctrl(BIO *h, int cmd, long num, void *ptr)
openssl_tls_init_hook_typ openssl_tls_init_hook
int be_tls_get_cipher_bits(Port *port)
int be_tls_open_server(Port *port)
char * be_tls_get_certificate_hash(Port *port, size_t *len)
static int alpn_cb(SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *userdata)
const char * be_tls_get_cipher(Port *port)
static const char * SSLerrmessageExt(unsigned long ecode, const char *replacement)
static DH * load_dh_buffer(const char *buffer, size_t len)
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
static int ssl_set_port_bio(Port *port)
void be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
static int ssl_protocol_version_to_openssl(int v)
static bool initialize_dh(SSL_CTX *context, bool isServerStart)
void be_tls_close(Port *port)
void be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
static void host_context_cleanup_cb(void *arg)
static char * X509_NAME_to_cstring(X509_NAME *name)
static BIO_METHOD * port_bio_method(void)
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static char * prepare_cert_name(char *name)
static MemoryContext SSL_hosts_memcxt
static SSL_CTX * SSL_context
static bool ssl_is_server_start
static int verify_cb(int ok, X509_STORE_CTX *ctx)
static uint32 host_cache_pointer(const char *key)
static BIO_METHOD * port_bio_method_ptr
static struct hosts * SSL_hosts
static bool initialize_ecdh(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 bool dummy_ssl_passwd_cb_called
static DH * load_dh_file(char *filename, bool isServerStart)
static const unsigned char alpn_protos[]
void be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
char * ssl_dh_params_file
int ssl_min_protocol_version
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
bool SSLPreferServerCiphers
int ssl_max_protocol_version
char * ssl_passphrase_command
bool ssl_passphrase_command_supports_reload
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
#define Assert(condition)
int errcode_for_socket_access(void)
int errcode_for_file_access(void)
int errcode(int sqlerrcode)
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
void err(int eval, const char *fmt,...)
FILE * AllocateFile(const char *name, const char *mode)
#define ERRCODE_PROTOCOL_VIOLATION
#define palloc0_object(type)
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
uint32 string_hash(const void *key, Size keysize)
int WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout, uint32 wait_event_info)
List * lappend(List *list, void *datum)
char * pg_any_to_server(const char *s, int len, int encoding)
void * MemoryContextAlloc(MemoryContext context, Size size)
char * pstrdup(const char *in)
void MemoryContextRegisterResetCallback(MemoryContext context, MemoryContextCallback *cb)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
#define foreach_ptr(type, var, lst)
static char buf[DEFAULT_XLOG_SEG_SIZE]
unsigned char pg_tolower(unsigned char ch)
size_t strlcpy(char *dst, const char *src, size_t siz)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
#define PG_ALPN_PROTOCOL_VECTOR
static unsigned hash(unsigned *uv, int n)
char * pg_clean_ascii(const char *str, int alloc_flags)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
char * ssl_passphrase_cmd
bool ssl_passphrase_reload
#define WL_SOCKET_READABLE
#define WL_EXIT_ON_PM_DEATH
#define WL_SOCKET_WRITEABLE