LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 70.3 % 821 577
Test Date: 2026-08-15 13:15:45 Functions: 94.9 % 39 37
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 46.6 % 665 310

             Branch data     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-2026, 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/hashfn.h"
      31                 :             : #include "common/string.h"
      32                 :             : #include "libpq/libpq.h"
      33                 :             : #include "miscadmin.h"
      34                 :             : #include "pgstat.h"
      35                 :             : #include "storage/fd.h"
      36                 :             : #include "storage/latch.h"
      37                 :             : #include "utils/guc.h"
      38                 :             : #include "utils/memutils.h"
      39                 :             : #include "utils/wait_event.h"
      40                 :             : 
      41                 :             : /*
      42                 :             :  * These SSL-related #includes must come after all system-provided headers.
      43                 :             :  * This ensures that OpenSSL can take care of conflicts with Windows'
      44                 :             :  * <wincrypt.h> by #undef'ing the conflicting macros.  (We don't directly
      45                 :             :  * include <wincrypt.h>, but some other Windows headers do.)
      46                 :             :  */
      47                 :             : #include "common/openssl.h"
      48                 :             : #include <openssl/bn.h>
      49                 :             : #include <openssl/conf.h>
      50                 :             : #include <openssl/dh.h>
      51                 :             : #include <openssl/ec.h>
      52                 :             : #include <openssl/x509v3.h>
      53                 :             : 
      54                 :             : /*
      55                 :             :  * Simplehash for tracking configured hostnames to guard against duplicate
      56                 :             :  * entries.  Each list of hosts is traversed and added to the hash during
      57                 :             :  * parsing and if a duplicate error is detected an error will be thrown.
      58                 :             :  */
      59                 :             : typedef struct
      60                 :             : {
      61                 :             :     uint32      status;
      62                 :             :     const char *hostname;
      63                 :             : } HostCacheEntry;
      64                 :             : static uint32 host_cache_pointer(const char *key);
      65                 :             : #define SH_PREFIX       host_cache
      66                 :             : #define SH_ELEMENT_TYPE HostCacheEntry
      67                 :             : #define SH_KEY_TYPE     const char *
      68                 :             : #define SH_KEY          hostname
      69                 :             : #define SH_HASH_KEY(tb, key)    host_cache_pointer(key)
      70                 :             : #define SH_EQUAL(tb, a, b)      (pg_strcasecmp(a, b) == 0)
      71                 :             : #define SH_SCOPE                static inline
      72                 :             : #define SH_DECLARE
      73                 :             : #define SH_DEFINE
      74                 :             : #include "lib/simplehash.h"
      75                 :             : 
      76                 :             : /* default init hook can be overridden by a shared library */
      77                 :             : static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart);
      78                 :             : openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init;
      79                 :             : 
      80                 :             : static int  port_bio_read(BIO *h, char *buf, int size);
      81                 :             : static int  port_bio_write(BIO *h, const char *buf, int size);
      82                 :             : static BIO_METHOD *port_bio_method(void);
      83                 :             : static int  ssl_set_port_bio(Port *port);
      84                 :             : 
      85                 :             : static DH  *load_dh_file(char *filename, bool isServerStart);
      86                 :             : static DH  *load_dh_buffer(const char *buffer, size_t len);
      87                 :             : static int  ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      88                 :             : static int  dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      89                 :             : static int  verify_cb(int ok, X509_STORE_CTX *ctx);
      90                 :             : static void info_cb(const SSL *ssl, int type, int args);
      91                 :             : static int  alpn_cb(SSL *ssl,
      92                 :             :                     const unsigned char **out,
      93                 :             :                     unsigned char *outlen,
      94                 :             :                     const unsigned char *in,
      95                 :             :                     unsigned int inlen,
      96                 :             :                     void *userdata);
      97                 :             : static bool initialize_dh(SSL_CTX *context, bool isServerStart);
      98                 :             : static bool initialize_ecdh(SSL_CTX *context, bool isServerStart);
      99                 :             : static const char *SSLerrmessageExt(unsigned long ecode, const char *replacement);
     100                 :             : static const char *SSLerrmessage(unsigned long ecode);
     101                 :             : static bool init_host_context(HostsLine *host, bool isServerStart, bool *hasWarned)
     102                 :             :             pg_attribute_nonnull(3);
     103                 :             : static void host_context_cleanup_cb(void *arg);
     104                 :             : #ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
     105                 :             : static int  sni_clienthello_cb(SSL *ssl, int *al, void *arg);
     106                 :             : #endif
     107                 :             : 
     108                 :             : static char *X509_NAME_to_cstring(const X509_NAME *name);
     109                 :             : 
     110                 :             : static SSL_CTX *SSL_context = NULL;
     111                 :             : static MemoryContext SSL_hosts_memcxt = NULL;
     112                 :             : static struct hosts
     113                 :             : {
     114                 :             :     /*
     115                 :             :      * List of HostsLine structures containing SSL configurations for
     116                 :             :      * connections with hostnames defined in the SNI extension.
     117                 :             :      */
     118                 :             :     List       *sni;
     119                 :             : 
     120                 :             :     /* The SSL configuration to use for connections without SNI */
     121                 :             :     HostsLine  *no_sni;
     122                 :             : 
     123                 :             :     /*
     124                 :             :      * The default SSL configuration to use as a fallback in case no hostname
     125                 :             :      * matches the supplied hostname in the SNI extension.
     126                 :             :      */
     127                 :             :     HostsLine  *default_host;
     128                 :             : }          *SSL_hosts;
     129                 :             : 
     130                 :             : static bool dummy_ssl_passwd_cb_called = false;
     131                 :             : static bool ssl_is_server_start;
     132                 :             : 
     133                 :             : static int  ssl_protocol_version_to_openssl(int v);
     134                 :             : static const char *ssl_protocol_version_to_string(int v);
     135                 :             : 
     136                 :             : struct CallbackErr
     137                 :             : {
     138                 :             :     /*
     139                 :             :      * Storage for passing certificate verification error logging from the
     140                 :             :      * callback.
     141                 :             :      */
     142                 :             :     char       *cert_errdetail;
     143                 :             : };
     144                 :             : 
     145                 :             : /* ------------------------------------------------------------ */
     146                 :             : /*                       Public interface                       */
     147                 :             : /* ------------------------------------------------------------ */
     148                 :             : 
     149                 :             : int
     150                 :          65 : be_tls_init(bool isServerStart)
     151                 :             : {
     152                 :          65 :     List       *pg_hosts = NIL;
     153                 :             :     ListCell   *line;
     154                 :             :     MemoryContext oldcxt;
     155                 :          65 :     MemoryContext host_memcxt = NULL;
     156                 :             :     MemoryContextCallback *host_memcxt_cb;
     157                 :          65 :     char       *err_msg = NULL;
     158                 :             :     HostsFileLoadResult res;
     159                 :             :     struct hosts *new_hosts;
     160                 :          65 :     SSL_CTX    *context = NULL;
     161                 :          65 :     int         ssl_ver_min = -1;
     162                 :          65 :     int         ssl_ver_max = -1;
     163                 :          65 :     host_cache_hash *host_cache = NULL;
     164                 :          65 :     bool        hasWarned = false;
     165                 :             : 
     166                 :             :     /*
     167                 :             :      * Since we don't know which host we're using until the ClientHello is
     168                 :             :      * sent, ssl_loaded_verify_locations *always* starts out as false. The
     169                 :             :      * only place it's set to true is in sni_clienthello_cb().
     170                 :             :      */
     171                 :          65 :     ssl_loaded_verify_locations = false;
     172                 :             : 
     173                 :          65 :     host_memcxt = AllocSetContextCreate(CurrentMemoryContext,
     174                 :             :                                         "hosts file parser context",
     175                 :             :                                         ALLOCSET_SMALL_SIZES);
     176                 :          65 :     oldcxt = MemoryContextSwitchTo(host_memcxt);
     177                 :             : 
     178                 :             :     /* Allocate a tentative replacement for SSL_hosts. */
     179                 :          65 :     new_hosts = palloc0_object(struct hosts);
     180                 :             : 
     181                 :             :     /*
     182                 :             :      * Register a reset callback for the memory context which is responsible
     183                 :             :      * for freeing OpenSSL managed allocations upon context deletion.  The
     184                 :             :      * callback is allocated here to make sure it gets cleaned up along with
     185                 :             :      * the memory context it's registered for.
     186                 :             :      */
     187                 :          65 :     host_memcxt_cb = palloc0_object(MemoryContextCallback);
     188                 :          65 :     host_memcxt_cb->func = host_context_cleanup_cb;
     189                 :          65 :     host_memcxt_cb->arg = new_hosts;
     190                 :          65 :     MemoryContextRegisterResetCallback(host_memcxt, host_memcxt_cb);
     191                 :             : 
     192                 :             :     /*
     193                 :             :      * If ssl_sni is enabled, attempt to load and parse TLS configuration from
     194                 :             :      * the pg_hosts.conf file with the set of hosts returned as a list.  If
     195                 :             :      * there are hosts configured they take precedence over the configuration
     196                 :             :      * in postgresql.conf.  Make sure to allocate the parsed rows in their own
     197                 :             :      * memory context so that we can delete them easily in case parsing fails.
     198                 :             :      * If ssl_sni is disabled then set the state accordingly to make sure we
     199                 :             :      * instead parse the config from postgresql.conf.
     200                 :             :      *
     201                 :             :      * The reason for not doing everything in this if-else conditional is that
     202                 :             :      * we want to use the same processing of postgresql.conf for when ssl_sni
     203                 :             :      * is off as well as when it's on but the hosts file is missing etc.  Thus
     204                 :             :      * we set res to the state and continue with a new conditional instead of
     205                 :             :      * duplicating logic and risk it diverging over time.
     206                 :             :      */
     207         [ +  + ]:          65 :     if (ssl_sni)
     208                 :             :     {
     209                 :             :         /*
     210                 :             :          * The GUC check hook should have already blocked this but to be on
     211                 :             :          * the safe side we double-check here.
     212                 :             :          */
     213                 :             : #ifndef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
     214                 :             :         ereport(isServerStart ? FATAL : LOG,
     215                 :             :                 errcode(ERRCODE_CONFIG_FILE_ERROR),
     216                 :             :                 errmsg("ssl_sni is not supported with LibreSSL"));
     217                 :             :         goto error;
     218                 :             : #endif
     219                 :             : 
     220                 :             :         /* Attempt to load configuration from pg_hosts.conf */
     221                 :          25 :         res = load_hosts(&pg_hosts, &err_msg);
     222                 :             : 
     223                 :             :         /*
     224                 :             :          * pg_hosts.conf is not required to contain configuration, but if it
     225                 :             :          * does we error out in case it fails to load rather than continue to
     226                 :             :          * try the postgresql.conf configuration to avoid silently falling
     227                 :             :          * back on an undesired configuration.
     228                 :             :          */
     229         [ +  + ]:          25 :         if (res == HOSTSFILE_LOAD_FAILED)
     230                 :             :         {
     231   [ +  -  +  -  :           3 :             ereport(isServerStart ? FATAL : LOG,
                   +  - ]
     232                 :             :                     errcode(ERRCODE_CONFIG_FILE_ERROR),
     233                 :             :                     errmsg("could not load \"%s\": %s", HostsFileName,
     234                 :             :                            err_msg ? err_msg : "unknown error"));
     235                 :           0 :             goto error;
     236                 :             :         }
     237                 :             :     }
     238                 :             :     else
     239                 :          40 :         res = HOSTSFILE_DISABLED;
     240                 :             : 
     241                 :             :     /*
     242                 :             :      * Loading and parsing the hosts file was successful, create configs for
     243                 :             :      * each host entry and add to the list of hosts to be checked during
     244                 :             :      * login.
     245                 :             :      */
     246         [ +  + ]:          62 :     if (res == HOSTSFILE_LOAD_OK)
     247                 :             :     {
     248                 :             :         Assert(ssl_sni);
     249                 :             : 
     250   [ +  -  +  +  :          49 :         foreach(line, pg_hosts)
                   +  + ]
     251                 :             :         {
     252                 :          34 :             HostsLine  *host = lfirst(line);
     253                 :             : 
     254         [ +  + ]:          34 :             if (!init_host_context(host, isServerStart, &hasWarned))
     255                 :           1 :                 goto error;
     256                 :             : 
     257                 :             :             /*
     258                 :             :              * The hostname in the config will be set to NULL for the default
     259                 :             :              * host as well as in configs used for non-SNI connections.  Lists
     260                 :             :              * of hostnames in pg_hosts.conf are not allowed to contain the
     261                 :             :              * default '*' entry or a '/no_sni/' entry and this is checked
     262                 :             :              * during parsing.  Thus we can inspect the head of the hostnames
     263                 :             :              * list for these since they will never be anywhere else.
     264                 :             :              */
     265         [ +  + ]:          32 :             if (strcmp(linitial(host->hostnames), "*") == 0)
     266                 :             :             {
     267         [ +  + ]:           6 :                 if (new_hosts->default_host)
     268                 :             :                 {
     269   [ +  -  +  - ]:           1 :                     ereport(isServerStart ? FATAL : LOG,
     270                 :             :                             errcode(ERRCODE_CONFIG_FILE_ERROR),
     271                 :             :                             errmsg("multiple default hosts specified"),
     272                 :             :                             errcontext("line %d of configuration file \"%s\"",
     273                 :             :                                        host->linenumber, host->sourcefile));
     274                 :           0 :                     goto error;
     275                 :             :                 }
     276                 :             : 
     277                 :           5 :                 new_hosts->default_host = host;
     278                 :             :             }
     279         [ +  + ]:          26 :             else if (strcmp(linitial(host->hostnames), "/no_sni/") == 0)
     280                 :             :             {
     281         [ +  + ]:           3 :                 if (new_hosts->no_sni)
     282                 :             :                 {
     283   [ +  -  +  - ]:           1 :                     ereport(isServerStart ? FATAL : LOG,
     284                 :             :                             errcode(ERRCODE_CONFIG_FILE_ERROR),
     285                 :             :                             errmsg("multiple no_sni hosts specified"),
     286                 :             :                             errcontext("line %d of configuration file \"%s\"",
     287                 :             :                                        host->linenumber, host->sourcefile));
     288                 :           0 :                     goto error;
     289                 :             :                 }
     290                 :             : 
     291                 :           2 :                 new_hosts->no_sni = host;
     292                 :             :             }
     293                 :             :             else
     294                 :             :             {
     295                 :             :                 /* Check the hostnames for duplicates */
     296         [ +  + ]:          23 :                 if (!host_cache)
     297                 :          15 :                     host_cache = host_cache_create(host_memcxt, 32, NULL);
     298                 :             : 
     299   [ +  -  +  +  :          71 :                 foreach_ptr(char, hostname, host->hostnames)
                   +  + ]
     300                 :             :                 {
     301                 :             :                     HostCacheEntry *entry;
     302                 :             :                     bool        found;
     303                 :             : 
     304                 :          29 :                     entry = host_cache_insert(host_cache, hostname, &found);
     305         [ +  + ]:          29 :                     if (found)
     306                 :             :                     {
     307   [ +  -  +  - ]:           2 :                         ereport(isServerStart ? FATAL : LOG,
     308                 :             :                                 errcode(ERRCODE_CONFIG_FILE_ERROR),
     309                 :             :                                 errmsg("multiple entries for host \"%s\" specified",
     310                 :             :                                        hostname),
     311                 :             :                                 errcontext("line %d of configuration file \"%s\"",
     312                 :             :                                            host->linenumber, host->sourcefile));
     313                 :           0 :                         goto error;
     314                 :             :                     }
     315                 :             :                     else
     316                 :          27 :                         entry->hostname = pstrdup(hostname);
     317                 :             :                 }
     318                 :             : 
     319                 :             :                 /*
     320                 :             :                  * At this point we know we have a configuration with a list
     321                 :             :                  * of distinct 1..n hostnames for literal string matching with
     322                 :             :                  * the SNI extension from the user.
     323                 :             :                  */
     324                 :          21 :                 new_hosts->sni = lappend(new_hosts->sni, host);
     325                 :             :             }
     326                 :             :         }
     327                 :             :     }
     328                 :             : 
     329                 :             :     /*
     330                 :             :      * If SNI is disabled, then we load configuration from postgresql.conf. If
     331                 :             :      * SNI is enabled but the pg_hosts.conf file doesn't exist, or is empty,
     332                 :             :      * then we also load the config from postgresql.conf.
     333                 :             :      */
     334   [ +  +  +  -  :          41 :     else if (res == HOSTSFILE_DISABLED || res == HOSTSFILE_EMPTY || res == HOSTSFILE_MISSING)
                   +  - ]
     335                 :             :     {
     336                 :          41 :         HostsLine  *pgconf = palloc0(sizeof(HostsLine));
     337                 :             : 
     338                 :             : #ifdef USE_ASSERT_CHECKING
     339                 :             :         if (res == HOSTSFILE_DISABLED)
     340                 :             :             Assert(ssl_sni == false);
     341                 :             : #endif
     342                 :             : 
     343                 :          41 :         pgconf->ssl_cert = ssl_cert_file;
     344                 :          41 :         pgconf->ssl_key = ssl_key_file;
     345                 :          41 :         pgconf->ssl_ca = ssl_ca_file;
     346                 :          41 :         pgconf->ssl_passphrase_cmd = ssl_passphrase_command;
     347                 :          41 :         pgconf->ssl_passphrase_reload = ssl_passphrase_command_supports_reload;
     348                 :             : 
     349         [ +  + ]:          41 :         if (!init_host_context(pgconf, isServerStart, &hasWarned))
     350                 :           1 :             goto error;
     351                 :             : 
     352                 :             :         /*
     353                 :             :          * If postgresql.conf is used to configure SSL then by definition it
     354                 :             :          * will be the default context as we don't have per-host config.
     355                 :             :          */
     356                 :          38 :         new_hosts->default_host = pgconf;
     357                 :             :     }
     358                 :             : 
     359                 :             :     /*
     360                 :             :      * Make sure we have at least one configuration loaded to use, without
     361                 :             :      * that we cannot drive a connection so exit.
     362                 :             :      */
     363   [ +  +  +  +  :          53 :     if (new_hosts->sni == NIL && !new_hosts->default_host && !new_hosts->no_sni)
                   -  + ]
     364                 :             :     {
     365   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     366                 :             :                 errcode(ERRCODE_CONFIG_FILE_ERROR),
     367                 :             :                 errmsg("no SSL configurations loaded"),
     368                 :             :         /*- translator: The two %s contain filenames */
     369                 :             :                 errhint("If ssl_sni is enabled then add configuration to \"%s\", else \"%s\"",
     370                 :             :                         HostsFileName, "postgresql.conf"));
     371                 :           0 :         goto error;
     372                 :             :     }
     373                 :             : 
     374                 :             : #ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
     375                 :             : 
     376                 :             :     /*
     377                 :             :      * Create a new SSL context into which we'll load all the configuration
     378                 :             :      * settings.  If we fail partway through, we can avoid memory leakage by
     379                 :             :      * freeing this context; we don't install it as active until the end.
     380                 :             :      */
     381                 :          53 :     context = SSL_CTX_new(TLS_method());
     382         [ -  + ]:          53 :     if (!context)
     383                 :             :     {
     384   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     385                 :             :                 (errmsg("could not create SSL context: %s",
     386                 :             :                         SSLerrmessage(ERR_get_error()))));
     387                 :           0 :         goto error;
     388                 :             :     }
     389                 :             : #else
     390                 :             : 
     391                 :             :     /*
     392                 :             :      * If the client hello callback isn't supported we want to use the default
     393                 :             :      * context as the one to drive the handshake so avoid creating a new one
     394                 :             :      * and use the already existing default one instead.
     395                 :             :      */
     396                 :             :     context = new_hosts->default_host->ssl_ctx;
     397                 :             : 
     398                 :             :     /*
     399                 :             :      * Since we don't allocate a new SSL_CTX here like we do when SNI has been
     400                 :             :      * enabled we need to bump the reference count on context to avoid double
     401                 :             :      * free of the context when using the same cleanup logic across the cases.
     402                 :             :      */
     403                 :             :     SSL_CTX_up_ref(context);
     404                 :             : #endif
     405                 :             : 
     406                 :             :     /*
     407                 :             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     408                 :             :      * unnecessary failures in nonblocking send cases.
     409                 :             :      */
     410                 :          53 :     SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     411                 :             : 
     412         [ +  - ]:          53 :     if (ssl_min_protocol_version)
     413                 :             :     {
     414                 :          53 :         ssl_ver_min = ssl_protocol_version_to_openssl(ssl_min_protocol_version);
     415                 :             : 
     416         [ -  + ]:          53 :         if (ssl_ver_min == -1)
     417                 :             :         {
     418   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     419                 :             :             /*- translator: first %s is a GUC option name, second %s is its value */
     420                 :             :                     (errmsg("\"%s\" setting \"%s\" not supported by this build",
     421                 :             :                             "ssl_min_protocol_version",
     422                 :             :                             GetConfigOption("ssl_min_protocol_version",
     423                 :             :                                             false, false))));
     424                 :           0 :             goto error;
     425                 :             :         }
     426                 :             : 
     427         [ -  + ]:          53 :         if (!SSL_CTX_set_min_proto_version(context, ssl_ver_min))
     428                 :             :         {
     429   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     430                 :             :                     (errmsg("could not set minimum SSL protocol version")));
     431                 :           0 :             goto error;
     432                 :             :         }
     433                 :             :     }
     434                 :             : 
     435         [ +  + ]:          53 :     if (ssl_max_protocol_version)
     436                 :             :     {
     437                 :           1 :         ssl_ver_max = ssl_protocol_version_to_openssl(ssl_max_protocol_version);
     438                 :             : 
     439         [ -  + ]:           1 :         if (ssl_ver_max == -1)
     440                 :             :         {
     441   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     442                 :             :             /*- translator: first %s is a GUC option name, second %s is its value */
     443                 :             :                     (errmsg("\"%s\" setting \"%s\" not supported by this build",
     444                 :             :                             "ssl_max_protocol_version",
     445                 :             :                             GetConfigOption("ssl_max_protocol_version",
     446                 :             :                                             false, false))));
     447                 :           0 :             goto error;
     448                 :             :         }
     449                 :             : 
     450         [ -  + ]:           1 :         if (!SSL_CTX_set_max_proto_version(context, ssl_ver_max))
     451                 :             :         {
     452   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     453                 :             :                     (errmsg("could not set maximum SSL protocol version")));
     454                 :           0 :             goto error;
     455                 :             :         }
     456                 :             :     }
     457                 :             : 
     458                 :             :     /* Check compatibility of min/max protocols */
     459   [ +  -  +  + ]:          53 :     if (ssl_min_protocol_version &&
     460                 :             :         ssl_max_protocol_version)
     461                 :             :     {
     462                 :             :         /*
     463                 :             :          * No need to check for invalid values (-1) for each protocol number
     464                 :             :          * as the code above would have already generated an error.
     465                 :             :          */
     466         [ +  - ]:           1 :         if (ssl_ver_min > ssl_ver_max)
     467                 :             :         {
     468   [ +  -  +  - ]:           1 :             ereport(isServerStart ? FATAL : LOG,
     469                 :             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     470                 :             :                      errmsg("could not set SSL protocol version range"),
     471                 :             :                      errdetail("\"%s\" cannot be higher than \"%s\".",
     472                 :             :                                "ssl_min_protocol_version",
     473                 :             :                                "ssl_max_protocol_version")));
     474                 :           0 :             goto error;
     475                 :             :         }
     476                 :             :     }
     477                 :             : 
     478                 :             :     /*
     479                 :             :      * Disallow SSL session tickets. OpenSSL use both stateful and stateless
     480                 :             :      * tickets for TLSv1.3, and stateless ticket for TLSv1.2. SSL_OP_NO_TICKET
     481                 :             :      * is available since 0.9.8f but only turns off stateless tickets. In
     482                 :             :      * order to turn off stateful tickets we need SSL_CTX_set_num_tickets,
     483                 :             :      * which is available since OpenSSL 1.1.1.  LibreSSL 3.5.4 (from OpenBSD
     484                 :             :      * 7.1) introduced this API for compatibility, but doesn't support session
     485                 :             :      * tickets at all so it's a no-op there.
     486                 :             :      */
     487                 :             : #ifdef HAVE_SSL_CTX_SET_NUM_TICKETS
     488                 :          52 :     SSL_CTX_set_num_tickets(context, 0);
     489                 :             : #endif
     490                 :          52 :     SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
     491                 :             : 
     492                 :             :     /* disallow SSL session caching, too */
     493                 :          52 :     SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
     494                 :             : 
     495                 :             :     /* disallow SSL compression */
     496                 :          52 :     SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION);
     497                 :             : 
     498                 :             :     /*
     499                 :             :      * Disallow SSL renegotiation.  This concerns only TLSv1.2 and older
     500                 :             :      * protocol versions, as TLSv1.3 has no support for renegotiation.
     501                 :             :      * SSL_OP_NO_RENEGOTIATION is available in OpenSSL since 1.1.0h (via a
     502                 :             :      * backport from 1.1.1). SSL_OP_NO_CLIENT_RENEGOTIATION is available in
     503                 :             :      * LibreSSL since 2.5.1 disallowing all client-initiated renegotiation
     504                 :             :      * (this is usually on by default).
     505                 :             :      */
     506                 :             : #ifdef SSL_OP_NO_RENEGOTIATION
     507                 :          52 :     SSL_CTX_set_options(context, SSL_OP_NO_RENEGOTIATION);
     508                 :             : #endif
     509                 :             : #ifdef SSL_OP_NO_CLIENT_RENEGOTIATION
     510                 :             :     SSL_CTX_set_options(context, SSL_OP_NO_CLIENT_RENEGOTIATION);
     511                 :             : #endif
     512                 :             : 
     513                 :             :     /* set up ephemeral DH and ECDH keys */
     514         [ -  + ]:          52 :     if (!initialize_dh(context, isServerStart))
     515                 :           0 :         goto error;
     516         [ -  + ]:          52 :     if (!initialize_ecdh(context, isServerStart))
     517                 :           0 :         goto error;
     518                 :             : 
     519                 :             :     /* set up the allowed cipher list for TLSv1.2 and below */
     520         [ -  + ]:          50 :     if (SSL_CTX_set_cipher_list(context, SSLCipherList) != 1)
     521                 :             :     {
     522   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     523                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     524                 :             :                  errmsg("could not set the TLSv1.2 cipher list (no valid ciphers available)")));
     525                 :           0 :         goto error;
     526                 :             :     }
     527                 :             : 
     528                 :             :     /*
     529                 :             :      * Set up the allowed cipher suites for TLSv1.3. If the GUC is an empty
     530                 :             :      * string we leave the allowed suites to be the OpenSSL default value.
     531                 :             :      */
     532         [ +  + ]:          50 :     if (SSLCipherSuites[0])
     533                 :             :     {
     534                 :             :         /* set up the allowed cipher suites */
     535         [ -  + ]:          43 :         if (SSL_CTX_set_ciphersuites(context, SSLCipherSuites) != 1)
     536                 :             :         {
     537   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     538                 :             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     539                 :             :                      errmsg("could not set the TLSv1.3 cipher suites (no valid ciphers available)")));
     540                 :           0 :             goto error;
     541                 :             :         }
     542                 :             :     }
     543                 :             : 
     544                 :             :     /* Let server choose order */
     545         [ +  - ]:          50 :     if (SSLPreferServerCiphers)
     546                 :          50 :         SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
     547                 :             : 
     548                 :             :     /*
     549                 :             :      * Success!  Replace any existing SSL_context and host configurations.
     550                 :             :      */
     551         [ +  + ]:          50 :     if (SSL_context)
     552                 :             :     {
     553                 :          11 :         SSL_CTX_free(SSL_context);
     554                 :          11 :         SSL_context = NULL;
     555                 :             :     }
     556                 :             : 
     557                 :          50 :     MemoryContextSwitchTo(oldcxt);
     558                 :             : 
     559         [ +  + ]:          50 :     if (SSL_hosts_memcxt)
     560                 :          11 :         MemoryContextDelete(SSL_hosts_memcxt);
     561                 :             : 
     562                 :          50 :     SSL_hosts_memcxt = host_memcxt;
     563                 :          50 :     SSL_hosts = new_hosts;
     564                 :          50 :     SSL_context = context;
     565                 :             : 
     566                 :          50 :     return 0;
     567                 :             : 
     568                 :             :     /*
     569                 :             :      * Clean up by releasing working SSL contexts as well as allocations
     570                 :             :      * performed during parsing.  Since all our allocations are done in a
     571                 :             :      * local memory context all we need to do is delete it.
     572                 :             :      */
     573                 :           2 : error:
     574         [ -  + ]:           2 :     if (context)
     575                 :           0 :         SSL_CTX_free(context);
     576                 :             : 
     577                 :           2 :     MemoryContextSwitchTo(oldcxt);
     578                 :           2 :     MemoryContextDelete(host_memcxt);
     579                 :           2 :     return -1;
     580                 :             : }
     581                 :             : 
     582                 :             : /*
     583                 :             :  * host_context_cleanup_cb
     584                 :             :  *
     585                 :             :  * Memory context reset callback for clearing OpenSSL managed resources when
     586                 :             :  * hosts are reloaded and the previous set of configured hosts are freed. As
     587                 :             :  * all hosts are allocated in a single context we don't need to free each host
     588                 :             :  * individually, just resources managed by OpenSSL.
     589                 :             :  */
     590                 :             : static void
     591                 :         409 : host_context_cleanup_cb(void *arg)
     592                 :             : {
     593                 :         409 :     struct hosts *hosts = arg;
     594                 :             : 
     595   [ +  +  +  +  :         929 :     foreach_ptr(HostsLine, host, hosts->sni)
                   +  + ]
     596                 :             :     {
     597         [ +  - ]:         111 :         if (host->ssl_ctx != NULL)
     598                 :         111 :             SSL_CTX_free(host->ssl_ctx);
     599                 :             :     }
     600                 :             : 
     601   [ +  +  +  - ]:         409 :     if (hosts->no_sni && hosts->no_sni->ssl_ctx)
     602                 :           9 :         SSL_CTX_free(hosts->no_sni->ssl_ctx);
     603                 :             : 
     604   [ +  +  +  - ]:         409 :     if (hosts->default_host && hosts->default_host->ssl_ctx)
     605                 :         350 :         SSL_CTX_free(hosts->default_host->ssl_ctx);
     606                 :         409 : }
     607                 :             : 
     608                 :             : 
     609                 :             : /*
     610                 :             :  * init_host_context
     611                 :             :  *
     612                 :             :  * Creates and initializes an OpenSSL SSL_CTX structure for the host config
     613                 :             :  * passed in the host parameter.  The SSL_CTX will be initialized with cert,
     614                 :             :  * key, CA and CRL; the remaining options are copied from the main context
     615                 :             :  * during connection setup in case this context ends up being used.
     616                 :             :  *
     617                 :             :  * If an ssl init hook has been defined, and ssl_sni is enabled, then issue a
     618                 :             :  * warning since the hook won't be executed.  hasWarned will be is set to true
     619                 :             :  * to indicate that the warning has been issued, and passing it back as true
     620                 :             :  * will omit future warning to avoid flooding the logs.
     621                 :             :  */
     622                 :             : static bool
     623                 :          75 : init_host_context(HostsLine *host, bool isServerStart, bool *hasWarned)
     624                 :             : {
     625                 :          75 :     SSL_CTX    *ctx = SSL_CTX_new(TLS_method());
     626                 :             : 
     627         [ -  + ]:          75 :     if (!ctx)
     628                 :             :     {
     629   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     630                 :             :                 (errmsg("could not create SSL context: %s",
     631                 :             :                         SSLerrmessage(ERR_get_error()))));
     632                 :           0 :         goto error;
     633                 :             :     }
     634                 :             : 
     635                 :             :     /*
     636                 :             :      * Call init hook (usually to set password callback) in case SNI hasn't
     637                 :             :      * been enabled. If SNI is enabled the hook won't operate on the actual
     638                 :             :      * TLS context used so it cannot function properly; we warn if one has
     639                 :             :      * been installed.
     640                 :             :      *
     641                 :             :      * If SNI is enabled, we set password callback based what was configured.
     642                 :             :      */
     643         [ +  + ]:          75 :     if (!ssl_sni)
     644                 :          40 :         (*openssl_tls_init_hook) (ctx, isServerStart);
     645                 :             :     else
     646                 :             :     {
     647   [ +  +  +  + ]:          35 :         if (openssl_tls_init_hook != default_openssl_tls_init && !*hasWarned)
     648                 :             :         {
     649         [ +  - ]:           1 :             ereport(WARNING,
     650                 :             :                     errcode(ERRCODE_CONFIG_FILE_ERROR),
     651                 :             :                     errmsg("SNI is enabled; installed TLS init hook will be ignored"),
     652                 :             :             /*- translator: first %s is a GUC, second %s contains a filename */
     653                 :             :                     errhint("TLS init hooks are incompatible with SNI. "
     654                 :             :                             "Set \"%s\" to \"off\" to make use of the hook "
     655                 :             :                             "that is currently installed, or remove the hook "
     656                 :             :                             "and use per-host passphrase commands in \"%s\".",
     657                 :             :                             "ssl_sni", HostsFileName));
     658                 :           1 :             *hasWarned = true;
     659                 :             :         }
     660                 :             : 
     661                 :             :         /*
     662                 :             :          * Set up the password callback, if configured.
     663                 :             :          */
     664         [ +  + ]:          35 :         if (isServerStart)
     665                 :             :         {
     666   [ +  +  +  - ]:          24 :             if (host->ssl_passphrase_cmd && host->ssl_passphrase_cmd[0])
     667                 :             :             {
     668                 :           5 :                 SSL_CTX_set_default_passwd_cb(ctx, ssl_external_passwd_cb);
     669                 :           5 :                 SSL_CTX_set_default_passwd_cb_userdata(ctx, host->ssl_passphrase_cmd);
     670                 :             :             }
     671                 :             :         }
     672                 :             :         else
     673                 :             :         {
     674                 :             :             /*
     675                 :             :              * If ssl_passphrase_reload is true then ssl_passphrase_cmd cannot
     676                 :             :              * be NULL due to their parsing order, but just in case and to
     677                 :             :              * self-document the code we replicate the nullness checks.
     678                 :             :              */
     679         [ +  + ]:          11 :             if (host->ssl_passphrase_reload &&
     680   [ +  -  +  - ]:           4 :                 (host->ssl_passphrase_cmd && host->ssl_passphrase_cmd[0]))
     681                 :             :             {
     682                 :           4 :                 SSL_CTX_set_default_passwd_cb(ctx, ssl_external_passwd_cb);
     683                 :           4 :                 SSL_CTX_set_default_passwd_cb_userdata(ctx, host->ssl_passphrase_cmd);
     684                 :             :             }
     685                 :             :             else
     686                 :             :             {
     687                 :             :                 /*
     688                 :             :                  * If reloading and no external command is configured,
     689                 :             :                  * override OpenSSL's default handling of passphrase-protected
     690                 :             :                  * files, because we don't want to prompt for a passphrase in
     691                 :             :                  * an already-running server.
     692                 :             :                  */
     693                 :           7 :                 SSL_CTX_set_default_passwd_cb(ctx, dummy_ssl_passwd_cb);
     694                 :             :             }
     695                 :             :         }
     696                 :             :     }
     697                 :             : 
     698                 :             :     /*
     699                 :             :      * Load and verify server's certificate and private key
     700                 :             :      */
     701         [ -  + ]:          75 :     if (SSL_CTX_use_certificate_chain_file(ctx, host->ssl_cert) != 1)
     702                 :             :     {
     703   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     704                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     705                 :             :                  errmsg("could not load server certificate file \"%s\": %s",
     706                 :             :                         host->ssl_cert, SSLerrmessage(ERR_get_error()))));
     707                 :           0 :         goto error;
     708                 :             :     }
     709                 :             : 
     710         [ -  + ]:          75 :     if (!check_ssl_key_file_permissions(host->ssl_key, isServerStart))
     711                 :           0 :         goto error;
     712                 :             : 
     713                 :             : 
     714                 :             :     /* used by the callback */
     715                 :          75 :     ssl_is_server_start = isServerStart;
     716                 :             : 
     717                 :             :     /*
     718                 :             :      * OK, try to load the private key file.
     719                 :             :      */
     720                 :          75 :     dummy_ssl_passwd_cb_called = false;
     721                 :             : 
     722         [ +  + ]:          75 :     if (SSL_CTX_use_PrivateKey_file(ctx,
     723                 :          75 :                                     host->ssl_key,
     724                 :             :                                     SSL_FILETYPE_PEM) != 1)
     725                 :             :     {
     726         [ +  + ]:           5 :         if (dummy_ssl_passwd_cb_called)
     727   [ -  +  +  - ]:           2 :             ereport(isServerStart ? FATAL : LOG,
     728                 :             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     729                 :             :                      errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
     730                 :             :                             host->ssl_key)));
     731                 :             :         else
     732   [ +  -  +  - ]:           3 :             ereport(isServerStart ? FATAL : LOG,
     733                 :             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     734                 :             :                      errmsg("could not load private key file \"%s\": %s",
     735                 :             :                             host->ssl_key, SSLerrmessage(ERR_get_error()))));
     736                 :           2 :         goto error;
     737                 :             :     }
     738                 :             : 
     739         [ -  + ]:          70 :     if (SSL_CTX_check_private_key(ctx) != 1)
     740                 :             :     {
     741   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
     742                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     743                 :             :                  errmsg("check of private key failed: %s",
     744                 :             :                         SSLerrmessage(ERR_get_error()))));
     745                 :           0 :         goto error;
     746                 :             :     }
     747                 :             : 
     748                 :             :     /*
     749                 :             :      * Load CA store, so we can verify client certificates if needed.
     750                 :             :      */
     751   [ +  +  +  + ]:          70 :     if (host->ssl_ca && host->ssl_ca[0])
     752                 :             :     {
     753                 :             :         STACK_OF(X509_NAME) * root_cert_list;
     754                 :             : 
     755   [ +  -  -  + ]:          94 :         if (SSL_CTX_load_verify_locations(ctx, host->ssl_ca, NULL) != 1 ||
     756                 :          47 :             (root_cert_list = SSL_load_client_CA_file(host->ssl_ca)) == NULL)
     757                 :             :         {
     758   [ #  #  #  # ]:           0 :             ereport(isServerStart ? FATAL : LOG,
     759                 :             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     760                 :             :                      errmsg("could not load root certificate file \"%s\": %s",
     761                 :             :                             host->ssl_ca, SSLerrmessage(ERR_get_error()))));
     762                 :           0 :             goto error;
     763                 :             :         }
     764                 :             : 
     765                 :             :         /*
     766                 :             :          * Tell OpenSSL to send the list of root certs we trust to clients in
     767                 :             :          * CertificateRequests.  This lets a client with a keystore select the
     768                 :             :          * appropriate client certificate to send to us.  Also, this ensures
     769                 :             :          * that the SSL context will "own" the root_cert_list and remember to
     770                 :             :          * free it when no longer needed.
     771                 :             :          */
     772                 :          47 :         SSL_CTX_set_client_CA_list(ctx, root_cert_list);
     773                 :             :     }
     774                 :             : 
     775                 :             :     /*----------
     776                 :             :      * Load the Certificate Revocation List (CRL).
     777                 :             :      * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
     778                 :             :      *----------
     779                 :             :      */
     780   [ +  +  -  + ]:          70 :     if (ssl_crl_file[0] || ssl_crl_dir[0])
     781                 :             :     {
     782                 :          62 :         X509_STORE *cvstore = SSL_CTX_get_cert_store(ctx);
     783                 :             : 
     784         [ +  - ]:          62 :         if (cvstore)
     785                 :             :         {
     786                 :             :             /* Set the flags to check against the complete CRL chain */
     787         [ +  - ]:         124 :             if (X509_STORE_load_locations(cvstore,
     788         [ +  - ]:          62 :                                           ssl_crl_file[0] ? ssl_crl_file : NULL,
     789         [ +  + ]:          62 :                                           ssl_crl_dir[0] ? ssl_crl_dir : NULL)
     790                 :             :                 == 1)
     791                 :             :             {
     792                 :          62 :                 X509_STORE_set_flags(cvstore,
     793                 :             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     794                 :             :             }
     795         [ #  # ]:           0 :             else if (ssl_crl_dir[0] == 0)
     796                 :             :             {
     797   [ #  #  #  # ]:           0 :                 ereport(isServerStart ? FATAL : LOG,
     798                 :             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     799                 :             :                          errmsg("could not load SSL certificate revocation list file \"%s\": %s",
     800                 :             :                                 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
     801                 :           0 :                 goto error;
     802                 :             :             }
     803         [ #  # ]:           0 :             else if (ssl_crl_file[0] == 0)
     804                 :             :             {
     805   [ #  #  #  # ]:           0 :                 ereport(isServerStart ? FATAL : LOG,
     806                 :             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     807                 :             :                          errmsg("could not load SSL certificate revocation list directory \"%s\": %s",
     808                 :             :                                 ssl_crl_dir, SSLerrmessage(ERR_get_error()))));
     809                 :           0 :                 goto error;
     810                 :             :             }
     811                 :             :             else
     812                 :             :             {
     813   [ #  #  #  # ]:           0 :                 ereport(isServerStart ? FATAL : LOG,
     814                 :             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     815                 :             :                          errmsg("could not load SSL certificate revocation list file \"%s\" or directory \"%s\": %s",
     816                 :             :                                 ssl_crl_file, ssl_crl_dir,
     817                 :             :                                 SSLerrmessage(ERR_get_error()))));
     818                 :           0 :                 goto error;
     819                 :             :             }
     820                 :             :         }
     821                 :             :     }
     822                 :             : 
     823                 :          70 :     host->ssl_ctx = ctx;
     824                 :          70 :     return true;
     825                 :             : 
     826                 :           2 : error:
     827         [ +  - ]:           2 :     if (ctx)
     828                 :           2 :         SSL_CTX_free(ctx);
     829                 :           2 :     return false;
     830                 :             : }
     831                 :             : 
     832                 :             : void
     833                 :         157 : be_tls_destroy(void)
     834                 :             : {
     835         [ +  + ]:         157 :     if (SSL_context)
     836                 :           1 :         SSL_CTX_free(SSL_context);
     837                 :         157 :     SSL_context = NULL;
     838                 :         157 :     ssl_loaded_verify_locations = false;
     839                 :         157 : }
     840                 :             : 
     841                 :             : int
     842                 :         170 : be_tls_open_server(Port *port)
     843                 :             : {
     844                 :             :     int         r;
     845                 :             :     int         err;
     846                 :             :     int         waitfor;
     847                 :             :     unsigned long ecode;
     848                 :             :     bool        give_proto_hint;
     849                 :             :     static struct CallbackErr err_context;
     850                 :             : 
     851                 :             :     Assert(!port->ssl);
     852                 :             :     Assert(!port->peer);
     853                 :             : 
     854         [ -  + ]:         170 :     if (!SSL_context)
     855                 :             :     {
     856         [ #  # ]:           0 :         ereport(COMMERROR,
     857                 :             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     858                 :             :                  errmsg("could not initialize SSL connection: SSL context not set up")));
     859                 :           0 :         return -1;
     860                 :             :     }
     861                 :             : 
     862                 :             :     /* set up debugging/info callback */
     863                 :         170 :     SSL_CTX_set_info_callback(SSL_context, info_cb);
     864                 :             : 
     865                 :             :     /* enable ALPN */
     866                 :         170 :     SSL_CTX_set_alpn_select_cb(SSL_context, alpn_cb, port);
     867                 :             : 
     868         [ -  + ]:         170 :     if (!(port->ssl = SSL_new(SSL_context)))
     869                 :             :     {
     870         [ #  # ]:           0 :         ereport(COMMERROR,
     871                 :             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     872                 :             :                  errmsg("could not initialize SSL connection: %s",
     873                 :             :                         SSLerrmessage(ERR_get_error()))));
     874                 :           0 :         return -1;
     875                 :             :     }
     876         [ -  + ]:         170 :     if (!ssl_set_port_bio(port))
     877                 :             :     {
     878         [ #  # ]:           0 :         ereport(COMMERROR,
     879                 :             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     880                 :             :                  errmsg("could not set SSL socket: %s",
     881                 :             :                         SSLerrmessage(ERR_get_error()))));
     882                 :           0 :         return -1;
     883                 :             :     }
     884                 :             : 
     885                 :             :     /*
     886                 :             :      * If the underlying TLS library supports the client hello callback we use
     887                 :             :      * that in order to support host based configuration using the SNI TLS
     888                 :             :      * extension.  If the user has disabled SNI via the ssl_sni GUC we still
     889                 :             :      * make use of the callback in order to have consistent handling of
     890                 :             :      * OpenSSL contexts, except in that case the callback will install the
     891                 :             :      * default configuration regardless of the hostname sent by the user in
     892                 :             :      * the handshake.
     893                 :             :      *
     894                 :             :      * In case the TLS library does not support the client hello callback, as
     895                 :             :      * of this writing LibreSSL does not, we need to install the client cert
     896                 :             :      * verification callback here (if the user configured a CA) since we
     897                 :             :      * cannot use the OpenSSL context update functionality.
     898                 :             :      */
     899                 :             : #ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
     900                 :         170 :     SSL_CTX_set_client_hello_cb(SSL_context, sni_clienthello_cb, NULL);
     901                 :             : #else
     902                 :             :     if (SSL_hosts->default_host->ssl_ca && SSL_hosts->default_host->ssl_ca[0])
     903                 :             :     {
     904                 :             :         /*
     905                 :             :          * Always ask for SSL client cert, but don't fail if it's not
     906                 :             :          * presented.  We might fail such connections later, depending on what
     907                 :             :          * we find in pg_hba.conf.
     908                 :             :          */
     909                 :             :         SSL_set_verify(port->ssl,
     910                 :             :                        (SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
     911                 :             :                        verify_cb);
     912                 :             : 
     913                 :             :         ssl_loaded_verify_locations = true;
     914                 :             :     }
     915                 :             : #endif
     916                 :             : 
     917                 :         170 :     err_context.cert_errdetail = NULL;
     918                 :         170 :     SSL_set_ex_data(port->ssl, 0, &err_context);
     919                 :             : 
     920                 :         170 :     port->ssl_in_use = true;
     921                 :             : 
     922                 :         608 : aloop:
     923                 :             : 
     924                 :             :     /*
     925                 :             :      * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
     926                 :             :      * queue.  In general, the current thread's error queue must be empty
     927                 :             :      * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
     928                 :             :      * not work reliably.  An extension may have failed to clear the
     929                 :             :      * per-thread error queue following another call to an OpenSSL I/O
     930                 :             :      * routine.
     931                 :             :      */
     932                 :         608 :     errno = 0;
     933                 :         608 :     ERR_clear_error();
     934                 :         608 :     r = SSL_accept(port->ssl);
     935         [ +  + ]:         608 :     if (r <= 0)
     936                 :             :     {
     937                 :         470 :         err = SSL_get_error(port->ssl, r);
     938                 :             : 
     939                 :             :         /*
     940                 :             :          * Other clients of OpenSSL in the backend may fail to call
     941                 :             :          * ERR_get_error(), but we always do, so as to not cause problems for
     942                 :             :          * OpenSSL clients that don't call ERR_clear_error() defensively.  Be
     943                 :             :          * sure that this happens by calling now. SSL_get_error() relies on
     944                 :             :          * the OpenSSL per-thread error queue being intact, so this is the
     945                 :             :          * earliest possible point ERR_get_error() may be called.
     946                 :             :          */
     947                 :         470 :         ecode = ERR_get_error();
     948   [ +  -  +  -  :         470 :         switch (err)
                      - ]
     949                 :             :         {
     950                 :         438 :             case SSL_ERROR_WANT_READ:
     951                 :             :             case SSL_ERROR_WANT_WRITE:
     952                 :             :                 /* not allowed during connection establishment */
     953                 :             :                 Assert(!port->noblock);
     954                 :             : 
     955                 :             :                 /*
     956                 :             :                  * No need to care about timeouts/interrupts here. At this
     957                 :             :                  * point authentication_timeout still employs
     958                 :             :                  * StartupPacketTimeoutHandler() which directly exits.
     959                 :             :                  */
     960         [ +  - ]:         438 :                 if (err == SSL_ERROR_WANT_READ)
     961                 :         438 :                     waitfor = WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH;
     962                 :             :                 else
     963                 :           0 :                     waitfor = WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH;
     964                 :             : 
     965                 :         438 :                 (void) WaitLatchOrSocket(NULL, waitfor, port->sock, 0,
     966                 :             :                                          WAIT_EVENT_SSL_OPEN_SERVER);
     967                 :         438 :                 goto aloop;
     968                 :           0 :             case SSL_ERROR_SYSCALL:
     969   [ #  #  #  # ]:           0 :                 if (r < 0 && errno != 0)
     970         [ #  # ]:           0 :                     ereport(COMMERROR,
     971                 :             :                             (errcode_for_socket_access(),
     972                 :             :                              errmsg("could not accept SSL connection: %m")));
     973                 :             :                 else
     974         [ #  # ]:           0 :                     ereport(COMMERROR,
     975                 :             :                             (errcode(ERRCODE_PROTOCOL_VIOLATION),
     976                 :             :                              errmsg("could not accept SSL connection: EOF detected")));
     977                 :           0 :                 break;
     978                 :          32 :             case SSL_ERROR_SSL:
     979         [ -  + ]:          32 :                 switch (ERR_GET_REASON(ecode))
     980                 :             :                 {
     981                 :             :                         /*
     982                 :             :                          * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
     983                 :             :                          * TLSV1_ALERT_PROTOCOL_VERSION have been observed
     984                 :             :                          * when trying to communicate with an old OpenSSL
     985                 :             :                          * library, or when the client and server specify
     986                 :             :                          * disjoint protocol ranges.  NO_PROTOCOLS_AVAILABLE
     987                 :             :                          * occurs if there's a local misconfiguration (which
     988                 :             :                          * can happen despite our checks, if openssl.cnf
     989                 :             :                          * injects a limit we didn't account for).  It's not
     990                 :             :                          * very clear what would make OpenSSL return the other
     991                 :             :                          * codes listed here, but a hint about protocol
     992                 :             :                          * versions seems like it's appropriate for all.
     993                 :             :                          */
     994                 :           0 :                     case SSL_R_NO_PROTOCOLS_AVAILABLE:
     995                 :             :                     case SSL_R_UNSUPPORTED_PROTOCOL:
     996                 :             :                     case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
     997                 :             :                     case SSL_R_UNKNOWN_PROTOCOL:
     998                 :             :                     case SSL_R_UNKNOWN_SSL_VERSION:
     999                 :             :                     case SSL_R_UNSUPPORTED_SSL_VERSION:
    1000                 :             :                     case SSL_R_WRONG_SSL_VERSION:
    1001                 :             :                     case SSL_R_WRONG_VERSION_NUMBER:
    1002                 :             :                     case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
    1003                 :             : #ifdef SSL_R_VERSION_TOO_HIGH
    1004                 :             :                     case SSL_R_VERSION_TOO_HIGH:
    1005                 :             : #endif
    1006                 :             : #ifdef SSL_R_VERSION_TOO_LOW
    1007                 :             :                     case SSL_R_VERSION_TOO_LOW:
    1008                 :             : #endif
    1009                 :           0 :                         give_proto_hint = true;
    1010                 :           0 :                         break;
    1011                 :          32 :                     default:
    1012                 :          32 :                         give_proto_hint = false;
    1013                 :          32 :                         break;
    1014                 :             :                 }
    1015   [ +  -  +  +  :          32 :                 ereport(COMMERROR,
          -  +  -  -  -  
                      - ]
    1016                 :             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1017                 :             :                          errmsg("could not accept SSL connection: %s",
    1018                 :             :                                 SSLerrmessage(ecode)),
    1019                 :             :                          err_context.cert_errdetail ? errdetail_internal("%s", err_context.cert_errdetail) : 0,
    1020                 :             :                          give_proto_hint ?
    1021                 :             :                          errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
    1022                 :             :                                  ssl_min_protocol_version ?
    1023                 :             :                                  ssl_protocol_version_to_string(ssl_min_protocol_version) :
    1024                 :             :                                  MIN_OPENSSL_TLS_VERSION,
    1025                 :             :                                  ssl_max_protocol_version ?
    1026                 :             :                                  ssl_protocol_version_to_string(ssl_max_protocol_version) :
    1027                 :             :                                  MAX_OPENSSL_TLS_VERSION) : 0));
    1028         [ +  + ]:          32 :                 if (err_context.cert_errdetail)
    1029                 :           9 :                     pfree(err_context.cert_errdetail);
    1030                 :          32 :                 break;
    1031                 :           0 :             case SSL_ERROR_ZERO_RETURN:
    1032         [ #  # ]:           0 :                 ereport(COMMERROR,
    1033                 :             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1034                 :             :                          errmsg("could not accept SSL connection: EOF detected")));
    1035                 :           0 :                 break;
    1036                 :           0 :             default:
    1037         [ #  # ]:           0 :                 ereport(COMMERROR,
    1038                 :             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1039                 :             :                          errmsg("unrecognized SSL error code: %d",
    1040                 :             :                                 err)));
    1041                 :           0 :                 break;
    1042                 :             :         }
    1043                 :          32 :         return -1;
    1044                 :             :     }
    1045                 :             : 
    1046                 :             :     /* Get the protocol selected by ALPN */
    1047                 :         138 :     port->alpn_used = false;
    1048                 :             :     {
    1049                 :             :         const unsigned char *selected;
    1050                 :             :         unsigned int len;
    1051                 :             : 
    1052                 :         138 :         SSL_get0_alpn_selected(port->ssl, &selected, &len);
    1053                 :             : 
    1054                 :             :         /* If ALPN is used, check that we negotiated the expected protocol */
    1055         [ +  - ]:         138 :         if (selected != NULL)
    1056                 :             :         {
    1057         [ +  - ]:         138 :             if (len == strlen(PG_ALPN_PROTOCOL) &&
    1058         [ +  - ]:         138 :                 memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) == 0)
    1059                 :             :             {
    1060                 :         138 :                 port->alpn_used = true;
    1061                 :             :             }
    1062                 :             :             else
    1063                 :             :             {
    1064                 :             :                 /* shouldn't happen */
    1065         [ #  # ]:           0 :                 ereport(COMMERROR,
    1066                 :             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1067                 :             :                          errmsg("received SSL connection request with unexpected ALPN protocol")));
    1068                 :             :             }
    1069                 :             :         }
    1070                 :             :     }
    1071                 :             : 
    1072                 :             :     /* Get client certificate, if available. */
    1073                 :         138 :     port->peer = SSL_get_peer_certificate(port->ssl);
    1074                 :             : 
    1075                 :             :     /* and extract the Common Name and Distinguished Name from it. */
    1076                 :         138 :     port->peer_cn = NULL;
    1077                 :         138 :     port->peer_dn = NULL;
    1078                 :         138 :     port->peer_cert_valid = false;
    1079         [ +  + ]:         138 :     if (port->peer != NULL)
    1080                 :             :     {
    1081                 :             :         int         len;
    1082                 :          31 :         const X509_NAME *x509name = X509_get_subject_name(port->peer);
    1083                 :             :         char       *peer_dn;
    1084                 :          31 :         BIO        *bio = NULL;
    1085                 :          31 :         BUF_MEM    *bio_buf = NULL;
    1086                 :             :         int         index;
    1087                 :             : 
    1088                 :          31 :         index = X509_NAME_get_index_by_NID(unconstify(X509_NAME *, x509name), NID_commonName, -1);
    1089         [ +  - ]:          31 :         if (index >= 0)
    1090                 :             :         {
    1091                 :             :             const X509_NAME_ENTRY *entry;
    1092                 :             :             const ASN1_STRING *peer_cn_asn1;
    1093                 :             :             const unsigned char *peer_cn_internal;
    1094                 :             :             char       *peer_cn;
    1095                 :             : 
    1096                 :          31 :             entry = X509_NAME_get_entry(unconstify(X509_NAME *, x509name), index);
    1097                 :          31 :             peer_cn_asn1 = X509_NAME_ENTRY_get_data(entry);
    1098                 :          31 :             len = ASN1_STRING_length(peer_cn_asn1);
    1099                 :          31 :             peer_cn_internal = ASN1_STRING_get0_data(peer_cn_asn1);
    1100                 :             : 
    1101                 :          31 :             peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
    1102                 :          31 :             memcpy(peer_cn, peer_cn_internal, len);
    1103                 :          31 :             peer_cn[len] = '\0';
    1104                 :             : 
    1105                 :             :             /*
    1106                 :             :              * Reject embedded NULLs in certificate common name to prevent
    1107                 :             :              * attacks like CVE-2009-4034.
    1108                 :             :              */
    1109         [ -  + ]:          31 :             if (len != strlen(peer_cn))
    1110                 :             :             {
    1111         [ #  # ]:           0 :                 ereport(COMMERROR,
    1112                 :             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1113                 :             :                          errmsg("SSL certificate's common name contains embedded null")));
    1114                 :           0 :                 pfree(peer_cn);
    1115                 :           0 :                 return -1;
    1116                 :             :             }
    1117                 :             : 
    1118                 :          31 :             port->peer_cn = peer_cn;
    1119                 :             :         }
    1120                 :             : 
    1121                 :          31 :         bio = BIO_new(BIO_s_mem());
    1122         [ -  + ]:          31 :         if (!bio)
    1123                 :             :         {
    1124         [ #  # ]:           0 :             if (port->peer_cn != NULL)
    1125                 :             :             {
    1126                 :           0 :                 pfree(port->peer_cn);
    1127                 :           0 :                 port->peer_cn = NULL;
    1128                 :             :             }
    1129                 :           0 :             return -1;
    1130                 :             :         }
    1131                 :             : 
    1132                 :             :         /*
    1133                 :             :          * RFC2253 is the closest thing to an accepted standard format for
    1134                 :             :          * DNs. We have documented how to produce this format from a
    1135                 :             :          * certificate. It uses commas instead of slashes for delimiters,
    1136                 :             :          * which make regular expression matching a bit easier. Also note that
    1137                 :             :          * it prints the Subject fields in reverse order.
    1138                 :             :          */
    1139   [ +  -  -  + ]:          62 :         if (X509_NAME_print_ex(bio, x509name, 0, XN_FLAG_RFC2253) == -1 ||
    1140                 :          31 :             BIO_get_mem_ptr(bio, &bio_buf) <= 0)
    1141                 :             :         {
    1142                 :           0 :             BIO_free(bio);
    1143         [ #  # ]:           0 :             if (port->peer_cn != NULL)
    1144                 :             :             {
    1145                 :           0 :                 pfree(port->peer_cn);
    1146                 :           0 :                 port->peer_cn = NULL;
    1147                 :             :             }
    1148                 :           0 :             return -1;
    1149                 :             :         }
    1150                 :          31 :         peer_dn = MemoryContextAlloc(TopMemoryContext, bio_buf->length + 1);
    1151                 :          31 :         memcpy(peer_dn, bio_buf->data, bio_buf->length);
    1152                 :          31 :         len = bio_buf->length;
    1153                 :          31 :         BIO_free(bio);
    1154                 :          31 :         peer_dn[len] = '\0';
    1155         [ -  + ]:          31 :         if (len != strlen(peer_dn))
    1156                 :             :         {
    1157         [ #  # ]:           0 :             ereport(COMMERROR,
    1158                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1159                 :             :                      errmsg("SSL certificate's distinguished name contains embedded null")));
    1160                 :           0 :             pfree(peer_dn);
    1161         [ #  # ]:           0 :             if (port->peer_cn != NULL)
    1162                 :             :             {
    1163                 :           0 :                 pfree(port->peer_cn);
    1164                 :           0 :                 port->peer_cn = NULL;
    1165                 :             :             }
    1166                 :           0 :             return -1;
    1167                 :             :         }
    1168                 :             : 
    1169                 :          31 :         port->peer_dn = peer_dn;
    1170                 :             : 
    1171                 :          31 :         port->peer_cert_valid = true;
    1172                 :             :     }
    1173                 :             : 
    1174                 :         138 :     return 0;
    1175                 :             : }
    1176                 :             : 
    1177                 :             : void
    1178                 :         170 : be_tls_close(Port *port)
    1179                 :             : {
    1180         [ +  - ]:         170 :     if (port->ssl)
    1181                 :             :     {
    1182                 :         170 :         SSL_shutdown(port->ssl);
    1183                 :         170 :         SSL_free(port->ssl);
    1184                 :         170 :         port->ssl = NULL;
    1185                 :         170 :         port->ssl_in_use = false;
    1186                 :             :     }
    1187                 :             : 
    1188         [ +  + ]:         170 :     if (port->peer)
    1189                 :             :     {
    1190                 :          31 :         X509_free(port->peer);
    1191                 :          31 :         port->peer = NULL;
    1192                 :             :     }
    1193                 :             : 
    1194         [ +  + ]:         170 :     if (port->peer_cn)
    1195                 :             :     {
    1196                 :          31 :         pfree(port->peer_cn);
    1197                 :          31 :         port->peer_cn = NULL;
    1198                 :             :     }
    1199                 :             : 
    1200         [ +  + ]:         170 :     if (port->peer_dn)
    1201                 :             :     {
    1202                 :          31 :         pfree(port->peer_dn);
    1203                 :          31 :         port->peer_dn = NULL;
    1204                 :             :     }
    1205                 :         170 : }
    1206                 :             : 
    1207                 :             : ssize_t
    1208                 :         738 : be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
    1209                 :             : {
    1210                 :             :     ssize_t     n;
    1211                 :             :     int         err;
    1212                 :             :     unsigned long ecode;
    1213                 :             : 
    1214                 :         738 :     errno = 0;
    1215                 :         738 :     ERR_clear_error();
    1216                 :         738 :     n = SSL_read(port->ssl, ptr, len);
    1217                 :         738 :     err = SSL_get_error(port->ssl, n);
    1218   [ +  +  -  + ]:         738 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
    1219   [ +  +  -  -  :         738 :     switch (err)
                -  +  - ]
    1220                 :             :     {
    1221                 :         355 :         case SSL_ERROR_NONE:
    1222                 :             :             /* a-ok */
    1223                 :         355 :             break;
    1224                 :         366 :         case SSL_ERROR_WANT_READ:
    1225                 :         366 :             *waitfor = WL_SOCKET_READABLE;
    1226                 :         366 :             errno = EWOULDBLOCK;
    1227                 :         366 :             n = -1;
    1228                 :         366 :             break;
    1229                 :           0 :         case SSL_ERROR_WANT_WRITE:
    1230                 :           0 :             *waitfor = WL_SOCKET_WRITEABLE;
    1231                 :           0 :             errno = EWOULDBLOCK;
    1232                 :           0 :             n = -1;
    1233                 :           0 :             break;
    1234                 :           0 :         case SSL_ERROR_SYSCALL:
    1235                 :             :             /* leave it to caller to ereport the value of errno */
    1236   [ #  #  #  # ]:           0 :             if (n != -1 || errno == 0)
    1237                 :             :             {
    1238                 :           0 :                 errno = ECONNRESET;
    1239                 :           0 :                 n = -1;
    1240                 :             :             }
    1241                 :           0 :             break;
    1242                 :           0 :         case SSL_ERROR_SSL:
    1243         [ #  # ]:           0 :             ereport(COMMERROR,
    1244                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1245                 :             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
    1246                 :           0 :             errno = ECONNRESET;
    1247                 :           0 :             n = -1;
    1248                 :           0 :             break;
    1249                 :          17 :         case SSL_ERROR_ZERO_RETURN:
    1250                 :             :             /* connection was cleanly shut down by peer */
    1251                 :          17 :             n = 0;
    1252                 :          17 :             break;
    1253                 :           0 :         default:
    1254         [ #  # ]:           0 :             ereport(COMMERROR,
    1255                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1256                 :             :                      errmsg("unrecognized SSL error code: %d",
    1257                 :             :                             err)));
    1258                 :           0 :             errno = ECONNRESET;
    1259                 :           0 :             n = -1;
    1260                 :           0 :             break;
    1261                 :             :     }
    1262                 :             : 
    1263                 :         738 :     return n;
    1264                 :             : }
    1265                 :             : 
    1266                 :             : ssize_t
    1267                 :         248 : be_tls_write(Port *port, const void *ptr, size_t len, int *waitfor)
    1268                 :             : {
    1269                 :             :     ssize_t     n;
    1270                 :             :     int         err;
    1271                 :             :     unsigned long ecode;
    1272                 :             : 
    1273                 :         248 :     errno = 0;
    1274                 :         248 :     ERR_clear_error();
    1275                 :         248 :     n = SSL_write(port->ssl, ptr, len);
    1276                 :         248 :     err = SSL_get_error(port->ssl, n);
    1277   [ +  -  -  + ]:         248 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
    1278   [ +  -  -  -  :         248 :     switch (err)
                -  -  - ]
    1279                 :             :     {
    1280                 :         248 :         case SSL_ERROR_NONE:
    1281                 :             :             /* a-ok */
    1282                 :         248 :             break;
    1283                 :           0 :         case SSL_ERROR_WANT_READ:
    1284                 :           0 :             *waitfor = WL_SOCKET_READABLE;
    1285                 :           0 :             errno = EWOULDBLOCK;
    1286                 :           0 :             n = -1;
    1287                 :           0 :             break;
    1288                 :           0 :         case SSL_ERROR_WANT_WRITE:
    1289                 :           0 :             *waitfor = WL_SOCKET_WRITEABLE;
    1290                 :           0 :             errno = EWOULDBLOCK;
    1291                 :           0 :             n = -1;
    1292                 :           0 :             break;
    1293                 :           0 :         case SSL_ERROR_SYSCALL:
    1294                 :             : 
    1295                 :             :             /*
    1296                 :             :              * Leave it to caller to ereport the value of errno.  However, if
    1297                 :             :              * errno is still zero then assume it's a read EOF situation, and
    1298                 :             :              * report ECONNRESET.  (This seems possible because SSL_write can
    1299                 :             :              * also do reads.)
    1300                 :             :              */
    1301   [ #  #  #  # ]:           0 :             if (n != -1 || errno == 0)
    1302                 :             :             {
    1303                 :           0 :                 errno = ECONNRESET;
    1304                 :           0 :                 n = -1;
    1305                 :             :             }
    1306                 :           0 :             break;
    1307                 :           0 :         case SSL_ERROR_SSL:
    1308         [ #  # ]:           0 :             ereport(COMMERROR,
    1309                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1310                 :             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
    1311                 :           0 :             errno = ECONNRESET;
    1312                 :           0 :             n = -1;
    1313                 :           0 :             break;
    1314                 :           0 :         case SSL_ERROR_ZERO_RETURN:
    1315                 :             : 
    1316                 :             :             /*
    1317                 :             :              * the SSL connection was closed, leave it to the caller to
    1318                 :             :              * ereport it
    1319                 :             :              */
    1320                 :           0 :             errno = ECONNRESET;
    1321                 :           0 :             n = -1;
    1322                 :           0 :             break;
    1323                 :           0 :         default:
    1324         [ #  # ]:           0 :             ereport(COMMERROR,
    1325                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1326                 :             :                      errmsg("unrecognized SSL error code: %d",
    1327                 :             :                             err)));
    1328                 :           0 :             errno = ECONNRESET;
    1329                 :           0 :             n = -1;
    1330                 :           0 :             break;
    1331                 :             :     }
    1332                 :             : 
    1333                 :         248 :     return n;
    1334                 :             : }
    1335                 :             : 
    1336                 :             : /* ------------------------------------------------------------ */
    1337                 :             : /*                      Internal functions                      */
    1338                 :             : /* ------------------------------------------------------------ */
    1339                 :             : 
    1340                 :             : /*
    1341                 :             :  * Private substitute BIO: this does the sending and receiving using send() and
    1342                 :             :  * recv() instead. This is so that we can enable and disable interrupts
    1343                 :             :  * just while calling recv(). We cannot have interrupts occurring while
    1344                 :             :  * the bulk of OpenSSL runs, because it uses malloc() and possibly other
    1345                 :             :  * non-reentrant libc facilities. We also need to call send() and recv()
    1346                 :             :  * directly so it gets passed through the socket/signals layer on Win32.
    1347                 :             :  *
    1348                 :             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
    1349                 :             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
    1350                 :             :  */
    1351                 :             : 
    1352                 :             : static BIO_METHOD *port_bio_method_ptr = NULL;
    1353                 :             : 
    1354                 :             : static int
    1355                 :        3125 : port_bio_read(BIO *h, char *buf, int size)
    1356                 :             : {
    1357                 :        3125 :     int         res = 0;
    1358                 :        3125 :     Port       *port = (Port *) BIO_get_data(h);
    1359                 :             : 
    1360         [ +  - ]:        3125 :     if (buf != NULL)
    1361                 :             :     {
    1362                 :        3125 :         res = (int) secure_raw_read(port, buf, size);
    1363                 :        3125 :         BIO_clear_retry_flags(h);
    1364                 :        3125 :         port->last_read_was_eof = res == 0;
    1365         [ +  + ]:        3125 :         if (res <= 0)
    1366                 :             :         {
    1367                 :             :             /* If we were interrupted, tell caller to retry */
    1368   [ +  -  +  +  :         809 :             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
                   -  + ]
    1369                 :             :             {
    1370                 :         804 :                 BIO_set_retry_read(h);
    1371                 :             :             }
    1372                 :             :         }
    1373                 :             :     }
    1374                 :             : 
    1375                 :        3125 :     return res;
    1376                 :             : }
    1377                 :             : 
    1378                 :             : static int
    1379                 :         714 : port_bio_write(BIO *h, const char *buf, int size)
    1380                 :             : {
    1381                 :         714 :     int         res = 0;
    1382                 :             : 
    1383                 :         714 :     res = (int) secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
    1384                 :         714 :     BIO_clear_retry_flags(h);
    1385         [ -  + ]:         714 :     if (res <= 0)
    1386                 :             :     {
    1387                 :             :         /* If we were interrupted, tell caller to retry */
    1388   [ #  #  #  #  :           0 :         if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
                   #  # ]
    1389                 :             :         {
    1390                 :           0 :             BIO_set_retry_write(h);
    1391                 :             :         }
    1392                 :             :     }
    1393                 :             : 
    1394                 :         714 :     return res;
    1395                 :             : }
    1396                 :             : 
    1397                 :             : static long
    1398                 :         811 : port_bio_ctrl(BIO *h, int cmd, long num, void *ptr)
    1399                 :             : {
    1400                 :             :     long        res;
    1401                 :         811 :     Port       *port = (Port *) BIO_get_data(h);
    1402                 :             : 
    1403      [ +  +  + ]:         811 :     switch (cmd)
    1404                 :             :     {
    1405                 :           5 :         case BIO_CTRL_EOF:
    1406                 :             : 
    1407                 :             :             /*
    1408                 :             :              * This should not be needed. port_bio_read already has a way to
    1409                 :             :              * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
    1410                 :             :              * backwards-incompatible change and now expects EOF via BIO_ctrl.
    1411                 :             :              * See https://github.com/openssl/openssl/issues/8208
    1412                 :             :              */
    1413                 :           5 :             res = port->last_read_was_eof;
    1414                 :           5 :             break;
    1415                 :         466 :         case BIO_CTRL_FLUSH:
    1416                 :             :             /* libssl expects all BIOs to support BIO_flush. */
    1417                 :         466 :             res = 1;
    1418                 :         466 :             break;
    1419                 :         340 :         default:
    1420                 :         340 :             res = 0;
    1421                 :         340 :             break;
    1422                 :             :     }
    1423                 :             : 
    1424                 :         811 :     return res;
    1425                 :             : }
    1426                 :             : 
    1427                 :             : static BIO_METHOD *
    1428                 :         170 : port_bio_method(void)
    1429                 :             : {
    1430         [ +  - ]:         170 :     if (!port_bio_method_ptr)
    1431                 :             :     {
    1432                 :             :         int         my_bio_index;
    1433                 :             : 
    1434                 :         170 :         my_bio_index = BIO_get_new_index();
    1435         [ -  + ]:         170 :         if (my_bio_index == -1)
    1436                 :           0 :             return NULL;
    1437                 :         170 :         my_bio_index |= BIO_TYPE_SOURCE_SINK;
    1438                 :         170 :         port_bio_method_ptr = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
    1439         [ -  + ]:         170 :         if (!port_bio_method_ptr)
    1440                 :           0 :             return NULL;
    1441   [ +  -  +  - ]:         340 :         if (!BIO_meth_set_write(port_bio_method_ptr, port_bio_write) ||
    1442         [ -  + ]:         340 :             !BIO_meth_set_read(port_bio_method_ptr, port_bio_read) ||
    1443                 :         170 :             !BIO_meth_set_ctrl(port_bio_method_ptr, port_bio_ctrl))
    1444                 :             :         {
    1445                 :           0 :             BIO_meth_free(port_bio_method_ptr);
    1446                 :           0 :             port_bio_method_ptr = NULL;
    1447                 :           0 :             return NULL;
    1448                 :             :         }
    1449                 :             :     }
    1450                 :         170 :     return port_bio_method_ptr;
    1451                 :             : }
    1452                 :             : 
    1453                 :             : static int
    1454                 :         170 : ssl_set_port_bio(Port *port)
    1455                 :             : {
    1456                 :             :     BIO        *bio;
    1457                 :             :     BIO_METHOD *bio_method;
    1458                 :             : 
    1459                 :         170 :     bio_method = port_bio_method();
    1460         [ -  + ]:         170 :     if (bio_method == NULL)
    1461                 :           0 :         return 0;
    1462                 :             : 
    1463                 :         170 :     bio = BIO_new(bio_method);
    1464         [ -  + ]:         170 :     if (bio == NULL)
    1465                 :           0 :         return 0;
    1466                 :             : 
    1467                 :         170 :     BIO_set_data(bio, port);
    1468                 :         170 :     BIO_set_init(bio, 1);
    1469                 :             : 
    1470                 :         170 :     SSL_set_bio(port->ssl, bio, bio);
    1471                 :         170 :     return 1;
    1472                 :             : }
    1473                 :             : 
    1474                 :             : /*
    1475                 :             :  *  Load precomputed DH parameters.
    1476                 :             :  *
    1477                 :             :  *  To prevent "downgrade" attacks, we perform a number of checks
    1478                 :             :  *  to verify that the DBA-generated DH parameters file contains
    1479                 :             :  *  what we expect it to contain.
    1480                 :             :  */
    1481                 :             : static DH  *
    1482                 :           0 : load_dh_file(char *filename, bool isServerStart)
    1483                 :             : {
    1484                 :             :     FILE       *fp;
    1485                 :           0 :     DH         *dh = NULL;
    1486                 :             :     int         codes;
    1487                 :             : 
    1488                 :             :     /* attempt to open file.  It's not an error if it doesn't exist. */
    1489         [ #  # ]:           0 :     if ((fp = AllocateFile(filename, "r")) == NULL)
    1490                 :             :     {
    1491   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    1492                 :             :                 (errcode_for_file_access(),
    1493                 :             :                  errmsg("could not open DH parameters file \"%s\": %m",
    1494                 :             :                         filename)));
    1495                 :           0 :         return NULL;
    1496                 :             :     }
    1497                 :             : 
    1498                 :           0 :     dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
    1499                 :           0 :     FreeFile(fp);
    1500                 :             : 
    1501         [ #  # ]:           0 :     if (dh == NULL)
    1502                 :             :     {
    1503   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    1504                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1505                 :             :                  errmsg("could not load DH parameters file: %s",
    1506                 :             :                         SSLerrmessage(ERR_get_error()))));
    1507                 :           0 :         return NULL;
    1508                 :             :     }
    1509                 :             : 
    1510                 :             :     /* make sure the DH parameters are usable */
    1511         [ #  # ]:           0 :     if (DH_check(dh, &codes) == 0)
    1512                 :             :     {
    1513   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    1514                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1515                 :             :                  errmsg("invalid DH parameters: %s",
    1516                 :             :                         SSLerrmessage(ERR_get_error()))));
    1517                 :           0 :         DH_free(dh);
    1518                 :           0 :         return NULL;
    1519                 :             :     }
    1520         [ #  # ]:           0 :     if (codes & DH_CHECK_P_NOT_PRIME)
    1521                 :             :     {
    1522   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    1523                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1524                 :             :                  errmsg("invalid DH parameters: p is not prime")));
    1525                 :           0 :         DH_free(dh);
    1526                 :           0 :         return NULL;
    1527                 :             :     }
    1528         [ #  # ]:           0 :     if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
    1529         [ #  # ]:           0 :         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
    1530                 :             :     {
    1531   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    1532                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1533                 :             :                  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
    1534                 :           0 :         DH_free(dh);
    1535                 :           0 :         return NULL;
    1536                 :             :     }
    1537                 :             : 
    1538                 :           0 :     return dh;
    1539                 :             : }
    1540                 :             : 
    1541                 :             : /*
    1542                 :             :  *  Load hardcoded DH parameters.
    1543                 :             :  *
    1544                 :             :  *  If DH parameters cannot be loaded from a specified file, we can load
    1545                 :             :  *  the hardcoded DH parameters supplied with the backend to prevent
    1546                 :             :  *  problems.
    1547                 :             :  */
    1548                 :             : static DH  *
    1549                 :          52 : load_dh_buffer(const char *buffer, size_t len)
    1550                 :             : {
    1551                 :             :     BIO        *bio;
    1552                 :          52 :     DH         *dh = NULL;
    1553                 :             : 
    1554                 :          52 :     bio = BIO_new_mem_buf(buffer, len);
    1555         [ -  + ]:          52 :     if (bio == NULL)
    1556                 :           0 :         return NULL;
    1557                 :          52 :     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
    1558         [ -  + ]:          52 :     if (dh == NULL)
    1559         [ #  # ]:           0 :         ereport(DEBUG2,
    1560                 :             :                 (errmsg_internal("DH load buffer: %s",
    1561                 :             :                                  SSLerrmessage(ERR_get_error()))));
    1562                 :          52 :     BIO_free(bio);
    1563                 :             : 
    1564                 :          52 :     return dh;
    1565                 :             : }
    1566                 :             : 
    1567                 :             : /*
    1568                 :             :  *  Passphrase collection callback using ssl_passphrase_command
    1569                 :             :  */
    1570                 :             : static int
    1571                 :          17 : ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1572                 :             : {
    1573                 :             :     /* same prompt as OpenSSL uses internally */
    1574                 :          17 :     const char *prompt = "Enter PEM pass phrase:";
    1575                 :          17 :     const char *cmd = userdata;
    1576                 :             : 
    1577                 :             :     Assert(rwflag == 0);
    1578                 :             : 
    1579                 :          17 :     return run_ssl_passphrase_command(cmd, prompt, ssl_is_server_start, buf, size);
    1580                 :             : }
    1581                 :             : 
    1582                 :             : /*
    1583                 :             :  * Dummy passphrase callback
    1584                 :             :  *
    1585                 :             :  * If OpenSSL is told to use a passphrase-protected server key, by default
    1586                 :             :  * it will issue a prompt on /dev/tty and try to read a key from there.
    1587                 :             :  * That's no good during a postmaster SIGHUP cycle, not to mention SSL context
    1588                 :             :  * reload in an EXEC_BACKEND postmaster child.  So override it with this dummy
    1589                 :             :  * function that just returns an empty passphrase, guaranteeing failure.
    1590                 :             :  */
    1591                 :             : static int
    1592                 :           2 : dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1593                 :             : {
    1594                 :             :     /* Set flag to change the error message we'll report */
    1595                 :           2 :     dummy_ssl_passwd_cb_called = true;
    1596                 :             :     /* And return empty string */
    1597                 :             :     Assert(size > 0);
    1598                 :           2 :     buf[0] = '\0';
    1599                 :           2 :     return 0;
    1600                 :             : }
    1601                 :             : 
    1602                 :             : /*
    1603                 :             :  * Examines the provided certificate name, and if it's too long to log or
    1604                 :             :  * contains unprintable ASCII, escapes and truncates it. The return value is
    1605                 :             :  * always a new palloc'd string. (The input string is still modified in place,
    1606                 :             :  * for ease of implementation.)
    1607                 :             :  */
    1608                 :             : static char *
    1609                 :          18 : prepare_cert_name(char *name)
    1610                 :             : {
    1611                 :          18 :     size_t      namelen = strlen(name);
    1612                 :          18 :     char       *truncated = name;
    1613                 :             : 
    1614                 :             :     /*
    1615                 :             :      * Common Names are 64 chars max, so for a common case where the CN is the
    1616                 :             :      * last field, we can still print the longest possible CN with a
    1617                 :             :      * 7-character prefix (".../CN=[64 chars]"), for a reasonable limit of 71
    1618                 :             :      * characters.
    1619                 :             :      */
    1620                 :             : #define MAXLEN 71
    1621                 :             : 
    1622         [ +  + ]:          18 :     if (namelen > MAXLEN)
    1623                 :             :     {
    1624                 :             :         /*
    1625                 :             :          * Keep the end of the name, not the beginning, since the most
    1626                 :             :          * specific field is likely to give users the most information.
    1627                 :             :          */
    1628                 :           1 :         truncated = name + namelen - MAXLEN;
    1629                 :           1 :         truncated[0] = truncated[1] = truncated[2] = '.';
    1630                 :           1 :         namelen = MAXLEN;
    1631                 :             :     }
    1632                 :             : 
    1633                 :             : #undef MAXLEN
    1634                 :             : 
    1635                 :          18 :     return pg_clean_ascii(truncated, 0);
    1636                 :             : }
    1637                 :             : 
    1638                 :             : /*
    1639                 :             :  *  Certificate verification callback
    1640                 :             :  *
    1641                 :             :  *  This callback allows us to examine intermediate problems during
    1642                 :             :  *  verification, for later logging.
    1643                 :             :  *
    1644                 :             :  *  This callback also allows us to override the default acceptance
    1645                 :             :  *  criteria (e.g., accepting self-signed or expired certs), but
    1646                 :             :  *  for now we accept the default checks.
    1647                 :             :  */
    1648                 :             : static int
    1649                 :         102 : verify_cb(int ok, X509_STORE_CTX *ctx)
    1650                 :             : {
    1651                 :             :     int         depth;
    1652                 :             :     int         errcode;
    1653                 :             :     const char *errstring;
    1654                 :             :     StringInfoData str;
    1655                 :             :     X509       *cert;
    1656                 :             :     SSL        *ssl;
    1657                 :             :     struct CallbackErr *cb_err;
    1658                 :             : 
    1659         [ +  + ]:         102 :     if (ok)
    1660                 :             :     {
    1661                 :             :         /* Nothing to do for the successful case. */
    1662                 :          93 :         return ok;
    1663                 :             :     }
    1664                 :             : 
    1665                 :             :     /* Pull all the information we have on the verification failure. */
    1666                 :           9 :     depth = X509_STORE_CTX_get_error_depth(ctx);
    1667                 :           9 :     errcode = X509_STORE_CTX_get_error(ctx);
    1668                 :           9 :     errstring = X509_verify_cert_error_string(errcode);
    1669                 :             : 
    1670                 :             :     /*
    1671                 :             :      * Extract the current SSL and CallbackErr object to use for passing error
    1672                 :             :      * detail back from the callback.
    1673                 :             :      */
    1674                 :           9 :     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
    1675                 :           9 :     cb_err = (struct CallbackErr *) SSL_get_ex_data(ssl, 0);
    1676                 :             : 
    1677                 :           9 :     initStringInfo(&str);
    1678                 :           9 :     appendStringInfo(&str,
    1679                 :           9 :                      _("Client certificate verification failed at depth %d: %s."),
    1680                 :             :                      depth, errstring);
    1681                 :             : 
    1682                 :           9 :     cert = X509_STORE_CTX_get_current_cert(ctx);
    1683         [ +  - ]:           9 :     if (cert)
    1684                 :             :     {
    1685                 :             :         char       *subject,
    1686                 :             :                    *issuer;
    1687                 :             :         char       *sub_prepared,
    1688                 :             :                    *iss_prepared;
    1689                 :             :         char       *serialno;
    1690                 :             :         ASN1_INTEGER *sn;
    1691                 :             :         BIGNUM     *b;
    1692                 :             : 
    1693                 :             :         /*
    1694                 :             :          * Get the Subject and Issuer for logging, but don't let maliciously
    1695                 :             :          * huge certs flood the logs, and don't reflect non-ASCII bytes into
    1696                 :             :          * it either.
    1697                 :             :          */
    1698                 :           9 :         subject = X509_NAME_to_cstring(X509_get_subject_name(cert));
    1699                 :           9 :         sub_prepared = prepare_cert_name(subject);
    1700                 :           9 :         pfree(subject);
    1701                 :             : 
    1702                 :           9 :         issuer = X509_NAME_to_cstring(X509_get_issuer_name(cert));
    1703                 :           9 :         iss_prepared = prepare_cert_name(issuer);
    1704                 :           9 :         pfree(issuer);
    1705                 :             : 
    1706                 :             :         /*
    1707                 :             :          * Pull the serial number, too, in case a Subject is still ambiguous.
    1708                 :             :          * This mirrors be_tls_get_peer_serial().
    1709                 :             :          */
    1710                 :           9 :         sn = X509_get_serialNumber(cert);
    1711                 :           9 :         b = ASN1_INTEGER_to_BN(sn, NULL);
    1712                 :           9 :         serialno = BN_bn2dec(b);
    1713                 :             : 
    1714                 :           9 :         appendStringInfoChar(&str, '\n');
    1715         [ -  + ]:           9 :         appendStringInfo(&str,
    1716                 :           9 :                          _("Failed certificate data (unverified): subject \"%s\", serial number %s, issuer \"%s\"."),
    1717                 :           0 :                          sub_prepared, serialno ? serialno : _("unknown"),
    1718                 :             :                          iss_prepared);
    1719                 :             : 
    1720                 :           9 :         BN_free(b);
    1721                 :           9 :         OPENSSL_free(serialno);
    1722                 :           9 :         pfree(iss_prepared);
    1723                 :           9 :         pfree(sub_prepared);
    1724                 :             :     }
    1725                 :             : 
    1726                 :             :     /* Store our detail message to be logged later. */
    1727                 :           9 :     cb_err->cert_errdetail = str.data;
    1728                 :             : 
    1729                 :           9 :     return ok;
    1730                 :             : }
    1731                 :             : 
    1732                 :             : /*
    1733                 :             :  *  This callback is used to copy SSL information messages
    1734                 :             :  *  into the PostgreSQL log.
    1735                 :             :  */
    1736                 :             : static void
    1737                 :        3881 : info_cb(const SSL *ssl, int type, int args)
    1738                 :             : {
    1739                 :             :     const char *desc;
    1740                 :             : 
    1741                 :        3881 :     desc = SSL_state_string_long(ssl);
    1742                 :             : 
    1743   [ +  +  +  +  :        3881 :     switch (type)
             -  -  +  +  
                      - ]
    1744                 :             :     {
    1745                 :         170 :         case SSL_CB_HANDSHAKE_START:
    1746         [ -  + ]:         170 :             ereport(DEBUG4,
    1747                 :             :                     (errmsg_internal("SSL: handshake start: \"%s\"", desc)));
    1748                 :         170 :             break;
    1749                 :         138 :         case SSL_CB_HANDSHAKE_DONE:
    1750         [ -  + ]:         138 :             ereport(DEBUG4,
    1751                 :             :                     (errmsg_internal("SSL: handshake done: \"%s\"", desc)));
    1752                 :         138 :             break;
    1753                 :        2778 :         case SSL_CB_ACCEPT_LOOP:
    1754         [ -  + ]:        2778 :             ereport(DEBUG4,
    1755                 :             :                     (errmsg_internal("SSL: accept loop: \"%s\"", desc)));
    1756                 :        2778 :             break;
    1757                 :         608 :         case SSL_CB_ACCEPT_EXIT:
    1758         [ -  + ]:         608 :             ereport(DEBUG4,
    1759                 :             :                     (errmsg_internal("SSL: accept exit (%d): \"%s\"", args, desc)));
    1760                 :         608 :             break;
    1761                 :           0 :         case SSL_CB_CONNECT_LOOP:
    1762         [ #  # ]:           0 :             ereport(DEBUG4,
    1763                 :             :                     (errmsg_internal("SSL: connect loop: \"%s\"", desc)));
    1764                 :           0 :             break;
    1765                 :           0 :         case SSL_CB_CONNECT_EXIT:
    1766         [ #  # ]:           0 :             ereport(DEBUG4,
    1767                 :             :                     (errmsg_internal("SSL: connect exit (%d): \"%s\"", args, desc)));
    1768                 :           0 :             break;
    1769                 :          29 :         case SSL_CB_READ_ALERT:
    1770         [ -  + ]:          29 :             ereport(DEBUG4,
    1771                 :             :                     (errmsg_internal("SSL: read alert (0x%04x): \"%s\"", args, desc)));
    1772                 :          29 :             break;
    1773                 :         158 :         case SSL_CB_WRITE_ALERT:
    1774         [ -  + ]:         158 :             ereport(DEBUG4,
    1775                 :             :                     (errmsg_internal("SSL: write alert (0x%04x): \"%s\"", args, desc)));
    1776                 :         158 :             break;
    1777                 :             :     }
    1778                 :        3881 : }
    1779                 :             : 
    1780                 :             : /* See pqcomm.h comments on OpenSSL implementation of ALPN (RFC 7301) */
    1781                 :             : static const unsigned char alpn_protos[] = PG_ALPN_PROTOCOL_VECTOR;
    1782                 :             : 
    1783                 :             : /*
    1784                 :             :  * Server callback for ALPN negotiation. We use the standard "helper" function
    1785                 :             :  * even though currently we only accept one value.
    1786                 :             :  */
    1787                 :             : static int
    1788                 :         306 : alpn_cb(SSL *ssl,
    1789                 :             :         const unsigned char **out,
    1790                 :             :         unsigned char *outlen,
    1791                 :             :         const unsigned char *in,
    1792                 :             :         unsigned int inlen,
    1793                 :             :         void *userdata)
    1794                 :             : {
    1795                 :             :     /*
    1796                 :             :      * Why does OpenSSL provide a helper function that requires a nonconst
    1797                 :             :      * vector when the callback is declared to take a const vector? What are
    1798                 :             :      * we to do with that?
    1799                 :             :      */
    1800                 :             :     int         retval;
    1801                 :             : 
    1802                 :             :     Assert(userdata != NULL);
    1803                 :             :     Assert(out != NULL);
    1804                 :             :     Assert(outlen != NULL);
    1805                 :             :     Assert(in != NULL);
    1806                 :             : 
    1807                 :         306 :     retval = SSL_select_next_proto((unsigned char **) out, outlen,
    1808                 :             :                                    alpn_protos, sizeof(alpn_protos),
    1809                 :             :                                    in, inlen);
    1810   [ +  -  +  -  :         306 :     if (*out == NULL || *outlen > sizeof(alpn_protos) || *outlen <= 0)
                   -  + ]
    1811                 :           0 :         return SSL_TLSEXT_ERR_NOACK;    /* can't happen */
    1812                 :             : 
    1813         [ +  - ]:         306 :     if (retval == OPENSSL_NPN_NEGOTIATED)
    1814                 :         306 :         return SSL_TLSEXT_ERR_OK;
    1815                 :             :     else
    1816                 :             :     {
    1817                 :             :         /*
    1818                 :             :          * The client doesn't support our protocol.  Reject the connection
    1819                 :             :          * with TLS "no_application_protocol" alert, per RFC 7301.
    1820                 :             :          */
    1821                 :           0 :         return SSL_TLSEXT_ERR_ALERT_FATAL;
    1822                 :             :     }
    1823                 :             : }
    1824                 :             : 
    1825                 :             : #ifdef HAVE_SSL_CTX_SET_CLIENT_HELLO_CB
    1826                 :             : /*
    1827                 :             :  * ssl_update_ssl
    1828                 :             :  *
    1829                 :             :  * Replace certificate/key and CA in an SSL object to match the, via the SNI
    1830                 :             :  * extension, selected host configuration for the connection.  The SSL_CTX
    1831                 :             :  * object to use should be passed in as ctx.  This function will update the
    1832                 :             :  * SSL object in-place.
    1833                 :             :  */
    1834                 :             : static bool
    1835                 :         306 : ssl_update_ssl(SSL *ssl, HostsLine *host_config)
    1836                 :             : {
    1837                 :         306 :     SSL_CTX    *ctx = host_config->ssl_ctx;
    1838                 :             : 
    1839                 :             :     X509       *cert;
    1840                 :             :     EVP_PKEY   *key;
    1841                 :             : 
    1842                 :             :     STACK_OF(X509) * chain;
    1843                 :             : 
    1844                 :             :     Assert(ctx != NULL);
    1845                 :             :     /*-
    1846                 :             :      * Make use of the already-loaded certificate chain and key. At first
    1847                 :             :      * glance, SSL_set_SSL_CTX() looks like the easiest way to do this, but
    1848                 :             :      * beware -- it has very odd behavior:
    1849                 :             :      *
    1850                 :             :      *     https://github.com/openssl/openssl/issues/6109
    1851                 :             :      */
    1852                 :         306 :     cert = SSL_CTX_get0_certificate(ctx);
    1853                 :         306 :     key = SSL_CTX_get0_privatekey(ctx);
    1854                 :             : 
    1855                 :             :     Assert(cert && key);
    1856                 :             : 
    1857         [ +  - ]:         306 :     if (!SSL_CTX_get0_chain_certs(ctx, &chain)
    1858         [ +  - ]:         306 :         || !SSL_use_cert_and_key(ssl, cert, key, chain, 1 /* override */ )
    1859         [ -  + ]:         306 :         || !SSL_check_private_key(ssl))
    1860                 :             :     {
    1861                 :             :         /*
    1862                 :             :          * This shouldn't really be possible, since the inputs came from a
    1863                 :             :          * SSL_CTX that was already populated by OpenSSL.
    1864                 :             :          */
    1865         [ #  # ]:           0 :         ereport(COMMERROR,
    1866                 :             :                 errcode(ERRCODE_INTERNAL_ERROR),
    1867                 :             :                 errmsg_internal("could not update certificate chain: %s",
    1868                 :             :                                 SSLerrmessage(ERR_get_error())));
    1869                 :           0 :         return false;
    1870                 :             :     }
    1871                 :             : 
    1872   [ +  +  +  + ]:         306 :     if (host_config->ssl_ca && host_config->ssl_ca[0])
    1873                 :             :     {
    1874                 :             :         /*
    1875                 :             :          * Copy the trust store and list of roots over from the SSL_CTX.
    1876                 :             :          */
    1877                 :         282 :         X509_STORE *ca_store = SSL_CTX_get_cert_store(ctx);
    1878                 :             : 
    1879                 :             :         STACK_OF(X509_NAME) * roots;
    1880                 :             : 
    1881                 :             :         /*
    1882                 :             :          * The trust store appears to be the only setting that this function
    1883                 :             :          * can't override via the (SSL *) pointer directly. Instead, share it
    1884                 :             :          * with the active SSL_CTX (this should always be SSL_context).
    1885                 :             :          */
    1886                 :             :         Assert(SSL_context == SSL_get_SSL_CTX(ssl));
    1887                 :         282 :         SSL_CTX_set1_cert_store(SSL_context, ca_store);
    1888                 :             : 
    1889                 :             :         /*
    1890                 :             :          * SSL_set_client_CA_list() will take ownership of its argument, so we
    1891                 :             :          * need to duplicate it.
    1892                 :             :          */
    1893         [ +  - ]:         282 :         if ((roots = SSL_CTX_get_client_CA_list(ctx)) == NULL
    1894         [ -  + ]:         282 :             || (roots = SSL_dup_CA_list(roots)) == NULL)
    1895                 :             :         {
    1896         [ #  # ]:           0 :             ereport(COMMERROR,
    1897                 :             :                     errcode(ERRCODE_INTERNAL_ERROR),
    1898                 :             :                     errmsg_internal("could not duplicate SSL_CTX CA list: %s",
    1899                 :             :                                     SSLerrmessage(ERR_get_error())));
    1900                 :           0 :             return false;
    1901                 :             :         }
    1902                 :             : 
    1903                 :         282 :         SSL_set_client_CA_list(ssl, roots);
    1904                 :             : 
    1905                 :             :         /*
    1906                 :             :          * Always ask for SSL client cert, but don't fail if it's not
    1907                 :             :          * presented.  We might fail such connections later, depending on what
    1908                 :             :          * we find in pg_hba.conf.
    1909                 :             :          */
    1910                 :         282 :         SSL_set_verify(ssl,
    1911                 :             :                        (SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE),
    1912                 :             :                        verify_cb);
    1913                 :             : 
    1914                 :         282 :         ssl_loaded_verify_locations = true;
    1915                 :             :     }
    1916                 :             : 
    1917                 :         306 :     return true;
    1918                 :             : }
    1919                 :             : 
    1920                 :             : /*
    1921                 :             :  * sni_clienthello_cb
    1922                 :             :  *
    1923                 :             :  * Callback for extracting the servername extension from the TLS handshake
    1924                 :             :  * during ClientHello.  There is a callback in OpenSSL for the servername
    1925                 :             :  * specifically but OpenSSL themselves advice against using it as it is more
    1926                 :             :  * dependent on ordering for execution.
    1927                 :             :  */
    1928                 :             : static int
    1929                 :         312 : sni_clienthello_cb(SSL *ssl, int *al, void *arg)
    1930                 :             : {
    1931                 :             :     const char *tlsext_hostname;
    1932                 :             :     const unsigned char *tlsext;
    1933                 :             :     size_t      left,
    1934                 :             :                 len;
    1935                 :         312 :     HostsLine  *install_config = NULL;
    1936                 :             : 
    1937         [ +  + ]:         312 :     if (!ssl_sni)
    1938                 :             :     {
    1939                 :         256 :         install_config = SSL_hosts->default_host;
    1940                 :         256 :         goto found;
    1941                 :             :     }
    1942                 :             : 
    1943         [ +  + ]:          56 :     if (SSL_client_hello_get0_ext(ssl, TLSEXT_TYPE_server_name, &tlsext, &left))
    1944                 :             :     {
    1945         [ -  + ]:          53 :         if (left <= 2)
    1946                 :             :         {
    1947                 :           0 :             *al = SSL_AD_DECODE_ERROR;
    1948                 :           0 :             return 0;
    1949                 :             :         }
    1950                 :          53 :         len = (*(tlsext++) << 8);
    1951                 :          53 :         len += *(tlsext)++;
    1952         [ -  + ]:          53 :         if (len + 2 != left)
    1953                 :             :         {
    1954                 :           0 :             *al = SSL_AD_DECODE_ERROR;
    1955                 :           0 :             return 0;
    1956                 :             :         }
    1957                 :             : 
    1958                 :          53 :         left = len;
    1959                 :             : 
    1960   [ +  -  -  + ]:          53 :         if (left == 0 || *tlsext++ != TLSEXT_NAMETYPE_host_name)
    1961                 :             :         {
    1962                 :           0 :             *al = SSL_AD_DECODE_ERROR;
    1963                 :           0 :             return 0;
    1964                 :             :         }
    1965                 :             : 
    1966                 :          53 :         left--;
    1967                 :             : 
    1968                 :             :         /*
    1969                 :             :          * Now we can finally pull out the byte array with the actual
    1970                 :             :          * hostname.
    1971                 :             :          */
    1972         [ -  + ]:          53 :         if (left <= 2)
    1973                 :             :         {
    1974                 :           0 :             *al = SSL_AD_DECODE_ERROR;
    1975                 :           0 :             return 0;
    1976                 :             :         }
    1977                 :          53 :         len = (*(tlsext++) << 8);
    1978                 :          53 :         len += *(tlsext++);
    1979         [ -  + ]:          53 :         if (len + 2 > left)
    1980                 :             :         {
    1981                 :           0 :             *al = SSL_AD_DECODE_ERROR;
    1982                 :           0 :             return 0;
    1983                 :             :         }
    1984                 :          53 :         left = len;
    1985                 :          53 :         tlsext_hostname = (const char *) tlsext;
    1986                 :             : 
    1987                 :             :         /*
    1988                 :             :          * We have a requested hostname from the client, match against all
    1989                 :             :          * entries in the pg_hosts configuration and attempt to find a match.
    1990                 :             :          * Matching is done case insensitive as per RFC 952 and RFC 921.
    1991                 :             :          */
    1992   [ +  +  +  +  :          90 :         foreach_ptr(HostsLine, host, SSL_hosts->sni)
                   +  + ]
    1993                 :             :         {
    1994   [ +  -  +  +  :         120 :             foreach_ptr(char, hostname, host->hostnames)
                   +  + ]
    1995                 :             :             {
    1996   [ +  +  +  + ]:         141 :                 if (strlen(hostname) == len &&
    1997                 :          65 :                     pg_strncasecmp(hostname, tlsext_hostname, len) == 0)
    1998                 :             :                 {
    1999                 :          38 :                     install_config = host;
    2000                 :          38 :                     goto found;
    2001                 :             :                 }
    2002                 :             :             }
    2003                 :             :         }
    2004                 :             : 
    2005                 :             :         /*
    2006                 :             :          * If no host specific match was found, and there is a default config,
    2007                 :             :          * then fall back to using that.
    2008                 :             :          */
    2009   [ +  -  +  + ]:          15 :         if (!install_config && SSL_hosts->default_host)
    2010                 :          10 :             install_config = SSL_hosts->default_host;
    2011                 :             :     }
    2012                 :             : 
    2013                 :             :     /*
    2014                 :             :      * No hostname TLS extension in the handshake, use the default or no_sni
    2015                 :             :      * configurations if available.
    2016                 :             :      */
    2017                 :             :     else
    2018                 :             :     {
    2019                 :           3 :         tlsext_hostname = NULL;
    2020                 :             : 
    2021         [ +  + ]:           3 :         if (SSL_hosts->no_sni)
    2022                 :           2 :             install_config = SSL_hosts->no_sni;
    2023         [ -  + ]:           1 :         else if (SSL_hosts->default_host)
    2024                 :           0 :             install_config = SSL_hosts->default_host;
    2025                 :             :         else
    2026                 :             :         {
    2027                 :             :             /*
    2028                 :             :              * Reaching here means that we didn't get a hostname in the TLS
    2029                 :             :              * extension and the server has been configured to not allow any
    2030                 :             :              * connections without a specified hostname.
    2031                 :             :              *
    2032                 :             :              * The error message for a missing server_name should, according
    2033                 :             :              * to RFC 8446, be missing_extension. This isn't entirely ideal
    2034                 :             :              * since the user won't be able to tell which extension the server
    2035                 :             :              * considered missing.  Sending unrecognized_name would be a more
    2036                 :             :              * helpful error, but for now we stick to the RFC.
    2037                 :             :              */
    2038                 :           1 :             *al = SSL_AD_MISSING_EXTENSION;
    2039                 :             : 
    2040         [ +  - ]:           1 :             ereport(COMMERROR,
    2041                 :             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    2042                 :             :                      errmsg("no hostname provided in callback, and no fallback configured")));
    2043                 :           1 :             return SSL_CLIENT_HELLO_ERROR;
    2044                 :             :         }
    2045                 :             :     }
    2046                 :             : 
    2047                 :             :     /*
    2048                 :             :      * If we reach here without a context chosen as the session context then
    2049                 :             :      * fail the handshake and terminate the connection.
    2050                 :             :      */
    2051         [ +  + ]:          17 :     if (install_config == NULL)
    2052                 :             :     {
    2053         [ +  - ]:           5 :         if (tlsext_hostname)
    2054                 :           5 :             *al = SSL_AD_UNRECOGNIZED_NAME;
    2055                 :             :         else
    2056                 :           0 :             *al = SSL_AD_MISSING_EXTENSION;
    2057                 :           5 :         return SSL_CLIENT_HELLO_ERROR;
    2058                 :             :     }
    2059                 :             : 
    2060                 :          12 : found:
    2061         [ -  + ]:         306 :     if (!ssl_update_ssl(ssl, install_config))
    2062                 :             :     {
    2063                 :           0 :         *al = SSL_AD_INTERNAL_ERROR;
    2064         [ #  # ]:           0 :         ereport(COMMERROR,
    2065                 :             :                 errcode(ERRCODE_PROTOCOL_VIOLATION),
    2066                 :             :                 errmsg("failed to switch to SSL configuration for host, terminating connection"));
    2067                 :           0 :         return SSL_CLIENT_HELLO_ERROR;
    2068                 :             :     }
    2069                 :             : 
    2070                 :         306 :     return SSL_CLIENT_HELLO_SUCCESS;
    2071                 :             : }
    2072                 :             : #endif                          /* HAVE_SSL_CTX_SET_CLIENT_HELLO_CB */
    2073                 :             : 
    2074                 :             : /*
    2075                 :             :  * Set DH parameters for generating ephemeral DH keys.  The
    2076                 :             :  * DH parameters can take a long time to compute, so they must be
    2077                 :             :  * precomputed.
    2078                 :             :  *
    2079                 :             :  * Since few sites will bother to create a parameter file, we also
    2080                 :             :  * provide a fallback to the parameters provided by the OpenSSL
    2081                 :             :  * project.
    2082                 :             :  *
    2083                 :             :  * These values can be static (once loaded or computed) since the
    2084                 :             :  * OpenSSL library can efficiently generate random keys from the
    2085                 :             :  * information provided.
    2086                 :             :  */
    2087                 :             : static bool
    2088                 :          52 : initialize_dh(SSL_CTX *context, bool isServerStart)
    2089                 :             : {
    2090                 :          52 :     DH         *dh = NULL;
    2091                 :             : 
    2092                 :          52 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
    2093                 :             : 
    2094         [ -  + ]:          52 :     if (ssl_dh_params_file[0])
    2095                 :           0 :         dh = load_dh_file(ssl_dh_params_file, isServerStart);
    2096         [ +  - ]:          52 :     if (!dh)
    2097                 :          52 :         dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
    2098         [ -  + ]:          52 :     if (!dh)
    2099                 :             :     {
    2100   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    2101                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    2102                 :             :                  errmsg("DH: could not load DH parameters")));
    2103                 :           0 :         return false;
    2104                 :             :     }
    2105                 :             : 
    2106         [ -  + ]:          52 :     if (SSL_CTX_set_tmp_dh(context, dh) != 1)
    2107                 :             :     {
    2108   [ #  #  #  # ]:           0 :         ereport(isServerStart ? FATAL : LOG,
    2109                 :             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    2110                 :             :                  errmsg("DH: could not set DH parameters: %s",
    2111                 :             :                         SSLerrmessage(ERR_get_error()))));
    2112                 :           0 :         DH_free(dh);
    2113                 :           0 :         return false;
    2114                 :             :     }
    2115                 :             : 
    2116                 :          52 :     DH_free(dh);
    2117                 :          52 :     return true;
    2118                 :             : }
    2119                 :             : 
    2120                 :             : /*
    2121                 :             :  * Set ECDH parameters for generating ephemeral Elliptic Curve DH
    2122                 :             :  * keys.  This is much simpler than the DH parameters, as we just
    2123                 :             :  * need to provide the name of the curve to OpenSSL.
    2124                 :             :  */
    2125                 :             : static bool
    2126                 :          52 : initialize_ecdh(SSL_CTX *context, bool isServerStart)
    2127                 :             : {
    2128         [ +  + ]:          52 :     if (SSL_CTX_set1_groups_list(context, SSLECDHCurve) != 1)
    2129                 :             :     {
    2130                 :             :         /*
    2131                 :             :          * OpenSSL 3.3.0 introduced proper error messages for group parsing
    2132                 :             :          * errors, earlier versions returns "no SSL error reported" which is
    2133                 :             :          * far from helpful. For older versions, we replace with a better
    2134                 :             :          * error message. Injecting the error into the OpenSSL error queue
    2135                 :             :          * need APIs from OpenSSL 3.0.
    2136                 :             :          */
    2137   [ +  -  +  - ]:           2 :         ereport(isServerStart ? FATAL : LOG,
    2138                 :             :                 errcode(ERRCODE_CONFIG_FILE_ERROR),
    2139                 :             :                 errmsg("could not set group names specified in ssl_groups: %s",
    2140                 :             :                        SSLerrmessageExt(ERR_get_error(),
    2141                 :             :                                         _("No valid groups found"))),
    2142                 :             :                 errhint("Ensure that each group name is spelled correctly and supported by the installed version of OpenSSL."));
    2143                 :           0 :         return false;
    2144                 :             :     }
    2145                 :             : 
    2146                 :          50 :     return true;
    2147                 :             : }
    2148                 :             : 
    2149                 :             : /*
    2150                 :             :  * Obtain reason string for passed SSL errcode with replacement
    2151                 :             :  *
    2152                 :             :  * The error message supplied in replacement will be used in case the error
    2153                 :             :  * code from OpenSSL is 0, else the error message from SSLerrmessage() will
    2154                 :             :  * be returned.
    2155                 :             :  *
    2156                 :             :  * Not all versions of OpenSSL place an error on the queue even for failing
    2157                 :             :  * operations, which will yield "no SSL error reported" by SSLerrmessage. This
    2158                 :             :  * function can be used to ensure that a proper error message is displayed for
    2159                 :             :  * versions reporting no error, while using the OpenSSL error via SSLerrmessage
    2160                 :             :  * for versions where there is one.
    2161                 :             :  */
    2162                 :             : static const char *
    2163                 :           2 : SSLerrmessageExt(unsigned long ecode, const char *replacement)
    2164                 :             : {
    2165         [ +  - ]:           2 :     if (ecode == 0)
    2166                 :           2 :         return replacement;
    2167                 :             :     else
    2168                 :           0 :         return SSLerrmessage(ecode);
    2169                 :             : }
    2170                 :             : 
    2171                 :             : /*
    2172                 :             :  * Obtain reason string for passed SSL errcode
    2173                 :             :  *
    2174                 :             :  * ERR_get_error() is used by caller to get errcode to pass here.
    2175                 :             :  *
    2176                 :             :  * Some caution is needed here since ERR_reason_error_string will return NULL
    2177                 :             :  * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code
    2178                 :             :  * represents a system errno value.  We don't want to return NULL ever.
    2179                 :             :  */
    2180                 :             : static const char *
    2181                 :          35 : SSLerrmessage(unsigned long ecode)
    2182                 :             : {
    2183                 :             :     const char *errreason;
    2184                 :             :     static char errbuf[36];
    2185                 :             : 
    2186         [ -  + ]:          35 :     if (ecode == 0)
    2187                 :           0 :         return _("no SSL error reported");
    2188                 :          35 :     errreason = ERR_reason_error_string(ecode);
    2189         [ +  - ]:          35 :     if (errreason != NULL)
    2190                 :          35 :         return errreason;
    2191                 :             : 
    2192                 :             :     /*
    2193                 :             :      * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
    2194                 :             :      * errno values anymore.  (See OpenSSL source code for the explanation.)
    2195                 :             :      * We can cover that shortcoming with this bit of code.  Older OpenSSL
    2196                 :             :      * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
    2197                 :             :      * they don't have the shortcoming either.
    2198                 :             :      */
    2199                 :             : #ifdef ERR_SYSTEM_ERROR
    2200         [ #  # ]:           0 :     if (ERR_SYSTEM_ERROR(ecode))
    2201                 :           0 :         return strerror(ERR_GET_REASON(ecode));
    2202                 :             : #endif
    2203                 :             : 
    2204                 :             :     /* No choice but to report the numeric ecode */
    2205                 :           0 :     snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
    2206                 :           0 :     return errbuf;
    2207                 :             : }
    2208                 :             : 
    2209                 :             : int
    2210                 :         220 : be_tls_get_cipher_bits(Port *port)
    2211                 :             : {
    2212                 :             :     int         bits;
    2213                 :             : 
    2214         [ +  - ]:         220 :     if (port->ssl)
    2215                 :             :     {
    2216                 :         220 :         SSL_get_cipher_bits(port->ssl, &bits);
    2217                 :         220 :         return bits;
    2218                 :             :     }
    2219                 :             :     else
    2220                 :           0 :         return 0;
    2221                 :             : }
    2222                 :             : 
    2223                 :             : const char *
    2224                 :         221 : be_tls_get_version(Port *port)
    2225                 :             : {
    2226         [ +  - ]:         221 :     if (port->ssl)
    2227                 :         221 :         return SSL_get_version(port->ssl);
    2228                 :             :     else
    2229                 :           0 :         return NULL;
    2230                 :             : }
    2231                 :             : 
    2232                 :             : const char *
    2233                 :         221 : be_tls_get_cipher(Port *port)
    2234                 :             : {
    2235         [ +  - ]:         221 :     if (port->ssl)
    2236                 :         221 :         return SSL_get_cipher(port->ssl);
    2237                 :             :     else
    2238                 :           0 :         return NULL;
    2239                 :             : }
    2240                 :             : 
    2241                 :             : void
    2242                 :         110 : be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
    2243                 :             : {
    2244         [ +  + ]:         110 :     if (port->peer)
    2245                 :          29 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
    2246                 :             :     else
    2247                 :          81 :         ptr[0] = '\0';
    2248                 :         110 : }
    2249                 :             : 
    2250                 :             : void
    2251                 :         111 : be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
    2252                 :             : {
    2253         [ +  + ]:         111 :     if (port->peer)
    2254                 :          30 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
    2255                 :             :     else
    2256                 :          81 :         ptr[0] = '\0';
    2257                 :         111 : }
    2258                 :             : 
    2259                 :             : void
    2260                 :         111 : be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
    2261                 :             : {
    2262         [ +  + ]:         111 :     if (port->peer)
    2263                 :             :     {
    2264                 :             :         ASN1_INTEGER *serial;
    2265                 :             :         BIGNUM     *b;
    2266                 :             :         char       *decimal;
    2267                 :             : 
    2268                 :          30 :         serial = X509_get_serialNumber(port->peer);
    2269                 :          30 :         b = ASN1_INTEGER_to_BN(serial, NULL);
    2270                 :          30 :         decimal = BN_bn2dec(b);
    2271                 :             : 
    2272                 :          30 :         BN_free(b);
    2273                 :          30 :         strlcpy(ptr, decimal, len);
    2274                 :          30 :         OPENSSL_free(decimal);
    2275                 :             :     }
    2276                 :             :     else
    2277                 :          81 :         ptr[0] = '\0';
    2278                 :         111 : }
    2279                 :             : 
    2280                 :             : char *
    2281                 :           5 : be_tls_get_certificate_hash(Port *port, size_t *len)
    2282                 :             : {
    2283                 :             :     X509       *server_cert;
    2284                 :             :     char       *cert_hash;
    2285                 :             : #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    2286                 :             :     EVP_MD     *algo_type;
    2287                 :             :     const char *algo_name;
    2288                 :             : #else
    2289                 :             :     const EVP_MD *algo_type = NULL;
    2290                 :             : #endif
    2291                 :             :     unsigned char hash[EVP_MAX_MD_SIZE];    /* size for SHA-512 */
    2292                 :             :     unsigned int hash_size;
    2293                 :             :     int         algo_nid;
    2294                 :             : 
    2295                 :           5 :     *len = 0;
    2296                 :           5 :     server_cert = SSL_get_certificate(port->ssl);
    2297         [ -  + ]:           5 :     if (server_cert == NULL)
    2298                 :           0 :         return NULL;
    2299                 :             : 
    2300                 :             :     /*
    2301                 :             :      * Get the signature algorithm of the certificate to determine the hash
    2302                 :             :      * algorithm to use for the result.  Prefer X509_get_signature_info(),
    2303                 :             :      * introduced in OpenSSL 1.1.1, which can handle RSA-PSS signatures.
    2304                 :             :      */
    2305                 :             : #if HAVE_X509_GET_SIGNATURE_INFO
    2306         [ -  + ]:           5 :     if (!X509_get_signature_info(server_cert, &algo_nid, NULL, NULL, NULL))
    2307                 :             : #else
    2308                 :             :     if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
    2309                 :             :                              &algo_nid, NULL))
    2310                 :             : #endif
    2311         [ #  # ]:           0 :         elog(ERROR, "could not determine server certificate signature algorithm");
    2312                 :             : 
    2313                 :             :     /*
    2314                 :             :      * The TLS server's certificate bytes need to be hashed with SHA-256 if
    2315                 :             :      * its signature algorithm is MD5 or SHA-1 as per RFC 5929
    2316                 :             :      * (https://tools.ietf.org/html/rfc5929#section-4.1).  If something else
    2317                 :             :      * is used, the same hash as the signature algorithm is used.
    2318                 :             :      */
    2319                 :             : #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    2320         [ -  + ]:           5 :     switch (algo_nid)
    2321                 :             :     {
    2322                 :           0 :         case NID_md5:
    2323                 :             :         case NID_sha1:
    2324                 :           0 :             algo_name = "SHA256";
    2325                 :           0 :             break;
    2326                 :           5 :         default:
    2327                 :           5 :             algo_name = OBJ_nid2sn(algo_nid);
    2328         [ -  + ]:           5 :             if (algo_name == NULL)
    2329         [ #  # ]:           0 :                 elog(ERROR, "could not find digest for NID %d",
    2330                 :             :                      algo_nid);
    2331                 :           5 :             break;
    2332                 :             :     }
    2333                 :             : 
    2334                 :           5 :     algo_type = EVP_MD_fetch(NULL, algo_name, NULL);
    2335         [ -  + ]:           5 :     if (algo_type == NULL)
    2336         [ #  # ]:           0 :         elog(ERROR, "could not fetch digest \"%s\"", algo_name);
    2337                 :             : #else
    2338                 :             :     switch (algo_nid)
    2339                 :             :     {
    2340                 :             :         case NID_md5:
    2341                 :             :         case NID_sha1:
    2342                 :             :             algo_type = EVP_sha256();
    2343                 :             :             break;
    2344                 :             :         default:
    2345                 :             :             algo_type = EVP_get_digestbynid(algo_nid);
    2346                 :             :             if (algo_type == NULL)
    2347                 :             :                 elog(ERROR, "could not find digest for NID %s",
    2348                 :             :                      OBJ_nid2sn(algo_nid));
    2349                 :             :             break;
    2350                 :             :     }
    2351                 :             : #endif
    2352                 :             : 
    2353                 :             :     /* generate and save the certificate hash */
    2354         [ -  + ]:           5 :     if (!X509_digest(server_cert, algo_type, hash, &hash_size))
    2355                 :             :     {
    2356                 :             : #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    2357                 :           0 :         EVP_MD_free(algo_type);
    2358                 :             : #endif
    2359         [ #  # ]:           0 :         elog(ERROR, "could not generate server certificate hash");
    2360                 :             :     }
    2361                 :             : 
    2362                 :             : #if OPENSSL_VERSION_NUMBER >= 0x30000000L
    2363                 :           5 :     EVP_MD_free(algo_type);
    2364                 :             : #endif
    2365                 :             : 
    2366                 :           5 :     cert_hash = palloc(hash_size);
    2367                 :           5 :     memcpy(cert_hash, hash, hash_size);
    2368                 :           5 :     *len = hash_size;
    2369                 :             : 
    2370                 :           5 :     return cert_hash;
    2371                 :             : }
    2372                 :             : 
    2373                 :             : /*
    2374                 :             :  * Convert an X509 subject name to a cstring.
    2375                 :             :  *
    2376                 :             :  */
    2377                 :             : static char *
    2378                 :          77 : X509_NAME_to_cstring(const X509_NAME *name)
    2379                 :             : {
    2380                 :          77 :     BIO        *membuf = BIO_new(BIO_s_mem());
    2381                 :             :     int         i,
    2382                 :             :                 nid,
    2383                 :          77 :                 count = X509_NAME_entry_count(name);
    2384                 :             :     const X509_NAME_ENTRY *e;
    2385                 :             :     const ASN1_STRING *v;
    2386                 :             :     const char *field_name;
    2387                 :             :     size_t      size;
    2388                 :             :     char        nullterm;
    2389                 :             :     char       *sp;
    2390                 :             :     char       *dp;
    2391                 :             :     char       *result;
    2392                 :             : 
    2393         [ -  + ]:          77 :     if (membuf == NULL)
    2394         [ #  # ]:           0 :         ereport(ERROR,
    2395                 :             :                 (errcode(ERRCODE_OUT_OF_MEMORY),
    2396                 :             :                  errmsg("could not create BIO")));
    2397                 :             : 
    2398                 :          77 :     (void) BIO_set_close(membuf, BIO_CLOSE);
    2399         [ +  + ]:         165 :     for (i = 0; i < count; i++)
    2400                 :             :     {
    2401                 :          88 :         e = X509_NAME_get_entry(name, i);
    2402                 :          88 :         nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
    2403         [ -  + ]:          88 :         if (nid == NID_undef)
    2404         [ #  # ]:           0 :             ereport(ERROR,
    2405                 :             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2406                 :             :                      errmsg("could not get NID for ASN1_OBJECT object")));
    2407                 :          88 :         v = X509_NAME_ENTRY_get_data(e);
    2408                 :          88 :         field_name = OBJ_nid2sn(nid);
    2409         [ -  + ]:          88 :         if (field_name == NULL)
    2410                 :           0 :             field_name = OBJ_nid2ln(nid);
    2411         [ -  + ]:          88 :         if (field_name == NULL)
    2412         [ #  # ]:           0 :             ereport(ERROR,
    2413                 :             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    2414                 :             :                      errmsg("could not convert NID %d to an ASN1_OBJECT structure", nid)));
    2415                 :          88 :         BIO_printf(membuf, "/%s=", field_name);
    2416                 :          88 :         ASN1_STRING_print_ex(membuf, v,
    2417                 :             :                              ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
    2418                 :             :                               | ASN1_STRFLGS_UTF8_CONVERT));
    2419                 :             :     }
    2420                 :             : 
    2421                 :             :     /* ensure null termination of the BIO's content */
    2422                 :          77 :     nullterm = '\0';
    2423                 :          77 :     BIO_write(membuf, &nullterm, 1);
    2424                 :          77 :     size = BIO_get_mem_data(membuf, &sp);
    2425                 :          77 :     dp = pg_any_to_server(sp, size - 1, PG_UTF8);
    2426                 :             : 
    2427                 :          77 :     result = pstrdup(dp);
    2428         [ -  + ]:          77 :     if (dp != sp)
    2429                 :           0 :         pfree(dp);
    2430         [ -  + ]:          77 :     if (BIO_free(membuf) != 1)
    2431         [ #  # ]:           0 :         elog(ERROR, "could not free OpenSSL BIO structure");
    2432                 :             : 
    2433                 :          77 :     return result;
    2434                 :             : }
    2435                 :             : 
    2436                 :             : /*
    2437                 :             :  * Convert TLS protocol version GUC enum to OpenSSL values
    2438                 :             :  *
    2439                 :             :  * This is a straightforward one-to-one mapping, but doing it this way makes
    2440                 :             :  * the definitions of ssl_min_protocol_version and ssl_max_protocol_version
    2441                 :             :  * independent of OpenSSL availability and version.
    2442                 :             :  *
    2443                 :             :  * If a version is passed that is not supported by the current OpenSSL
    2444                 :             :  * version, then we return -1.  If a nonnegative value is returned,
    2445                 :             :  * subsequent code can assume it's working with a supported version.
    2446                 :             :  *
    2447                 :             :  * Note: this is rather similar to libpq's routine in fe-secure-openssl.c,
    2448                 :             :  * so make sure to update both routines if changing this one.
    2449                 :             :  */
    2450                 :             : static int
    2451                 :          54 : ssl_protocol_version_to_openssl(int v)
    2452                 :             : {
    2453   [ -  -  +  +  :          54 :     switch (v)
                   -  - ]
    2454                 :             :     {
    2455                 :           0 :         case PG_TLS_ANY:
    2456                 :           0 :             return 0;
    2457                 :           0 :         case PG_TLS1_VERSION:
    2458                 :             : #ifndef OPENSSL_NO_TLS1
    2459                 :           0 :             return TLS1_VERSION;
    2460                 :             : #else
    2461                 :             :             break;
    2462                 :             : #endif
    2463                 :           1 :         case PG_TLS1_1_VERSION:
    2464                 :             : #ifndef OPENSSL_NO_TLS1_1
    2465                 :           1 :             return TLS1_1_VERSION;
    2466                 :             : #else
    2467                 :             :             break;
    2468                 :             : #endif
    2469                 :          53 :         case PG_TLS1_2_VERSION:
    2470                 :             : #ifndef OPENSSL_NO_TLS1_2
    2471                 :          53 :             return TLS1_2_VERSION;
    2472                 :             : #else
    2473                 :             :             break;
    2474                 :             : #endif
    2475                 :           0 :         case PG_TLS1_3_VERSION:
    2476                 :             : #ifndef OPENSSL_NO_TLS1_3
    2477                 :           0 :             return TLS1_3_VERSION;
    2478                 :             : #else
    2479                 :             :             break;
    2480                 :             : #endif
    2481                 :             :     }
    2482                 :             : 
    2483                 :           0 :     return -1;
    2484                 :             : }
    2485                 :             : 
    2486                 :             : /*
    2487                 :             :  * Likewise provide a mapping to strings.
    2488                 :             :  */
    2489                 :             : static const char *
    2490                 :           0 : ssl_protocol_version_to_string(int v)
    2491                 :             : {
    2492   [ #  #  #  #  :           0 :     switch (v)
                   #  # ]
    2493                 :             :     {
    2494                 :           0 :         case PG_TLS_ANY:
    2495                 :           0 :             return "any";
    2496                 :           0 :         case PG_TLS1_VERSION:
    2497                 :           0 :             return "TLSv1";
    2498                 :           0 :         case PG_TLS1_1_VERSION:
    2499                 :           0 :             return "TLSv1.1";
    2500                 :           0 :         case PG_TLS1_2_VERSION:
    2501                 :           0 :             return "TLSv1.2";
    2502                 :           0 :         case PG_TLS1_3_VERSION:
    2503                 :           0 :             return "TLSv1.3";
    2504                 :             :     }
    2505                 :             : 
    2506                 :           0 :     return "(unrecognized)";
    2507                 :             : }
    2508                 :             : 
    2509                 :             : static uint32
    2510                 :          29 : host_cache_pointer(const char *key)
    2511                 :             : {
    2512                 :             :     uint32      hash;
    2513                 :          29 :     char       *lkey = pstrdup(key);
    2514                 :          29 :     int         len = strlen(key);
    2515                 :             : 
    2516         [ +  + ]:         336 :     for (int i = 0; i < len; i++)
    2517                 :         307 :         lkey[i] = pg_tolower(lkey[i]);
    2518                 :             : 
    2519                 :          29 :     hash = string_hash((const void *) lkey, len);
    2520                 :          29 :     pfree(lkey);
    2521                 :          29 :     return hash;
    2522                 :             : }
    2523                 :             : 
    2524                 :             : static void
    2525                 :          37 : default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
    2526                 :             : {
    2527         [ +  + ]:          37 :     if (isServerStart)
    2528                 :             :     {
    2529         [ +  + ]:          33 :         if (ssl_passphrase_command[0])
    2530                 :             :         {
    2531                 :           7 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    2532                 :           7 :             SSL_CTX_set_default_passwd_cb_userdata(context, ssl_passphrase_command);
    2533                 :             :         }
    2534                 :             :     }
    2535                 :             :     else
    2536                 :             :     {
    2537   [ +  +  +  + ]:           4 :         if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
    2538                 :             :         {
    2539                 :           1 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    2540                 :           1 :             SSL_CTX_set_default_passwd_cb_userdata(context, ssl_passphrase_command);
    2541                 :             :         }
    2542                 :             :         else
    2543                 :             : 
    2544                 :             :             /*
    2545                 :             :              * If reloading and no external command is configured, override
    2546                 :             :              * OpenSSL's default handling of passphrase-protected files,
    2547                 :             :              * because we don't want to prompt for a passphrase in an
    2548                 :             :              * already-running server.
    2549                 :             :              */
    2550                 :           3 :             SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
    2551                 :             :     }
    2552                 :          37 : }
        

Generated by: LCOV version 2.0-1