LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 14devel Lines: 314 521 60.3 %
Date: 2020-08-05 07:06:24 Functions: 28 31 90.3 %
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-2020, 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             : #ifdef HAVE_NETINET_TCP_H
      28             : #include <netinet/tcp.h>
      29             : #include <arpa/inet.h>
      30             : #endif
      31             : 
      32             : #include <openssl/ssl.h>
      33             : #include <openssl/dh.h>
      34             : #include <openssl/conf.h>
      35             : #ifndef OPENSSL_NO_ECDH
      36             : #include <openssl/ec.h>
      37             : #endif
      38             : 
      39             : #include "common/openssl.h"
      40             : #include "libpq/libpq.h"
      41             : #include "miscadmin.h"
      42             : #include "pgstat.h"
      43             : #include "storage/fd.h"
      44             : #include "storage/latch.h"
      45             : #include "tcop/tcopprot.h"
      46             : #include "utils/memutils.h"
      47             : 
      48             : /* default init hook can be overridden by a shared library */
      49             : static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart);
      50             : openssl_tls_init_hook_typ openssl_tls_init_hook = default_openssl_tls_init;
      51             : 
      52             : static int  my_sock_read(BIO *h, char *buf, int size);
      53             : static int  my_sock_write(BIO *h, const char *buf, int size);
      54             : static BIO_METHOD *my_BIO_s_socket(void);
      55             : static int  my_SSL_set_fd(Port *port, int fd);
      56             : 
      57             : static DH  *load_dh_file(char *filename, bool isServerStart);
      58             : static DH  *load_dh_buffer(const char *, size_t);
      59             : static int  ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      60             : static int  dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      61             : static int  verify_cb(int, X509_STORE_CTX *);
      62             : static void info_cb(const SSL *ssl, int type, int args);
      63             : static bool initialize_dh(SSL_CTX *context, bool isServerStart);
      64             : static bool initialize_ecdh(SSL_CTX *context, bool isServerStart);
      65             : static const char *SSLerrmessage(unsigned long ecode);
      66             : 
      67             : static char *X509_NAME_to_cstring(X509_NAME *name);
      68             : 
      69             : static SSL_CTX *SSL_context = NULL;
      70             : static bool SSL_initialized = false;
      71             : static bool dummy_ssl_passwd_cb_called = false;
      72             : static bool ssl_is_server_start;
      73             : 
      74             : static int  ssl_protocol_version_to_openssl(int v);
      75             : static const char *ssl_protocol_version_to_string(int v);
      76             : 
      77             : /* ------------------------------------------------------------ */
      78             : /*                       Public interface                       */
      79             : /* ------------------------------------------------------------ */
      80             : 
      81             : int
      82          30 : be_tls_init(bool isServerStart)
      83             : {
      84          30 :     STACK_OF(X509_NAME) * root_cert_list = NULL;
      85             :     SSL_CTX    *context;
      86          30 :     int         ssl_ver_min = -1;
      87          30 :     int         ssl_ver_max = -1;
      88             : 
      89             :     /* This stuff need be done only once. */
      90          30 :     if (!SSL_initialized)
      91             :     {
      92             : #ifdef HAVE_OPENSSL_INIT_SSL
      93          30 :         OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
      94             : #else
      95             :         OPENSSL_config(NULL);
      96             :         SSL_library_init();
      97             :         SSL_load_error_strings();
      98             : #endif
      99          30 :         SSL_initialized = true;
     100             :     }
     101             : 
     102             :     /*
     103             :      * We use SSLv23_method() because it can negotiate use of the highest
     104             :      * mutually supported protocol version, while alternatives like
     105             :      * TLSv1_2_method() permit only one specific version.  Note that we don't
     106             :      * actually allow SSL v2 or v3, only TLS protocols (see below).
     107             :      */
     108          30 :     context = SSL_CTX_new(SSLv23_method());
     109          30 :     if (!context)
     110             :     {
     111           0 :         ereport(isServerStart ? FATAL : LOG,
     112             :                 (errmsg("could not create SSL context: %s",
     113             :                         SSLerrmessage(ERR_get_error()))));
     114           0 :         goto error;
     115             :     }
     116             : 
     117             :     /*
     118             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     119             :      * unnecessary failures in nonblocking send cases.
     120             :      */
     121          30 :     SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     122             : 
     123             :     /*
     124             :      * Call init hook (usually to set password callback)
     125             :      */
     126          30 :     (*openssl_tls_init_hook) (context, isServerStart);
     127             : 
     128             :     /* used by the callback */
     129          30 :     ssl_is_server_start = isServerStart;
     130             : 
     131             :     /*
     132             :      * Load and verify server's certificate and private key
     133             :      */
     134          30 :     if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
     135             :     {
     136           0 :         ereport(isServerStart ? FATAL : LOG,
     137             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     138             :                  errmsg("could not load server certificate file \"%s\": %s",
     139             :                         ssl_cert_file, SSLerrmessage(ERR_get_error()))));
     140           0 :         goto error;
     141             :     }
     142             : 
     143          30 :     if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
     144           0 :         goto error;
     145             : 
     146             :     /*
     147             :      * OK, try to load the private key file.
     148             :      */
     149          30 :     dummy_ssl_passwd_cb_called = false;
     150             : 
     151          30 :     if (SSL_CTX_use_PrivateKey_file(context,
     152             :                                     ssl_key_file,
     153             :                                     SSL_FILETYPE_PEM) != 1)
     154             :     {
     155           4 :         if (dummy_ssl_passwd_cb_called)
     156           0 :             ereport(isServerStart ? FATAL : LOG,
     157             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     158             :                      errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
     159             :                             ssl_key_file)));
     160             :         else
     161           4 :             ereport(isServerStart ? FATAL : LOG,
     162             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     163             :                      errmsg("could not load private key file \"%s\": %s",
     164             :                             ssl_key_file, SSLerrmessage(ERR_get_error()))));
     165           0 :         goto error;
     166             :     }
     167             : 
     168          26 :     if (SSL_CTX_check_private_key(context) != 1)
     169             :     {
     170           0 :         ereport(isServerStart ? FATAL : LOG,
     171             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     172             :                  errmsg("check of private key failed: %s",
     173             :                         SSLerrmessage(ERR_get_error()))));
     174           0 :         goto error;
     175             :     }
     176             : 
     177          26 :     if (ssl_min_protocol_version)
     178             :     {
     179          26 :         ssl_ver_min = ssl_protocol_version_to_openssl(ssl_min_protocol_version);
     180             : 
     181          26 :         if (ssl_ver_min == -1)
     182             :         {
     183           0 :             ereport(isServerStart ? FATAL : LOG,
     184             :                     (errmsg("\"%s\" setting \"%s\" not supported by this build",
     185             :                             "ssl_min_protocol_version",
     186             :                             GetConfigOption("ssl_min_protocol_version",
     187             :                                             false, false))));
     188           0 :             goto error;
     189             :         }
     190             : 
     191          26 :         if (!SSL_CTX_set_min_proto_version(context, ssl_ver_min))
     192             :         {
     193           0 :             ereport(isServerStart ? FATAL : LOG,
     194             :                     (errmsg("could not set minimum SSL protocol version")));
     195           0 :             goto error;
     196             :         }
     197             :     }
     198             : 
     199          26 :     if (ssl_max_protocol_version)
     200             :     {
     201           2 :         ssl_ver_max = ssl_protocol_version_to_openssl(ssl_max_protocol_version);
     202             : 
     203           2 :         if (ssl_ver_max == -1)
     204             :         {
     205           0 :             ereport(isServerStart ? FATAL : LOG,
     206             :                     (errmsg("\"%s\" setting \"%s\" not supported by this build",
     207             :                             "ssl_max_protocol_version",
     208             :                             GetConfigOption("ssl_max_protocol_version",
     209             :                                             false, false))));
     210           0 :             goto error;
     211             :         }
     212             : 
     213           2 :         if (!SSL_CTX_set_max_proto_version(context, ssl_ver_max))
     214             :         {
     215           0 :             ereport(isServerStart ? FATAL : LOG,
     216             :                     (errmsg("could not set maximum SSL protocol version")));
     217           0 :             goto error;
     218             :         }
     219             :     }
     220             : 
     221             :     /* Check compatibility of min/max protocols */
     222          26 :     if (ssl_min_protocol_version &&
     223             :         ssl_max_protocol_version)
     224             :     {
     225             :         /*
     226             :          * No need to check for invalid values (-1) for each protocol number
     227             :          * as the code above would have already generated an error.
     228             :          */
     229           2 :         if (ssl_ver_min > ssl_ver_max)
     230             :         {
     231           2 :             ereport(isServerStart ? FATAL : LOG,
     232             :                     (errmsg("could not set SSL protocol version range"),
     233             :                      errdetail("\"%s\" cannot be higher than \"%s\"",
     234             :                                "ssl_min_protocol_version",
     235             :                                "ssl_max_protocol_version")));
     236           0 :             goto error;
     237             :         }
     238             :     }
     239             : 
     240             :     /* disallow SSL session tickets */
     241          24 :     SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
     242             : 
     243             :     /* disallow SSL session caching, too */
     244          24 :     SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
     245             : 
     246             :     /* set up ephemeral DH and ECDH keys */
     247          24 :     if (!initialize_dh(context, isServerStart))
     248           0 :         goto error;
     249          24 :     if (!initialize_ecdh(context, isServerStart))
     250           0 :         goto error;
     251             : 
     252             :     /* set up the allowed cipher list */
     253          24 :     if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
     254             :     {
     255           0 :         ereport(isServerStart ? FATAL : LOG,
     256             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     257             :                  errmsg("could not set the cipher list (no valid ciphers available)")));
     258           0 :         goto error;
     259             :     }
     260             : 
     261             :     /* Let server choose order */
     262          24 :     if (SSLPreferServerCiphers)
     263          24 :         SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
     264             : 
     265             :     /*
     266             :      * Load CA store, so we can verify client certificates if needed.
     267             :      */
     268          24 :     if (ssl_ca_file[0])
     269             :     {
     270          32 :         if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
     271          16 :             (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
     272             :         {
     273           0 :             ereport(isServerStart ? FATAL : LOG,
     274             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     275             :                      errmsg("could not load root certificate file \"%s\": %s",
     276             :                             ssl_ca_file, SSLerrmessage(ERR_get_error()))));
     277           0 :             goto error;
     278             :         }
     279             :     }
     280             : 
     281             :     /*----------
     282             :      * Load the Certificate Revocation List (CRL).
     283             :      * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
     284             :      *----------
     285             :      */
     286          24 :     if (ssl_crl_file[0])
     287             :     {
     288          16 :         X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
     289             : 
     290          16 :         if (cvstore)
     291             :         {
     292             :             /* Set the flags to check against the complete CRL chain */
     293          16 :             if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
     294             :             {
     295          16 :                 X509_STORE_set_flags(cvstore,
     296             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     297             :             }
     298             :             else
     299             :             {
     300           0 :                 ereport(isServerStart ? FATAL : LOG,
     301             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     302             :                          errmsg("could not load SSL certificate revocation list file \"%s\": %s",
     303             :                                 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
     304           0 :                 goto error;
     305             :             }
     306             :         }
     307             :     }
     308             : 
     309          24 :     if (ssl_ca_file[0])
     310             :     {
     311             :         /*
     312             :          * Always ask for SSL client cert, but don't fail if it's not
     313             :          * presented.  We might fail such connections later, depending on what
     314             :          * we find in pg_hba.conf.
     315             :          */
     316          16 :         SSL_CTX_set_verify(context,
     317             :                            (SSL_VERIFY_PEER |
     318             :                             SSL_VERIFY_CLIENT_ONCE),
     319             :                            verify_cb);
     320             : 
     321             :         /*
     322             :          * Tell OpenSSL to send the list of root certs we trust to clients in
     323             :          * CertificateRequests.  This lets a client with a keystore select the
     324             :          * appropriate client certificate to send to us.
     325             :          */
     326          16 :         SSL_CTX_set_client_CA_list(context, root_cert_list);
     327             :     }
     328             : 
     329             :     /*
     330             :      * Success!  Replace any existing SSL_context.
     331             :      */
     332          24 :     if (SSL_context)
     333           0 :         SSL_CTX_free(SSL_context);
     334             : 
     335          24 :     SSL_context = context;
     336             : 
     337             :     /*
     338             :      * Set flag to remember whether CA store has been loaded into SSL_context.
     339             :      */
     340          24 :     if (ssl_ca_file[0])
     341          16 :         ssl_loaded_verify_locations = true;
     342             :     else
     343           8 :         ssl_loaded_verify_locations = false;
     344             : 
     345          24 :     return 0;
     346             : 
     347           0 : error:
     348           0 :     if (context)
     349           0 :         SSL_CTX_free(context);
     350           0 :     return -1;
     351             : }
     352             : 
     353             : void
     354          78 : be_tls_destroy(void)
     355             : {
     356          78 :     if (SSL_context)
     357           0 :         SSL_CTX_free(SSL_context);
     358          78 :     SSL_context = NULL;
     359          78 :     ssl_loaded_verify_locations = false;
     360          78 : }
     361             : 
     362             : int
     363          96 : be_tls_open_server(Port *port)
     364             : {
     365             :     int         r;
     366             :     int         err;
     367             :     int         waitfor;
     368             :     unsigned long ecode;
     369             :     bool        give_proto_hint;
     370             : 
     371             :     Assert(!port->ssl);
     372             :     Assert(!port->peer);
     373             : 
     374          96 :     if (!SSL_context)
     375             :     {
     376           0 :         ereport(COMMERROR,
     377             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     378             :                  errmsg("could not initialize SSL connection: SSL context not set up")));
     379           0 :         return -1;
     380             :     }
     381             : 
     382          96 :     if (!(port->ssl = SSL_new(SSL_context)))
     383             :     {
     384           0 :         ereport(COMMERROR,
     385             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     386             :                  errmsg("could not initialize SSL connection: %s",
     387             :                         SSLerrmessage(ERR_get_error()))));
     388           0 :         return -1;
     389             :     }
     390          96 :     if (!my_SSL_set_fd(port, port->sock))
     391             :     {
     392           0 :         ereport(COMMERROR,
     393             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     394             :                  errmsg("could not set SSL socket: %s",
     395             :                         SSLerrmessage(ERR_get_error()))));
     396           0 :         return -1;
     397             :     }
     398          96 :     port->ssl_in_use = true;
     399             : 
     400         198 : aloop:
     401             : 
     402             :     /*
     403             :      * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
     404             :      * queue.  In general, the current thread's error queue must be empty
     405             :      * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
     406             :      * not work reliably.  An extension may have failed to clear the
     407             :      * per-thread error queue following another call to an OpenSSL I/O
     408             :      * routine.
     409             :      */
     410         198 :     ERR_clear_error();
     411         198 :     r = SSL_accept(port->ssl);
     412         198 :     if (r <= 0)
     413             :     {
     414         124 :         err = SSL_get_error(port->ssl, r);
     415             : 
     416             :         /*
     417             :          * Other clients of OpenSSL in the backend may fail to call
     418             :          * ERR_get_error(), but we always do, so as to not cause problems for
     419             :          * OpenSSL clients that don't call ERR_clear_error() defensively.  Be
     420             :          * sure that this happens by calling now. SSL_get_error() relies on
     421             :          * the OpenSSL per-thread error queue being intact, so this is the
     422             :          * earliest possible point ERR_get_error() may be called.
     423             :          */
     424         124 :         ecode = ERR_get_error();
     425         124 :         switch (err)
     426             :         {
     427         102 :             case SSL_ERROR_WANT_READ:
     428             :             case SSL_ERROR_WANT_WRITE:
     429             :                 /* not allowed during connection establishment */
     430             :                 Assert(!port->noblock);
     431             : 
     432             :                 /*
     433             :                  * No need to care about timeouts/interrupts here. At this
     434             :                  * point authentication_timeout still employs
     435             :                  * StartupPacketTimeoutHandler() which directly exits.
     436             :                  */
     437         102 :                 if (err == SSL_ERROR_WANT_READ)
     438         102 :                     waitfor = WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH;
     439             :                 else
     440           0 :                     waitfor = WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH;
     441             : 
     442         102 :                 (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
     443             :                                          WAIT_EVENT_SSL_OPEN_SERVER);
     444         102 :                 goto aloop;
     445           8 :             case SSL_ERROR_SYSCALL:
     446           8 :                 if (r < 0)
     447           8 :                     ereport(COMMERROR,
     448             :                             (errcode_for_socket_access(),
     449             :                              errmsg("could not accept SSL connection: %m")));
     450             :                 else
     451           0 :                     ereport(COMMERROR,
     452             :                             (errcode(ERRCODE_PROTOCOL_VIOLATION),
     453             :                              errmsg("could not accept SSL connection: EOF detected")));
     454           8 :                 break;
     455          14 :             case SSL_ERROR_SSL:
     456          14 :                 switch (ERR_GET_REASON(ecode))
     457             :                 {
     458             :                         /*
     459             :                          * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
     460             :                          * TLSV1_ALERT_PROTOCOL_VERSION have been observed
     461             :                          * when trying to communicate with an old OpenSSL
     462             :                          * library, or when the client and server specify
     463             :                          * disjoint protocol ranges.  NO_PROTOCOLS_AVAILABLE
     464             :                          * occurs if there's a local misconfiguration (which
     465             :                          * can happen despite our checks, if openssl.cnf
     466             :                          * injects a limit we didn't account for).  It's not
     467             :                          * very clear what would make OpenSSL return the other
     468             :                          * codes listed here, but a hint about protocol
     469             :                          * versions seems like it's appropriate for all.
     470             :                          */
     471           0 :                     case SSL_R_NO_PROTOCOLS_AVAILABLE:
     472             :                     case SSL_R_UNSUPPORTED_PROTOCOL:
     473             :                     case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
     474             :                     case SSL_R_UNKNOWN_PROTOCOL:
     475             :                     case SSL_R_UNKNOWN_SSL_VERSION:
     476             :                     case SSL_R_UNSUPPORTED_SSL_VERSION:
     477             :                     case SSL_R_WRONG_SSL_VERSION:
     478             :                     case SSL_R_WRONG_VERSION_NUMBER:
     479             :                     case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
     480             : #ifdef SSL_R_VERSION_TOO_HIGH
     481             :                     case SSL_R_VERSION_TOO_HIGH:
     482             :                     case SSL_R_VERSION_TOO_LOW:
     483             : #endif
     484           0 :                         give_proto_hint = true;
     485           0 :                         break;
     486          14 :                     default:
     487          14 :                         give_proto_hint = false;
     488          14 :                         break;
     489             :                 }
     490          14 :                 ereport(COMMERROR,
     491             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     492             :                          errmsg("could not accept SSL connection: %s",
     493             :                                 SSLerrmessage(ecode)),
     494             :                          give_proto_hint ?
     495             :                          errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
     496             :                                  ssl_min_protocol_version ?
     497             :                                  ssl_protocol_version_to_string(ssl_min_protocol_version) :
     498             :                                  MIN_OPENSSL_TLS_VERSION,
     499             :                                  ssl_max_protocol_version ?
     500             :                                  ssl_protocol_version_to_string(ssl_max_protocol_version) :
     501             :                                  MAX_OPENSSL_TLS_VERSION) : 0));
     502          14 :                 break;
     503           0 :             case SSL_ERROR_ZERO_RETURN:
     504           0 :                 ereport(COMMERROR,
     505             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     506             :                          errmsg("could not accept SSL connection: EOF detected")));
     507           0 :                 break;
     508           0 :             default:
     509           0 :                 ereport(COMMERROR,
     510             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     511             :                          errmsg("unrecognized SSL error code: %d",
     512             :                                 err)));
     513           0 :                 break;
     514             :         }
     515          22 :         return -1;
     516             :     }
     517             : 
     518             :     /* Get client certificate, if available. */
     519          74 :     port->peer = SSL_get_peer_certificate(port->ssl);
     520             : 
     521             :     /* and extract the Common Name from it. */
     522          74 :     port->peer_cn = NULL;
     523          74 :     port->peer_cert_valid = false;
     524          74 :     if (port->peer != NULL)
     525             :     {
     526             :         int         len;
     527             : 
     528          20 :         len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
     529             :                                         NID_commonName, NULL, 0);
     530          20 :         if (len != -1)
     531             :         {
     532             :             char       *peer_cn;
     533             : 
     534          20 :             peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
     535          20 :             r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
     536             :                                           NID_commonName, peer_cn, len + 1);
     537          20 :             peer_cn[len] = '\0';
     538          20 :             if (r != len)
     539             :             {
     540             :                 /* shouldn't happen */
     541           0 :                 pfree(peer_cn);
     542           0 :                 return -1;
     543             :             }
     544             : 
     545             :             /*
     546             :              * Reject embedded NULLs in certificate common name to prevent
     547             :              * attacks like CVE-2009-4034.
     548             :              */
     549          20 :             if (len != strlen(peer_cn))
     550             :             {
     551           0 :                 ereport(COMMERROR,
     552             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     553             :                          errmsg("SSL certificate's common name contains embedded null")));
     554           0 :                 pfree(peer_cn);
     555           0 :                 return -1;
     556             :             }
     557             : 
     558          20 :             port->peer_cn = peer_cn;
     559             :         }
     560          20 :         port->peer_cert_valid = true;
     561             :     }
     562             : 
     563             :     /* set up debugging/info callback */
     564          74 :     SSL_CTX_set_info_callback(SSL_context, info_cb);
     565             : 
     566          74 :     return 0;
     567             : }
     568             : 
     569             : void
     570          96 : be_tls_close(Port *port)
     571             : {
     572          96 :     if (port->ssl)
     573             :     {
     574          96 :         SSL_shutdown(port->ssl);
     575          96 :         SSL_free(port->ssl);
     576          96 :         port->ssl = NULL;
     577          96 :         port->ssl_in_use = false;
     578             :     }
     579             : 
     580          96 :     if (port->peer)
     581             :     {
     582          20 :         X509_free(port->peer);
     583          20 :         port->peer = NULL;
     584             :     }
     585             : 
     586          96 :     if (port->peer_cn)
     587             :     {
     588          20 :         pfree(port->peer_cn);
     589          20 :         port->peer_cn = NULL;
     590             :     }
     591          96 : }
     592             : 
     593             : ssize_t
     594         282 : be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
     595             : {
     596             :     ssize_t     n;
     597             :     int         err;
     598             :     unsigned long ecode;
     599             : 
     600         282 :     errno = 0;
     601         282 :     ERR_clear_error();
     602         282 :     n = SSL_read(port->ssl, ptr, len);
     603         282 :     err = SSL_get_error(port->ssl, n);
     604         282 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     605         282 :     switch (err)
     606             :     {
     607         206 :         case SSL_ERROR_NONE:
     608             :             /* a-ok */
     609         206 :             break;
     610          70 :         case SSL_ERROR_WANT_READ:
     611          70 :             *waitfor = WL_SOCKET_READABLE;
     612          70 :             errno = EWOULDBLOCK;
     613          70 :             n = -1;
     614          70 :             break;
     615           0 :         case SSL_ERROR_WANT_WRITE:
     616           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     617           0 :             errno = EWOULDBLOCK;
     618           0 :             n = -1;
     619           0 :             break;
     620           0 :         case SSL_ERROR_SYSCALL:
     621             :             /* leave it to caller to ereport the value of errno */
     622           0 :             if (n != -1)
     623             :             {
     624           0 :                 errno = ECONNRESET;
     625           0 :                 n = -1;
     626             :             }
     627           0 :             break;
     628           0 :         case SSL_ERROR_SSL:
     629           0 :             ereport(COMMERROR,
     630             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     631             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     632           0 :             errno = ECONNRESET;
     633           0 :             n = -1;
     634           0 :             break;
     635           6 :         case SSL_ERROR_ZERO_RETURN:
     636             :             /* connection was cleanly shut down by peer */
     637           6 :             n = 0;
     638           6 :             break;
     639           0 :         default:
     640           0 :             ereport(COMMERROR,
     641             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     642             :                      errmsg("unrecognized SSL error code: %d",
     643             :                             err)));
     644           0 :             errno = ECONNRESET;
     645           0 :             n = -1;
     646           0 :             break;
     647             :     }
     648             : 
     649         282 :     return n;
     650             : }
     651             : 
     652             : ssize_t
     653         144 : be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
     654             : {
     655             :     ssize_t     n;
     656             :     int         err;
     657             :     unsigned long ecode;
     658             : 
     659         144 :     errno = 0;
     660         144 :     ERR_clear_error();
     661         144 :     n = SSL_write(port->ssl, ptr, len);
     662         144 :     err = SSL_get_error(port->ssl, n);
     663         144 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     664         144 :     switch (err)
     665             :     {
     666         144 :         case SSL_ERROR_NONE:
     667             :             /* a-ok */
     668         144 :             break;
     669           0 :         case SSL_ERROR_WANT_READ:
     670           0 :             *waitfor = WL_SOCKET_READABLE;
     671           0 :             errno = EWOULDBLOCK;
     672           0 :             n = -1;
     673           0 :             break;
     674           0 :         case SSL_ERROR_WANT_WRITE:
     675           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     676           0 :             errno = EWOULDBLOCK;
     677           0 :             n = -1;
     678           0 :             break;
     679           0 :         case SSL_ERROR_SYSCALL:
     680             :             /* leave it to caller to ereport the value of errno */
     681           0 :             if (n != -1)
     682             :             {
     683           0 :                 errno = ECONNRESET;
     684           0 :                 n = -1;
     685             :             }
     686           0 :             break;
     687           0 :         case SSL_ERROR_SSL:
     688           0 :             ereport(COMMERROR,
     689             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     690             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     691           0 :             errno = ECONNRESET;
     692           0 :             n = -1;
     693           0 :             break;
     694           0 :         case SSL_ERROR_ZERO_RETURN:
     695             : 
     696             :             /*
     697             :              * the SSL connection was closed, leave it to the caller to
     698             :              * ereport it
     699             :              */
     700           0 :             errno = ECONNRESET;
     701           0 :             n = -1;
     702           0 :             break;
     703           0 :         default:
     704           0 :             ereport(COMMERROR,
     705             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     706             :                      errmsg("unrecognized SSL error code: %d",
     707             :                             err)));
     708           0 :             errno = ECONNRESET;
     709           0 :             n = -1;
     710           0 :             break;
     711             :     }
     712             : 
     713         144 :     return n;
     714             : }
     715             : 
     716             : /* ------------------------------------------------------------ */
     717             : /*                      Internal functions                      */
     718             : /* ------------------------------------------------------------ */
     719             : 
     720             : /*
     721             :  * Private substitute BIO: this does the sending and receiving using send() and
     722             :  * recv() instead. This is so that we can enable and disable interrupts
     723             :  * just while calling recv(). We cannot have interrupts occurring while
     724             :  * the bulk of OpenSSL runs, because it uses malloc() and possibly other
     725             :  * non-reentrant libc facilities. We also need to call send() and recv()
     726             :  * directly so it gets passed through the socket/signals layer on Win32.
     727             :  *
     728             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
     729             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
     730             :  * XXX OpenSSL 1.0.1e considers many more errcodes than just EINTR as reasons
     731             :  * to retry; do we need to adopt their logic for that?
     732             :  */
     733             : 
     734             : #ifndef HAVE_BIO_GET_DATA
     735             : #define BIO_get_data(bio) (bio->ptr)
     736             : #define BIO_set_data(bio, data) (bio->ptr = data)
     737             : #endif
     738             : 
     739             : static BIO_METHOD *my_bio_methods = NULL;
     740             : 
     741             : static int
     742        1496 : my_sock_read(BIO *h, char *buf, int size)
     743             : {
     744        1496 :     int         res = 0;
     745             : 
     746        1496 :     if (buf != NULL)
     747             :     {
     748        1496 :         res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
     749        1496 :         BIO_clear_retry_flags(h);
     750        1496 :         if (res <= 0)
     751             :         {
     752             :             /* If we were interrupted, tell caller to retry */
     753         180 :             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     754             :             {
     755         172 :                 BIO_set_retry_read(h);
     756             :             }
     757             :         }
     758             :     }
     759             : 
     760        1496 :     return res;
     761             : }
     762             : 
     763             : static int
     764         540 : my_sock_write(BIO *h, const char *buf, int size)
     765             : {
     766         540 :     int         res = 0;
     767             : 
     768         540 :     res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
     769         540 :     BIO_clear_retry_flags(h);
     770         540 :     if (res <= 0)
     771             :     {
     772             :         /* If we were interrupted, tell caller to retry */
     773           8 :         if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     774             :         {
     775           0 :             BIO_set_retry_write(h);
     776             :         }
     777             :     }
     778             : 
     779         540 :     return res;
     780             : }
     781             : 
     782             : static BIO_METHOD *
     783          96 : my_BIO_s_socket(void)
     784             : {
     785          96 :     if (!my_bio_methods)
     786             :     {
     787          96 :         BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
     788             : #ifdef HAVE_BIO_METH_NEW
     789             :         int         my_bio_index;
     790             : 
     791          96 :         my_bio_index = BIO_get_new_index();
     792          96 :         if (my_bio_index == -1)
     793           0 :             return NULL;
     794          96 :         my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
     795          96 :         if (!my_bio_methods)
     796           0 :             return NULL;
     797         192 :         if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
     798         192 :             !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
     799         192 :             !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
     800         192 :             !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
     801         192 :             !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
     802         192 :             !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
     803         192 :             !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
     804          96 :             !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
     805             :         {
     806           0 :             BIO_meth_free(my_bio_methods);
     807           0 :             my_bio_methods = NULL;
     808           0 :             return NULL;
     809             :         }
     810             : #else
     811             :         my_bio_methods = malloc(sizeof(BIO_METHOD));
     812             :         if (!my_bio_methods)
     813             :             return NULL;
     814             :         memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
     815             :         my_bio_methods->bread = my_sock_read;
     816             :         my_bio_methods->bwrite = my_sock_write;
     817             : #endif
     818             :     }
     819          96 :     return my_bio_methods;
     820             : }
     821             : 
     822             : /* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
     823             : static int
     824          96 : my_SSL_set_fd(Port *port, int fd)
     825             : {
     826          96 :     int         ret = 0;
     827             :     BIO        *bio;
     828             :     BIO_METHOD *bio_method;
     829             : 
     830          96 :     bio_method = my_BIO_s_socket();
     831          96 :     if (bio_method == NULL)
     832             :     {
     833           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     834           0 :         goto err;
     835             :     }
     836          96 :     bio = BIO_new(bio_method);
     837             : 
     838          96 :     if (bio == NULL)
     839             :     {
     840           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     841           0 :         goto err;
     842             :     }
     843          96 :     BIO_set_data(bio, port);
     844             : 
     845          96 :     BIO_set_fd(bio, fd, BIO_NOCLOSE);
     846          96 :     SSL_set_bio(port->ssl, bio, bio);
     847          96 :     ret = 1;
     848          96 : err:
     849          96 :     return ret;
     850             : }
     851             : 
     852             : /*
     853             :  *  Load precomputed DH parameters.
     854             :  *
     855             :  *  To prevent "downgrade" attacks, we perform a number of checks
     856             :  *  to verify that the DBA-generated DH parameters file contains
     857             :  *  what we expect it to contain.
     858             :  */
     859             : static DH  *
     860           0 : load_dh_file(char *filename, bool isServerStart)
     861             : {
     862             :     FILE       *fp;
     863           0 :     DH         *dh = NULL;
     864             :     int         codes;
     865             : 
     866             :     /* attempt to open file.  It's not an error if it doesn't exist. */
     867           0 :     if ((fp = AllocateFile(filename, "r")) == NULL)
     868             :     {
     869           0 :         ereport(isServerStart ? FATAL : LOG,
     870             :                 (errcode_for_file_access(),
     871             :                  errmsg("could not open DH parameters file \"%s\": %m",
     872             :                         filename)));
     873           0 :         return NULL;
     874             :     }
     875             : 
     876           0 :     dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
     877           0 :     FreeFile(fp);
     878             : 
     879           0 :     if (dh == NULL)
     880             :     {
     881           0 :         ereport(isServerStart ? FATAL : LOG,
     882             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     883             :                  errmsg("could not load DH parameters file: %s",
     884             :                         SSLerrmessage(ERR_get_error()))));
     885           0 :         return NULL;
     886             :     }
     887             : 
     888             :     /* make sure the DH parameters are usable */
     889           0 :     if (DH_check(dh, &codes) == 0)
     890             :     {
     891           0 :         ereport(isServerStart ? FATAL : LOG,
     892             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     893             :                  errmsg("invalid DH parameters: %s",
     894             :                         SSLerrmessage(ERR_get_error()))));
     895           0 :         return NULL;
     896             :     }
     897           0 :     if (codes & DH_CHECK_P_NOT_PRIME)
     898             :     {
     899           0 :         ereport(isServerStart ? FATAL : LOG,
     900             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     901             :                  errmsg("invalid DH parameters: p is not prime")));
     902           0 :         return NULL;
     903             :     }
     904           0 :     if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
     905           0 :         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
     906             :     {
     907           0 :         ereport(isServerStart ? FATAL : LOG,
     908             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     909             :                  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
     910           0 :         return NULL;
     911             :     }
     912             : 
     913           0 :     return dh;
     914             : }
     915             : 
     916             : /*
     917             :  *  Load hardcoded DH parameters.
     918             :  *
     919             :  *  If DH parameters cannot be loaded from a specified file, we can load
     920             :  *  the hardcoded DH parameters supplied with the backend to prevent
     921             :  *  problems.
     922             :  */
     923             : static DH  *
     924          24 : load_dh_buffer(const char *buffer, size_t len)
     925             : {
     926             :     BIO        *bio;
     927          24 :     DH         *dh = NULL;
     928             : 
     929          24 :     bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
     930          24 :     if (bio == NULL)
     931           0 :         return NULL;
     932          24 :     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
     933          24 :     if (dh == NULL)
     934           0 :         ereport(DEBUG2,
     935             :                 (errmsg_internal("DH load buffer: %s",
     936             :                                  SSLerrmessage(ERR_get_error()))));
     937          24 :     BIO_free(bio);
     938             : 
     939          24 :     return dh;
     940             : }
     941             : 
     942             : /*
     943             :  *  Passphrase collection callback using ssl_passphrase_command
     944             :  */
     945             : static int
     946           8 : ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
     947             : {
     948             :     /* same prompt as OpenSSL uses internally */
     949           8 :     const char *prompt = "Enter PEM pass phrase:";
     950             : 
     951             :     Assert(rwflag == 0);
     952             : 
     953           8 :     return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
     954             : }
     955             : 
     956             : /*
     957             :  * Dummy passphrase callback
     958             :  *
     959             :  * If OpenSSL is told to use a passphrase-protected server key, by default
     960             :  * it will issue a prompt on /dev/tty and try to read a key from there.
     961             :  * That's no good during a postmaster SIGHUP cycle, not to mention SSL context
     962             :  * reload in an EXEC_BACKEND postmaster child.  So override it with this dummy
     963             :  * function that just returns an empty passphrase, guaranteeing failure.
     964             :  */
     965             : static int
     966           0 : dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
     967             : {
     968             :     /* Set flag to change the error message we'll report */
     969           0 :     dummy_ssl_passwd_cb_called = true;
     970             :     /* And return empty string */
     971             :     Assert(size > 0);
     972           0 :     buf[0] = '\0';
     973           0 :     return 0;
     974             : }
     975             : 
     976             : /*
     977             :  *  Certificate verification callback
     978             :  *
     979             :  *  This callback allows us to log intermediate problems during
     980             :  *  verification, but for now we'll see if the final error message
     981             :  *  contains enough information.
     982             :  *
     983             :  *  This callback also allows us to override the default acceptance
     984             :  *  criteria (e.g., accepting self-signed or expired certs), but
     985             :  *  for now we accept the default checks.
     986             :  */
     987             : static int
     988          62 : verify_cb(int ok, X509_STORE_CTX *ctx)
     989             : {
     990          62 :     return ok;
     991             : }
     992             : 
     993             : /*
     994             :  *  This callback is used to copy SSL information messages
     995             :  *  into the PostgreSQL log.
     996             :  */
     997             : static void
     998          76 : info_cb(const SSL *ssl, int type, int args)
     999             : {
    1000          76 :     switch (type)
    1001             :     {
    1002           0 :         case SSL_CB_HANDSHAKE_START:
    1003           0 :             ereport(DEBUG4,
    1004             :                     (errmsg_internal("SSL: handshake start")));
    1005           0 :             break;
    1006           0 :         case SSL_CB_HANDSHAKE_DONE:
    1007           0 :             ereport(DEBUG4,
    1008             :                     (errmsg_internal("SSL: handshake done")));
    1009           0 :             break;
    1010           0 :         case SSL_CB_ACCEPT_LOOP:
    1011           0 :             ereport(DEBUG4,
    1012             :                     (errmsg_internal("SSL: accept loop")));
    1013           0 :             break;
    1014           0 :         case SSL_CB_ACCEPT_EXIT:
    1015           0 :             ereport(DEBUG4,
    1016             :                     (errmsg_internal("SSL: accept exit (%d)", args)));
    1017           0 :             break;
    1018           0 :         case SSL_CB_CONNECT_LOOP:
    1019           0 :             ereport(DEBUG4,
    1020             :                     (errmsg_internal("SSL: connect loop")));
    1021           0 :             break;
    1022           0 :         case SSL_CB_CONNECT_EXIT:
    1023           0 :             ereport(DEBUG4,
    1024             :                     (errmsg_internal("SSL: connect exit (%d)", args)));
    1025           0 :             break;
    1026           6 :         case SSL_CB_READ_ALERT:
    1027           6 :             ereport(DEBUG4,
    1028             :                     (errmsg_internal("SSL: read alert (0x%04x)", args)));
    1029           6 :             break;
    1030          70 :         case SSL_CB_WRITE_ALERT:
    1031          70 :             ereport(DEBUG4,
    1032             :                     (errmsg_internal("SSL: write alert (0x%04x)", args)));
    1033          70 :             break;
    1034             :     }
    1035          76 : }
    1036             : 
    1037             : /*
    1038             :  * Set DH parameters for generating ephemeral DH keys.  The
    1039             :  * DH parameters can take a long time to compute, so they must be
    1040             :  * precomputed.
    1041             :  *
    1042             :  * Since few sites will bother to create a parameter file, we also
    1043             :  * provide a fallback to the parameters provided by the OpenSSL
    1044             :  * project.
    1045             :  *
    1046             :  * These values can be static (once loaded or computed) since the
    1047             :  * OpenSSL library can efficiently generate random keys from the
    1048             :  * information provided.
    1049             :  */
    1050             : static bool
    1051          24 : initialize_dh(SSL_CTX *context, bool isServerStart)
    1052             : {
    1053          24 :     DH         *dh = NULL;
    1054             : 
    1055          24 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
    1056             : 
    1057          24 :     if (ssl_dh_params_file[0])
    1058           0 :         dh = load_dh_file(ssl_dh_params_file, isServerStart);
    1059          24 :     if (!dh)
    1060          24 :         dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
    1061          24 :     if (!dh)
    1062             :     {
    1063           0 :         ereport(isServerStart ? FATAL : LOG,
    1064             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1065             :                  errmsg("DH: could not load DH parameters")));
    1066           0 :         return false;
    1067             :     }
    1068             : 
    1069          24 :     if (SSL_CTX_set_tmp_dh(context, dh) != 1)
    1070             :     {
    1071           0 :         ereport(isServerStart ? FATAL : LOG,
    1072             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1073             :                  errmsg("DH: could not set DH parameters: %s",
    1074             :                         SSLerrmessage(ERR_get_error()))));
    1075           0 :         DH_free(dh);
    1076           0 :         return false;
    1077             :     }
    1078             : 
    1079          24 :     DH_free(dh);
    1080          24 :     return true;
    1081             : }
    1082             : 
    1083             : /*
    1084             :  * Set ECDH parameters for generating ephemeral Elliptic Curve DH
    1085             :  * keys.  This is much simpler than the DH parameters, as we just
    1086             :  * need to provide the name of the curve to OpenSSL.
    1087             :  */
    1088             : static bool
    1089          24 : initialize_ecdh(SSL_CTX *context, bool isServerStart)
    1090             : {
    1091             : #ifndef OPENSSL_NO_ECDH
    1092             :     EC_KEY     *ecdh;
    1093             :     int         nid;
    1094             : 
    1095          24 :     nid = OBJ_sn2nid(SSLECDHCurve);
    1096          24 :     if (!nid)
    1097             :     {
    1098           0 :         ereport(isServerStart ? FATAL : LOG,
    1099             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1100             :                  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
    1101           0 :         return false;
    1102             :     }
    1103             : 
    1104          24 :     ecdh = EC_KEY_new_by_curve_name(nid);
    1105          24 :     if (!ecdh)
    1106             :     {
    1107           0 :         ereport(isServerStart ? FATAL : LOG,
    1108             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1109             :                  errmsg("ECDH: could not create key")));
    1110           0 :         return false;
    1111             :     }
    1112             : 
    1113          24 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
    1114          24 :     SSL_CTX_set_tmp_ecdh(context, ecdh);
    1115          24 :     EC_KEY_free(ecdh);
    1116             : #endif
    1117             : 
    1118          24 :     return true;
    1119             : }
    1120             : 
    1121             : /*
    1122             :  * Obtain reason string for passed SSL errcode
    1123             :  *
    1124             :  * ERR_get_error() is used by caller to get errcode to pass here.
    1125             :  *
    1126             :  * Some caution is needed here since ERR_reason_error_string will
    1127             :  * return NULL if it doesn't recognize the error code.  We don't
    1128             :  * want to return NULL ever.
    1129             :  */
    1130             : static const char *
    1131          18 : SSLerrmessage(unsigned long ecode)
    1132             : {
    1133             :     const char *errreason;
    1134             :     static char errbuf[36];
    1135             : 
    1136          18 :     if (ecode == 0)
    1137           0 :         return _("no SSL error reported");
    1138          18 :     errreason = ERR_reason_error_string(ecode);
    1139          18 :     if (errreason != NULL)
    1140          18 :         return errreason;
    1141           0 :     snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
    1142           0 :     return errbuf;
    1143             : }
    1144             : 
    1145             : int
    1146         124 : be_tls_get_cipher_bits(Port *port)
    1147             : {
    1148             :     int         bits;
    1149             : 
    1150         124 :     if (port->ssl)
    1151             :     {
    1152         124 :         SSL_get_cipher_bits(port->ssl, &bits);
    1153         124 :         return bits;
    1154             :     }
    1155             :     else
    1156           0 :         return 0;
    1157             : }
    1158             : 
    1159             : bool
    1160         124 : be_tls_get_compression(Port *port)
    1161             : {
    1162         124 :     if (port->ssl)
    1163         124 :         return (SSL_get_current_compression(port->ssl) != NULL);
    1164             :     else
    1165           0 :         return false;
    1166             : }
    1167             : 
    1168             : const char *
    1169         124 : be_tls_get_version(Port *port)
    1170             : {
    1171         124 :     if (port->ssl)
    1172         124 :         return SSL_get_version(port->ssl);
    1173             :     else
    1174           0 :         return NULL;
    1175             : }
    1176             : 
    1177             : const char *
    1178         124 : be_tls_get_cipher(Port *port)
    1179             : {
    1180         124 :     if (port->ssl)
    1181         124 :         return SSL_get_cipher(port->ssl);
    1182             :     else
    1183           0 :         return NULL;
    1184             : }
    1185             : 
    1186             : void
    1187          62 : be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
    1188             : {
    1189          62 :     if (port->peer)
    1190          16 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
    1191             :     else
    1192          46 :         ptr[0] = '\0';
    1193          62 : }
    1194             : 
    1195             : void
    1196          62 : be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
    1197             : {
    1198          62 :     if (port->peer)
    1199          16 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
    1200             :     else
    1201          46 :         ptr[0] = '\0';
    1202          62 : }
    1203             : 
    1204             : void
    1205          62 : be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
    1206             : {
    1207          62 :     if (port->peer)
    1208             :     {
    1209             :         ASN1_INTEGER *serial;
    1210             :         BIGNUM     *b;
    1211             :         char       *decimal;
    1212             : 
    1213          16 :         serial = X509_get_serialNumber(port->peer);
    1214          16 :         b = ASN1_INTEGER_to_BN(serial, NULL);
    1215          16 :         decimal = BN_bn2dec(b);
    1216             : 
    1217          16 :         BN_free(b);
    1218          16 :         strlcpy(ptr, decimal, len);
    1219          16 :         OPENSSL_free(decimal);
    1220             :     }
    1221             :     else
    1222          46 :         ptr[0] = '\0';
    1223          62 : }
    1224             : 
    1225             : #ifdef HAVE_X509_GET_SIGNATURE_NID
    1226             : char *
    1227           4 : be_tls_get_certificate_hash(Port *port, size_t *len)
    1228             : {
    1229             :     X509       *server_cert;
    1230             :     char       *cert_hash;
    1231           4 :     const EVP_MD *algo_type = NULL;
    1232             :     unsigned char hash[EVP_MAX_MD_SIZE];    /* size for SHA-512 */
    1233             :     unsigned int hash_size;
    1234             :     int         algo_nid;
    1235             : 
    1236           4 :     *len = 0;
    1237           4 :     server_cert = SSL_get_certificate(port->ssl);
    1238           4 :     if (server_cert == NULL)
    1239           0 :         return NULL;
    1240             : 
    1241             :     /*
    1242             :      * Get the signature algorithm of the certificate to determine the hash
    1243             :      * algorithm to use for the result.
    1244             :      */
    1245           4 :     if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
    1246             :                              &algo_nid, NULL))
    1247           0 :         elog(ERROR, "could not determine server certificate signature algorithm");
    1248             : 
    1249             :     /*
    1250             :      * The TLS server's certificate bytes need to be hashed with SHA-256 if
    1251             :      * its signature algorithm is MD5 or SHA-1 as per RFC 5929
    1252             :      * (https://tools.ietf.org/html/rfc5929#section-4.1).  If something else
    1253             :      * is used, the same hash as the signature algorithm is used.
    1254             :      */
    1255           4 :     switch (algo_nid)
    1256             :     {
    1257           0 :         case NID_md5:
    1258             :         case NID_sha1:
    1259           0 :             algo_type = EVP_sha256();
    1260           0 :             break;
    1261           4 :         default:
    1262           4 :             algo_type = EVP_get_digestbynid(algo_nid);
    1263           4 :             if (algo_type == NULL)
    1264           0 :                 elog(ERROR, "could not find digest for NID %s",
    1265             :                      OBJ_nid2sn(algo_nid));
    1266           4 :             break;
    1267             :     }
    1268             : 
    1269             :     /* generate and save the certificate hash */
    1270           4 :     if (!X509_digest(server_cert, algo_type, hash, &hash_size))
    1271           0 :         elog(ERROR, "could not generate server certificate hash");
    1272             : 
    1273           4 :     cert_hash = palloc(hash_size);
    1274           4 :     memcpy(cert_hash, hash, hash_size);
    1275           4 :     *len = hash_size;
    1276             : 
    1277           4 :     return cert_hash;
    1278             : }
    1279             : #endif
    1280             : 
    1281             : /*
    1282             :  * Convert an X509 subject name to a cstring.
    1283             :  *
    1284             :  */
    1285             : static char *
    1286          32 : X509_NAME_to_cstring(X509_NAME *name)
    1287             : {
    1288          32 :     BIO        *membuf = BIO_new(BIO_s_mem());
    1289             :     int         i,
    1290             :                 nid,
    1291          32 :                 count = X509_NAME_entry_count(name);
    1292             :     X509_NAME_ENTRY *e;
    1293             :     ASN1_STRING *v;
    1294             :     const char *field_name;
    1295             :     size_t      size;
    1296             :     char        nullterm;
    1297             :     char       *sp;
    1298             :     char       *dp;
    1299             :     char       *result;
    1300             : 
    1301          32 :     (void) BIO_set_close(membuf, BIO_CLOSE);
    1302          64 :     for (i = 0; i < count; i++)
    1303             :     {
    1304          32 :         e = X509_NAME_get_entry(name, i);
    1305          32 :         nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
    1306          32 :         v = X509_NAME_ENTRY_get_data(e);
    1307          32 :         field_name = OBJ_nid2sn(nid);
    1308          32 :         if (!field_name)
    1309           0 :             field_name = OBJ_nid2ln(nid);
    1310          32 :         BIO_printf(membuf, "/%s=", field_name);
    1311          32 :         ASN1_STRING_print_ex(membuf, v,
    1312             :                              ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
    1313             :                               | ASN1_STRFLGS_UTF8_CONVERT));
    1314             :     }
    1315             : 
    1316             :     /* ensure null termination of the BIO's content */
    1317          32 :     nullterm = '\0';
    1318          32 :     BIO_write(membuf, &nullterm, 1);
    1319          32 :     size = BIO_get_mem_data(membuf, &sp);
    1320          32 :     dp = pg_any_to_server(sp, size - 1, PG_UTF8);
    1321             : 
    1322          32 :     result = pstrdup(dp);
    1323          32 :     if (dp != sp)
    1324           0 :         pfree(dp);
    1325          32 :     BIO_free(membuf);
    1326             : 
    1327          32 :     return result;
    1328             : }
    1329             : 
    1330             : /*
    1331             :  * Convert TLS protocol version GUC enum to OpenSSL values
    1332             :  *
    1333             :  * This is a straightforward one-to-one mapping, but doing it this way makes
    1334             :  * guc.c independent of OpenSSL availability and version.
    1335             :  *
    1336             :  * If a version is passed that is not supported by the current OpenSSL
    1337             :  * version, then we return -1.  If a nonnegative value is returned,
    1338             :  * subsequent code can assume it's working with a supported version.
    1339             :  *
    1340             :  * Note: this is rather similar to libpq's routine in fe-secure-openssl.c,
    1341             :  * so make sure to update both routines if changing this one.
    1342             :  */
    1343             : static int
    1344          28 : ssl_protocol_version_to_openssl(int v)
    1345             : {
    1346          28 :     switch (v)
    1347             :     {
    1348           0 :         case PG_TLS_ANY:
    1349           0 :             return 0;
    1350           0 :         case PG_TLS1_VERSION:
    1351           0 :             return TLS1_VERSION;
    1352           2 :         case PG_TLS1_1_VERSION:
    1353             : #ifdef TLS1_1_VERSION
    1354           2 :             return TLS1_1_VERSION;
    1355             : #else
    1356             :             break;
    1357             : #endif
    1358          26 :         case PG_TLS1_2_VERSION:
    1359             : #ifdef TLS1_2_VERSION
    1360          26 :             return TLS1_2_VERSION;
    1361             : #else
    1362             :             break;
    1363             : #endif
    1364           0 :         case PG_TLS1_3_VERSION:
    1365             : #ifdef TLS1_3_VERSION
    1366           0 :             return TLS1_3_VERSION;
    1367             : #else
    1368             :             break;
    1369             : #endif
    1370             :     }
    1371             : 
    1372           0 :     return -1;
    1373             : }
    1374             : 
    1375             : /*
    1376             :  * Likewise provide a mapping to strings.
    1377             :  */
    1378             : static const char *
    1379           0 : ssl_protocol_version_to_string(int v)
    1380             : {
    1381           0 :     switch (v)
    1382             :     {
    1383           0 :         case PG_TLS_ANY:
    1384           0 :             return "any";
    1385           0 :         case PG_TLS1_VERSION:
    1386           0 :             return "TLSv1";
    1387           0 :         case PG_TLS1_1_VERSION:
    1388           0 :             return "TLSv1.1";
    1389           0 :         case PG_TLS1_2_VERSION:
    1390           0 :             return "TLSv1.2";
    1391           0 :         case PG_TLS1_3_VERSION:
    1392           0 :             return "TLSv1.3";
    1393             :     }
    1394             : 
    1395           0 :     return "(unrecognized)";
    1396             : }
    1397             : 
    1398             : 
    1399             : static void
    1400          24 : default_openssl_tls_init(SSL_CTX *context, bool isServerStart)
    1401             : {
    1402          24 :     if (isServerStart)
    1403             :     {
    1404          24 :         if (ssl_passphrase_command[0])
    1405           8 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    1406             :     }
    1407             :     else
    1408             :     {
    1409           0 :         if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
    1410           0 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
    1411             :         else
    1412             : 
    1413             :             /*
    1414             :              * If reloading and no external command is configured, override
    1415             :              * OpenSSL's default handling of passphrase-protected files,
    1416             :              * because we don't want to prompt for a passphrase in an
    1417             :              * already-running server.
    1418             :              */
    1419           0 :             SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
    1420             :     }
    1421          24 : }

Generated by: LCOV version 1.13