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

Generated by: LCOV version 1.14