LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 17devel Lines: 397 623 63.7 %
Date: 2024-05-09 18:11:10 Functions: 29 32 90.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * be-secure-openssl.c
       4             :  *    functions for OpenSSL support in the backend.
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/backend/libpq/be-secure-openssl.c
      13             :  *
      14             :  *-------------------------------------------------------------------------
      15             :  */
      16             : 
      17             : #include "postgres.h"
      18             : 
      19             : #include <sys/stat.h>
      20             : #include <signal.h>
      21             : #include <fcntl.h>
      22             : #include <ctype.h>
      23             : #include <sys/socket.h>
      24             : #include <unistd.h>
      25             : #include <netdb.h>
      26             : #include <netinet/in.h>
      27             : #include <netinet/tcp.h>
      28             : #include <arpa/inet.h>
      29             : 
      30             : #include "common/string.h"
      31             : #include "libpq/libpq.h"
      32             : #include "miscadmin.h"
      33             : #include "pgstat.h"
      34             : #include "storage/fd.h"
      35             : #include "storage/latch.h"
      36             : #include "tcop/tcopprot.h"
      37             : #include "utils/builtins.h"
      38             : #include "utils/memutils.h"
      39             : 
      40             : /*
      41             :  * These SSL-related #includes must come after all system-provided headers.
      42             :  * This ensures that OpenSSL can take care of conflicts with Windows'
      43             :  * <wincrypt.h> by #undef'ing the conflicting macros.  (We don't directly
      44             :  * include <wincrypt.h>, but some other Windows headers do.)
      45             :  */
      46             : #include "common/openssl.h"
      47             : #include <openssl/conf.h>
      48             : #include <openssl/dh.h>
      49             : #ifndef OPENSSL_NO_ECDH
      50             : #include <openssl/ec.h>
      51             : #endif
      52             : #include <openssl/x509v3.h>
      53             : 
      54             : 
      55             : /* default init hook can be overridden by a shared library */
      56             : static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart);
      57             : openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init;
      58             : 
      59             : static int  my_sock_read(BIO *h, char *buf, int size);
      60             : static int  my_sock_write(BIO *h, const char *buf, int size);
      61             : static BIO_METHOD *my_BIO_s_socket(void);
      62             : static int  my_SSL_set_fd(Port *port, int fd);
      63             : 
      64             : static DH  *load_dh_file(char *filename, bool isServerStart);
      65             : static DH  *load_dh_buffer(const char *buffer, size_t len);
      66             : static int  ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      67             : static int  dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      68             : static int  verify_cb(int ok, X509_STORE_CTX *ctx);
      69             : static void info_cb(const SSL *ssl, int type, int args);
      70             : static int  alpn_cb(SSL *ssl,
      71             :                     const unsigned char **out,
      72             :                     unsigned char *outlen,
      73             :                     const unsigned char *in,
      74             :                     unsigned int inlen,
      75             :                     void *userdata);
      76             : static bool initialize_dh(SSL_CTX *context, bool isServerStart);
      77             : static bool initialize_ecdh(SSL_CTX *context, bool isServerStart);
      78             : static const char *SSLerrmessage(unsigned long ecode);
      79             : 
      80             : static char *X509_NAME_to_cstring(X509_NAME *name);
      81             : 
      82             : static SSL_CTX *SSL_context = NULL;
      83             : static bool SSL_initialized = false;
      84             : static bool dummy_ssl_passwd_cb_called = false;
      85             : static bool ssl_is_server_start;
      86             : 
      87             : static int  ssl_protocol_version_to_openssl(int v);
      88             : static const char *ssl_protocol_version_to_string(int v);
      89             : 
      90             : /* for passing data back from verify_cb() */
      91             : static const char *cert_errdetail;
      92             : 
      93             : /* ------------------------------------------------------------ */
      94             : /*                       Public interface                       */
      95             : /* ------------------------------------------------------------ */
      96             : 
      97             : int
      98          52 : be_tls_init(bool isServerStart)
      99             : {
     100             :     SSL_CTX    *context;
     101          52 :     int         ssl_ver_min = -1;
     102          52 :     int         ssl_ver_max = -1;
     103             : 
     104             :     /* This stuff need be done only once. */
     105          52 :     if (!SSL_initialized)
     106             :     {
     107             : #ifdef HAVE_OPENSSL_INIT_SSL
     108          52 :         OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
     109             : #else
     110             :         OPENSSL_config(NULL);
     111             :         SSL_library_init();
     112             :         SSL_load_error_strings();
     113             : #endif
     114          52 :         SSL_initialized = true;
     115             :     }
     116             : 
     117             :     /*
     118             :      * Create a new SSL context into which we'll load all the configuration
     119             :      * settings.  If we fail partway through, we can avoid memory leakage by
     120             :      * freeing this context; we don't install it as active until the end.
     121             :      *
     122             :      * We use SSLv23_method() because it can negotiate use of the highest
     123             :      * mutually supported protocol version, while alternatives like
     124             :      * TLSv1_2_method() permit only one specific version.  Note that we don't
     125             :      * actually allow SSL v2 or v3, only TLS protocols (see below).
     126             :      */
     127          52 :     context = SSL_CTX_new(SSLv23_method());
     128          52 :     if (!context)
     129             :     {
     130           0 :         ereport(isServerStart ? FATAL : LOG,
     131             :                 (errmsg("could not create SSL context: %s",
     132             :                         SSLerrmessage(ERR_get_error()))));
     133           0 :         goto error;
     134             :     }
     135             : 
     136             :     /*
     137             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     138             :      * unnecessary failures in nonblocking send cases.
     139             :      */
     140          52 :     SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     141             : 
     142             :     /*
     143             :      * Call init hook (usually to set password callback)
     144             :      */
     145          52 :     (*openssl_tls_init_hook) (context, isServerStart);
     146             : 
     147             :     /* used by the callback */
     148          52 :     ssl_is_server_start = isServerStart;
     149             : 
     150             :     /*
     151             :      * Load and verify server's certificate and private key
     152             :      */
     153          52 :     if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
     154             :     {
     155           0 :         ereport(isServerStart ? FATAL : LOG,
     156             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     157             :                  errmsg("could not load server certificate file \"%s\": %s",
     158             :                         ssl_cert_file, SSLerrmessage(ERR_get_error()))));
     159           0 :         goto error;
     160             :     }
     161             : 
     162          52 :     if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
     163           0 :         goto error;
     164             : 
     165             :     /*
     166             :      * OK, try to load the private key file.
     167             :      */
     168          52 :     dummy_ssl_passwd_cb_called = false;
     169             : 
     170          52 :     if (SSL_CTX_use_PrivateKey_file(context,
     171             :                                     ssl_key_file,
     172             :                                     SSL_FILETYPE_PEM) != 1)
     173             :     {
     174           4 :         if (dummy_ssl_passwd_cb_called)
     175           0 :             ereport(isServerStart ? FATAL : LOG,
     176             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     177             :                      errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
     178             :                             ssl_key_file)));
     179             :         else
     180           4 :             ereport(isServerStart ? FATAL : LOG,
     181             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     182             :                      errmsg("could not load private key file \"%s\": %s",
     183             :                             ssl_key_file, SSLerrmessage(ERR_get_error()))));
     184           0 :         goto error;
     185             :     }
     186             : 
     187          48 :     if (SSL_CTX_check_private_key(context) != 1)
     188             :     {
     189           0 :         ereport(isServerStart ? FATAL : LOG,
     190             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     191             :                  errmsg("check of private key failed: %s",
     192             :                         SSLerrmessage(ERR_get_error()))));
     193           0 :         goto error;
     194             :     }
     195             : 
     196          48 :     if (ssl_min_protocol_version)
     197             :     {
     198          48 :         ssl_ver_min = ssl_protocol_version_to_openssl(ssl_min_protocol_version);
     199             : 
     200          48 :         if (ssl_ver_min == -1)
     201             :         {
     202           0 :             ereport(isServerStart ? FATAL : LOG,
     203             :             /*- translator: first %s is a GUC option name, second %s is its value */
     204             :                     (errmsg("%s setting \"%s\" not supported by this build",
     205             :                             "ssl_min_protocol_version",
     206             :                             GetConfigOption("ssl_min_protocol_version",
     207             :                                             false, false))));
     208           0 :             goto error;
     209             :         }
     210             : 
     211          48 :         if (!SSL_CTX_set_min_proto_version(context, ssl_ver_min))
     212             :         {
     213           0 :             ereport(isServerStart ? FATAL : LOG,
     214             :                     (errmsg("could not set minimum SSL protocol version")));
     215           0 :             goto error;
     216             :         }
     217             :     }
     218             : 
     219          48 :     if (ssl_max_protocol_version)
     220             :     {
     221           2 :         ssl_ver_max = ssl_protocol_version_to_openssl(ssl_max_protocol_version);
     222             : 
     223           2 :         if (ssl_ver_max == -1)
     224             :         {
     225           0 :             ereport(isServerStart ? FATAL : LOG,
     226             :             /*- translator: first %s is a GUC option name, second %s is its value */
     227             :                     (errmsg("%s setting \"%s\" not supported by this build",
     228             :                             "ssl_max_protocol_version",
     229             :                             GetConfigOption("ssl_max_protocol_version",
     230             :                                             false, false))));
     231           0 :             goto error;
     232             :         }
     233             : 
     234           2 :         if (!SSL_CTX_set_max_proto_version(context, ssl_ver_max))
     235             :         {
     236           0 :             ereport(isServerStart ? FATAL : LOG,
     237             :                     (errmsg("could not set maximum SSL protocol version")));
     238           0 :             goto error;
     239             :         }
     240             :     }
     241             : 
     242             :     /* Check compatibility of min/max protocols */
     243          48 :     if (ssl_min_protocol_version &&
     244             :         ssl_max_protocol_version)
     245             :     {
     246             :         /*
     247             :          * No need to check for invalid values (-1) for each protocol number
     248             :          * as the code above would have already generated an error.
     249             :          */
     250           2 :         if (ssl_ver_min > ssl_ver_max)
     251             :         {
     252           2 :             ereport(isServerStart ? FATAL : LOG,
     253             :                     (errmsg("could not set SSL protocol version range"),
     254             :                      errdetail("%s cannot be higher than %s",
     255             :                                "ssl_min_protocol_version",
     256             :                                "ssl_max_protocol_version")));
     257           0 :             goto error;
     258             :         }
     259             :     }
     260             : 
     261             :     /* disallow SSL session tickets */
     262          46 :     SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
     263             : 
     264             :     /* disallow SSL session caching, too */
     265          46 :     SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
     266             : 
     267             :     /* disallow SSL compression */
     268          46 :     SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
     269             : 
     270             :     /*
     271             :      * Disallow SSL renegotiation.  This concerns only TLSv1.2 and older
     272             :      * protocol versions, as TLSv1.3 has no support for renegotiation.
     273             :      * SSL_OP_NO_RENEGOTIATION is available in OpenSSL since 1.1.0h (via a
     274             :      * backport from 1.1.1). SSL_OP_NO_CLIENT_RENEGOTIATION is available in
     275             :      * LibreSSL since 2.5.1 disallowing all client-initiated renegotiation
     276             :      * (this is usually on by default).
     277             :      */
     278             : #ifdef SSL_OP_NO_RENEGOTIATION
     279          46 :     SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
     280             : #endif
     281             : #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
     282             :     SSL_CTX_set_options(context, SSL_OP_NO_CLIENT_RENEGOTIATION);
     283             : #endif
     284             : 
     285             :     /* set up ephemeral DH and ECDH keys */
     286          46 :     if (!initialize_dh(context, isServerStart))
     287           0 :         goto error;
     288          46 :     if (!initialize_ecdh(context, isServerStart))
     289           0 :         goto error;
     290             : 
     291             :     /* set up the allowed cipher list */
     292          46 :     if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
     293             :     {
     294           0 :         ereport(isServerStart ? FATAL : LOG,
     295             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     296             :                  errmsg("could not set the cipher list (no valid ciphers available)")));
     297           0 :         goto error;
     298             :     }
     299             : 
     300             :     /* Let server choose order */
     301          46 :     if (SSLPreferServerCiphers)
     302          46 :         SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
     303             : 
     304             :     /*
     305             :      * Load CA store, so we can verify client certificates if needed.
     306             :      */
     307          46 :     if (ssl_ca_file[0])
     308             :     {
     309             :         STACK_OF(X509_NAME) * root_cert_list;
     310             : 
     311          84 :         if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
     312          42 :             (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
     313             :         {
     314           0 :             ereport(isServerStart ? FATAL : LOG,
     315             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     316             :                      errmsg("could not load root certificate file \"%s\": %s",
     317             :                             ssl_ca_file, SSLerrmessage(ERR_get_error()))));
     318           0 :             goto error;
     319             :         }
     320             : 
     321             :         /*
     322             :          * Tell OpenSSL to send the list of root certs we trust to clients in
     323             :          * CertificateRequests.  This lets a client with a keystore select the
     324             :          * appropriate client certificate to send to us.  Also, this ensures
     325             :          * that the SSL context will "own" the root_cert_list and remember to
     326             :          * free it when no longer needed.
     327             :          */
     328          42 :         SSL_CTX_set_client_CA_list(context, root_cert_list);
     329             : 
     330             :         /*
     331             :          * Always ask for SSL client cert, but don't fail if it's not
     332             :          * presented.  We might fail such connections later, depending on what
     333             :          * we find in pg_hba.conf.
     334             :          */
     335          42 :         SSL_CTX_set_verify(context,
     336             :                            (SSL_VERIFY_PEER |
     337             :                             SSL_VERIFY_CLIENT_ONCE),
     338             :                            verify_cb);
     339             :     }
     340             : 
     341             :     /*----------
     342             :      * Load the Certificate Revocation List (CRL).
     343             :      * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
     344             :      *----------
     345             :      */
     346          46 :     if (ssl_crl_file[0] || ssl_crl_dir[0])
     347             :     {
     348          42 :         X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
     349             : 
     350          42 :         if (cvstore)
     351             :         {
     352             :             /* Set the flags to check against the complete CRL chain */
     353          84 :             if (X509_STORE_load_locations(cvstore,
     354          42 :                                           ssl_crl_file[0] ? ssl_crl_file : NULL,
     355          42 :                                           ssl_crl_dir[0] ? ssl_crl_dir : NULL)
     356             :                 == 1)
     357             :             {
     358          42 :                 X509_STORE_set_flags(cvstore,
     359             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     360             :             }
     361           0 :             else if (ssl_crl_dir[0] == 0)
     362             :             {
     363           0 :                 ereport(isServerStart ? FATAL : LOG,
     364             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     365             :                          errmsg("could not load SSL certificate revocation list file \"%s\": %s",
     366             :                                 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
     367           0 :                 goto error;
     368             :             }
     369           0 :             else if (ssl_crl_file[0] == 0)
     370             :             {
     371           0 :                 ereport(isServerStart ? FATAL : LOG,
     372             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     373             :                          errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
     374             :                                 ssl_crl_dir, SSLerrmessage(ERR_get_error()))));
     375           0 :                 goto error;
     376             :             }
     377             :             else
     378             :             {
     379           0 :                 ereport(isServerStart ? FATAL : LOG,
     380             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     381             :                          errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
     382             :                                 ssl_crl_file, ssl_crl_dir,
     383             :                                 SSLerrmessage(ERR_get_error()))));
     384           0 :                 goto error;
     385             :             }
     386             :         }
     387             :     }
     388             : 
     389             :     /*
     390             :      * Success!  Replace any existing SSL_context.
     391             :      */
     392          46 :     if (SSL_context)
     393           0 :         SSL_CTX_free(SSL_context);
     394             : 
     395          46 :     SSL_context = context;
     396             : 
     397             :     /*
     398             :      * Set flag to remember whether CA store has been loaded into SSL_context.
     399             :      */
     400          46 :     if (ssl_ca_file[0])
     401          42 :         ssl_loaded_verify_locations = true;
     402             :     else
     403           4 :         ssl_loaded_verify_locations = false;
     404             : 
     405          46 :     return 0;
     406             : 
     407             :     /* Clean up by releasing working context. */
     408           0 : error:
     409           0 :     if (context)
     410           0 :         SSL_CTX_free(context);
     411           0 :     return -1;
     412             : }
     413             : 
     414             : void
     415         246 : be_tls_destroy(void)
     416             : {
     417         246 :     if (SSL_context)
     418           0 :         SSL_CTX_free(SSL_context);
     419         246 :     SSL_context = NULL;
     420         246 :     ssl_loaded_verify_locations = false;
     421         246 : }
     422             : 
     423             : int
     424         226 : be_tls_open_server(Port *port)
     425             : {
     426             :     int         r;
     427             :     int         err;
     428             :     int         waitfor;
     429             :     unsigned long ecode;
     430             :     bool        give_proto_hint;
     431             : 
     432             :     Assert(!port->ssl);
     433             :     Assert(!port->peer);
     434             : 
     435         226 :     if (!SSL_context)
     436             :     {
     437           0 :         ereport(COMMERROR,
     438             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     439             :                  errmsg("could not initialize SSL connection: SSL context not set up")));
     440           0 :         return -1;
     441             :     }
     442             : 
     443             :     /* set up debugging/info callback */
     444         226 :     SSL_CTX_set_info_callback(SSL_context, info_cb);
     445             : 
     446             :     /* enable ALPN */
     447         226 :     SSL_CTX_set_alpn_select_cb(SSL_context, alpn_cb, port);
     448             : 
     449         226 :     if (!(port->ssl = SSL_new(SSL_context)))
     450             :     {
     451           0 :         ereport(COMMERROR,
     452             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     453             :                  errmsg("could not initialize SSL connection: %s",
     454             :                         SSLerrmessage(ERR_get_error()))));
     455           0 :         return -1;
     456             :     }
     457         226 :     if (!my_SSL_set_fd(port, port->sock))
     458             :     {
     459           0 :         ereport(COMMERROR,
     460             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     461             :                  errmsg("could not set SSL socket: %s",
     462             :                         SSLerrmessage(ERR_get_error()))));
     463           0 :         return -1;
     464             :     }
     465         226 :     port->ssl_in_use = true;
     466             : 
     467         538 : aloop:
     468             : 
     469             :     /*
     470             :      * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
     471             :      * queue.  In general, the current thread's error queue must be empty
     472             :      * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
     473             :      * not work reliably.  An extension may have failed to clear the
     474             :      * per-thread error queue following another call to an OpenSSL I/O
     475             :      * routine.
     476             :      */
     477         538 :     errno = 0;
     478         538 :     ERR_clear_error();
     479         538 :     r = SSL_accept(port->ssl);
     480         538 :     if (r <= 0)
     481             :     {
     482         348 :         err = SSL_get_error(port->ssl, r);
     483             : 
     484             :         /*
     485             :          * Other clients of OpenSSL in the backend may fail to call
     486             :          * ERR_get_error(), but we always do, so as to not cause problems for
     487             :          * OpenSSL clients that don't call ERR_clear_error() defensively.  Be
     488             :          * sure that this happens by calling now. SSL_get_error() relies on
     489             :          * the OpenSSL per-thread error queue being intact, so this is the
     490             :          * earliest possible point ERR_get_error() may be called.
     491             :          */
     492         348 :         ecode = ERR_get_error();
     493         348 :         switch (err)
     494             :         {
     495         312 :             case SSL_ERROR_WANT_READ:
     496             :             case SSL_ERROR_WANT_WRITE:
     497             :                 /* not allowed during connection establishment */
     498             :                 Assert(!port->noblock);
     499             : 
     500             :                 /*
     501             :                  * No need to care about timeouts/interrupts here. At this
     502             :                  * point authentication_timeout still employs
     503             :                  * StartupPacketTimeoutHandler() which directly exits.
     504             :                  */
     505         312 :                 if (err == SSL_ERROR_WANT_READ)
     506         312 :                     waitfor = WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH;
     507             :                 else
     508           0 :                     waitfor = WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH;
     509             : 
     510         312 :                 (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
     511             :                                          WAIT_EVENT_SSL_OPEN_SERVER);
     512         312 :                 goto aloop;
     513           8 :             case SSL_ERROR_SYSCALL:
     514           8 :                 if (r < 0 && errno != 0)
     515           0 :                     ereport(COMMERROR,
     516             :                             (errcode_for_socket_access(),
     517             :                              errmsg("could not accept SSL connection: %m")));
     518             :                 else
     519           8 :                     ereport(COMMERROR,
     520             :                             (errcode(ERRCODE_PROTOCOL_VIOLATION),
     521             :                              errmsg("could not accept SSL connection: EOF detected")));
     522           8 :                 break;
     523          28 :             case SSL_ERROR_SSL:
     524          28 :                 switch (ERR_GET_REASON(ecode))
     525             :                 {
     526             :                         /*
     527             :                          * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
     528             :                          * TLSV1_ALERT_PROTOCOL_VERSION have been observed
     529             :                          * when trying to communicate with an old OpenSSL
     530             :                          * library, or when the client and server specify
     531             :                          * disjoint protocol ranges.  NO_PROTOCOLS_AVAILABLE
     532             :                          * occurs if there's a local misconfiguration (which
     533             :                          * can happen despite our checks, if openssl.cnf
     534             :                          * injects a limit we didn't account for).  It's not
     535             :                          * very clear what would make OpenSSL return the other
     536             :                          * codes listed here, but a hint about protocol
     537             :                          * versions seems like it's appropriate for all.
     538             :                          */
     539           0 :                     case SSL_R_NO_PROTOCOLS_AVAILABLE:
     540             :                     case SSL_R_UNSUPPORTED_PROTOCOL:
     541             :                     case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
     542             :                     case SSL_R_UNKNOWN_PROTOCOL:
     543             :                     case SSL_R_UNKNOWN_SSL_VERSION:
     544             :                     case SSL_R_UNSUPPORTED_SSL_VERSION:
     545             :                     case SSL_R_WRONG_SSL_VERSION:
     546             :                     case SSL_R_WRONG_VERSION_NUMBER:
     547             :                     case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
     548             : #ifdef SSL_R_VERSION_TOO_HIGH
     549             :                     case SSL_R_VERSION_TOO_HIGH:
     550             : #endif
     551             : #ifdef SSL_R_VERSION_TOO_LOW
     552             :                     case SSL_R_VERSION_TOO_LOW:
     553             : #endif
     554           0 :                         give_proto_hint = true;
     555           0 :                         break;
     556          28 :                     default:
     557          28 :                         give_proto_hint = false;
     558          28 :                         break;
     559             :                 }
     560          28 :                 ereport(COMMERROR,
     561             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     562             :                          errmsg("could not accept SSL connection: %s",
     563             :                                 SSLerrmessage(ecode)),
     564             :                          cert_errdetail ? errdetail_internal("%s", cert_errdetail) : 0,
     565             :                          give_proto_hint ?
     566             :                          errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
     567             :                                  ssl_min_protocol_version ?
     568             :                                  ssl_protocol_version_to_string(ssl_min_protocol_version) :
     569             :                                  MIN_OPENSSL_TLS_VERSION,
     570             :                                  ssl_max_protocol_version ?
     571             :                                  ssl_protocol_version_to_string(ssl_max_protocol_version) :
     572             :                                  MAX_OPENSSL_TLS_VERSION) : 0));
     573          28 :                 cert_errdetail = NULL;
     574          28 :                 break;
     575           0 :             case SSL_ERROR_ZERO_RETURN:
     576           0 :                 ereport(COMMERROR,
     577             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     578             :                          errmsg("could not accept SSL connection: EOF detected")));
     579           0 :                 break;
     580           0 :             default:
     581           0 :                 ereport(COMMERROR,
     582             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     583             :                          errmsg("unrecognized SSL error code: %d",
     584             :                                 err)));
     585           0 :                 break;
     586             :         }
     587          36 :         return -1;
     588             :     }
     589             : 
     590             :     /* Get the protocol selected by ALPN */
     591         190 :     port->alpn_used = false;
     592             :     {
     593             :         const unsigned char *selected;
     594             :         unsigned int len;
     595             : 
     596         190 :         SSL_get0_alpn_selected(port->ssl, &selected, &len);
     597             : 
     598             :         /* If ALPN is used, check that we negotiated the expected protocol */
     599         190 :         if (selected != NULL)
     600             :         {
     601         190 :             if (len == strlen(PG_ALPN_PROTOCOL) &&
     602         190 :                 memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) == 0)
     603             :             {
     604         190 :                 port->alpn_used = true;
     605             :             }
     606             :             else
     607             :             {
     608             :                 /* shouldn't happen */
     609           0 :                 ereport(COMMERROR,
     610             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     611             :                          errmsg("received SSL connection request with unexpected ALPN protocol")));
     612             :             }
     613             :         }
     614             :     }
     615             : 
     616             :     /* Get client certificate, if available. */
     617         190 :     port->peer = SSL_get_peer_certificate(port->ssl);
     618             : 
     619             :     /* and extract the Common Name and Distinguished Name from it. */
     620         190 :     port->peer_cn = NULL;
     621         190 :     port->peer_dn = NULL;
     622         190 :     port->peer_cert_valid = false;
     623         190 :     if (port->peer != NULL)
     624             :     {
     625             :         int         len;
     626          58 :         X509_NAME  *x509name = X509_get_subject_name(port->peer);
     627             :         char       *peer_dn;
     628          58 :         BIO        *bio = NULL;
     629          58 :         BUF_MEM    *bio_buf = NULL;
     630             : 
     631          58 :         len = X509_NAME_get_text_by_NID(x509name, NID_commonName, NULL, 0);
     632          58 :         if (len != -1)
     633             :         {
     634             :             char       *peer_cn;
     635             : 
     636          58 :             peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
     637          58 :             r = X509_NAME_get_text_by_NID(x509name, NID_commonName, peer_cn,
     638             :                                           len + 1);
     639          58 :             peer_cn[len] = '\0';
     640          58 :             if (r != len)
     641             :             {
     642             :                 /* shouldn't happen */
     643           0 :                 pfree(peer_cn);
     644           0 :                 return -1;
     645             :             }
     646             : 
     647             :             /*
     648             :              * Reject embedded NULLs in certificate common name to prevent
     649             :              * attacks like CVE-2009-4034.
     650             :              */
     651          58 :             if (len != strlen(peer_cn))
     652             :             {
     653           0 :                 ereport(COMMERROR,
     654             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     655             :                          errmsg("SSL certificate's common name contains embedded null")));
     656           0 :                 pfree(peer_cn);
     657           0 :                 return -1;
     658             :             }
     659             : 
     660          58 :             port->peer_cn = peer_cn;
     661             :         }
     662             : 
     663          58 :         bio = BIO_new(BIO_s_mem());
     664          58 :         if (!bio)
     665             :         {
     666           0 :             if (port->peer_cn != NULL)
     667             :             {
     668           0 :                 pfree(port->peer_cn);
     669           0 :                 port->peer_cn = NULL;
     670             :             }
     671           0 :             return -1;
     672             :         }
     673             : 
     674             :         /*
     675             :          * RFC2253 is the closest thing to an accepted standard format for
     676             :          * DNs. We have documented how to produce this format from a
     677             :          * certificate. It uses commas instead of slashes for delimiters,
     678             :          * which make regular expression matching a bit easier. Also note that
     679             :          * it prints the Subject fields in reverse order.
     680             :          */
     681         116 :         if (X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253) == -1 ||
     682          58 :             BIO_get_mem_ptr(bio, &bio_buf) <= 0)
     683             :         {
     684           0 :             BIO_free(bio);
     685           0 :             if (port->peer_cn != NULL)
     686             :             {
     687           0 :                 pfree(port->peer_cn);
     688           0 :                 port->peer_cn = NULL;
     689             :             }
     690           0 :             return -1;
     691             :         }
     692          58 :         peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
     693          58 :         memcpy(peer_dn, bio_buf->data, bio_buf->length);
     694          58 :         len = bio_buf->length;
     695          58 :         BIO_free(bio);
     696          58 :         peer_dn[len] = '\0';
     697          58 :         if (len != strlen(peer_dn))
     698             :         {
     699           0 :             ereport(COMMERROR,
     700             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     701             :                      errmsg("SSL certificate's distinguished name contains embedded null")));
     702           0 :             pfree(peer_dn);
     703           0 :             if (port->peer_cn != NULL)
     704             :             {
     705           0 :                 pfree(port->peer_cn);
     706           0 :                 port->peer_cn = NULL;
     707             :             }
     708           0 :             return -1;
     709             :         }
     710             : 
     711          58 :         port->peer_dn = peer_dn;
     712             : 
     713          58 :         port->peer_cert_valid = true;
     714             :     }
     715             : 
     716         190 :     return 0;
     717             : }
     718             : 
     719             : void
     720         226 : be_tls_close(Port *port)
     721             : {
     722         226 :     if (port->ssl)
     723             :     {
     724         226 :         SSL_shutdown(port->ssl);
     725         226 :         SSL_free(port->ssl);
     726         226 :         port->ssl = NULL;
     727         226 :         port->ssl_in_use = false;
     728             :     }
     729             : 
     730         226 :     if (port->peer)
     731             :     {
     732          58 :         X509_free(port->peer);
     733          58 :         port->peer = NULL;
     734             :     }
     735             : 
     736         226 :     if (port->peer_cn)
     737             :     {
     738          58 :         pfree(port->peer_cn);
     739          58 :         port->peer_cn = NULL;
     740             :     }
     741             : 
     742         226 :     if (port->peer_dn)
     743             :     {
     744          58 :         pfree(port->peer_dn);
     745          58 :         port->peer_dn = NULL;
     746             :     }
     747         226 : }
     748             : 
     749             : ssize_t
     750         722 : be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
     751             : {
     752             :     ssize_t     n;
     753             :     int         err;
     754             :     unsigned long ecode;
     755             : 
     756         722 :     errno = 0;
     757         722 :     ERR_clear_error();
     758         722 :     n = SSL_read(port->ssl, ptr, len);
     759         722 :     err = SSL_get_error(port->ssl, n);
     760         722 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     761         722 :     switch (err)
     762             :     {
     763         482 :         case SSL_ERROR_NONE:
     764             :             /* a-ok */
     765         482 :             break;
     766         206 :         case SSL_ERROR_WANT_READ:
     767         206 :             *waitfor = WL_SOCKET_READABLE;
     768         206 :             errno = EWOULDBLOCK;
     769         206 :             n = -1;
     770         206 :             break;
     771           0 :         case SSL_ERROR_WANT_WRITE:
     772           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     773           0 :             errno = EWOULDBLOCK;
     774           0 :             n = -1;
     775           0 :             break;
     776           0 :         case SSL_ERROR_SYSCALL:
     777             :             /* leave it to caller to ereport the value of errno */
     778           0 :             if (n != -1 || errno == 0)
     779             :             {
     780           0 :                 errno = ECONNRESET;
     781           0 :                 n = -1;
     782             :             }
     783           0 :             break;
     784           0 :         case SSL_ERROR_SSL:
     785           0 :             ereport(COMMERROR,
     786             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     787             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     788           0 :             errno = ECONNRESET;
     789           0 :             n = -1;
     790           0 :             break;
     791          34 :         case SSL_ERROR_ZERO_RETURN:
     792             :             /* connection was cleanly shut down by peer */
     793          34 :             n = 0;
     794          34 :             break;
     795           0 :         default:
     796           0 :             ereport(COMMERROR,
     797             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     798             :                      errmsg("unrecognized SSL error code: %d",
     799             :                             err)));
     800           0 :             errno = ECONNRESET;
     801           0 :             n = -1;
     802           0 :             break;
     803             :     }
     804             : 
     805         722 :     return n;
     806             : }
     807             : 
     808             : ssize_t
     809         340 : be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
     810             : {
     811             :     ssize_t     n;
     812             :     int         err;
     813             :     unsigned long ecode;
     814             : 
     815         340 :     errno = 0;
     816         340 :     ERR_clear_error();
     817         340 :     n = SSL_write(port->ssl, ptr, len);
     818         340 :     err = SSL_get_error(port->ssl, n);
     819         340 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     820         340 :     switch (err)
     821             :     {
     822         340 :         case SSL_ERROR_NONE:
     823             :             /* a-ok */
     824         340 :             break;
     825           0 :         case SSL_ERROR_WANT_READ:
     826           0 :             *waitfor = WL_SOCKET_READABLE;
     827           0 :             errno = EWOULDBLOCK;
     828           0 :             n = -1;
     829           0 :             break;
     830           0 :         case SSL_ERROR_WANT_WRITE:
     831           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     832           0 :             errno = EWOULDBLOCK;
     833           0 :             n = -1;
     834           0 :             break;
     835           0 :         case SSL_ERROR_SYSCALL:
     836             : 
     837             :             /*
     838             :              * Leave it to caller to ereport the value of errno.  However, if
     839             :              * errno is still zero then assume it's a read EOF situation, and
     840             :              * report ECONNRESET.  (This seems possible because SSL_write can
     841             :              * also do reads.)
     842             :              */
     843           0 :             if (n != -1 || errno == 0)
     844             :             {
     845           0 :                 errno = ECONNRESET;
     846           0 :                 n = -1;
     847             :             }
     848           0 :             break;
     849           0 :         case SSL_ERROR_SSL:
     850           0 :             ereport(COMMERROR,
     851             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     852             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     853           0 :             errno = ECONNRESET;
     854           0 :             n = -1;
     855           0 :             break;
     856           0 :         case SSL_ERROR_ZERO_RETURN:
     857             : 
     858             :             /*
     859             :              * the SSL connection was closed, leave it to the caller to
     860             :              * ereport it
     861             :              */
     862           0 :             errno = ECONNRESET;
     863           0 :             n = -1;
     864           0 :             break;
     865           0 :         default:
     866           0 :             ereport(COMMERROR,
     867             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     868             :                      errmsg("unrecognized SSL error code: %d",
     869             :                             err)));
     870           0 :             errno = ECONNRESET;
     871           0 :             n = -1;
     872           0 :             break;
     873             :     }
     874             : 
     875         340 :     return n;
     876             : }
     877             : 
     878             : /* ------------------------------------------------------------ */
     879             : /*                      Internal functions                      */
     880             : /* ------------------------------------------------------------ */
     881             : 
     882             : /*
     883             :  * Private substitute BIO: this does the sending and receiving using send() and
     884             :  * recv() instead. This is so that we can enable and disable interrupts
     885             :  * just while calling recv(). We cannot have interrupts occurring while
     886             :  * the bulk of OpenSSL runs, because it uses malloc() and possibly other
     887             :  * non-reentrant libc facilities. We also need to call send() and recv()
     888             :  * directly so it gets passed through the socket/signals layer on Win32.
     889             :  *
     890             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
     891             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
     892             :  */
     893             : 
     894             : static BIO_METHOD *my_bio_methods = NULL;
     895             : 
     896             : static int
     897        3798 : my_sock_read(BIO *h, char *buf, int size)
     898             : {
     899        3798 :     int         res = 0;
     900             : 
     901        3798 :     if (buf != NULL)
     902             :     {
     903        3798 :         res = secure_raw_read(((Port *) BIO_get_app_data(h)), buf, size);
     904        3798 :         BIO_clear_retry_flags(h);
     905        3798 :         if (res <= 0)
     906             :         {
     907             :             /* If we were interrupted, tell caller to retry */
     908         526 :             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     909             :             {
     910         518 :                 BIO_set_retry_read(h);
     911             :             }
     912             :         }
     913             :     }
     914             : 
     915        3798 :     return res;
     916             : }
     917             : 
     918             : static int
     919        1348 : my_sock_write(BIO *h, const char *buf, int size)
     920             : {
     921        1348 :     int         res = 0;
     922             : 
     923        1348 :     res = secure_raw_write(((Port *) BIO_get_app_data(h)), buf, size);
     924        1348 :     BIO_clear_retry_flags(h);
     925        1348 :     if (res <= 0)
     926             :     {
     927             :         /* If we were interrupted, tell caller to retry */
     928          50 :         if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     929             :         {
     930           0 :             BIO_set_retry_write(h);
     931             :         }
     932             :     }
     933             : 
     934        1348 :     return res;
     935             : }
     936             : 
     937             : static BIO_METHOD *
     938         226 : my_BIO_s_socket(void)
     939             : {
     940         226 :     if (!my_bio_methods)
     941             :     {
     942         226 :         BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
     943             : #ifdef HAVE_BIO_METH_NEW
     944             :         int         my_bio_index;
     945             : 
     946         226 :         my_bio_index = BIO_get_new_index();
     947         226 :         if (my_bio_index == -1)
     948           0 :             return NULL;
     949         226 :         my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
     950         226 :         my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
     951         226 :         if (!my_bio_methods)
     952           0 :             return NULL;
     953         452 :         if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
     954         452 :             !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
     955         452 :             !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
     956         452 :             !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
     957         452 :             !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
     958         452 :             !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
     959         452 :             !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
     960         226 :             !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
     961             :         {
     962           0 :             BIO_meth_free(my_bio_methods);
     963           0 :             my_bio_methods = NULL;
     964           0 :             return NULL;
     965             :         }
     966             : #else
     967             :         my_bio_methods = malloc(sizeof(BIO_METHOD));
     968             :         if (!my_bio_methods)
     969             :             return NULL;
     970             :         memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
     971             :         my_bio_methods->bread = my_sock_read;
     972             :         my_bio_methods->bwrite = my_sock_write;
     973             : #endif
     974             :     }
     975         226 :     return my_bio_methods;
     976             : }
     977             : 
     978             : /* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
     979             : static int
     980         226 : my_SSL_set_fd(Port *port, int fd)
     981             : {
     982         226 :     int         ret = 0;
     983             :     BIO        *bio;
     984             :     BIO_METHOD *bio_method;
     985             : 
     986         226 :     bio_method = my_BIO_s_socket();
     987         226 :     if (bio_method == NULL)
     988             :     {
     989           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     990           0 :         goto err;
     991             :     }
     992         226 :     bio = BIO_new(bio_method);
     993             : 
     994         226 :     if (bio == NULL)
     995             :     {
     996           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     997           0 :         goto err;
     998             :     }
     999         226 :     BIO_set_app_data(bio, port);
    1000             : 
    1001         226 :     BIO_set_fd(bio, fd, BIO_NOCLOSE);
    1002         226 :     SSL_set_bio(port->ssl, bio, bio);
    1003         226 :     ret = 1;
    1004         226 : err:
    1005         226 :     return ret;
    1006             : }
    1007             : 
    1008             : /*
    1009             :  *  Load precomputed DH parameters.
    1010             :  *
    1011             :  *  To prevent "downgrade" attacks, we perform a number of checks
    1012             :  *  to verify that the DBA-generated DH parameters file contains
    1013             :  *  what we expect it to contain.
    1014             :  */
    1015             : static DH  *
    1016           0 : load_dh_file(char *filename, bool isServerStart)
    1017             : {
    1018             :     FILE       *fp;
    1019           0 :     DH         *dh = NULL;
    1020             :     int         codes;
    1021             : 
    1022             :     /* attempt to open file.  It's not an error if it doesn't exist. */
    1023           0 :     if ((fp = AllocateFile(filename, "r")) == NULL)
    1024             :     {
    1025           0 :         ereport(isServerStart ? FATAL : LOG,
    1026             :                 (errcode_for_file_access(),
    1027             :                  errmsg("could not open DH parameters file \"%s\": %m",
    1028             :                         filename)));
    1029           0 :         return NULL;
    1030             :     }
    1031             : 
    1032           0 :     dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
    1033           0 :     FreeFile(fp);
    1034             : 
    1035           0 :     if (dh == NULL)
    1036             :     {
    1037           0 :         ereport(isServerStart ? FATAL : LOG,
    1038             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1039             :                  errmsg("could not load DH parameters file: %s",
    1040             :                         SSLerrmessage(ERR_get_error()))));
    1041           0 :         return NULL;
    1042             :     }
    1043             : 
    1044             :     /* make sure the DH parameters are usable */
    1045           0 :     if (DH_check(dh, &codes) == 0)
    1046             :     {
    1047           0 :         ereport(isServerStart ? FATAL : LOG,
    1048             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1049             :                  errmsg("invalid DH parameters: %s",
    1050             :                         SSLerrmessage(ERR_get_error()))));
    1051           0 :         DH_free(dh);
    1052           0 :         return NULL;
    1053             :     }
    1054           0 :     if (codes & DH_CHECK_P_NOT_PRIME)
    1055             :     {
    1056           0 :         ereport(isServerStart ? FATAL : LOG,
    1057             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1058             :                  errmsg("invalid DH parameters: p is not prime")));
    1059           0 :         DH_free(dh);
    1060           0 :         return NULL;
    1061             :     }
    1062           0 :     if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
    1063           0 :         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
    1064             :     {
    1065           0 :         ereport(isServerStart ? FATAL : LOG,
    1066             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1067             :                  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
    1068           0 :         DH_free(dh);
    1069           0 :         return NULL;
    1070             :     }
    1071             : 
    1072           0 :     return dh;
    1073             : }
    1074             : 
    1075             : /*
    1076             :  *  Load hardcoded DH parameters.
    1077             :  *
    1078             :  *  If DH parameters cannot be loaded from a specified file, we can load
    1079             :  *  the hardcoded DH parameters supplied with the backend to prevent
    1080             :  *  problems.
    1081             :  */
    1082             : static DH  *
    1083          46 : load_dh_buffer(const char *buffer, size_t len)
    1084             : {
    1085             :     BIO        *bio;
    1086          46 :     DH         *dh = NULL;
    1087             : 
    1088          46 :     bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
    1089          46 :     if (bio == NULL)
    1090           0 :         return NULL;
    1091          46 :     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
    1092          46 :     if (dh == NULL)
    1093           0 :         ereport(DEBUG2,
    1094             :                 (errmsg_internal("DH load buffer: %s",
    1095             :                                  SSLerrmessage(ERR_get_error()))));
    1096          46 :     BIO_free(bio);
    1097             : 
    1098          46 :     return dh;
    1099             : }
    1100             : 
    1101             : /*
    1102             :  *  Passphrase collection callback using ssl_passphrase_command
    1103             :  */
    1104             : static int
    1105           8 : ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1106             : {
    1107             :     /* same prompt as OpenSSL uses internally */
    1108           8 :     const char *prompt = "Enter PEM pass phrase:";
    1109             : 
    1110             :     Assert(rwflag == 0);
    1111             : 
    1112           8 :     return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
    1113             : }
    1114             : 
    1115             : /*
    1116             :  * Dummy passphrase callback
    1117             :  *
    1118             :  * If OpenSSL is told to use a passphrase-protected server key, by default
    1119             :  * it will issue a prompt on /dev/tty and try to read a key from there.
    1120             :  * That's no good during a postmaster SIGHUP cycle, not to mention SSL context
    1121             :  * reload in an EXEC_BACKEND postmaster child.  So override it with this dummy
    1122             :  * function that just returns an empty passphrase, guaranteeing failure.
    1123             :  */
    1124             : static int
    1125           0 : dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1126             : {
    1127             :     /* Set flag to change the error message we'll report */
    1128           0 :     dummy_ssl_passwd_cb_called = true;
    1129             :     /* And return empty string */
    1130             :     Assert(size > 0);
    1131           0 :     buf[0] = '\0';
    1132           0 :     return 0;
    1133             : }
    1134             : 
    1135             : /*
    1136             :  * Examines the provided certificate name, and if it's too long to log or
    1137             :  * contains unprintable ASCII, escapes and truncates it. The return value is
    1138             :  * always a new palloc'd string. (The input string is still modified in place,
    1139             :  * for ease of implementation.)
    1140             :  */
    1141             : static char *
    1142          20 : prepare_cert_name(char *name)
    1143             : {
    1144          20 :     size_t      namelen = strlen(name);
    1145          20 :     char       *truncated = name;
    1146             : 
    1147             :     /*
    1148             :      * Common Names are 64 chars max, so for a common case where the CN is the
    1149             :      * last field, we can still print the longest possible CN with a
    1150             :      * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
    1151             :      * characters.
    1152             :      */
    1153             : #define MAXLEN 71
    1154             : 
    1155          20 :     if (namelen > MAXLEN)
    1156             :     {
    1157             :         /*
    1158             :          * Keep the end of the name, not the beginning, since the most
    1159             :          * specific field is likely to give users the most information.
    1160             :          */
    1161           2 :         truncated = name + namelen - MAXLEN;
    1162           2 :         truncated[0] = truncated[1] = truncated[2] = '.';
    1163           2 :         namelen = MAXLEN;
    1164             :     }
    1165             : 
    1166             : #undef MAXLEN
    1167             : 
    1168          20 :     return pg_clean_ascii(truncated, 0);
    1169             : }
    1170             : 
    1171             : /*
    1172             :  *  Certificate verification callback
    1173             :  *
    1174             :  *  This callback allows us to examine intermediate problems during
    1175             :  *  verification, for later logging.
    1176             :  *
    1177             :  *  This callback also allows us to override the default acceptance
    1178             :  *  criteria (e.g., accepting self-signed or expired certs), but
    1179             :  *  for now we accept the default checks.
    1180             :  */
    1181             : static int
    1182         184 : verify_cb(int ok, X509_STORE_CTX *ctx)
    1183             : {
    1184             :     int         depth;
    1185             :     int         errcode;
    1186             :     const char *errstring;
    1187             :     StringInfoData str;
    1188             :     X509       *cert;
    1189             : 
    1190         184 :     if (ok)
    1191             :     {
    1192             :         /* Nothing to do for the successful case. */
    1193         174 :         return ok;
    1194             :     }
    1195             : 
    1196             :     /* Pull all the information we have on the verification failure. */
    1197          10 :     depth = X509_STORE_CTX_get_error_depth(ctx);
    1198          10 :     errcode = X509_STORE_CTX_get_error(ctx);
    1199          10 :     errstring = X509_verify_cert_error_string(errcode);
    1200             : 
    1201          10 :     initStringInfo(&str);
    1202          10 :     appendStringInfo(&str,
    1203          10 :                      _("Client certificate verification failed at depth %d: %s."),
    1204             :                      depth, errstring);
    1205             : 
    1206          10 :     cert = X509_STORE_CTX_get_current_cert(ctx);
    1207          10 :     if (cert)
    1208             :     {
    1209             :         char       *subject,
    1210             :                    *issuer;
    1211             :         char       *sub_prepared,
    1212             :                    *iss_prepared;
    1213             :         char       *serialno;
    1214             :         ASN1_INTEGER *sn;
    1215             :         BIGNUM     *b;
    1216             : 
    1217             :         /*
    1218             :          * Get the Subject and Issuer for logging, but don't let maliciously
    1219             :          * huge certs flood the logs, and don't reflect non-ASCII bytes into
    1220             :          * it either.
    1221             :          */
    1222          10 :         subject = X509_NAME_to_cstring(X509_get_subject_name(cert));
    1223          10 :         sub_prepared = prepare_cert_name(subject);
    1224          10 :         pfree(subject);
    1225             : 
    1226          10 :         issuer = X509_NAME_to_cstring(X509_get_issuer_name(cert));
    1227          10 :         iss_prepared = prepare_cert_name(issuer);
    1228          10 :         pfree(issuer);
    1229             : 
    1230             :         /*
    1231             :          * Pull the serial number, too, in case a Subject is still ambiguous.
    1232             :          * This mirrors be_tls_get_peer_serial().
    1233             :          */
    1234          10 :         sn = X509_get_serialNumber(cert);
    1235          10 :         b = ASN1_INTEGER_to_BN(sn, NULL);
    1236          10 :         serialno = BN_bn2dec(b);
    1237             : 
    1238          10 :         appendStringInfoChar(&str, '\n');
    1239          10 :         appendStringInfo(&str,
    1240          10 :                          _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
    1241           0 :                          sub_prepared, serialno ? serialno : _("unknown"),
    1242             :                          iss_prepared);
    1243             : 
    1244          10 :         BN_free(b);
    1245          10 :         OPENSSL_free(serialno);
    1246          10 :         pfree(iss_prepared);
    1247          10 :         pfree(sub_prepared);
    1248             :     }
    1249             : 
    1250             :     /* Store our detail message to be logged later. */
    1251          10 :     cert_errdetail = str.data;
    1252             : 
    1253          10 :     return ok;
    1254             : }
    1255             : 
    1256             : /*
    1257             :  *  This callback is used to copy SSL information messages
    1258             :  *  into the PostgreSQL log.
    1259             :  */
    1260             : static void
    1261        5454 : info_cb(const SSL *ssl, int type, int args)
    1262             : {
    1263             :     const char *desc;
    1264             : 
    1265        5454 :     desc = SSL_state_string_long(ssl);
    1266             : 
    1267        5454 :     switch (type)
    1268             :     {
    1269         226 :         case SSL_CB_HANDSHAKE_START:
    1270         226 :             ereport(DEBUG4,
    1271             :                     (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
    1272         226 :             break;
    1273         190 :         case SSL_CB_HANDSHAKE_DONE:
    1274         190 :             ereport(DEBUG4,
    1275             :                     (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
    1276         190 :             break;
    1277        4276 :         case SSL_CB_ACCEPT_LOOP:
    1278        4276 :             ereport(DEBUG4,
    1279             :                     (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
    1280        4276 :             break;
    1281         538 :         case SSL_CB_ACCEPT_EXIT:
    1282         538 :             ereport(DEBUG4,
    1283             :                     (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
    1284         538 :             break;
    1285           0 :         case SSL_CB_CONNECT_LOOP:
    1286           0 :             ereport(DEBUG4,
    1287             :                     (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
    1288           0 :             break;
    1289           0 :         case SSL_CB_CONNECT_EXIT:
    1290           0 :             ereport(DEBUG4,
    1291             :                     (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
    1292           0 :             break;
    1293          52 :         case SSL_CB_READ_ALERT:
    1294          52 :             ereport(DEBUG4,
    1295             :                     (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
    1296          52 :             break;
    1297         172 :         case SSL_CB_WRITE_ALERT:
    1298         172 :             ereport(DEBUG4,
    1299             :                     (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
    1300         172 :             break;
    1301             :     }
    1302        5454 : }
    1303             : 
    1304             : /* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */
    1305             : static const unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR;
    1306             : 
    1307             : /*
    1308             :  * Server callback for ALPN negotiation. We use the standard "helper" function
    1309             :  * even though currently we only accept one value.
    1310             :  */
    1311             : static int
    1312         432 : alpn_cb(SSL *ssl,
    1313             :         const unsigned char **out,
    1314             :         unsigned char *outlen,
    1315             :         const unsigned char *in,
    1316             :         unsigned int inlen,
    1317             :         void *userdata)
    1318             : {
    1319             :     /*
    1320             :      * Why does OpenSSL provide a helper function that requires a nonconst
    1321             :      * vector when the callback is declared to take a const vector? What are
    1322             :      * we to do with that?
    1323             :      */
    1324             :     int         retval;
    1325             : 
    1326             :     Assert(userdata != NULL);
    1327             :     Assert(out != NULL);
    1328             :     Assert(outlen != NULL);
    1329             :     Assert(in != NULL);
    1330             : 
    1331         432 :     retval = SSL_select_next_proto((unsigned char **) out, outlen,
    1332             :                                    alpn_protos, sizeof(alpn_protos),
    1333             :                                    in, inlen);
    1334         432 :     if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
    1335           0 :         return SSL_TLSEXT_ERR_NOACK;    /* can't happen */
    1336             : 
    1337         432 :     if (retval == OPENSSL_NPN_NEGOTIATED)
    1338         432 :         return SSL_TLSEXT_ERR_OK;
    1339             :     else
    1340             :     {
    1341             :         /*
    1342             :          * The client doesn't support our protocol.  Reject the connection
    1343             :          * with TLS "no_application_protocol" alert, per RFC 7301.
    1344             :          */
    1345           0 :         return SSL_TLSEXT_ERR_ALERT_FATAL;
    1346             :     }
    1347             : }
    1348             : 
    1349             : 
    1350             : /*
    1351             :  * Set DH parameters for generating ephemeral DH keys.  The
    1352             :  * DH parameters can take a long time to compute, so they must be
    1353             :  * precomputed.
    1354             :  *
    1355             :  * Since few sites will bother to create a parameter file, we also
    1356             :  * provide a fallback to the parameters provided by the OpenSSL
    1357             :  * project.
    1358             :  *
    1359             :  * These values can be static (once loaded or computed) since the
    1360             :  * OpenSSL library can efficiently generate random keys from the
    1361             :  * information provided.
    1362             :  */
    1363             : static bool
    1364          46 : initialize_dh(SSL_CTX *context, bool isServerStart)
    1365             : {
    1366          46 :     DH         *dh = NULL;
    1367             : 
    1368          46 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
    1369             : 
    1370          46 :     if (ssl_dh_params_file[0])
    1371           0 :         dh = load_dh_file(ssl_dh_params_file, isServerStart);
    1372          46 :     if (!dh)
    1373          46 :         dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
    1374          46 :     if (!dh)
    1375             :     {
    1376           0 :         ereport(isServerStart ? FATAL : LOG,
    1377             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1378             :                  errmsg("DH: could not load DH parameters")));
    1379           0 :         return false;
    1380             :     }
    1381             : 
    1382          46 :     if (SSL_CTX_set_tmp_dh(context, dh) != 1)
    1383             :     {
    1384           0 :         ereport(isServerStart ? FATAL : LOG,
    1385             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1386             :                  errmsg("DH: could not set DH parameters: %s",
    1387             :                         SSLerrmessage(ERR_get_error()))));
    1388           0 :         DH_free(dh);
    1389           0 :         return false;
    1390             :     }
    1391             : 
    1392          46 :     DH_free(dh);
    1393          46 :     return true;
    1394             : }
    1395             : 
    1396             : /*
    1397             :  * Set ECDH parameters for generating ephemeral Elliptic Curve DH
    1398             :  * keys.  This is much simpler than the DH parameters, as we just
    1399             :  * need to provide the name of the curve to OpenSSL.
    1400             :  */
    1401             : static bool
    1402          46 : initialize_ecdh(SSL_CTX *context, bool isServerStart)
    1403             : {
    1404             : #ifndef OPENSSL_NO_ECDH
    1405             :     EC_KEY     *ecdh;
    1406             :     int         nid;
    1407             : 
    1408          46 :     nid = OBJ_sn2nid(SSLECDHCurve);
    1409          46 :     if (!nid)
    1410             :     {
    1411           0 :         ereport(isServerStart ? FATAL : LOG,
    1412             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1413             :                  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
    1414           0 :         return false;
    1415             :     }
    1416             : 
    1417          46 :     ecdh = EC_KEY_new_by_curve_name(nid);
    1418          46 :     if (!ecdh)
    1419             :     {
    1420           0 :         ereport(isServerStart ? FATAL : LOG,
    1421             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1422             :                  errmsg("ECDH: could not create key")));
    1423           0 :         return false;
    1424             :     }
    1425             : 
    1426          46 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
    1427          46 :     SSL_CTX_set_tmp_ecdh(context, ecdh);
    1428          46 :     EC_KEY_free(ecdh);
    1429             : #endif
    1430             : 
    1431          46 :     return true;
    1432             : }
    1433             : 
    1434             : /*
    1435             :  * Obtain reason string for passed SSL errcode
    1436             :  *
    1437             :  * ERR_get_error() is used by caller to get errcode to pass here.
    1438             :  *
    1439             :  * Some caution is needed here since ERR_reason_error_string will return NULL
    1440             :  * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code
    1441             :  * represents a system errno value.  We don't want to return NULL ever.
    1442             :  */
    1443             : static const char *
    1444          32 : SSLerrmessage(unsigned long ecode)
    1445             : {
    1446             :     const char *errreason;
    1447             :     static char errbuf[36];
    1448             : 
    1449          32 :     if (ecode == 0)
    1450           0 :         return _("no SSL error reported");
    1451          32 :     errreason = ERR_reason_error_string(ecode);
    1452          32 :     if (errreason != NULL)
    1453          32 :         return errreason;
    1454             : 
    1455             :     /*
    1456             :      * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to
    1457             :      * map system errno values.  We can cover that shortcoming with this bit
    1458             :      * of code.  Older OpenSSL versions don't have the ERR_SYSTEM_ERROR macro,
    1459             :      * but that's okay because they don't have the shortcoming either.
    1460             :      */
    1461             : #ifdef ERR_SYSTEM_ERROR
    1462             :     if (ERR_SYSTEM_ERROR(ecode))
    1463             :         return strerror(ERR_GET_REASON(ecode));
    1464             : #endif
    1465             : 
    1466             :     /* No choice but to report the numeric ecode */
    1467           0 :     snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
    1468           0 :     return errbuf;
    1469             : }
    1470             : 
    1471             : int
    1472         304 : be_tls_get_cipher_bits(Port *port)
    1473             : {
    1474             :     int         bits;
    1475             : 
    1476         304 :     if (port->ssl)
    1477             :     {
    1478         304 :         SSL_get_cipher_bits(port->ssl, &bits);
    1479         304 :         return bits;
    1480             :     }
    1481             :     else
    1482           0 :         return 0;
    1483             : }
    1484             : 
    1485             : const char *
    1486         306 : be_tls_get_version(Port *port)
    1487             : {
    1488         306 :     if (port->ssl)
    1489         306 :         return SSL_get_version(port->ssl);
    1490             :     else
    1491           0 :         return NULL;
    1492             : }
    1493             : 
    1494             : const char *
    1495         306 : be_tls_get_cipher(Port *port)
    1496             : {
    1497         306 :     if (port->ssl)
    1498         306 :         return SSL_get_cipher(port->ssl);
    1499             :     else
    1500           0 :         return NULL;
    1501             : }
    1502             : 
    1503             : void
    1504         152 : be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
    1505             : {
    1506         152 :     if (port->peer)
    1507          54 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
    1508             :     else
    1509          98 :         ptr[0] = '\0';
    1510         152 : }
    1511             : 
    1512             : void
    1513         154 : be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
    1514             : {
    1515         154 :     if (port->peer)
    1516          56 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
    1517             :     else
    1518          98 :         ptr[0] = '\0';
    1519         154 : }
    1520             : 
    1521             : void
    1522         154 : be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
    1523             : {
    1524         154 :     if (port->peer)
    1525             :     {
    1526             :         ASN1_INTEGER *serial;
    1527             :         BIGNUM     *b;
    1528             :         char       *decimal;
    1529             : 
    1530          56 :         serial = X509_get_serialNumber(port->peer);
    1531          56 :         b = ASN1_INTEGER_to_BN(serial, NULL);
    1532          56 :         decimal = BN_bn2dec(b);
    1533             : 
    1534          56 :         BN_free(b);
    1535          56 :         strlcpy(ptr, decimal, len);
    1536          56 :         OPENSSL_free(decimal);
    1537             :     }
    1538             :     else
    1539          98 :         ptr[0] = '\0';
    1540         154 : }
    1541             : 
    1542             : char *
    1543           8 : be_tls_get_certificate_hash(Port *port, size_t *len)
    1544             : {
    1545             :     X509       *server_cert;
    1546             :     char       *cert_hash;
    1547           8 :     const EVP_MD *algo_type = NULL;
    1548             :     unsigned char hash[EVP_MAX_MD_SIZE];    /* size for SHA-512 */
    1549             :     unsigned int hash_size;
    1550             :     int         algo_nid;
    1551             : 
    1552           8 :     *len = 0;
    1553           8 :     server_cert = SSL_get_certificate(port->ssl);
    1554           8 :     if (server_cert == NULL)
    1555           0 :         return NULL;
    1556             : 
    1557             :     /*
    1558             :      * Get the signature algorithm of the certificate to determine the hash
    1559             :      * algorithm to use for the result.  Prefer X509_get_signature_info(),
    1560             :      * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
    1561             :      */
    1562             : #if HAVE_X509_GET_SIGNATURE_INFO
    1563           8 :     if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
    1564             : #else
    1565             :     if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
    1566             :                              &algo_nid, NULL))
    1567             : #endif
    1568           0 :         elog(ERROR, "could not determine server certificate signature algorithm");
    1569             : 
    1570             :     /*
    1571             :      * The TLS server's certificate bytes need to be hashed with SHA-256 if
    1572             :      * its signature algorithm is MD5 or SHA-1 as per RFC 5929
    1573             :      * (https://tools.ietf.org/html/rfc5929#section-4.1).  If something else
    1574             :      * is used, the same hash as the signature algorithm is used.
    1575             :      */
    1576           8 :     switch (algo_nid)
    1577             :     {
    1578           0 :         case NID_md5:
    1579             :         case NID_sha1:
    1580           0 :             algo_type = EVP_sha256();
    1581           0 :             break;
    1582           8 :         default:
    1583           8 :             algo_type = EVP_get_digestbynid(algo_nid);
    1584           8 :             if (algo_type == NULL)
    1585           0 :                 elog(ERROR, "could not find digest for NID %s",
    1586             :                      OBJ_nid2sn(algo_nid));
    1587           8 :             break;
    1588             :     }
    1589             : 
    1590             :     /* generate and save the certificate hash */
    1591           8 :     if (!X509_digest(server_cert, algo_type, hash, &hash_size))
    1592           0 :         elog(ERROR, "could not generate server certificate hash");
    1593             : 
    1594           8 :     cert_hash = palloc(hash_size);
    1595           8 :     memcpy(cert_hash, hash, hash_size);
    1596           8 :     *len = hash_size;
    1597             : 
    1598           8 :     return cert_hash;
    1599             : }
    1600             : 
    1601             : /*
    1602             :  * Convert an X509 subject name to a cstring.
    1603             :  *
    1604             :  */
    1605             : static char *
    1606         130 : X509_NAME_to_cstring(X509_NAME *name)
    1607             : {
    1608         130 :     BIO        *membuf = BIO_new(BIO_s_mem());
    1609             :     int         i,
    1610             :                 nid,
    1611         130 :                 count = X509_NAME_entry_count(name);
    1612             :     X509_NAME_ENTRY *e;
    1613             :     ASN1_STRING *v;
    1614             :     const char *field_name;
    1615             :     size_t      size;
    1616             :     char        nullterm;
    1617             :     char       *sp;
    1618             :     char       *dp;
    1619             :     char       *result;
    1620             : 
    1621         130 :     if (membuf == NULL)
    1622           0 :         ereport(ERROR,
    1623             :                 (errcode(ERRCODE_OUT_OF_MEMORY),
    1624             :                  errmsg("could not create BIO")));
    1625             : 
    1626         130 :     (void) BIO_set_close(membuf, BIO_CLOSE);
    1627         282 :     for (i = 0; i < count; i++)
    1628             :     {
    1629         152 :         e = X509_NAME_get_entry(name, i);
    1630         152 :         nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
    1631         152 :         if (nid == NID_undef)
    1632           0 :             ereport(ERROR,
    1633             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1634             :                      errmsg("could not get NID for ASN1_OBJECT object")));
    1635         152 :         v = X509_NAME_ENTRY_get_data(e);
    1636         152 :         field_name = OBJ_nid2sn(nid);
    1637         152 :         if (field_name == NULL)
    1638           0 :             field_name = OBJ_nid2ln(nid);
    1639         152 :         if (field_name == NULL)
    1640           0 :             ereport(ERROR,
    1641             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1642             :                      errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
    1643         152 :         BIO_printf(membuf, "/%s=", field_name);
    1644         152 :         ASN1_STRING_print_ex(membuf, v,
    1645             :                              ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
    1646             :                               | ASN1_STRFLGS_UTF8_CONVERT));
    1647             :     }
    1648             : 
    1649             :     /* ensure null termination of the BIO's content */
    1650         130 :     nullterm = '\0';
    1651         130 :     BIO_write(membuf, &nullterm, 1);
    1652         130 :     size = BIO_get_mem_data(membuf, &sp);
    1653         130 :     dp = pg_any_to_server(sp, size - 1, PG_UTF8);
    1654             : 
    1655         130 :     result = pstrdup(dp);
    1656         130 :     if (dp != sp)
    1657           0 :         pfree(dp);
    1658         130 :     if (BIO_free(membuf) != 1)
    1659           0 :         elog(ERROR, "could not free OpenSSL BIO structure");
    1660             : 
    1661         130 :     return result;
    1662             : }
    1663             : 
    1664             : /*
    1665             :  * Convert TLS protocol version GUC enum to OpenSSL values
    1666             :  *
    1667             :  * This is a straightforward one-to-one mapping, but doing it this way makes
    1668             :  * the definitions of ssl_min_protocol_version and ssl_max_protocol_version
    1669             :  * independent of OpenSSL availability and version.
    1670             :  *
    1671             :  * If a version is passed that is not supported by the current OpenSSL
    1672             :  * version, then we return -1.  If a nonnegative value is returned,
    1673             :  * subsequent code can assume it's working with a supported version.
    1674             :  *
    1675             :  * Note: this is rather similar to libpq's routine in fe-secure-openssl.c,
    1676             :  * so make sure to update both routines if changing this one.
    1677             :  */
    1678             : static int
    1679          50 : ssl_protocol_version_to_openssl(int v)
    1680             : {
    1681          50 :     switch (v)
    1682             :     {
    1683           0 :         case PG_TLS_ANY:
    1684           0 :             return 0;
    1685           0 :         case PG_TLS1_VERSION:
    1686           0 :             return TLS1_VERSION;
    1687           2 :         case PG_TLS1_1_VERSION:
    1688             : #ifdef TLS1_1_VERSION
    1689           2 :             return TLS1_1_VERSION;
    1690             : #else
    1691             :             break;
    1692             : #endif
    1693          48 :         case PG_TLS1_2_VERSION:
    1694             : #ifdef TLS1_2_VERSION
    1695          48 :             return TLS1_2_VERSION;
    1696             : #else
    1697             :             break;
    1698             : #endif
    1699           0 :         case PG_TLS1_3_VERSION:
    1700             : #ifdef TLS1_3_VERSION
    1701           0 :             return TLS1_3_VERSION;
    1702             : #else
    1703             :             break;
    1704             : #endif
    1705             :     }
    1706             : 
    1707           0 :     return -1;
    1708             : }
    1709             : 
    1710             : /*
    1711             :  * Likewise provide a mapping to strings.
    1712             :  */
    1713             : static const char *
    1714           0 : ssl_protocol_version_to_string(int v)
    1715             : {
    1716           0 :     switch (v)
    1717             :     {
    1718           0 :         case PG_TLS_ANY:
    1719           0 :             return "any";
    1720           0 :         case PG_TLS1_VERSION:
    1721           0 :             return "TLSv1";
    1722           0 :         case PG_TLS1_1_VERSION:
    1723           0 :             return "TLSv1.1";
    1724           0 :         case PG_TLS1_2_VERSION:
    1725           0 :             return "TLSv1.2";
    1726           0 :         case PG_TLS1_3_VERSION:
    1727           0 :             return "TLSv1.3";
    1728             :     }
    1729             : 
    1730           0 :     return "(unrecognized)";
    1731             : }
    1732             : 
    1733             : 
    1734             : static void
    1735          46 : default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
    1736             : {
    1737          46 :     if (isServerStart)
    1738             :     {
    1739          46 :         if (ssl_passphrase_command[0])
    1740           8 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    1741             :     }
    1742             :     else
    1743             :     {
    1744           0 :         if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
    1745           0 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    1746             :         else
    1747             : 
    1748             :             /*
    1749             :              * If reloading and no external command is configured, override
    1750             :              * OpenSSL's default handling of passphrase-protected files,
    1751             :              * because we don't want to prompt for a passphrase in an
    1752             :              * already-running server.
    1753             :              */
    1754           0 :             SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
    1755             :     }
    1756          46 : }

Generated by: LCOV version 1.14