LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 718 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 34 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 714 0

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

Generated by: LCOV version 2.3.2-1