PostgreSQL Source Code git master
be-secure-openssl.c File Reference
#include "postgres.h"
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include "common/string.h"
#include "libpq/libpq.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "storage/fd.h"
#include "storage/latch.h"
#include "utils/guc.h"
#include "utils/memutils.h"
#include "common/openssl.h"
#include <openssl/bn.h>
#include <openssl/conf.h>
#include <openssl/dh.h>
#include <openssl/ec.h>
#include <openssl/x509v3.h>
Include dependency graph for be-secure-openssl.c:

Go to the source code of this file.

Macros

#define MAXLEN   71
 

Functions

static void default_openssl_tls_init (SSL_CTX *context, bool isServerStart)
 
static int port_bio_read (BIO *h, char *buf, int size)
 
static int port_bio_write (BIO *h, const char *buf, int size)
 
static BIO_METHOD * port_bio_method (void)
 
static int ssl_set_port_bio (Port *port)
 
static DH * load_dh_file (char *filename, bool isServerStart)
 
static DH * load_dh_buffer (const char *buffer, size_t len)
 
static int ssl_external_passwd_cb (char *buf, int size, int rwflag, void *userdata)
 
static int dummy_ssl_passwd_cb (char *buf, int size, int rwflag, void *userdata)
 
static int verify_cb (int ok, X509_STORE_CTX *ctx)
 
static void info_cb (const SSL *ssl, int type, int args)
 
static int alpn_cb (SSL *ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *userdata)
 
static bool initialize_dh (SSL_CTX *context, bool isServerStart)
 
static bool initialize_ecdh (SSL_CTX *context, bool isServerStart)
 
static const char * SSLerrmessageExt (unsigned long ecode, const char *replacement)
 
static const char * SSLerrmessage (unsigned long ecode)
 
static char * X509_NAME_to_cstring (X509_NAME *name)
 
static int ssl_protocol_version_to_openssl (int v)
 
static const char * ssl_protocol_version_to_string (int v)
 
int be_tls_init (bool isServerStart)
 
void be_tls_destroy (void)
 
int be_tls_open_server (Port *port)
 
void be_tls_close (Port *port)
 
ssize_t be_tls_read (Port *port, void *ptr, size_t len, int *waitfor)
 
ssize_t be_tls_write (Port *port, void *ptr, size_t len, int *waitfor)
 
static long port_bio_ctrl (BIO *h, int cmd, long num, void *ptr)
 
static char * prepare_cert_name (char *name)
 
int be_tls_get_cipher_bits (Port *port)
 
const char * be_tls_get_version (Port *port)
 
const char * be_tls_get_cipher (Port *port)
 
void be_tls_get_peer_subject_name (Port *port, char *ptr, size_t len)
 
void be_tls_get_peer_issuer_name (Port *port, char *ptr, size_t len)
 
void be_tls_get_peer_serial (Port *port, char *ptr, size_t len)
 
char * be_tls_get_certificate_hash (Port *port, size_t *len)
 

Variables

openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init
 
static SSL_CTX * SSL_context = NULL
 
static bool dummy_ssl_passwd_cb_called = false
 
static bool ssl_is_server_start
 
static const char * cert_errdetail
 
static BIO_METHOD * port_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 1335 of file be-secure-openssl.c.

1341{
1342 /*
1343 * Why does OpenSSL provide a helper function that requires a nonconst
1344 * vector when the callback is declared to take a const vector? What are
1345 * we to do with that?
1346 */
1347 int retval;
1348
1349 Assert(userdata != NULL);
1350 Assert(out != NULL);
1351 Assert(outlen != NULL);
1352 Assert(in != NULL);
1353
1354 retval = SSL_select_next_proto((unsigned char **) out, outlen,
1355 alpn_protos, sizeof(alpn_protos),
1356 in, inlen);
1357 if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
1358 return SSL_TLSEXT_ERR_NOACK; /* can't happen */
1359
1360 if (retval == OPENSSL_NPN_NEGOTIATED)
1361 return SSL_TLSEXT_ERR_OK;
1362 else
1363 {
1364 /*
1365 * The client doesn't support our protocol. Reject the connection
1366 * with TLS "no_application_protocol" alert, per RFC 7301.
1367 */
1368 return SSL_TLSEXT_ERR_ALERT_FATAL;
1369 }
1370}
static const unsigned char alpn_protos[]
#define Assert(condition)
Definition: c.h:815

References alpn_protos, and Assert.

Referenced by be_tls_open_server().

◆ be_tls_close()

void be_tls_close ( Port port)

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

736{
737 if (port->ssl)
738 {
739 SSL_shutdown(port->ssl);
740 SSL_free(port->ssl);
741 port->ssl = NULL;
742 port->ssl_in_use = false;
743 }
744
745 if (port->peer)
746 {
747 X509_free(port->peer);
748 port->peer = NULL;
749 }
750
751 if (port->peer_cn)
752 {
753 pfree(port->peer_cn);
754 port->peer_cn = NULL;
755 }
756
757 if (port->peer_dn)
758 {
759 pfree(port->peer_dn);
760 port->peer_dn = NULL;
761 }
762}
void pfree(void *pointer)
Definition: mcxt.c:1521
static int port
Definition: pg_regress.c:115

References pfree(), and port.

Referenced by secure_close().

◆ be_tls_destroy()

void be_tls_destroy ( void  )

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

431{
432 if (SSL_context)
433 SSL_CTX_free(SSL_context);
434 SSL_context = NULL;
435 ssl_loaded_verify_locations = false;
436}
static SSL_CTX * SSL_context

References SSL_context.

Referenced by secure_destroy().

◆ be_tls_get_certificate_hash()

char * be_tls_get_certificate_hash ( Port port,
size_t *  len 
)

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

1583{
1584 X509 *server_cert;
1585 char *cert_hash;
1586 const EVP_MD *algo_type = NULL;
1587 unsigned char hash[EVP_MAX_MD_SIZE]; /* size for SHA-512 */
1588 unsigned int hash_size;
1589 int algo_nid;
1590
1591 *len = 0;
1592 server_cert = SSL_get_certificate(port->ssl);
1593 if (server_cert == NULL)
1594 return NULL;
1595
1596 /*
1597 * Get the signature algorithm of the certificate to determine the hash
1598 * algorithm to use for the result. Prefer X509_get_signature_info(),
1599 * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
1600 */
1601#if HAVE_X509_GET_SIGNATURE_INFO
1602 if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
1603#else
1604 if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
1605 &algo_nid, NULL))
1606#endif
1607 elog(ERROR, "could not determine server certificate signature algorithm");
1608
1609 /*
1610 * The TLS server's certificate bytes need to be hashed with SHA-256 if
1611 * its signature algorithm is MD5 or SHA-1 as per RFC 5929
1612 * (https://tools.ietf.org/html/rfc5929#section-4.1). If something else
1613 * is used, the same hash as the signature algorithm is used.
1614 */
1615 switch (algo_nid)
1616 {
1617 case NID_md5:
1618 case NID_sha1:
1619 algo_type = EVP_sha256();
1620 break;
1621 default:
1622 algo_type = EVP_get_digestbynid(algo_nid);
1623 if (algo_type == NULL)
1624 elog(ERROR, "could not find digest for NID %s",
1625 OBJ_nid2sn(algo_nid));
1626 break;
1627 }
1628
1629 /* generate and save the certificate hash */
1630 if (!X509_digest(server_cert, algo_type, hash, &hash_size))
1631 elog(ERROR, "could not generate server certificate hash");
1632
1633 cert_hash = palloc(hash_size);
1634 memcpy(cert_hash, hash, hash_size);
1635 *len = hash_size;
1636
1637 return cert_hash;
1638}
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
void * palloc(Size size)
Definition: mcxt.c:1317
const void size_t len
static unsigned hash(unsigned *uv, int n)
Definition: rege_dfa.c:715

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

Referenced by read_client_final_message().

◆ be_tls_get_cipher()

const char * be_tls_get_cipher ( Port port)

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

1535{
1536 if (port->ssl)
1537 return SSL_get_cipher(port->ssl);
1538 else
1539 return NULL;
1540}

References port.

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

◆ be_tls_get_cipher_bits()

int be_tls_get_cipher_bits ( Port port)

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

1512{
1513 int bits;
1514
1515 if (port->ssl)
1516 {
1517 SSL_get_cipher_bits(port->ssl, &bits);
1518 return bits;
1519 }
1520 else
1521 return 0;
1522}

References port.

Referenced by PerformAuthentication(), and pgstat_bestart().

◆ be_tls_get_peer_issuer_name()

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

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

1553{
1554 if (port->peer)
1555 strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
1556 else
1557 ptr[0] = '\0';
1558}
static char * X509_NAME_to_cstring(X509_NAME *name)
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45

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

Referenced by pgstat_bestart(), and ssl_issuer_dn().

◆ be_tls_get_peer_serial()

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

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

1562{
1563 if (port->peer)
1564 {
1565 ASN1_INTEGER *serial;
1566 BIGNUM *b;
1567 char *decimal;
1568
1569 serial = X509_get_serialNumber(port->peer);
1570 b = ASN1_INTEGER_to_BN(serial, NULL);
1571 decimal = BN_bn2dec(b);
1572
1573 BN_free(b);
1574 strlcpy(ptr, decimal, len);
1575 OPENSSL_free(decimal);
1576 }
1577 else
1578 ptr[0] = '\0';
1579}
int b
Definition: isn.c:69

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

Referenced by pgstat_bestart(), and ssl_client_serial().

◆ be_tls_get_peer_subject_name()

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

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

1544{
1545 if (port->peer)
1546 strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
1547 else
1548 ptr[0] = '\0';
1549}

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

Referenced by pgstat_bestart(), and ssl_client_dn().

◆ be_tls_get_version()

const char * be_tls_get_version ( Port port)

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

1526{
1527 if (port->ssl)
1528 return SSL_get_version(port->ssl);
1529 else
1530 return NULL;
1531}

References port.

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

◆ be_tls_init()

int be_tls_init ( bool  isServerStart)

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

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

References check_ssl_key_file_permissions(), dummy_ssl_passwd_cb_called, ereport, errcode(), errdetail(), errmsg(), error(), FATAL, GetConfigOption(), initialize_dh(), initialize_ecdh(), LOG, ssl_ca_file, ssl_cert_file, SSL_context, ssl_crl_dir, ssl_crl_file, ssl_is_server_start, ssl_key_file, ssl_max_protocol_version, ssl_min_protocol_version, ssl_protocol_version_to_openssl(), 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 439 of file be-secure-openssl.c.

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

References alpn_cb(), Assert, cert_errdetail, COMMERROR, ereport, err(), errcode(), errcode_for_socket_access(), errdetail_internal(), errhint(), errmsg(), info_cb(), len, MemoryContextAlloc(), 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 765 of file be-secure-openssl.c.

766{
767 ssize_t n;
768 int err;
769 unsigned long ecode;
770
771 errno = 0;
772 ERR_clear_error();
773 n = SSL_read(port->ssl, ptr, len);
774 err = SSL_get_error(port->ssl, n);
775 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
776 switch (err)
777 {
778 case SSL_ERROR_NONE:
779 /* a-ok */
780 break;
781 case SSL_ERROR_WANT_READ:
782 *waitfor = WL_SOCKET_READABLE;
783 errno = EWOULDBLOCK;
784 n = -1;
785 break;
786 case SSL_ERROR_WANT_WRITE:
787 *waitfor = WL_SOCKET_WRITEABLE;
788 errno = EWOULDBLOCK;
789 n = -1;
790 break;
791 case SSL_ERROR_SYSCALL:
792 /* leave it to caller to ereport the value of errno */
793 if (n != -1 || errno == 0)
794 {
795 errno = ECONNRESET;
796 n = -1;
797 }
798 break;
799 case SSL_ERROR_SSL:
801 (errcode(ERRCODE_PROTOCOL_VIOLATION),
802 errmsg("SSL error: %s", SSLerrmessage(ecode))));
803 errno = ECONNRESET;
804 n = -1;
805 break;
806 case SSL_ERROR_ZERO_RETURN:
807 /* connection was cleanly shut down by peer */
808 n = 0;
809 break;
810 default:
812 (errcode(ERRCODE_PROTOCOL_VIOLATION),
813 errmsg("unrecognized SSL error code: %d",
814 err)));
815 errno = ECONNRESET;
816 n = -1;
817 break;
818 }
819
820 return n;
821}
#define EWOULDBLOCK
Definition: win32_port.h:370
#define ECONNRESET
Definition: win32_port.h:374

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

Referenced by secure_read().

◆ be_tls_write()

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

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

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

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

Referenced by secure_write().

◆ default_openssl_tls_init()

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

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

1775{
1776 if (isServerStart)
1777 {
1779 SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1780 }
1781 else
1782 {
1784 SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
1785 else
1786
1787 /*
1788 * If reloading and no external command is configured, override
1789 * OpenSSL's default handling of passphrase-protected files,
1790 * because we don't want to prompt for a passphrase in an
1791 * already-running server.
1792 */
1793 SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
1794 }
1795}
static int dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
static int ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
char * ssl_passphrase_command
Definition: be-secure.c:43
bool ssl_passphrase_command_supports_reload
Definition: be-secure.c:44

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

◆ dummy_ssl_passwd_cb()

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

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

1149{
1150 /* Set flag to change the error message we'll report */
1152 /* And return empty string */
1153 Assert(size > 0);
1154 buf[0] = '\0';
1155 return 0;
1156}
static char * buf
Definition: pg_test_fsync.c:72
static pg_noinline void Size size
Definition: slab.c:607

References Assert, buf, dummy_ssl_passwd_cb_called, and size.

Referenced by default_openssl_tls_init().

◆ info_cb()

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

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

1285{
1286 const char *desc;
1287
1288 desc = SSL_state_string_long(ssl);
1289
1290 switch (type)
1291 {
1292 case SSL_CB_HANDSHAKE_START:
1294 (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
1295 break;
1296 case SSL_CB_HANDSHAKE_DONE:
1298 (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
1299 break;
1300 case SSL_CB_ACCEPT_LOOP:
1302 (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
1303 break;
1304 case SSL_CB_ACCEPT_EXIT:
1306 (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
1307 break;
1308 case SSL_CB_CONNECT_LOOP:
1310 (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
1311 break;
1312 case SSL_CB_CONNECT_EXIT:
1314 (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
1315 break;
1316 case SSL_CB_READ_ALERT:
1318 (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
1319 break;
1320 case SSL_CB_WRITE_ALERT:
1322 (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
1323 break;
1324 }
1325}
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1157
#define DEBUG4
Definition: elog.h:27
const char * type

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

Referenced by be_tls_open_server().

◆ initialize_dh()

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

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

1388{
1389 DH *dh = NULL;
1390
1391 SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
1392
1393 if (ssl_dh_params_file[0])
1394 dh = load_dh_file(ssl_dh_params_file, isServerStart);
1395 if (!dh)
1396 dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
1397 if (!dh)
1398 {
1399 ereport(isServerStart ? FATAL : LOG,
1400 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1401 errmsg("DH: could not load DH parameters")));
1402 return false;
1403 }
1404
1405 if (SSL_CTX_set_tmp_dh(context, dh) != 1)
1406 {
1407 ereport(isServerStart ? FATAL : LOG,
1408 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1409 errmsg("DH: could not set DH parameters: %s",
1410 SSLerrmessage(ERR_get_error()))));
1411 DH_free(dh);
1412 return false;
1413 }
1414
1415 DH_free(dh);
1416 return true;
1417}
static DH * load_dh_buffer(const char *buffer, size_t len)
static DH * load_dh_file(char *filename, bool isServerStart)
char * ssl_dh_params_file
Definition: be-secure.c:42

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

Referenced by be_tls_init().

◆ initialize_ecdh()

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

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

1426{
1427#ifndef OPENSSL_NO_ECDH
1428 if (SSL_CTX_set1_groups_list(context, SSLECDHCurve) != 1)
1429 {
1430 /*
1431 * OpenSSL 3.3.0 introduced proper error messages for group parsing
1432 * errors, earlier versions returns "no SSL error reported" which is
1433 * far from helpful. For older versions, we replace with a better
1434 * error message. Injecting the error into the OpenSSL error queue
1435 * need APIs from OpenSSL 3.0.
1436 */
1437 ereport(isServerStart ? FATAL : LOG,
1438 errcode(ERRCODE_CONFIG_FILE_ERROR),
1439 errmsg("failed to set group names specified in ssl_groups: %s",
1440 SSLerrmessageExt(ERR_get_error(),
1441 _("No valid groups found"))),
1442 errhint("Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL"));
1443 return false;
1444 }
1445#endif
1446
1447 return true;
1448}
static const char * SSLerrmessageExt(unsigned long ecode, const char *replacement)
char * SSLECDHCurve
Definition: be-secure.c:55
#define _(x)
Definition: elog.c:90

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

1107{
1108 BIO *bio;
1109 DH *dh = NULL;
1110
1111 bio = BIO_new_mem_buf(buffer, len);
1112 if (bio == NULL)
1113 return NULL;
1114 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
1115 if (dh == NULL)
1117 (errmsg_internal("DH load buffer: %s",
1118 SSLerrmessage(ERR_get_error()))));
1119 BIO_free(bio);
1120
1121 return dh;
1122}
#define DEBUG2
Definition: elog.h:29

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

Referenced by initialize_dh().

◆ load_dh_file()

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

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

1040{
1041 FILE *fp;
1042 DH *dh = NULL;
1043 int codes;
1044
1045 /* attempt to open file. It's not an error if it doesn't exist. */
1046 if ((fp = AllocateFile(filename, "r")) == NULL)
1047 {
1048 ereport(isServerStart ? FATAL : LOG,
1050 errmsg("could not open DH parameters file \"%s\": %m",
1051 filename)));
1052 return NULL;
1053 }
1054
1055 dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
1056 FreeFile(fp);
1057
1058 if (dh == NULL)
1059 {
1060 ereport(isServerStart ? FATAL : LOG,
1061 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1062 errmsg("could not load DH parameters file: %s",
1063 SSLerrmessage(ERR_get_error()))));
1064 return NULL;
1065 }
1066
1067 /* make sure the DH parameters are usable */
1068 if (DH_check(dh, &codes) == 0)
1069 {
1070 ereport(isServerStart ? FATAL : LOG,
1071 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1072 errmsg("invalid DH parameters: %s",
1073 SSLerrmessage(ERR_get_error()))));
1074 DH_free(dh);
1075 return NULL;
1076 }
1077 if (codes & DH_CHECK_P_NOT_PRIME)
1078 {
1079 ereport(isServerStart ? FATAL : LOG,
1080 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1081 errmsg("invalid DH parameters: p is not prime")));
1082 DH_free(dh);
1083 return NULL;
1084 }
1085 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
1086 (codes & DH_CHECK_P_NOT_SAFE_PRIME))
1087 {
1088 ereport(isServerStart ? FATAL : LOG,
1089 (errcode(ERRCODE_CONFIG_FILE_ERROR),
1090 errmsg("invalid DH parameters: neither suitable generator or safe prime")));
1091 DH_free(dh);
1092 return NULL;
1093 }
1094
1095 return dh;
1096}
int errcode_for_file_access(void)
Definition: elog.c:876
int FreeFile(FILE *file)
Definition: fd.c:2803
FILE * AllocateFile(const char *name, const char *mode)
Definition: fd.c:2605
static char * filename
Definition: pg_dumpall.c:119

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

Referenced by initialize_dh().

◆ port_bio_ctrl()

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

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

956{
957 long res;
958 Port *port = (Port *) BIO_get_data(h);
959
960 switch (cmd)
961 {
962 case BIO_CTRL_EOF:
963
964 /*
965 * This should not be needed. port_bio_read already has a way to
966 * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
967 * backwards-incompatible change and now expects EOF via BIO_ctrl.
968 * See https://github.com/openssl/openssl/issues/8208
969 */
970 res = port->last_read_was_eof;
971 break;
972 case BIO_CTRL_FLUSH:
973 /* libssl expects all BIOs to support BIO_flush. */
974 res = 1;
975 break;
976 default:
977 res = 0;
978 break;
979 }
980
981 return res;
982}
Definition: libpq-be.h:135

References port, and res.

Referenced by port_bio_method().

◆ port_bio_method()

static BIO_METHOD * port_bio_method ( void  )
static

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

986{
988 {
989 int my_bio_index;
990
991 my_bio_index = BIO_get_new_index();
992 if (my_bio_index == -1)
993 return NULL;
994 my_bio_index |= BIO_TYPE_SOURCE_SINK;
995 port_bio_method_ptr = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
997 return NULL;
998 if (!BIO_meth_set_write(port_bio_method_ptr, port_bio_write) ||
999 !BIO_meth_set_read(port_bio_method_ptr, port_bio_read) ||
1000 !BIO_meth_set_ctrl(port_bio_method_ptr, port_bio_ctrl))
1001 {
1002 BIO_meth_free(port_bio_method_ptr);
1003 port_bio_method_ptr = NULL;
1004 return NULL;
1005 }
1006 }
1007 return port_bio_method_ptr;
1008}
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 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 912 of file be-secure-openssl.c.

913{
914 int res = 0;
915 Port *port = (Port *) BIO_get_data(h);
916
917 if (buf != NULL)
918 {
920 BIO_clear_retry_flags(h);
921 port->last_read_was_eof = res == 0;
922 if (res <= 0)
923 {
924 /* If we were interrupted, tell caller to retry */
925 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
926 {
927 BIO_set_retry_read(h);
928 }
929 }
930 }
931
932 return res;
933}
ssize_t secure_raw_read(Port *port, void *ptr, size_t len)
Definition: be-secure.c:268
#define EINTR
Definition: win32_port.h:364
#define EAGAIN
Definition: win32_port.h:362

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

Referenced by port_bio_method().

◆ port_bio_write()

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

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

937{
938 int res = 0;
939
940 res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
941 BIO_clear_retry_flags(h);
942 if (res <= 0)
943 {
944 /* If we were interrupted, tell caller to retry */
945 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
946 {
947 BIO_set_retry_write(h);
948 }
949 }
950
951 return res;
952}
ssize_t secure_raw_write(Port *port, const void *ptr, size_t len)
Definition: be-secure.c:377

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

Referenced by port_bio_method().

◆ prepare_cert_name()

static char * prepare_cert_name ( char *  name)
static

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

1166{
1167 size_t namelen = strlen(name);
1168 char *truncated = name;
1169
1170 /*
1171 * Common Names are 64 chars max, so for a common case where the CN is the
1172 * last field, we can still print the longest possible CN with a
1173 * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
1174 * characters.
1175 */
1176#define MAXLEN 71
1177
1178 if (namelen > MAXLEN)
1179 {
1180 /*
1181 * Keep the end of the name, not the beginning, since the most
1182 * specific field is likely to give users the most information.
1183 */
1184 truncated = name + namelen - MAXLEN;
1185 truncated[0] = truncated[1] = truncated[2] = '.';
1186 namelen = MAXLEN;
1187 }
1188
1189#undef MAXLEN
1190
1191 return pg_clean_ascii(truncated, 0);
1192}
#define MAXLEN
char * pg_clean_ascii(const char *str, int alloc_flags)
Definition: string.c:85
const char * name

References MAXLEN, name, and pg_clean_ascii().

Referenced by verify_cb().

◆ ssl_external_passwd_cb()

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

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

1129{
1130 /* same prompt as OpenSSL uses internally */
1131 const char *prompt = "Enter PEM pass phrase:";
1132
1133 Assert(rwflag == 0);
1134
1136}
int run_ssl_passphrase_command(const char *prompt, bool is_server_start, char *buf, int size)

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

Referenced by default_openssl_tls_init().

◆ ssl_protocol_version_to_openssl()

static int ssl_protocol_version_to_openssl ( int  v)
static

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

1719{
1720 switch (v)
1721 {
1722 case PG_TLS_ANY:
1723 return 0;
1724 case PG_TLS1_VERSION:
1725 return TLS1_VERSION;
1726 case PG_TLS1_1_VERSION:
1727#ifdef TLS1_1_VERSION
1728 return TLS1_1_VERSION;
1729#else
1730 break;
1731#endif
1732 case PG_TLS1_2_VERSION:
1733#ifdef TLS1_2_VERSION
1734 return TLS1_2_VERSION;
1735#else
1736 break;
1737#endif
1738 case PG_TLS1_3_VERSION:
1739#ifdef TLS1_3_VERSION
1740 return TLS1_3_VERSION;
1741#else
1742 break;
1743#endif
1744 }
1745
1746 return -1;
1747}
@ PG_TLS1_VERSION
Definition: libpq.h:131
@ PG_TLS1_3_VERSION
Definition: libpq.h:134
@ PG_TLS1_1_VERSION
Definition: libpq.h:132
@ PG_TLS1_2_VERSION
Definition: libpq.h:133
@ PG_TLS_ANY
Definition: libpq.h:130

References PG_TLS1_1_VERSION, PG_TLS1_2_VERSION, PG_TLS1_3_VERSION, PG_TLS1_VERSION, and PG_TLS_ANY.

Referenced by be_tls_init().

◆ ssl_protocol_version_to_string()

static const char * ssl_protocol_version_to_string ( int  v)
static

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

1754{
1755 switch (v)
1756 {
1757 case PG_TLS_ANY:
1758 return "any";
1759 case PG_TLS1_VERSION:
1760 return "TLSv1";
1761 case PG_TLS1_1_VERSION:
1762 return "TLSv1.1";
1763 case PG_TLS1_2_VERSION:
1764 return "TLSv1.2";
1765 case PG_TLS1_3_VERSION:
1766 return "TLSv1.3";
1767 }
1768
1769 return "(unrecognized)";
1770}

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

1012{
1013 BIO *bio;
1014 BIO_METHOD *bio_method;
1015
1016 bio_method = port_bio_method();
1017 if (bio_method == NULL)
1018 return 0;
1019
1020 bio = BIO_new(bio_method);
1021 if (bio == NULL)
1022 return 0;
1023
1024 BIO_set_data(bio, port);
1025 BIO_set_init(bio, 1);
1026
1027 SSL_set_bio(port->ssl, bio, bio);
1028 return 1;
1029}
static BIO_METHOD * port_bio_method(void)

References port, and port_bio_method().

Referenced by be_tls_open_server().

◆ SSLerrmessage()

static const char * SSLerrmessage ( unsigned long  ecode)
static

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

1483{
1484 const char *errreason;
1485 static char errbuf[36];
1486
1487 if (ecode == 0)
1488 return _("no SSL error reported");
1489 errreason = ERR_reason_error_string(ecode);
1490 if (errreason != NULL)
1491 return errreason;
1492
1493 /*
1494 * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
1495 * errno values anymore. (See OpenSSL source code for the explanation.)
1496 * We can cover that shortcoming with this bit of code. Older OpenSSL
1497 * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
1498 * they don't have the shortcoming either.
1499 */
1500#ifdef ERR_SYSTEM_ERROR
1501 if (ERR_SYSTEM_ERROR(ecode))
1502 return strerror(ERR_GET_REASON(ecode));
1503#endif
1504
1505 /* No choice but to report the numeric ecode */
1506 snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
1507 return errbuf;
1508}
#define strerror
Definition: port.h:251
#define snprintf
Definition: port.h:238

References _, snprintf, and strerror.

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

◆ SSLerrmessageExt()

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

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

1465{
1466 if (ecode == 0)
1467 return replacement;
1468 else
1469 return SSLerrmessage(ecode);
1470}

References SSLerrmessage().

Referenced by initialize_ecdh().

◆ verify_cb()

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

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

1206{
1207 int depth;
1208 int errcode;
1209 const char *errstring;
1211 X509 *cert;
1212
1213 if (ok)
1214 {
1215 /* Nothing to do for the successful case. */
1216 return ok;
1217 }
1218
1219 /* Pull all the information we have on the verification failure. */
1220 depth = X509_STORE_CTX_get_error_depth(ctx);
1221 errcode = X509_STORE_CTX_get_error(ctx);
1222 errstring = X509_verify_cert_error_string(errcode);
1223
1226 _("Client certificate verification failed at depth %d: %s."),
1227 depth, errstring);
1228
1229 cert = X509_STORE_CTX_get_current_cert(ctx);
1230 if (cert)
1231 {
1232 char *subject,
1233 *issuer;
1234 char *sub_prepared,
1235 *iss_prepared;
1236 char *serialno;
1237 ASN1_INTEGER *sn;
1238 BIGNUM *b;
1239
1240 /*
1241 * Get the Subject and Issuer for logging, but don't let maliciously
1242 * huge certs flood the logs, and don't reflect non-ASCII bytes into
1243 * it either.
1244 */
1245 subject = X509_NAME_to_cstring(X509_get_subject_name(cert));
1246 sub_prepared = prepare_cert_name(subject);
1247 pfree(subject);
1248
1249 issuer = X509_NAME_to_cstring(X509_get_issuer_name(cert));
1250 iss_prepared = prepare_cert_name(issuer);
1251 pfree(issuer);
1252
1253 /*
1254 * Pull the serial number, too, in case a Subject is still ambiguous.
1255 * This mirrors be_tls_get_peer_serial().
1256 */
1257 sn = X509_get_serialNumber(cert);
1258 b = ASN1_INTEGER_to_BN(sn, NULL);
1259 serialno = BN_bn2dec(b);
1260
1261 appendStringInfoChar(&str, '\n');
1263 _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
1264 sub_prepared, serialno ? serialno : _("unknown"),
1265 iss_prepared);
1266
1267 BN_free(b);
1268 OPENSSL_free(serialno);
1269 pfree(iss_prepared);
1270 pfree(sub_prepared);
1271 }
1272
1273 /* Store our detail message to be logged later. */
1274 cert_errdetail = str.data;
1275
1276 return ok;
1277}
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, cert_errdetail, errcode(), initStringInfo(), pfree(), prepare_cert_name(), str, and X509_NAME_to_cstring().

Referenced by be_tls_init().

◆ X509_NAME_to_cstring()

static char * X509_NAME_to_cstring ( X509_NAME *  name)
static

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

1646{
1647 BIO *membuf = BIO_new(BIO_s_mem());
1648 int i,
1649 nid,
1650 count = X509_NAME_entry_count(name);
1651 X509_NAME_ENTRY *e;
1652 ASN1_STRING *v;
1653 const char *field_name;
1654 size_t size;
1655 char nullterm;
1656 char *sp;
1657 char *dp;
1658 char *result;
1659
1660 if (membuf == NULL)
1661 ereport(ERROR,
1662 (errcode(ERRCODE_OUT_OF_MEMORY),
1663 errmsg("could not create BIO")));
1664
1665 (void) BIO_set_close(membuf, BIO_CLOSE);
1666 for (i = 0; i < count; i++)
1667 {
1668 e = X509_NAME_get_entry(name, i);
1669 nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
1670 if (nid == NID_undef)
1671 ereport(ERROR,
1672 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1673 errmsg("could not get NID for ASN1_OBJECT object")));
1674 v = X509_NAME_ENTRY_get_data(e);
1675 field_name = OBJ_nid2sn(nid);
1676 if (field_name == NULL)
1677 field_name = OBJ_nid2ln(nid);
1678 if (field_name == NULL)
1679 ereport(ERROR,
1680 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1681 errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
1682 BIO_printf(membuf, "/%s=", field_name);
1683 ASN1_STRING_print_ex(membuf, v,
1684 ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
1685 | ASN1_STRFLGS_UTF8_CONVERT));
1686 }
1687
1688 /* ensure null termination of the BIO's content */
1689 nullterm = '\0';
1690 BIO_write(membuf, &nullterm, 1);
1691 size = BIO_get_mem_data(membuf, &sp);
1692 dp = pg_any_to_server(sp, size - 1, PG_UTF8);
1693
1694 result = pstrdup(dp);
1695 if (dp != sp)
1696 pfree(dp);
1697 if (BIO_free(membuf) != 1)
1698 elog(ERROR, "could not free OpenSSL BIO structure");
1699
1700 return result;
1701}
int i
Definition: isn.c:72
char * pg_any_to_server(const char *s, int len, int encoding)
Definition: mbutils.c:676
char * pstrdup(const char *in)
Definition: mcxt.c:1696
@ PG_UTF8
Definition: pg_wchar.h:232
e
Definition: preproc-init.c:82

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

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

Variable Documentation

◆ alpn_protos

const unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR
static

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

Referenced by alpn_cb().

◆ cert_errdetail

const char* cert_errdetail
static

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

Referenced by be_tls_open_server(), and verify_cb().

◆ dummy_ssl_passwd_cb_called

bool dummy_ssl_passwd_cb_called = false
static

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

Referenced by be_tls_init(), and dummy_ssl_passwd_cb().

◆ openssl_tls_init_hook

openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init

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

Referenced by _PG_init().

◆ port_bio_method_ptr

BIO_METHOD* port_bio_method_ptr = NULL
static

Definition at line 909 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 85 of file be-secure-openssl.c.

Referenced by be_tls_init(), and ssl_external_passwd_cb().