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/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 dependency graph for be-secure-openssl.c:

Go to the source code of this file.

Data Structures

struct  CallbackErr
 

Macros

#define MAXLEN   71
 

Functions

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 charX509_NAME_to_cstring (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 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

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

1363{
1364 /*
1365 * Why does OpenSSL provide a helper function that requires a nonconst
1366 * vector when the callback is declared to take a const vector? What are
1367 * we to do with that?
1368 */
1369 int retval;
1370
1371 Assert(userdata != NULL);
1372 Assert(out != NULL);
1373 Assert(outlen != NULL);
1374 Assert(in != NULL);
1375
1376 retval = SSL_select_next_proto((unsigned char **) out, outlen,
1377 alpn_protos, sizeof(alpn_protos),
1378 in, inlen);
1379 if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
1380 return SSL_TLSEXT_ERR_NOACK; /* can't happen */
1381
1382 if (retval == OPENSSL_NPN_NEGOTIATED)
1383 return SSL_TLSEXT_ERR_OK;
1384 else
1385 {
1386 /*
1387 * The client doesn't support our protocol. Reject the connection
1388 * with TLS "no_application_protocol" alert, per RFC 7301.
1389 */
1391 }
1392}
static const unsigned char alpn_protos[]
#define Assert(condition)
Definition c.h:915
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 748 of file be-secure-openssl.c.

749{
750 if (port->ssl)
751 {
752 SSL_shutdown(port->ssl);
753 SSL_free(port->ssl);
754 port->ssl = NULL;
755 port->ssl_in_use = false;
756 }
757
758 if (port->peer)
759 {
760 X509_free(port->peer);
761 port->peer = NULL;
762 }
763
764 if (port->peer_cn)
765 {
766 pfree(port->peer_cn);
767 port->peer_cn = NULL;
768 }
769
770 if (port->peer_dn)
771 {
772 pfree(port->peer_dn);
773 port->peer_dn = NULL;
774 }
775}
void pfree(void *pointer)
Definition mcxt.c:1616
static int port
Definition pg_regress.c:115

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

Referenced by secure_close().

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

438{
439 if (SSL_context)
443}
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 1604 of file be-secure-openssl.c.

1605{
1607 char *cert_hash;
1608 const EVP_MD *algo_type = NULL;
1609 unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
1610 unsigned int hash_size;
1611 int algo_nid;
1612
1613 *len = 0;
1615 if (server_cert == NULL)
1616 return NULL;
1617
1618 /*
1619 * Get the signature algorithm of the certificate to determine the hash
1620 * algorithm to use for the result. Prefer X509_get_signature_info(),
1621 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
1622 */
1623#if HAVE_X509_GET_SIGNATURE_INFO
1625#else
1627 &algo_nid, NULL))
1628#endif
1629 elog(ERROR, "could not determine server certificate signature algorithm");
1630
1631 /*
1632 * The TLS server's certificate bytes need to be hashed with SHA-256 if
1633 * its signature algorithm is MD5 or SHA-1 as per RFC 5929
1634 * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
1635 * is used, the same hash as the signature algorithm is used.
1636 */
1637 switch (algo_nid)
1638 {
1639 case NID_md5:
1640 case NID_sha1:
1642 break;
1643 default:
1645 if (algo_type == NULL)
1646 elog(ERROR, "could not find digest for NID %s",
1648 break;
1649 }
1650
1651 /* generate and save the certificate hash */
1653 elog(ERROR, "could not generate server certificate hash");
1654
1657 *len = hash_size;
1658
1659 return cert_hash;
1660}
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
void * palloc(Size size)
Definition mcxt.c:1387
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition rege_dfa.c:715

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

1557{
1558 if (port->ssl)
1559 return SSL_get_cipher(port->ssl);
1560 else
1561 return NULL;
1562}

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

1534{
1535 int bits;
1536
1537 if (port->ssl)
1538 {
1539 SSL_get_cipher_bits(port->ssl, &bits);
1540 return bits;
1541 }
1542 else
1543 return 0;
1544}

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

1575{
1576 if (port->peer)
1578 else
1579 ptr[0] = '\0';
1580}
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 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 1583 of file be-secure-openssl.c.

1584{
1585 if (port->peer)
1586 {
1588 BIGNUM *b;
1589 char *decimal;
1590
1593 decimal = BN_bn2dec(b);
1594
1595 BN_free(b);
1596 strlcpy(ptr, decimal, len);
1598 }
1599 else
1600 ptr[0] = '\0';
1601}
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 1565 of file be-secure-openssl.c.

1566{
1567 if (port->peer)
1569 else
1570 ptr[0] = '\0';
1571}

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

1548{
1549 if (port->ssl)
1550 return SSL_get_version(port->ssl);
1551 else
1552 return NULL;
1553}

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

106{
107 SSL_CTX *context;
108 int ssl_ver_min = -1;
109 int ssl_ver_max = -1;
110
111 /*
112 * Create a new SSL context into which we'll load all the configuration
113 * settings. If we fail partway through, we can avoid memory leakage by
114 * freeing this context; we don't install it as active until the end.
115 *
116 * We use SSLv23_method() because it can negotiate use of the highest
117 * mutually supported protocol version, while alternatives like
118 * TLSv1_2_method() permit only one specific version. Note that we don't
119 * actually allow SSL v2 or v3, only TLS protocols (see below).
120 */
121 context = SSL_CTX_new(SSLv23_method());
122 if (!context)
123 {
125 (errmsg("could not create SSL context: %s",
127 goto error;
128 }
129
130 /*
131 * Disable OpenSSL's moving-write-buffer sanity check, because it causes
132 * unnecessary failures in nonblocking send cases.
133 */
135
136 /*
137 * Call init hook (usually to set password callback)
138 */
139 (*openssl_tls_init_hook) (context, isServerStart);
140
141 /* used by the callback */
143
144 /*
145 * Load and verify server's certificate and private key
146 */
148 {
151 errmsg("could not load server certificate file \"%s\": %s",
153 goto error;
154 }
155
157 goto error;
158
159 /*
160 * OK, try to load the private key file.
161 */
163
164 if (SSL_CTX_use_PrivateKey_file(context,
166 SSL_FILETYPE_PEM) != 1)
167 {
171 errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
172 ssl_key_file)));
173 else
176 errmsg("could not load private key file \"%s\": %s",
178 goto error;
179 }
180
181 if (SSL_CTX_check_private_key(context) != 1)
182 {
185 errmsg("check of private key failed: %s",
187 goto error;
188 }
189
191 {
193
194 if (ssl_ver_min == -1)
195 {
197 /*- translator: first %s is a GUC option name, second %s is its value */
198 (errmsg("\"%s\" setting \"%s\" not supported by this build",
199 "ssl_min_protocol_version",
200 GetConfigOption("ssl_min_protocol_version",
201 false, false))));
202 goto error;
203 }
204
206 {
208 (errmsg("could not set minimum SSL protocol version")));
209 goto error;
210 }
211 }
212
214 {
216
217 if (ssl_ver_max == -1)
218 {
220 /*- translator: first %s is a GUC option name, second %s is its value */
221 (errmsg("\"%s\" setting \"%s\" not supported by this build",
222 "ssl_max_protocol_version",
223 GetConfigOption("ssl_max_protocol_version",
224 false, false))));
225 goto error;
226 }
227
229 {
231 (errmsg("could not set maximum SSL protocol version")));
232 goto error;
233 }
234 }
235
236 /* Check compatibility of min/max protocols */
239 {
240 /*
241 * No need to check for invalid values (-1) for each protocol number
242 * as the code above would have already generated an error.
243 */
245 {
248 errmsg("could not set SSL protocol version range"),
249 errdetail("\"%s\" cannot be higher than \"%s\"",
250 "ssl_min_protocol_version",
251 "ssl_max_protocol_version")));
252 goto error;
253 }
254 }
255
256 /*
257 * Disallow SSL session tickets. OpenSSL use both stateful and stateless
258 * tickets for TLSv1.3, and stateless ticket for TLSv1.2. SSL_OP_NO_TICKET
259 * is available since 0.9.8f but only turns off stateless tickets. In
260 * order to turn off stateful tickets we need SSL_CTX_set_num_tickets,
261 * which is available since OpenSSL 1.1.1. LibreSSL 3.5.4 (from OpenBSD
262 * 7.1) introduced this API for compatibility, but doesn't support session
263 * tickets at all so it's a no-op there.
264 */
265#ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
266 SSL_CTX_set_num_tickets(context, 0);
267#endif
269
270 /* disallow SSL session caching, too */
272
273 /* disallow SSL compression */
275
276 /*
277 * Disallow SSL renegotiation. This concerns only TLSv1.2 and older
278 * protocol versions, as TLSv1.3 has no support for renegotiation.
279 * SSL_OP_NO_RENEGOTIATION is available in OpenSSL since 1.1.0h (via a
280 * backport from 1.1.1). SSL_OP_NO_CLIENT_RENEGOTIATION is available in
281 * LibreSSL since 2.5.1 disallowing all client-initiated renegotiation
282 * (this is usually on by default).
283 */
284#ifdef SSL_OP_NO_RENEGOTIATION
286#endif
287#ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
289#endif
290
291 /* set up ephemeral DH and ECDH keys */
292 if (!initialize_dh(context, isServerStart))
293 goto error;
294 if (!initialize_ecdh(context, isServerStart))
295 goto error;
296
297 /* set up the allowed cipher list for TLSv1.2 and below */
298 if (SSL_CTX_set_cipher_list(context, SSLCipherList) != 1)
299 {
302 errmsg("could not set the TLSv1.2 cipher list (no valid ciphers available)")));
303 goto error;
304 }
305
306 /*
307 * Set up the allowed cipher suites for TLSv1.3. If the GUC is an empty
308 * string we leave the allowed suites to be the OpenSSL default value.
309 */
310 if (SSLCipherSuites[0])
311 {
312 /* set up the allowed cipher suites */
313 if (SSL_CTX_set_ciphersuites(context, SSLCipherSuites) != 1)
314 {
317 errmsg("could not set the TLSv1.3 cipher suites (no valid ciphers available)")));
318 goto error;
319 }
320 }
321
322 /* Let server choose order */
325
326 /*
327 * Load CA store, so we can verify client certificates if needed.
328 */
329 if (ssl_ca_file[0])
330 {
332
333 if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
335 {
338 errmsg("could not load root certificate file \"%s\": %s",
340 goto error;
341 }
342
343 /*
344 * Tell OpenSSL to send the list of root certs we trust to clients in
345 * CertificateRequests. This lets a client with a keystore select the
346 * appropriate client certificate to send to us. Also, this ensures
347 * that the SSL context will "own" the root_cert_list and remember to
348 * free it when no longer needed.
349 */
351
352 /*
353 * Always ask for SSL client cert, but don't fail if it's not
354 * presented. We might fail such connections later, depending on what
355 * we find in pg_hba.conf.
356 */
357 SSL_CTX_set_verify(context,
360 verify_cb);
361 }
362
363 /*----------
364 * Load the Certificate Revocation List (CRL).
365 * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
366 *----------
367 */
368 if (ssl_crl_file[0] || ssl_crl_dir[0])
369 {
371
372 if (cvstore)
373 {
374 /* Set the flags to check against the complete CRL chain */
378 == 1)
379 {
382 }
383 else if (ssl_crl_dir[0] == 0)
384 {
387 errmsg("could not load SSL certificate revocation list file \"%s\": %s",
389 goto error;
390 }
391 else if (ssl_crl_file[0] == 0)
392 {
395 errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
397 goto error;
398 }
399 else
400 {
403 errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
406 goto error;
407 }
408 }
409 }
410
411 /*
412 * Success! Replace any existing SSL_context.
413 */
414 if (SSL_context)
416
417 SSL_context = context;
418
419 /*
420 * Set flag to remember whether CA store has been loaded into SSL_context.
421 */
422 if (ssl_ca_file[0])
424 else
426
427 return 0;
428
429 /* Clean up by releasing working context. */
430error:
431 if (context)
432 SSL_CTX_free(context);
433 return -1;
434}
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:42
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
int ssl_max_protocol_version
Definition be-secure.c:62
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_crl_file
Definition be-secure.c:41
char * ssl_ca_file
Definition be-secure.c:40
int errcode(int sqlerrcode)
Definition elog.c:874
#define LOG
Definition elog.h:31
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:41
#define ereport(elevel,...)
Definition elog.h:150
const char * GetConfigOption(const char *name, bool missing_ok, bool restrict_privileged)
Definition guc.c:4219
#define false
static char * errmsg
static void error(void)

References check_ssl_key_file_permissions(), dummy_ssl_passwd_cb_called, ereport, errcode(), errdetail(), errmsg, error(), FATAL, fb(), 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(), SSLCipherList, SSLCipherSuites, SSLerrmessage(), SSLPreferServerCiphers, and verify_cb().

Referenced by secure_initialize().

◆ be_tls_open_server()

int be_tls_open_server ( Port port)

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

447{
448 int r;
449 int err;
450 int waitfor;
451 unsigned long ecode;
452 bool give_proto_hint;
453 static struct CallbackErr err_context;
454
455 Assert(!port->ssl);
456 Assert(!port->peer);
457
458 if (!SSL_context)
459 {
462 errmsg("could not initialize SSL connection: SSL context not set up")));
463 return -1;
464 }
465
466 /* set up debugging/info callback */
468
469 /* enable ALPN */
471
472 if (!(port->ssl = SSL_new(SSL_context)))
473 {
476 errmsg("could not initialize SSL connection: %s",
478 return -1;
479 }
481 {
484 errmsg("could not set SSL socket: %s",
486 return -1;
487 }
488
489 err_context.cert_errdetail = NULL;
491
492 port->ssl_in_use = true;
493
494aloop:
495
496 /*
497 * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
498 * queue. In general, the current thread's error queue must be empty
499 * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
500 * not work reliably. An extension may have failed to clear the
501 * per-thread error queue following another call to an OpenSSL I/O
502 * routine.
503 */
504 errno = 0;
506 r = SSL_accept(port->ssl);
507 if (r <= 0)
508 {
509 err = SSL_get_error(port->ssl, r);
510
511 /*
512 * Other clients of OpenSSL in the backend may fail to call
513 * ERR_get_error(), but we always do, so as to not cause problems for
514 * OpenSSL clients that don't call ERR_clear_error() defensively. Be
515 * sure that this happens by calling now. SSL_get_error() relies on
516 * the OpenSSL per-thread error queue being intact, so this is the
517 * earliest possible point ERR_get_error() may be called.
518 */
520 switch (err)
521 {
524 /* not allowed during connection establishment */
525 Assert(!port->noblock);
526
527 /*
528 * No need to care about timeouts/interrupts here. At this
529 * point authentication_timeout still employs
530 * StartupPacketTimeoutHandler() which directly exits.
531 */
534 else
536
539 goto aloop;
541 if (r < 0 && errno != 0)
544 errmsg("could not accept SSL connection: %m")));
545 else
548 errmsg("could not accept SSL connection: EOF detected")));
549 break;
550 case SSL_ERROR_SSL:
551 switch (ERR_GET_REASON(ecode))
552 {
553 /*
554 * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
555 * TLSV1_ALERT_PROTOCOL_VERSION have been observed
556 * when trying to communicate with an old OpenSSL
557 * library, or when the client and server specify
558 * disjoint protocol ranges. NO_PROTOCOLS_AVAILABLE
559 * occurs if there's a local misconfiguration (which
560 * can happen despite our checks, if openssl.cnf
561 * injects a limit we didn't account for). It's not
562 * very clear what would make OpenSSL return the other
563 * codes listed here, but a hint about protocol
564 * versions seems like it's appropriate for all.
565 */
575#ifdef SSL_R_VERSION_TOO_HIGH
577#endif
578#ifdef SSL_R_VERSION_TOO_LOW
580#endif
581 give_proto_hint = true;
582 break;
583 default:
584 give_proto_hint = false;
585 break;
586 }
589 errmsg("could not accept SSL connection: %s",
591 err_context.cert_errdetail ? errdetail_internal("%s", err_context.cert_errdetail) : 0,
593 errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
600 if (err_context.cert_errdetail)
601 pfree(err_context.cert_errdetail);
602 break;
606 errmsg("could not accept SSL connection: EOF detected")));
607 break;
608 default:
611 errmsg("unrecognized SSL error code: %d",
612 err)));
613 break;
614 }
615 return -1;
616 }
617
618 /* Get the protocol selected by ALPN */
619 port->alpn_used = false;
620 {
621 const unsigned char *selected;
622 unsigned int len;
623
624 SSL_get0_alpn_selected(port->ssl, &selected, &len);
625
626 /* If ALPN is used, check that we negotiated the expected protocol */
627 if (selected != NULL)
628 {
629 if (len == strlen(PG_ALPN_PROTOCOL) &&
631 {
632 port->alpn_used = true;
633 }
634 else
635 {
636 /* shouldn't happen */
639 errmsg("received SSL connection request with unexpected ALPN protocol")));
640 }
641 }
642 }
643
644 /* Get client certificate, if available. */
645 port->peer = SSL_get_peer_certificate(port->ssl);
646
647 /* and extract the Common Name and Distinguished Name from it. */
648 port->peer_cn = NULL;
649 port->peer_dn = NULL;
650 port->peer_cert_valid = false;
651 if (port->peer != NULL)
652 {
653 int len;
655 char *peer_dn;
656 BIO *bio = NULL;
658
660 if (len != -1)
661 {
662 char *peer_cn;
663
666 len + 1);
667 peer_cn[len] = '\0';
668 if (r != len)
669 {
670 /* shouldn't happen */
671 pfree(peer_cn);
672 return -1;
673 }
674
675 /*
676 * Reject embedded NULLs in certificate common name to prevent
677 * attacks like CVE-2009-4034.
678 */
679 if (len != strlen(peer_cn))
680 {
683 errmsg("SSL certificate's common name contains embedded null")));
684 pfree(peer_cn);
685 return -1;
686 }
687
688 port->peer_cn = peer_cn;
689 }
690
691 bio = BIO_new(BIO_s_mem());
692 if (!bio)
693 {
694 if (port->peer_cn != NULL)
695 {
696 pfree(port->peer_cn);
697 port->peer_cn = NULL;
698 }
699 return -1;
700 }
701
702 /*
703 * RFC2253 is the closest thing to an accepted standard format for
704 * DNs. We have documented how to produce this format from a
705 * certificate. It uses commas instead of slashes for delimiters,
706 * which make regular expression matching a bit easier. Also note that
707 * it prints the Subject fields in reverse order.
708 */
711 {
712 BIO_free(bio);
713 if (port->peer_cn != NULL)
714 {
715 pfree(port->peer_cn);
716 port->peer_cn = NULL;
717 }
718 return -1;
719 }
720 peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
721 memcpy(peer_dn, bio_buf->data, bio_buf->length);
722 len = bio_buf->length;
723 BIO_free(bio);
724 peer_dn[len] = '\0';
725 if (len != strlen(peer_dn))
726 {
729 errmsg("SSL certificate's distinguished name contains embedded null")));
730 pfree(peer_dn);
731 if (port->peer_cn != NULL)
732 {
733 pfree(port->peer_cn);
734 port->peer_cn = NULL;
735 }
736 return -1;
737 }
738
739 port->peer_dn = peer_dn;
740
741 port->peer_cert_valid = true;
742 }
743
744 return 0;
745}
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)
int errcode_for_socket_access(void)
Definition elog.c:976
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
#define COMMERROR
Definition elog.h:33
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:1232
MemoryContext TopMemoryContext
Definition mcxt.c:166
#define PG_ALPN_PROTOCOL
Definition pqcomm.h:189
#define WL_SOCKET_READABLE
#define WL_EXIT_ON_PM_DEATH
#define WL_SOCKET_WRITEABLE

References alpn_cb(), Assert, COMMERROR, ereport, err(), errcode(), errcode_for_socket_access(), ERRCODE_PROTOCOL_VIOLATION, errdetail_internal(), errhint(), errmsg, fb(), info_cb(), len, MemoryContextAlloc(), pfree(), PG_ALPN_PROTOCOL, port, SSL_context, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_string(), ssl_set_port_bio(), 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 778 of file be-secure-openssl.c.

779{
780 ssize_t n;
781 int err;
782 unsigned long ecode;
783
784 errno = 0;
786 n = SSL_read(port->ssl, ptr, len);
787 err = SSL_get_error(port->ssl, n);
788 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
789 switch (err)
790 {
791 case SSL_ERROR_NONE:
792 /* a-ok */
793 break;
797 n = -1;
798 break;
802 n = -1;
803 break;
805 /* leave it to caller to ereport the value of errno */
806 if (n != -1 || errno == 0)
807 {
809 n = -1;
810 }
811 break;
812 case SSL_ERROR_SSL:
815 errmsg("SSL error: %s", SSLerrmessage(ecode))));
817 n = -1;
818 break;
820 /* connection was cleanly shut down by peer */
821 n = 0;
822 break;
823 default:
826 errmsg("unrecognized SSL error code: %d",
827 err)));
829 n = -1;
830 break;
831 }
832
833 return n;
834}
#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 837 of file be-secure-openssl.c.

838{
839 ssize_t n;
840 int err;
841 unsigned long ecode;
842
843 errno = 0;
845 n = SSL_write(port->ssl, ptr, len);
846 err = SSL_get_error(port->ssl, n);
847 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
848 switch (err)
849 {
850 case SSL_ERROR_NONE:
851 /* a-ok */
852 break;
856 n = -1;
857 break;
861 n = -1;
862 break;
864
865 /*
866 * Leave it to caller to ereport the value of errno. However, if
867 * errno is still zero then assume it's a read EOF situation, and
868 * report ECONNRESET. (This seems possible because SSL_write can
869 * also do reads.)
870 */
871 if (n != -1 || errno == 0)
872 {
874 n = -1;
875 }
876 break;
877 case SSL_ERROR_SSL:
880 errmsg("SSL error: %s", SSLerrmessage(ecode))));
882 n = -1;
883 break;
885
886 /*
887 * the SSL connection was closed, leave it to the caller to
888 * ereport it
889 */
891 n = -1;
892 break;
893 default:
896 errmsg("unrecognized SSL error code: %d",
897 err)));
899 n = -1;
900 break;
901 }
902
903 return n;
904}

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

1797{
1798 if (isServerStart)
1799 {
1802 }
1803 else
1804 {
1807 else
1808
1809 /*
1810 * If reloading and no external command is configured, override
1811 * OpenSSL's default handling of passphrase-protected files,
1812 * because we don't want to prompt for a passphrase in an
1813 * already-running server.
1814 */
1816 }
1817}
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:44
bool ssl_passphrase_command_supports_reload
Definition be-secure.c:45

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

1162{
1163 /* Set flag to change the error message we'll report */
1165 /* And return empty string */
1166 Assert(size > 0);
1167 buf[0] = '\0';
1168 return 0;
1169}
static char buf[DEFAULT_XLOG_SEG_SIZE]

References Assert, buf, and dummy_ssl_passwd_cb_called.

Referenced by default_openssl_tls_init().

◆ info_cb()

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

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

1307{
1308 const char *desc;
1309
1310 desc = SSL_state_string_long(ssl);
1311
1312 switch (type)
1313 {
1316 (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1317 break;
1320 (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1321 break;
1322 case SSL_CB_ACCEPT_LOOP:
1324 (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1325 break;
1326 case SSL_CB_ACCEPT_EXIT:
1328 (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1329 break;
1332 (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1333 break;
1336 (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1337 break;
1338 case SSL_CB_READ_ALERT:
1340 (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1341 break;
1342 case SSL_CB_WRITE_ALERT:
1344 (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1345 break;
1346 }
1347}
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG4
Definition elog.h:27
const char * type

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

Referenced by be_tls_open_server().

◆ initialize_dh()

static bool initialize_dh ( SSL_CTX context,
bool  isServerStart 
)
static

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

1410{
1411 DH *dh = NULL;
1412
1414
1415 if (ssl_dh_params_file[0])
1417 if (!dh)
1419 if (!dh)
1420 {
1423 errmsg("DH: could not load DH parameters")));
1424 return false;
1425 }
1426
1427 if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1428 {
1431 errmsg("DH: could not set DH parameters: %s",
1433 DH_free(dh);
1434 return false;
1435 }
1436
1437 DH_free(dh);
1438 return true;
1439}
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 1447 of file be-secure-openssl.c.

1448{
1449#ifndef OPENSSL_NO_ECDH
1450 if (SSL_CTX_set1_groups_list(context, SSLECDHCurve) != 1)
1451 {
1452 /*
1453 * OpenSSL 3.3.0 introduced proper error messages for group parsing
1454 * errors, earlier versions returns "no SSL error reported" which is
1455 * far from helpful. For older versions, we replace with a better
1456 * error message. Injecting the error into the OpenSSL error queue
1457 * need APIs from OpenSSL 3.0.
1458 */
1461 errmsg("could not set group names specified in ssl_groups: %s",
1463 _("No valid groups found"))),
1464 errhint("Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL."));
1465 return false;
1466 }
1467#endif
1468
1469 return true;
1470}
static const char * SSLerrmessageExt(unsigned long ecode, const char *replacement)
char * SSLECDHCurve
Definition be-secure.c:56
#define _(x)
Definition elog.c:95

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

1120{
1121 BIO *bio;
1122 DH *dh = NULL;
1123
1124 bio = BIO_new_mem_buf(buffer, len);
1125 if (bio == NULL)
1126 return NULL;
1128 if (dh == NULL)
1130 (errmsg_internal("DH load buffer: %s",
1132 BIO_free(bio);
1133
1134 return dh;
1135}
#define DEBUG2
Definition elog.h:29

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

1053{
1054 FILE *fp;
1055 DH *dh = NULL;
1056 int codes;
1057
1058 /* attempt to open file. It's not an error if it doesn't exist. */
1059 if ((fp = AllocateFile(filename, "r")) == NULL)
1060 {
1063 errmsg("could not open DH parameters file \"%s\": %m",
1064 filename)));
1065 return NULL;
1066 }
1067
1069 FreeFile(fp);
1070
1071 if (dh == NULL)
1072 {
1075 errmsg("could not load DH parameters file: %s",
1077 return NULL;
1078 }
1079
1080 /* make sure the DH parameters are usable */
1081 if (DH_check(dh, &codes) == 0)
1082 {
1085 errmsg("invalid DH parameters: %s",
1087 DH_free(dh);
1088 return NULL;
1089 }
1091 {
1094 errmsg("invalid DH parameters: p is not prime")));
1095 DH_free(dh);
1096 return NULL;
1097 }
1100 {
1103 errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1104 DH_free(dh);
1105 return NULL;
1106 }
1107
1108 return dh;
1109}
int errcode_for_file_access(void)
Definition elog.c:897
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 968 of file be-secure-openssl.c.

969{
970 long res;
971 Port *port = (Port *) BIO_get_data(h);
972
973 switch (cmd)
974 {
975 case BIO_CTRL_EOF:
976
977 /*
978 * This should not be needed. port_bio_read already has a way to
979 * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
980 * backwards-incompatible change and now expects EOF via BIO_ctrl.
981 * See https://github.com/openssl/openssl/issues/8208
982 */
983 res = port->last_read_was_eof;
984 break;
985 case BIO_CTRL_FLUSH:
986 /* libssl expects all BIOs to support BIO_flush. */
987 res = 1;
988 break;
989 default:
990 res = 0;
991 break;
992 }
993
994 return res;
995}
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 998 of file be-secure-openssl.c.

999{
1001 {
1002 int my_bio_index;
1003
1005 if (my_bio_index == -1)
1006 return NULL;
1008 port_bio_method_ptr = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
1010 return NULL;
1014 {
1017 return NULL;
1018 }
1019 }
1020 return port_bio_method_ptr;
1021}
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 925 of file be-secure-openssl.c.

926{
927 int res = 0;
928 Port *port = (Port *) BIO_get_data(h);
929
930 if (buf != NULL)
931 {
932 res = secure_raw_read(port, buf, size);
934 port->last_read_was_eof = res == 0;
935 if (res <= 0)
936 {
937 /* If we were interrupted, tell caller to retry */
938 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
939 {
941 }
942 }
943 }
944
945 return res;
946}
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition be-secure.c:269
#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 949 of file be-secure-openssl.c.

950{
951 int res = 0;
952
953 res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
955 if (res <= 0)
956 {
957 /* If we were interrupted, tell caller to retry */
958 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
959 {
961 }
962 }
963
964 return res;
965}
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition be-secure.c:378

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

1179{
1180 size_t namelen = strlen(name);
1181 char *truncated = name;
1182
1183 /*
1184 * Common Names are 64 chars max, so for a common case where the CN is the
1185 * last field, we can still print the longest possible CN with a
1186 * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
1187 * characters.
1188 */
1189#define MAXLEN 71
1190
1191 if (namelen > MAXLEN)
1192 {
1193 /*
1194 * Keep the end of the name, not the beginning, since the most
1195 * specific field is likely to give users the most information.
1196 */
1197 truncated = name + namelen - MAXLEN;
1198 truncated[0] = truncated[1] = truncated[2] = '.';
1199 namelen = MAXLEN;
1200 }
1201
1202#undef MAXLEN
1203
1204 return pg_clean_ascii(truncated, 0);
1205}
#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 1141 of file be-secure-openssl.c.

1142{
1143 /* same prompt as OpenSSL uses internally */
1144 const char *prompt = "Enter PEM pass phrase:";
1145
1146 Assert(rwflag == 0);
1147
1149}
int run_ssl_passphrase_command(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().

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( int  v)
static

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

1741{
1742 switch (v)
1743 {
1744 case PG_TLS_ANY:
1745 return 0;
1746 case PG_TLS1_VERSION:
1747 return TLS1_VERSION;
1748 case PG_TLS1_1_VERSION:
1749#ifdef TLS1_1_VERSION
1750 return TLS1_1_VERSION;
1751#else
1752 break;
1753#endif
1754 case PG_TLS1_2_VERSION:
1755#ifdef TLS1_2_VERSION
1756 return TLS1_2_VERSION;
1757#else
1758 break;
1759#endif
1760 case PG_TLS1_3_VERSION:
1761#ifdef TLS1_3_VERSION
1762 return TLS1_3_VERSION;
1763#else
1764 break;
1765#endif
1766 }
1767
1768 return -1;
1769}
@ PG_TLS1_VERSION
Definition libpq.h:152
@ PG_TLS1_3_VERSION
Definition libpq.h:155
@ PG_TLS1_1_VERSION
Definition libpq.h:153
@ PG_TLS1_2_VERSION
Definition libpq.h:154
@ PG_TLS_ANY
Definition libpq.h:151

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

1776{
1777 switch (v)
1778 {
1779 case PG_TLS_ANY:
1780 return "any";
1781 case PG_TLS1_VERSION:
1782 return "TLSv1";
1783 case PG_TLS1_1_VERSION:
1784 return "TLSv1.1";
1785 case PG_TLS1_2_VERSION:
1786 return "TLSv1.2";
1787 case PG_TLS1_3_VERSION:
1788 return "TLSv1.3";
1789 }
1790
1791 return "(unrecognized)";
1792}

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

1025{
1026 BIO *bio;
1028
1030 if (bio_method == NULL)
1031 return 0;
1032
1034 if (bio == NULL)
1035 return 0;
1036
1038 BIO_set_init(bio, 1);
1039
1040 SSL_set_bio(port->ssl, bio, bio);
1041 return 1;
1042}
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 1504 of file be-secure-openssl.c.

1505{
1506 const char *errreason;
1507 static char errbuf[36];
1508
1509 if (ecode == 0)
1510 return _("no SSL error reported");
1511 errreason = ERR_reason_error_string(ecode);
1512 if (errreason != NULL)
1513 return errreason;
1514
1515 /*
1516 * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
1517 * errno values anymore. (See OpenSSL source code for the explanation.)
1518 * We can cover that shortcoming with this bit of code. Older OpenSSL
1519 * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
1520 * they don't have the shortcoming either.
1521 */
1522#ifdef ERR_SYSTEM_ERROR
1524 return strerror(ERR_GET_REASON(ecode));
1525#endif
1526
1527 /* No choice but to report the numeric ecode */
1528 snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1529 return errbuf;
1530}
#define strerror
Definition port.h:273
#define snprintf
Definition port.h:260

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

Referenced by be_tls_init(), be_tls_open_server(), be_tls_read(), be_tls_write(), 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 1486 of file be-secure-openssl.c.

1487{
1488 if (ecode == 0)
1489 return replacement;
1490 else
1491 return SSLerrmessage(ecode);
1492}

References fb(), and SSLerrmessage().

Referenced by initialize_ecdh().

◆ verify_cb()

static int verify_cb ( int  ok,
X509_STORE_CTX ctx 
)
static

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

1219{
1220 int depth;
1221 int errcode;
1222 const char *errstring;
1224 X509 *cert;
1225 SSL *ssl;
1226 struct CallbackErr *cb_err;
1227
1228 if (ok)
1229 {
1230 /* Nothing to do for the successful case. */
1231 return ok;
1232 }
1233
1234 /* Pull all the information we have on the verification failure. */
1235 depth = X509_STORE_CTX_get_error_depth(ctx);
1238
1239 /*
1240 * Extract the current SSL and CallbackErr object to use for passing error
1241 * detail back from the callback.
1242 */
1244 cb_err = (struct CallbackErr *) SSL_get_ex_data(ssl, 0);
1245
1248 _("Client certificate verification failed at depth %d: %s."),
1249 depth, errstring);
1250
1252 if (cert)
1253 {
1254 char *subject,
1255 *issuer;
1256 char *sub_prepared,
1257 *iss_prepared;
1258 char *serialno;
1259 ASN1_INTEGER *sn;
1260 BIGNUM *b;
1261
1262 /*
1263 * Get the Subject and Issuer for logging, but don't let maliciously
1264 * huge certs flood the logs, and don't reflect non-ASCII bytes into
1265 * it either.
1266 */
1269 pfree(subject);
1270
1273 pfree(issuer);
1274
1275 /*
1276 * Pull the serial number, too, in case a Subject is still ambiguous.
1277 * This mirrors be_tls_get_peer_serial().
1278 */
1280 b = ASN1_INTEGER_to_BN(sn, NULL);
1281 serialno = BN_bn2dec(b);
1282
1283 appendStringInfoChar(&str, '\n');
1285 _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1286 sub_prepared, serialno ? serialno : _("unknown"),
1287 iss_prepared);
1288
1289 BN_free(b);
1293 }
1294
1295 /* Store our detail message to be logged later. */
1296 cb_err->cert_errdetail = str.data;
1297
1298 return ok;
1299}
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_init().

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME name)
static

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

1668{
1670 int i,
1671 nid,
1672 count = X509_NAME_entry_count(name);
1674 ASN1_STRING *v;
1675 const char *field_name;
1676 size_t size;
1677 char nullterm;
1678 char *sp;
1679 char *dp;
1680 char *result;
1681
1682 if (membuf == NULL)
1683 ereport(ERROR,
1685 errmsg("could not create BIO")));
1686
1688 for (i = 0; i < count; i++)
1689 {
1692 if (nid == NID_undef)
1693 ereport(ERROR,
1695 errmsg("could not get NID for ASN1_OBJECT object")));
1698 if (field_name == NULL)
1700 if (field_name == NULL)
1701 ereport(ERROR,
1703 errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1704 BIO_printf(membuf, "/%s=", field_name);
1708 }
1709
1710 /* ensure null termination of the BIO's content */
1711 nullterm = '\0';
1713 size = BIO_get_mem_data(membuf, &sp);
1714 dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1715
1716 result = pstrdup(dp);
1717 if (dp != sp)
1718 pfree(dp);
1719 if (BIO_free(membuf) != 1)
1720 elog(ERROR, "could not free OpenSSL BIO structure");
1721
1722 return result;
1723}
int i
Definition isn.c:77
#define PG_UTF8
Definition mbprint.c:43
char * pg_any_to_server(const char *s, int len, int encoding)
Definition mbutils.c:687
char * pstrdup(const char *in)
Definition mcxt.c:1781
e

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

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

Referenced by be_tls_init(), and dummy_ssl_passwd_cb().

◆ openssl_tls_init_hook

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

Referenced by _PG_init().

◆ port_bio_method_ptr

BIO_METHOD* port_bio_method_ptr = NULL
static

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

Referenced by port_bio_method().

◆ SSL_context

SSL_CTX* SSL_context = NULL
static

◆ ssl_is_server_start

bool ssl_is_server_start
static

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

Referenced by be_tls_init(), and ssl_external_passwd_cb().