LCOV - differential code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Coverage Total Hit UNC UBC GNC CBC EUB ECB DUB DCB
Current: c38de3ae6098ccf1904109f2e550eb4777f66024 vs e352ac8c5c90ed6ce792f044c22145578542a330 Lines: 71.0 % 853 606 6 241 27 579 4 6 2 15
Current Date: 2026-11-05 14:14:01 +0100 Functions: 94.9 % 39 37 2 8 29 1
Baseline: lcov-20261105-baseline Branches: 47.8 % 719 344 8 367 12 332 4 2
Baseline Date: 2026-11-05 14:14:01 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 73.1 % 26 19 7 2 17
(30,360] days: 86.3 % 248 214 6 28 25 189
(360..) days: 64.4 % 579 373 206 373 4 6
Function coverage date bins:
(30,360] days: 100.0 % 6 6 1 5
(360..) days: 93.9 % 33 31 2 7 24
Branch coverage date bins:
(7,30] days: 57.7 % 26 15 11 2 13
(30,360] days: 68.0 % 244 166 8 70 10 156
(360..) days: 35.8 % 455 163 286 163 4 2

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

Generated by: LCOV version 2.0-1