LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 396 623 63.6 %
Date: 2024-07-27 00:11:07 Functions: 29 32 90.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14