LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 15devel Lines: 323 638 50.6 %
Date: 2021-12-09 04:09:06 Functions: 22 29 75.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * fe-secure-openssl.c
       4             :  *    OpenSSL support
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/interfaces/libpq/fe-secure-openssl.c
      13             :  *
      14             :  * NOTES
      15             :  *
      16             :  *    We don't provide informational callbacks here (like
      17             :  *    info_cb() in be-secure-openssl.c), since there's no good mechanism to
      18             :  *    display such information to the user.
      19             :  *
      20             :  *-------------------------------------------------------------------------
      21             :  */
      22             : 
      23             : #include "postgres_fe.h"
      24             : 
      25             : #include <signal.h>
      26             : #include <fcntl.h>
      27             : #include <ctype.h>
      28             : 
      29             : #include "libpq-fe.h"
      30             : #include "fe-auth.h"
      31             : #include "fe-secure-common.h"
      32             : #include "libpq-int.h"
      33             : 
      34             : #ifdef WIN32
      35             : #include "win32.h"
      36             : #else
      37             : #include <sys/socket.h>
      38             : #include <unistd.h>
      39             : #include <netdb.h>
      40             : #include <netinet/in.h>
      41             : #ifdef HAVE_NETINET_TCP_H
      42             : #include <netinet/tcp.h>
      43             : #endif
      44             : #include <arpa/inet.h>
      45             : #endif
      46             : 
      47             : #include <sys/stat.h>
      48             : 
      49             : #ifdef ENABLE_THREAD_SAFETY
      50             : #ifdef WIN32
      51             : #include "pthread-win32.h"
      52             : #else
      53             : #include <pthread.h>
      54             : #endif
      55             : #endif
      56             : 
      57             : /*
      58             :  * These SSL-related #includes must come after all system-provided headers.
      59             :  * This ensures that OpenSSL can take care of conflicts with Windows'
      60             :  * <wincrypt.h> by #undef'ing the conflicting macros.  (We don't directly
      61             :  * include <wincrypt.h>, but some other Windows headers do.)
      62             :  */
      63             : #include "common/openssl.h"
      64             : #include <openssl/conf.h>
      65             : #ifdef USE_SSL_ENGINE
      66             : #include <openssl/engine.h>
      67             : #endif
      68             : #include <openssl/x509v3.h>
      69             : 
      70             : 
      71             : static int  verify_cb(int ok, X509_STORE_CTX *ctx);
      72             : static int  openssl_verify_peer_name_matches_certificate_name(PGconn *conn,
      73             :                                                               ASN1_STRING *name,
      74             :                                                               char **store_name);
      75             : static void destroy_ssl_system(void);
      76             : static int  initialize_SSL(PGconn *conn);
      77             : static PostgresPollingStatusType open_client_SSL(PGconn *);
      78             : static char *SSLerrmessage(unsigned long ecode);
      79             : static void SSLerrfree(char *buf);
      80             : static int  PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      81             : 
      82             : static int  my_sock_read(BIO *h, char *buf, int size);
      83             : static int  my_sock_write(BIO *h, const char *buf, int size);
      84             : static BIO_METHOD *my_BIO_s_socket(void);
      85             : static int  my_SSL_set_fd(PGconn *conn, int fd);
      86             : 
      87             : 
      88             : static bool pq_init_ssl_lib = true;
      89             : static bool pq_init_crypto_lib = true;
      90             : 
      91             : static bool ssl_lib_initialized = false;
      92             : 
      93             : #ifdef ENABLE_THREAD_SAFETY
      94             : static long crypto_open_connections = 0;
      95             : 
      96             : #ifndef WIN32
      97             : static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
      98             : #else
      99             : static pthread_mutex_t ssl_config_mutex = NULL;
     100             : static long win32_ssl_create_mutex = 0;
     101             : #endif
     102             : #endif                          /* ENABLE_THREAD_SAFETY */
     103             : 
     104             : static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
     105             : static int  ssl_protocol_version_to_openssl(const char *protocol);
     106             : 
     107             : /* ------------------------------------------------------------ */
     108             : /*           Procedures common to all secure sessions           */
     109             : /* ------------------------------------------------------------ */
     110             : 
     111             : void
     112           0 : pgtls_init_library(bool do_ssl, int do_crypto)
     113             : {
     114             : #ifdef ENABLE_THREAD_SAFETY
     115             : 
     116             :     /*
     117             :      * Disallow changing the flags while we have open connections, else we'd
     118             :      * get completely confused.
     119             :      */
     120           0 :     if (crypto_open_connections != 0)
     121           0 :         return;
     122             : #endif
     123             : 
     124           0 :     pq_init_ssl_lib = do_ssl;
     125           0 :     pq_init_crypto_lib = do_crypto;
     126             : }
     127             : 
     128             : PostgresPollingStatusType
     129         436 : pgtls_open_client(PGconn *conn)
     130             : {
     131             :     /* First time through? */
     132         436 :     if (conn->ssl == NULL)
     133             :     {
     134             :         /*
     135             :          * Create a connection-specific SSL object, and load client
     136             :          * certificate, private key, and trusted CA certs.
     137             :          */
     138         152 :         if (initialize_SSL(conn) != 0)
     139             :         {
     140             :             /* initialize_SSL already put a message in conn->errorMessage */
     141           8 :             pgtls_close(conn);
     142           8 :             return PGRES_POLLING_FAILED;
     143             :         }
     144             :     }
     145             : 
     146             :     /* Begin or continue the actual handshake */
     147         428 :     return open_client_SSL(conn);
     148             : }
     149             : 
     150             : ssize_t
     151         480 : pgtls_read(PGconn *conn, void *ptr, size_t len)
     152             : {
     153             :     ssize_t     n;
     154         480 :     int         result_errno = 0;
     155             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     156             :     int         err;
     157             :     unsigned long ecode;
     158             : 
     159         480 : rloop:
     160             : 
     161             :     /*
     162             :      * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
     163             :      * queue.  In general, the current thread's error queue must be empty
     164             :      * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
     165             :      * not work reliably.  Since the possibility exists that other OpenSSL
     166             :      * clients running in the same thread but not under our control will fail
     167             :      * to call ERR_get_error() themselves (after their own I/O operations),
     168             :      * pro-actively clear the per-thread error queue now.
     169             :      */
     170         480 :     SOCK_ERRNO_SET(0);
     171         480 :     ERR_clear_error();
     172         480 :     n = SSL_read(conn->ssl, ptr, len);
     173         480 :     err = SSL_get_error(conn->ssl, n);
     174             : 
     175             :     /*
     176             :      * Other clients of OpenSSL may fail to call ERR_get_error(), but we
     177             :      * always do, so as to not cause problems for OpenSSL clients that don't
     178             :      * call ERR_clear_error() defensively.  Be sure that this happens by
     179             :      * calling now.  SSL_get_error() relies on the OpenSSL per-thread error
     180             :      * queue being intact, so this is the earliest possible point
     181             :      * ERR_get_error() may be called.
     182             :      */
     183         480 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     184         480 :     switch (err)
     185             :     {
     186         224 :         case SSL_ERROR_NONE:
     187         224 :             if (n < 0)
     188             :             {
     189             :                 /* Not supposed to happen, so we don't translate the msg */
     190           0 :                 appendPQExpBufferStr(&conn->errorMessage,
     191             :                                      "SSL_read failed but did not provide error information\n");
     192             :                 /* assume the connection is broken */
     193           0 :                 result_errno = ECONNRESET;
     194             :             }
     195         224 :             break;
     196         250 :         case SSL_ERROR_WANT_READ:
     197         250 :             n = 0;
     198         250 :             break;
     199           0 :         case SSL_ERROR_WANT_WRITE:
     200             : 
     201             :             /*
     202             :              * Returning 0 here would cause caller to wait for read-ready,
     203             :              * which is not correct since what SSL wants is wait for
     204             :              * write-ready.  The former could get us stuck in an infinite
     205             :              * wait, so don't risk it; busy-loop instead.
     206             :              */
     207           0 :             goto rloop;
     208           0 :         case SSL_ERROR_SYSCALL:
     209           0 :             if (n < 0)
     210             :             {
     211           0 :                 result_errno = SOCK_ERRNO;
     212           0 :                 if (result_errno == EPIPE ||
     213             :                     result_errno == ECONNRESET)
     214           0 :                     appendPQExpBufferStr(&conn->errorMessage,
     215           0 :                                          libpq_gettext("server closed the connection unexpectedly\n"
     216             :                                                        "\tThis probably means the server terminated abnormally\n"
     217             :                                                        "\tbefore or while processing the request.\n"));
     218             :                 else
     219           0 :                     appendPQExpBuffer(&conn->errorMessage,
     220           0 :                                       libpq_gettext("SSL SYSCALL error: %s\n"),
     221             :                                       SOCK_STRERROR(result_errno,
     222             :                                                     sebuf, sizeof(sebuf)));
     223             :             }
     224             :             else
     225             :             {
     226           0 :                 appendPQExpBufferStr(&conn->errorMessage,
     227           0 :                                      libpq_gettext("SSL SYSCALL error: EOF detected\n"));
     228             :                 /* assume the connection is broken */
     229           0 :                 result_errno = ECONNRESET;
     230           0 :                 n = -1;
     231             :             }
     232           0 :             break;
     233           6 :         case SSL_ERROR_SSL:
     234             :             {
     235           6 :                 char       *errm = SSLerrmessage(ecode);
     236             : 
     237           6 :                 appendPQExpBuffer(&conn->errorMessage,
     238           6 :                                   libpq_gettext("SSL error: %s\n"), errm);
     239           6 :                 SSLerrfree(errm);
     240             :                 /* assume the connection is broken */
     241           6 :                 result_errno = ECONNRESET;
     242           6 :                 n = -1;
     243           6 :                 break;
     244             :             }
     245           0 :         case SSL_ERROR_ZERO_RETURN:
     246             : 
     247             :             /*
     248             :              * Per OpenSSL documentation, this error code is only returned for
     249             :              * a clean connection closure, so we should not report it as a
     250             :              * server crash.
     251             :              */
     252           0 :             appendPQExpBufferStr(&conn->errorMessage,
     253           0 :                                  libpq_gettext("SSL connection has been closed unexpectedly\n"));
     254           0 :             result_errno = ECONNRESET;
     255           0 :             n = -1;
     256           0 :             break;
     257           0 :         default:
     258           0 :             appendPQExpBuffer(&conn->errorMessage,
     259           0 :                               libpq_gettext("unrecognized SSL error code: %d\n"),
     260             :                               err);
     261             :             /* assume the connection is broken */
     262           0 :             result_errno = ECONNRESET;
     263           0 :             n = -1;
     264           0 :             break;
     265             :     }
     266             : 
     267             :     /* ensure we return the intended errno to caller */
     268         480 :     SOCK_ERRNO_SET(result_errno);
     269             : 
     270         480 :     return n;
     271             : }
     272             : 
     273             : bool
     274         666 : pgtls_read_pending(PGconn *conn)
     275             : {
     276         666 :     return SSL_pending(conn->ssl) > 0;
     277             : }
     278             : 
     279             : ssize_t
     280         326 : pgtls_write(PGconn *conn, const void *ptr, size_t len)
     281             : {
     282             :     ssize_t     n;
     283         326 :     int         result_errno = 0;
     284             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     285             :     int         err;
     286             :     unsigned long ecode;
     287             : 
     288         326 :     SOCK_ERRNO_SET(0);
     289         326 :     ERR_clear_error();
     290         326 :     n = SSL_write(conn->ssl, ptr, len);
     291         326 :     err = SSL_get_error(conn->ssl, n);
     292         326 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     293         326 :     switch (err)
     294             :     {
     295         326 :         case SSL_ERROR_NONE:
     296         326 :             if (n < 0)
     297             :             {
     298             :                 /* Not supposed to happen, so we don't translate the msg */
     299           0 :                 appendPQExpBufferStr(&conn->errorMessage,
     300             :                                      "SSL_write failed but did not provide error information\n");
     301             :                 /* assume the connection is broken */
     302           0 :                 result_errno = ECONNRESET;
     303             :             }
     304         326 :             break;
     305           0 :         case SSL_ERROR_WANT_READ:
     306             : 
     307             :             /*
     308             :              * Returning 0 here causes caller to wait for write-ready, which
     309             :              * is not really the right thing, but it's the best we can do.
     310             :              */
     311           0 :             n = 0;
     312           0 :             break;
     313           0 :         case SSL_ERROR_WANT_WRITE:
     314           0 :             n = 0;
     315           0 :             break;
     316           0 :         case SSL_ERROR_SYSCALL:
     317           0 :             if (n < 0)
     318             :             {
     319           0 :                 result_errno = SOCK_ERRNO;
     320           0 :                 if (result_errno == EPIPE || result_errno == ECONNRESET)
     321           0 :                     appendPQExpBufferStr(&conn->errorMessage,
     322           0 :                                          libpq_gettext("server closed the connection unexpectedly\n"
     323             :                                                        "\tThis probably means the server terminated abnormally\n"
     324             :                                                        "\tbefore or while processing the request.\n"));
     325             :                 else
     326           0 :                     appendPQExpBuffer(&conn->errorMessage,
     327           0 :                                       libpq_gettext("SSL SYSCALL error: %s\n"),
     328             :                                       SOCK_STRERROR(result_errno,
     329             :                                                     sebuf, sizeof(sebuf)));
     330             :             }
     331             :             else
     332             :             {
     333           0 :                 appendPQExpBufferStr(&conn->errorMessage,
     334           0 :                                      libpq_gettext("SSL SYSCALL error: EOF detected\n"));
     335             :                 /* assume the connection is broken */
     336           0 :                 result_errno = ECONNRESET;
     337           0 :                 n = -1;
     338             :             }
     339           0 :             break;
     340           0 :         case SSL_ERROR_SSL:
     341             :             {
     342           0 :                 char       *errm = SSLerrmessage(ecode);
     343             : 
     344           0 :                 appendPQExpBuffer(&conn->errorMessage,
     345           0 :                                   libpq_gettext("SSL error: %s\n"), errm);
     346           0 :                 SSLerrfree(errm);
     347             :                 /* assume the connection is broken */
     348           0 :                 result_errno = ECONNRESET;
     349           0 :                 n = -1;
     350           0 :                 break;
     351             :             }
     352           0 :         case SSL_ERROR_ZERO_RETURN:
     353             : 
     354             :             /*
     355             :              * Per OpenSSL documentation, this error code is only returned for
     356             :              * a clean connection closure, so we should not report it as a
     357             :              * server crash.
     358             :              */
     359           0 :             appendPQExpBufferStr(&conn->errorMessage,
     360           0 :                                  libpq_gettext("SSL connection has been closed unexpectedly\n"));
     361           0 :             result_errno = ECONNRESET;
     362           0 :             n = -1;
     363           0 :             break;
     364           0 :         default:
     365           0 :             appendPQExpBuffer(&conn->errorMessage,
     366           0 :                               libpq_gettext("unrecognized SSL error code: %d\n"),
     367             :                               err);
     368             :             /* assume the connection is broken */
     369           0 :             result_errno = ECONNRESET;
     370           0 :             n = -1;
     371           0 :             break;
     372             :     }
     373             : 
     374             :     /* ensure we return the intended errno to caller */
     375         326 :     SOCK_ERRNO_SET(result_errno);
     376             : 
     377         326 :     return n;
     378             : }
     379             : 
     380             : #ifdef HAVE_X509_GET_SIGNATURE_NID
     381             : char *
     382           6 : pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
     383             : {
     384             :     X509       *peer_cert;
     385             :     const EVP_MD *algo_type;
     386             :     unsigned char hash[EVP_MAX_MD_SIZE];    /* size for SHA-512 */
     387             :     unsigned int hash_size;
     388             :     int         algo_nid;
     389             :     char       *cert_hash;
     390             : 
     391           6 :     *len = 0;
     392             : 
     393           6 :     if (!conn->peer)
     394           0 :         return NULL;
     395             : 
     396           6 :     peer_cert = conn->peer;
     397             : 
     398             :     /*
     399             :      * Get the signature algorithm of the certificate to determine the hash
     400             :      * algorithm to use for the result.
     401             :      */
     402           6 :     if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
     403             :                              &algo_nid, NULL))
     404             :     {
     405           0 :         appendPQExpBufferStr(&conn->errorMessage,
     406           0 :                              libpq_gettext("could not determine server certificate signature algorithm\n"));
     407           0 :         return NULL;
     408             :     }
     409             : 
     410             :     /*
     411             :      * The TLS server's certificate bytes need to be hashed with SHA-256 if
     412             :      * its signature algorithm is MD5 or SHA-1 as per RFC 5929
     413             :      * (https://tools.ietf.org/html/rfc5929#section-4.1).  If something else
     414             :      * is used, the same hash as the signature algorithm is used.
     415             :      */
     416           6 :     switch (algo_nid)
     417             :     {
     418           0 :         case NID_md5:
     419             :         case NID_sha1:
     420           0 :             algo_type = EVP_sha256();
     421           0 :             break;
     422           6 :         default:
     423           6 :             algo_type = EVP_get_digestbynid(algo_nid);
     424           6 :             if (algo_type == NULL)
     425             :             {
     426           0 :                 appendPQExpBuffer(&conn->errorMessage,
     427           0 :                                   libpq_gettext("could not find digest for NID %s\n"),
     428             :                                   OBJ_nid2sn(algo_nid));
     429           0 :                 return NULL;
     430             :             }
     431           6 :             break;
     432             :     }
     433             : 
     434           6 :     if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
     435             :     {
     436           0 :         appendPQExpBufferStr(&conn->errorMessage,
     437           0 :                              libpq_gettext("could not generate peer certificate hash\n"));
     438           0 :         return NULL;
     439             :     }
     440             : 
     441             :     /* save result */
     442           6 :     cert_hash = malloc(hash_size);
     443           6 :     if (cert_hash == NULL)
     444             :     {
     445           0 :         appendPQExpBufferStr(&conn->errorMessage,
     446           0 :                              libpq_gettext("out of memory\n"));
     447           0 :         return NULL;
     448             :     }
     449           6 :     memcpy(cert_hash, hash, hash_size);
     450           6 :     *len = hash_size;
     451             : 
     452           6 :     return cert_hash;
     453             : }
     454             : #endif                          /* HAVE_X509_GET_SIGNATURE_NID */
     455             : 
     456             : /* ------------------------------------------------------------ */
     457             : /*                      OpenSSL specific code                   */
     458             : /* ------------------------------------------------------------ */
     459             : 
     460             : /*
     461             :  *  Certificate verification callback
     462             :  *
     463             :  *  This callback allows us to log intermediate problems during
     464             :  *  verification, but there doesn't seem to be a clean way to get
     465             :  *  our PGconn * structure.  So we can't log anything!
     466             :  *
     467             :  *  This callback also allows us to override the default acceptance
     468             :  *  criteria (e.g., accepting self-signed or expired certs), but
     469             :  *  for now we accept the default checks.
     470             :  */
     471             : static int
     472         352 : verify_cb(int ok, X509_STORE_CTX *ctx)
     473             : {
     474         352 :     return ok;
     475             : }
     476             : 
     477             : 
     478             : /*
     479             :  * OpenSSL-specific wrapper around
     480             :  * pq_verify_peer_name_matches_certificate_name(), converting the ASN1_STRING
     481             :  * into a plain C string.
     482             :  */
     483             : static int
     484          44 : openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
     485             :                                                   char **store_name)
     486             : {
     487             :     int         len;
     488             :     const unsigned char *namedata;
     489             : 
     490             :     /* Should not happen... */
     491          44 :     if (name_entry == NULL)
     492             :     {
     493           0 :         appendPQExpBufferStr(&conn->errorMessage,
     494           0 :                              libpq_gettext("SSL certificate's name entry is missing\n"));
     495           0 :         return -1;
     496             :     }
     497             : 
     498             :     /*
     499             :      * GEN_DNS can be only IA5String, equivalent to US ASCII.
     500             :      */
     501             : #ifdef HAVE_ASN1_STRING_GET0_DATA
     502          44 :     namedata = ASN1_STRING_get0_data(name_entry);
     503             : #else
     504             :     namedata = ASN1_STRING_data(name_entry);
     505             : #endif
     506          44 :     len = ASN1_STRING_length(name_entry);
     507             : 
     508             :     /* OK to cast from unsigned to plain char, since it's all ASCII. */
     509          44 :     return pq_verify_peer_name_matches_certificate_name(conn, (const char *) namedata, len, store_name);
     510             : }
     511             : 
     512             : /*
     513             :  *  Verify that the server certificate matches the hostname we connected to.
     514             :  *
     515             :  * The certificate's Common Name and Subject Alternative Names are considered.
     516             :  */
     517             : int
     518          28 : pgtls_verify_peer_name_matches_certificate_guts(PGconn *conn,
     519             :                                                 int *names_examined,
     520             :                                                 char **first_name)
     521             : {
     522             :     STACK_OF(GENERAL_NAME) * peer_san;
     523             :     int         i;
     524          28 :     int         rc = 0;
     525             : 
     526             :     /*
     527             :      * First, get the Subject Alternative Names (SANs) from the certificate,
     528             :      * and compare them against the originally given hostname.
     529             :      */
     530             :     peer_san = (STACK_OF(GENERAL_NAME) *)
     531          28 :         X509_get_ext_d2i(conn->peer, NID_subject_alt_name, NULL, NULL);
     532             : 
     533          28 :     if (peer_san)
     534             :     {
     535          22 :         int         san_len = sk_GENERAL_NAME_num(peer_san);
     536             : 
     537          50 :         for (i = 0; i < san_len; i++)
     538             :         {
     539          40 :             const GENERAL_NAME *name = sk_GENERAL_NAME_value(peer_san, i);
     540             : 
     541          40 :             if (name->type == GEN_DNS)
     542             :             {
     543             :                 char       *alt_name;
     544             : 
     545          40 :                 (*names_examined)++;
     546          40 :                 rc = openssl_verify_peer_name_matches_certificate_name(conn,
     547          40 :                                                                        name->d.dNSName,
     548             :                                                                        &alt_name);
     549             : 
     550          40 :                 if (alt_name)
     551             :                 {
     552          40 :                     if (!*first_name)
     553          22 :                         *first_name = alt_name;
     554             :                     else
     555          18 :                         free(alt_name);
     556             :                 }
     557             :             }
     558          40 :             if (rc != 0)
     559          12 :                 break;
     560             :         }
     561          22 :         sk_GENERAL_NAME_pop_free(peer_san, GENERAL_NAME_free);
     562             :     }
     563             : 
     564             :     /*
     565             :      * If there is no subjectAltName extension of type dNSName, check the
     566             :      * Common Name.
     567             :      *
     568             :      * (Per RFC 2818 and RFC 6125, if the subjectAltName extension of type
     569             :      * dNSName is present, the CN must be ignored.)
     570             :      */
     571          28 :     if (*names_examined == 0)
     572             :     {
     573             :         X509_NAME  *subject_name;
     574             : 
     575           6 :         subject_name = X509_get_subject_name(conn->peer);
     576           6 :         if (subject_name != NULL)
     577             :         {
     578             :             int         cn_index;
     579             : 
     580           6 :             cn_index = X509_NAME_get_index_by_NID(subject_name,
     581             :                                                   NID_commonName, -1);
     582           6 :             if (cn_index >= 0)
     583             :             {
     584           4 :                 (*names_examined)++;
     585           4 :                 rc = openssl_verify_peer_name_matches_certificate_name(conn,
     586           4 :                                                                        X509_NAME_ENTRY_get_data(X509_NAME_get_entry(subject_name, cn_index)),
     587             :                                                                        first_name);
     588             :             }
     589             :         }
     590             :     }
     591             : 
     592          28 :     return rc;
     593             : }
     594             : 
     595             : #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
     596             : /*
     597             :  *  Callback functions for OpenSSL internal locking.  (OpenSSL 1.1.0
     598             :  *  does its own locking, and doesn't need these anymore.  The
     599             :  *  CRYPTO_lock() function was removed in 1.1.0, when the callbacks
     600             :  *  were made obsolete, so we assume that if CRYPTO_lock() exists,
     601             :  *  the callbacks are still required.)
     602             :  */
     603             : 
     604             : static unsigned long
     605             : pq_threadidcallback(void)
     606             : {
     607             :     /*
     608             :      * This is not standards-compliant.  pthread_self() returns pthread_t, and
     609             :      * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
     610             :      * it, so we have to do it.
     611             :      */
     612             :     return (unsigned long) pthread_self();
     613             : }
     614             : 
     615             : static pthread_mutex_t *pq_lockarray;
     616             : 
     617             : static void
     618             : pq_lockingcallback(int mode, int n, const char *file, int line)
     619             : {
     620             :     /*
     621             :      * There's no way to report a mutex-primitive failure, so we just Assert
     622             :      * in development builds, and ignore any errors otherwise.  Fortunately
     623             :      * this is all obsolete in modern OpenSSL.
     624             :      */
     625             :     if (mode & CRYPTO_LOCK)
     626             :     {
     627             :         if (pthread_mutex_lock(&pq_lockarray[n]))
     628             :             Assert(false);
     629             :     }
     630             :     else
     631             :     {
     632             :         if (pthread_mutex_unlock(&pq_lockarray[n]))
     633             :             Assert(false);
     634             :     }
     635             : }
     636             : #endif                          /* ENABLE_THREAD_SAFETY && HAVE_CRYPTO_LOCK */
     637             : 
     638             : /*
     639             :  * Initialize SSL library.
     640             :  *
     641             :  * In threadsafe mode, this includes setting up libcrypto callback functions
     642             :  * to do thread locking.
     643             :  *
     644             :  * If the caller has told us (through PQinitOpenSSL) that he's taking care
     645             :  * of libcrypto, we expect that callbacks are already set, and won't try to
     646             :  * override it.
     647             :  */
     648             : int
     649       12936 : pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
     650             : {
     651             : #ifdef ENABLE_THREAD_SAFETY
     652             : #ifdef WIN32
     653             :     /* Also see similar code in fe-connect.c, default_threadlock() */
     654             :     if (ssl_config_mutex == NULL)
     655             :     {
     656             :         while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
     657             :              /* loop, another thread own the lock */ ;
     658             :         if (ssl_config_mutex == NULL)
     659             :         {
     660             :             if (pthread_mutex_init(&ssl_config_mutex, NULL))
     661             :                 return -1;
     662             :         }
     663             :         InterlockedExchange(&win32_ssl_create_mutex, 0);
     664             :     }
     665             : #endif
     666       12936 :     if (pthread_mutex_lock(&ssl_config_mutex))
     667           0 :         return -1;
     668             : 
     669             : #ifdef HAVE_CRYPTO_LOCK
     670             :     if (pq_init_crypto_lib)
     671             :     {
     672             :         /*
     673             :          * If necessary, set up an array to hold locks for libcrypto.
     674             :          * libcrypto will tell us how big to make this array.
     675             :          */
     676             :         if (pq_lockarray == NULL)
     677             :         {
     678             :             int         i;
     679             : 
     680             :             pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
     681             :             if (!pq_lockarray)
     682             :             {
     683             :                 pthread_mutex_unlock(&ssl_config_mutex);
     684             :                 return -1;
     685             :             }
     686             :             for (i = 0; i < CRYPTO_num_locks(); i++)
     687             :             {
     688             :                 if (pthread_mutex_init(&pq_lockarray[i], NULL))
     689             :                 {
     690             :                     free(pq_lockarray);
     691             :                     pq_lockarray = NULL;
     692             :                     pthread_mutex_unlock(&ssl_config_mutex);
     693             :                     return -1;
     694             :                 }
     695             :             }
     696             :         }
     697             : 
     698             :         if (do_crypto && !conn->crypto_loaded)
     699             :         {
     700             :             if (crypto_open_connections++ == 0)
     701             :             {
     702             :                 /*
     703             :                  * These are only required for threaded libcrypto
     704             :                  * applications, but make sure we don't stomp on them if
     705             :                  * they're already set.
     706             :                  */
     707             :                 if (CRYPTO_get_id_callback() == NULL)
     708             :                     CRYPTO_set_id_callback(pq_threadidcallback);
     709             :                 if (CRYPTO_get_locking_callback() == NULL)
     710             :                     CRYPTO_set_locking_callback(pq_lockingcallback);
     711             :             }
     712             : 
     713             :             conn->crypto_loaded = true;
     714             :         }
     715             :     }
     716             : #endif                          /* HAVE_CRYPTO_LOCK */
     717             : #endif                          /* ENABLE_THREAD_SAFETY */
     718             : 
     719       12936 :     if (!ssl_lib_initialized && do_ssl)
     720             :     {
     721         152 :         if (pq_init_ssl_lib)
     722             :         {
     723             : #ifdef HAVE_OPENSSL_INIT_SSL
     724         152 :             OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
     725             : #else
     726             :             OPENSSL_config(NULL);
     727             :             SSL_library_init();
     728             :             SSL_load_error_strings();
     729             : #endif
     730             :         }
     731         152 :         ssl_lib_initialized = true;
     732             :     }
     733             : 
     734             : #ifdef ENABLE_THREAD_SAFETY
     735       12936 :     pthread_mutex_unlock(&ssl_config_mutex);
     736             : #endif
     737       12936 :     return 0;
     738             : }
     739             : 
     740             : /*
     741             :  *  This function is needed because if the libpq library is unloaded
     742             :  *  from the application, the callback functions will no longer exist when
     743             :  *  libcrypto is used by other parts of the system.  For this reason,
     744             :  *  we unregister the callback functions when the last libpq
     745             :  *  connection is closed.  (The same would apply for OpenSSL callbacks
     746             :  *  if we had any.)
     747             :  *
     748             :  *  Callbacks are only set when we're compiled in threadsafe mode, so
     749             :  *  we only need to remove them in this case. They are also not needed
     750             :  *  with OpenSSL 1.1.0 anymore.
     751             :  */
     752             : static void
     753         148 : destroy_ssl_system(void)
     754             : {
     755             : #if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
     756             :     /* Mutex is created in pgtls_init() */
     757             :     if (pthread_mutex_lock(&ssl_config_mutex))
     758             :         return;
     759             : 
     760             :     if (pq_init_crypto_lib && crypto_open_connections > 0)
     761             :         --crypto_open_connections;
     762             : 
     763             :     if (pq_init_crypto_lib && crypto_open_connections == 0)
     764             :     {
     765             :         /*
     766             :          * No connections left, unregister libcrypto callbacks, if no one
     767             :          * registered different ones in the meantime.
     768             :          */
     769             :         if (CRYPTO_get_locking_callback() == pq_lockingcallback)
     770             :             CRYPTO_set_locking_callback(NULL);
     771             :         if (CRYPTO_get_id_callback() == pq_threadidcallback)
     772             :             CRYPTO_set_id_callback(NULL);
     773             : 
     774             :         /*
     775             :          * We don't free the lock array. If we get another connection in this
     776             :          * process, we will just re-use them with the existing mutexes.
     777             :          *
     778             :          * This means we leak a little memory on repeated load/unload of the
     779             :          * library.
     780             :          */
     781             :     }
     782             : 
     783             :     pthread_mutex_unlock(&ssl_config_mutex);
     784             : #endif
     785         148 : }
     786             : 
     787             : /*
     788             :  *  Create per-connection SSL object, and load the client certificate,
     789             :  *  private key, and trusted CA certs.
     790             :  *
     791             :  *  Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
     792             :  */
     793             : static int
     794         152 : initialize_SSL(PGconn *conn)
     795             : {
     796             :     SSL_CTX    *SSL_context;
     797             :     struct stat buf;
     798             :     char        homedir[MAXPGPATH];
     799             :     char        fnbuf[MAXPGPATH];
     800             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     801             :     bool        have_homedir;
     802             :     bool        have_cert;
     803             :     bool        have_rootcert;
     804         152 :     EVP_PKEY   *pkey = NULL;
     805             : 
     806             :     /*
     807             :      * We'll need the home directory if any of the relevant parameters are
     808             :      * defaulted.  If pqGetHomeDirectory fails, act as though none of the
     809             :      * files could be found.
     810             :      */
     811         152 :     if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
     812         148 :         !(conn->sslkey && strlen(conn->sslkey) > 0) ||
     813          62 :         !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
     814          62 :         !((conn->sslcrl && strlen(conn->sslcrl) > 0) ||
     815          62 :           (conn->sslcrldir && strlen(conn->sslcrldir) > 0)))
     816         152 :         have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
     817             :     else                        /* won't need it */
     818           0 :         have_homedir = false;
     819             : 
     820             :     /*
     821             :      * Create a new SSL_CTX object.
     822             :      *
     823             :      * We used to share a single SSL_CTX between all connections, but it was
     824             :      * complicated if connections used different certificates. So now we
     825             :      * create a separate context for each connection, and accept the overhead.
     826             :      */
     827         152 :     SSL_context = SSL_CTX_new(SSLv23_method());
     828         152 :     if (!SSL_context)
     829             :     {
     830           0 :         char       *err = SSLerrmessage(ERR_get_error());
     831             : 
     832           0 :         appendPQExpBuffer(&conn->errorMessage,
     833           0 :                           libpq_gettext("could not create SSL context: %s\n"),
     834             :                           err);
     835           0 :         SSLerrfree(err);
     836           0 :         return -1;
     837             :     }
     838             : 
     839             :     /*
     840             :      * Delegate the client cert password prompt to the libpq wrapper callback
     841             :      * if any is defined.
     842             :      *
     843             :      * If the application hasn't installed its own and the sslpassword
     844             :      * parameter is non-null, we install ours now to make sure we supply
     845             :      * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin.
     846             :      *
     847             :      * This will replace OpenSSL's default PEM_def_callback (which prompts on
     848             :      * stdin), but we're only setting it for this SSL context so it's
     849             :      * harmless.
     850             :      */
     851         152 :     if (PQsslKeyPassHook
     852         152 :         || (conn->sslpassword && strlen(conn->sslpassword) > 0))
     853             :     {
     854           6 :         SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb);
     855           6 :         SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn);
     856             :     }
     857             : 
     858             :     /* Disable old protocol versions */
     859         152 :     SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
     860             : 
     861             :     /* Set the minimum and maximum protocol versions if necessary */
     862         152 :     if (conn->ssl_min_protocol_version &&
     863         152 :         strlen(conn->ssl_min_protocol_version) != 0)
     864             :     {
     865             :         int         ssl_min_ver;
     866             : 
     867         152 :         ssl_min_ver = ssl_protocol_version_to_openssl(conn->ssl_min_protocol_version);
     868             : 
     869         152 :         if (ssl_min_ver == -1)
     870             :         {
     871           0 :             appendPQExpBuffer(&conn->errorMessage,
     872           0 :                               libpq_gettext("invalid value \"%s\" for minimum SSL protocol version\n"),
     873             :                               conn->ssl_min_protocol_version);
     874           0 :             SSL_CTX_free(SSL_context);
     875           0 :             return -1;
     876             :         }
     877             : 
     878         152 :         if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver))
     879             :         {
     880           0 :             char       *err = SSLerrmessage(ERR_get_error());
     881             : 
     882           0 :             appendPQExpBuffer(&conn->errorMessage,
     883           0 :                               libpq_gettext("could not set minimum SSL protocol version: %s\n"),
     884             :                               err);
     885           0 :             SSLerrfree(err);
     886           0 :             SSL_CTX_free(SSL_context);
     887           0 :             return -1;
     888             :         }
     889             :     }
     890             : 
     891         152 :     if (conn->ssl_max_protocol_version &&
     892           4 :         strlen(conn->ssl_max_protocol_version) != 0)
     893             :     {
     894             :         int         ssl_max_ver;
     895             : 
     896           4 :         ssl_max_ver = ssl_protocol_version_to_openssl(conn->ssl_max_protocol_version);
     897             : 
     898           4 :         if (ssl_max_ver == -1)
     899             :         {
     900           0 :             appendPQExpBuffer(&conn->errorMessage,
     901           0 :                               libpq_gettext("invalid value \"%s\" for maximum SSL protocol version\n"),
     902             :                               conn->ssl_max_protocol_version);
     903           0 :             SSL_CTX_free(SSL_context);
     904           0 :             return -1;
     905             :         }
     906             : 
     907           4 :         if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver))
     908             :         {
     909           0 :             char       *err = SSLerrmessage(ERR_get_error());
     910             : 
     911           0 :             appendPQExpBuffer(&conn->errorMessage,
     912           0 :                               libpq_gettext("could not set maximum SSL protocol version: %s\n"),
     913             :                               err);
     914           0 :             SSLerrfree(err);
     915           0 :             SSL_CTX_free(SSL_context);
     916           0 :             return -1;
     917             :         }
     918             :     }
     919             : 
     920             :     /*
     921             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     922             :      * unnecessary failures in nonblocking send cases.
     923             :      */
     924         152 :     SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     925             : 
     926             :     /*
     927             :      * If the root cert file exists, load it so we can perform certificate
     928             :      * verification. If sslmode is "verify-full" we will also do further
     929             :      * verification after the connection has been completed.
     930             :      */
     931         152 :     if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
     932         152 :         strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
     933           0 :     else if (have_homedir)
     934           0 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
     935             :     else
     936           0 :         fnbuf[0] = '\0';
     937             : 
     938         304 :     if (fnbuf[0] != '\0' &&
     939         152 :         stat(fnbuf, &buf) == 0)
     940         132 :     {
     941             :         X509_STORE *cvstore;
     942             : 
     943         132 :         if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
     944             :         {
     945           0 :             char       *err = SSLerrmessage(ERR_get_error());
     946             : 
     947           0 :             appendPQExpBuffer(&conn->errorMessage,
     948           0 :                               libpq_gettext("could not read root certificate file \"%s\": %s\n"),
     949             :                               fnbuf, err);
     950           0 :             SSLerrfree(err);
     951           0 :             SSL_CTX_free(SSL_context);
     952           0 :             return -1;
     953             :         }
     954             : 
     955         132 :         if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
     956             :         {
     957         132 :             char       *fname = NULL;
     958         132 :             char       *dname = NULL;
     959             : 
     960         132 :             if (conn->sslcrl && strlen(conn->sslcrl) > 0)
     961           8 :                 fname = conn->sslcrl;
     962         132 :             if (conn->sslcrldir && strlen(conn->sslcrldir) > 0)
     963           6 :                 dname = conn->sslcrldir;
     964             : 
     965             :             /* defaults to use the default CRL file */
     966         132 :             if (!fname && !dname && have_homedir)
     967             :             {
     968         118 :                 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
     969         118 :                 fname = fnbuf;
     970             :             }
     971             : 
     972             :             /* Set the flags to check against the complete CRL chain */
     973         264 :             if ((fname || dname) &&
     974         132 :                 X509_STORE_load_locations(cvstore, fname, dname) == 1)
     975             :             {
     976          12 :                 X509_STORE_set_flags(cvstore,
     977             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     978             :             }
     979             : 
     980             :             /* if not found, silently ignore;  we do not require CRL */
     981         132 :             ERR_clear_error();
     982             :         }
     983         132 :         have_rootcert = true;
     984             :     }
     985             :     else
     986             :     {
     987             :         /*
     988             :          * stat() failed; assume root file doesn't exist.  If sslmode is
     989             :          * verify-ca or verify-full, this is an error.  Otherwise, continue
     990             :          * without performing any server cert verification.
     991             :          */
     992          20 :         if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
     993             :         {
     994             :             /*
     995             :              * The only way to reach here with an empty filename is if
     996             :              * pqGetHomeDirectory failed.  That's a sufficiently unusual case
     997             :              * that it seems worth having a specialized error message for it.
     998             :              */
     999           4 :             if (fnbuf[0] == '\0')
    1000           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1001           0 :                                   libpq_gettext("could not get home directory to locate root certificate file\n"
    1002             :                                                 "Either provide the file or change sslmode to disable server certificate verification.\n"));
    1003             :             else
    1004           4 :                 appendPQExpBuffer(&conn->errorMessage,
    1005           4 :                                   libpq_gettext("root certificate file \"%s\" does not exist\n"
    1006             :                                                 "Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
    1007           4 :             SSL_CTX_free(SSL_context);
    1008           4 :             return -1;
    1009             :         }
    1010          16 :         have_rootcert = false;
    1011             :     }
    1012             : 
    1013             :     /* Read the client certificate file */
    1014         148 :     if (conn->sslcert && strlen(conn->sslcert) > 0)
    1015         144 :         strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
    1016           4 :     else if (have_homedir)
    1017           4 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
    1018             :     else
    1019           0 :         fnbuf[0] = '\0';
    1020             : 
    1021         148 :     if (fnbuf[0] == '\0')
    1022             :     {
    1023             :         /* no home directory, proceed without a client cert */
    1024           0 :         have_cert = false;
    1025             :     }
    1026         148 :     else if (stat(fnbuf, &buf) != 0)
    1027             :     {
    1028             :         /*
    1029             :          * If file is not present, just go on without a client cert; server
    1030             :          * might or might not accept the connection.  Any other error,
    1031             :          * however, is grounds for complaint.
    1032             :          */
    1033          86 :         if (errno != ENOENT && errno != ENOTDIR)
    1034             :         {
    1035           0 :             appendPQExpBuffer(&conn->errorMessage,
    1036           0 :                               libpq_gettext("could not open certificate file \"%s\": %s\n"),
    1037           0 :                               fnbuf, strerror_r(errno, sebuf, sizeof(sebuf)));
    1038           0 :             SSL_CTX_free(SSL_context);
    1039           0 :             return -1;
    1040             :         }
    1041          86 :         have_cert = false;
    1042             :     }
    1043             :     else
    1044             :     {
    1045             :         /*
    1046             :          * Cert file exists, so load it. Since OpenSSL doesn't provide the
    1047             :          * equivalent of "SSL_use_certificate_chain_file", we have to load it
    1048             :          * into the SSL context, rather than the SSL object.
    1049             :          */
    1050          62 :         if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
    1051             :         {
    1052           0 :             char       *err = SSLerrmessage(ERR_get_error());
    1053             : 
    1054           0 :             appendPQExpBuffer(&conn->errorMessage,
    1055           0 :                               libpq_gettext("could not read certificate file \"%s\": %s\n"),
    1056             :                               fnbuf, err);
    1057           0 :             SSLerrfree(err);
    1058           0 :             SSL_CTX_free(SSL_context);
    1059           0 :             return -1;
    1060             :         }
    1061             : 
    1062             :         /* need to load the associated private key, too */
    1063          62 :         have_cert = true;
    1064             :     }
    1065             : 
    1066             :     /*
    1067             :      * The SSL context is now loaded with the correct root and client
    1068             :      * certificates. Create a connection-specific SSL object. The private key
    1069             :      * is loaded directly into the SSL object. (We could load the private key
    1070             :      * into the context, too, but we have done it this way historically, and
    1071             :      * it doesn't really matter.)
    1072             :      */
    1073         296 :     if (!(conn->ssl = SSL_new(SSL_context)) ||
    1074         296 :         !SSL_set_app_data(conn->ssl, conn) ||
    1075         148 :         !my_SSL_set_fd(conn, conn->sock))
    1076             :     {
    1077           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1078             : 
    1079           0 :         appendPQExpBuffer(&conn->errorMessage,
    1080           0 :                           libpq_gettext("could not establish SSL connection: %s\n"),
    1081             :                           err);
    1082           0 :         SSLerrfree(err);
    1083           0 :         SSL_CTX_free(SSL_context);
    1084           0 :         return -1;
    1085             :     }
    1086         148 :     conn->ssl_in_use = true;
    1087             : 
    1088             :     /*
    1089             :      * SSL contexts are reference counted by OpenSSL. We can free it as soon
    1090             :      * as we have created the SSL object, and it will stick around for as long
    1091             :      * as it's actually needed.
    1092             :      */
    1093         148 :     SSL_CTX_free(SSL_context);
    1094         148 :     SSL_context = NULL;
    1095             : 
    1096             :     /*
    1097             :      * Set Server Name Indication (SNI), if enabled by connection parameters.
    1098             :      * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
    1099             :      * or IPv6).
    1100             :      */
    1101         148 :     if (conn->sslsni && conn->sslsni[0] == '1')
    1102             :     {
    1103         148 :         const char *host = conn->connhost[conn->whichhost].host;
    1104             : 
    1105         148 :         if (host && host[0] &&
    1106         148 :             !(strspn(host, "0123456789.") == strlen(host) ||
    1107         148 :               strchr(host, ':')))
    1108             :         {
    1109         148 :             if (SSL_set_tlsext_host_name(conn->ssl, host) != 1)
    1110             :             {
    1111           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1112             : 
    1113           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1114           0 :                                   libpq_gettext("could not set SSL Server Name Indication (SNI): %s\n"),
    1115             :                                   err);
    1116           0 :                 SSLerrfree(err);
    1117           0 :                 return -1;
    1118             :             }
    1119             :         }
    1120             :     }
    1121             : 
    1122             :     /*
    1123             :      * Read the SSL key. If a key is specified, treat it as an engine:key
    1124             :      * combination if there is colon present - we don't support files with
    1125             :      * colon in the name. The exception is if the second character is a colon,
    1126             :      * in which case it can be a Windows filename with drive specification.
    1127             :      */
    1128         148 :     if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0)
    1129             :     {
    1130             : #ifdef USE_SSL_ENGINE
    1131          62 :         if (strchr(conn->sslkey, ':')
    1132             : #ifdef WIN32
    1133             :             && conn->sslkey[1] != ':'
    1134             : #endif
    1135             :             )
    1136             :         {
    1137             :             /* Colon, but not in second character, treat as engine:key */
    1138           0 :             char       *engine_str = strdup(conn->sslkey);
    1139             :             char       *engine_colon;
    1140             : 
    1141           0 :             if (engine_str == NULL)
    1142             :             {
    1143           0 :                 appendPQExpBufferStr(&conn->errorMessage,
    1144           0 :                                      libpq_gettext("out of memory\n"));
    1145           0 :                 return -1;
    1146             :             }
    1147             : 
    1148             :             /* cannot return NULL because we already checked before strdup */
    1149           0 :             engine_colon = strchr(engine_str, ':');
    1150             : 
    1151           0 :             *engine_colon = '\0';   /* engine_str now has engine name */
    1152           0 :             engine_colon++;     /* engine_colon now has key name */
    1153             : 
    1154           0 :             conn->engine = ENGINE_by_id(engine_str);
    1155           0 :             if (conn->engine == NULL)
    1156             :             {
    1157           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1158             : 
    1159           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1160           0 :                                   libpq_gettext("could not load SSL engine \"%s\": %s\n"),
    1161             :                                   engine_str, err);
    1162           0 :                 SSLerrfree(err);
    1163           0 :                 free(engine_str);
    1164           0 :                 return -1;
    1165             :             }
    1166             : 
    1167           0 :             if (ENGINE_init(conn->engine) == 0)
    1168             :             {
    1169           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1170             : 
    1171           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1172           0 :                                   libpq_gettext("could not initialize SSL engine \"%s\": %s\n"),
    1173             :                                   engine_str, err);
    1174           0 :                 SSLerrfree(err);
    1175           0 :                 ENGINE_free(conn->engine);
    1176           0 :                 conn->engine = NULL;
    1177           0 :                 free(engine_str);
    1178           0 :                 return -1;
    1179             :             }
    1180             : 
    1181           0 :             pkey = ENGINE_load_private_key(conn->engine, engine_colon,
    1182             :                                            NULL, NULL);
    1183           0 :             if (pkey == NULL)
    1184             :             {
    1185           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1186             : 
    1187           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1188           0 :                                   libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
    1189             :                                   engine_colon, engine_str, err);
    1190           0 :                 SSLerrfree(err);
    1191           0 :                 ENGINE_finish(conn->engine);
    1192           0 :                 ENGINE_free(conn->engine);
    1193           0 :                 conn->engine = NULL;
    1194           0 :                 free(engine_str);
    1195           0 :                 return -1;
    1196             :             }
    1197           0 :             if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
    1198             :             {
    1199           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1200             : 
    1201           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1202           0 :                                   libpq_gettext("could not load private SSL key \"%s\" from engine \"%s\": %s\n"),
    1203             :                                   engine_colon, engine_str, err);
    1204           0 :                 SSLerrfree(err);
    1205           0 :                 ENGINE_finish(conn->engine);
    1206           0 :                 ENGINE_free(conn->engine);
    1207           0 :                 conn->engine = NULL;
    1208           0 :                 free(engine_str);
    1209           0 :                 return -1;
    1210             :             }
    1211             : 
    1212           0 :             free(engine_str);
    1213             : 
    1214           0 :             fnbuf[0] = '\0';    /* indicate we're not going to load from a
    1215             :                                  * file */
    1216             :         }
    1217             :         else
    1218             : #endif                          /* USE_SSL_ENGINE */
    1219             :         {
    1220             :             /* PGSSLKEY is not an engine, treat it as a filename */
    1221          62 :             strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
    1222             :         }
    1223             :     }
    1224          86 :     else if (have_homedir)
    1225             :     {
    1226             :         /* No PGSSLKEY specified, load default file */
    1227          86 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
    1228             :     }
    1229             :     else
    1230           0 :         fnbuf[0] = '\0';
    1231             : 
    1232         148 :     if (have_cert && fnbuf[0] != '\0')
    1233             :     {
    1234             :         /* read the client key from file */
    1235             : 
    1236          62 :         if (stat(fnbuf, &buf) != 0)
    1237             :         {
    1238           0 :             if (errno == ENOENT)
    1239           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1240           0 :                                   libpq_gettext("certificate present, but not private key file \"%s\"\n"),
    1241             :                                   fnbuf);
    1242             :             else
    1243           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1244           0 :                                   libpq_gettext("could not stat private key file \"%s\": %m\n"),
    1245             :                                   fnbuf);
    1246           0 :             return -1;
    1247             :         }
    1248             : #ifndef WIN32
    1249          62 :         if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
    1250             :         {
    1251           2 :             appendPQExpBuffer(&conn->errorMessage,
    1252           2 :                               libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
    1253             :                               fnbuf);
    1254           2 :             return -1;
    1255             :         }
    1256             : #endif
    1257             : 
    1258          60 :         if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
    1259             :         {
    1260           6 :             char       *err = SSLerrmessage(ERR_get_error());
    1261             : 
    1262             :             /*
    1263             :              * We'll try to load the file in DER (binary ASN.1) format, and if
    1264             :              * that fails too, report the original error. This could mask
    1265             :              * issues where there's something wrong with a DER-format cert,
    1266             :              * but we'd have to duplicate openssl's format detection to be
    1267             :              * smarter than this. We can't just probe for a leading -----BEGIN
    1268             :              * because PEM can have leading non-matching lines and blanks.
    1269             :              * OpenSSL doesn't expose its get_name(...) and its PEM routines
    1270             :              * don't differentiate between failure modes in enough detail to
    1271             :              * let us tell the difference between "not PEM, try DER" and
    1272             :              * "wrong password".
    1273             :              */
    1274           6 :             if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1)
    1275             :             {
    1276           2 :                 appendPQExpBuffer(&conn->errorMessage,
    1277           2 :                                   libpq_gettext("could not load private key file \"%s\": %s\n"),
    1278             :                                   fnbuf, err);
    1279           2 :                 SSLerrfree(err);
    1280           2 :                 return -1;
    1281             :             }
    1282             : 
    1283           4 :             SSLerrfree(err);
    1284             : 
    1285             :         }
    1286             :     }
    1287             : 
    1288             :     /* verify that the cert and key go together */
    1289         202 :     if (have_cert &&
    1290          58 :         SSL_check_private_key(conn->ssl) != 1)
    1291             :     {
    1292           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1293             : 
    1294           0 :         appendPQExpBuffer(&conn->errorMessage,
    1295           0 :                           libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
    1296             :                           fnbuf, err);
    1297           0 :         SSLerrfree(err);
    1298           0 :         return -1;
    1299             :     }
    1300             : 
    1301             :     /*
    1302             :      * If a root cert was loaded, also set our certificate verification
    1303             :      * callback.
    1304             :      */
    1305         144 :     if (have_rootcert)
    1306         128 :         SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
    1307             : 
    1308             :     /*
    1309             :      * Set compression option if necessary.
    1310             :      */
    1311         144 :     if (conn->sslcompression && conn->sslcompression[0] == '0')
    1312         144 :         SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
    1313             :     else
    1314           0 :         SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
    1315             : 
    1316         144 :     return 0;
    1317             : }
    1318             : 
    1319             : /*
    1320             :  *  Attempt to negotiate SSL connection.
    1321             :  */
    1322             : static PostgresPollingStatusType
    1323         428 : open_client_SSL(PGconn *conn)
    1324             : {
    1325             :     int         r;
    1326             : 
    1327         428 :     ERR_clear_error();
    1328         428 :     r = SSL_connect(conn->ssl);
    1329         428 :     if (r <= 0)
    1330             :     {
    1331         300 :         int         err = SSL_get_error(conn->ssl, r);
    1332             :         unsigned long ecode;
    1333             : 
    1334         300 :         ecode = ERR_get_error();
    1335         300 :         switch (err)
    1336             :         {
    1337         284 :             case SSL_ERROR_WANT_READ:
    1338         284 :                 return PGRES_POLLING_READING;
    1339             : 
    1340           0 :             case SSL_ERROR_WANT_WRITE:
    1341           0 :                 return PGRES_POLLING_WRITING;
    1342             : 
    1343           0 :             case SSL_ERROR_SYSCALL:
    1344             :                 {
    1345             :                     char        sebuf[PG_STRERROR_R_BUFLEN];
    1346             : 
    1347           0 :                     if (r == -1)
    1348           0 :                         appendPQExpBuffer(&conn->errorMessage,
    1349           0 :                                           libpq_gettext("SSL SYSCALL error: %s\n"),
    1350           0 :                                           SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
    1351             :                     else
    1352           0 :                         appendPQExpBufferStr(&conn->errorMessage,
    1353           0 :                                              libpq_gettext("SSL SYSCALL error: EOF detected\n"));
    1354           0 :                     pgtls_close(conn);
    1355           0 :                     return PGRES_POLLING_FAILED;
    1356             :                 }
    1357          16 :             case SSL_ERROR_SSL:
    1358             :                 {
    1359          16 :                     char       *err = SSLerrmessage(ecode);
    1360             : 
    1361          16 :                     appendPQExpBuffer(&conn->errorMessage,
    1362          16 :                                       libpq_gettext("SSL error: %s\n"),
    1363             :                                       err);
    1364          16 :                     SSLerrfree(err);
    1365          16 :                     switch (ERR_GET_REASON(ecode))
    1366             :                     {
    1367             :                             /*
    1368             :                              * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
    1369             :                              * TLSV1_ALERT_PROTOCOL_VERSION have been observed
    1370             :                              * when trying to communicate with an old OpenSSL
    1371             :                              * library, or when the client and server specify
    1372             :                              * disjoint protocol ranges.
    1373             :                              * NO_PROTOCOLS_AVAILABLE occurs if there's a
    1374             :                              * local misconfiguration (which can happen
    1375             :                              * despite our checks, if openssl.cnf injects a
    1376             :                              * limit we didn't account for).  It's not very
    1377             :                              * clear what would make OpenSSL return the other
    1378             :                              * codes listed here, but a hint about protocol
    1379             :                              * versions seems like it's appropriate for all.
    1380             :                              */
    1381           0 :                         case SSL_R_NO_PROTOCOLS_AVAILABLE:
    1382             :                         case SSL_R_UNSUPPORTED_PROTOCOL:
    1383             :                         case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
    1384             :                         case SSL_R_UNKNOWN_PROTOCOL:
    1385             :                         case SSL_R_UNKNOWN_SSL_VERSION:
    1386             :                         case SSL_R_UNSUPPORTED_SSL_VERSION:
    1387             :                         case SSL_R_WRONG_SSL_VERSION:
    1388             :                         case SSL_R_WRONG_VERSION_NUMBER:
    1389             :                         case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
    1390             : #ifdef SSL_R_VERSION_TOO_HIGH
    1391             :                         case SSL_R_VERSION_TOO_HIGH:
    1392             :                         case SSL_R_VERSION_TOO_LOW:
    1393             : #endif
    1394           0 :                             appendPQExpBuffer(&conn->errorMessage,
    1395           0 :                                               libpq_gettext("This may indicate that the server does not support any SSL protocol version between %s and %s.\n"),
    1396           0 :                                               conn->ssl_min_protocol_version ?
    1397             :                                               conn->ssl_min_protocol_version :
    1398             :                                               MIN_OPENSSL_TLS_VERSION,
    1399           0 :                                               conn->ssl_max_protocol_version ?
    1400             :                                               conn->ssl_max_protocol_version :
    1401             :                                               MAX_OPENSSL_TLS_VERSION);
    1402           0 :                             break;
    1403          16 :                         default:
    1404          16 :                             break;
    1405             :                     }
    1406          16 :                     pgtls_close(conn);
    1407          16 :                     return PGRES_POLLING_FAILED;
    1408             :                 }
    1409             : 
    1410           0 :             default:
    1411           0 :                 appendPQExpBuffer(&conn->errorMessage,
    1412           0 :                                   libpq_gettext("unrecognized SSL error code: %d\n"),
    1413             :                                   err);
    1414           0 :                 pgtls_close(conn);
    1415           0 :                 return PGRES_POLLING_FAILED;
    1416             :         }
    1417             :     }
    1418             : 
    1419             :     /*
    1420             :      * We already checked the server certificate in initialize_SSL() using
    1421             :      * SSL_CTX_set_verify(), if root.crt exists.
    1422             :      */
    1423             : 
    1424             :     /* get server certificate */
    1425         128 :     conn->peer = SSL_get_peer_certificate(conn->ssl);
    1426         128 :     if (conn->peer == NULL)
    1427             :     {
    1428           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1429             : 
    1430           0 :         appendPQExpBuffer(&conn->errorMessage,
    1431           0 :                           libpq_gettext("certificate could not be obtained: %s\n"),
    1432             :                           err);
    1433           0 :         SSLerrfree(err);
    1434           0 :         pgtls_close(conn);
    1435           0 :         return PGRES_POLLING_FAILED;
    1436             :     }
    1437             : 
    1438         128 :     if (!pq_verify_peer_name_matches_certificate(conn))
    1439             :     {
    1440          14 :         pgtls_close(conn);
    1441          14 :         return PGRES_POLLING_FAILED;
    1442             :     }
    1443             : 
    1444             :     /* SSL handshake is complete */
    1445         114 :     return PGRES_POLLING_OK;
    1446             : }
    1447             : 
    1448             : void
    1449       25648 : pgtls_close(PGconn *conn)
    1450             : {
    1451       25648 :     bool        destroy_needed = false;
    1452             : 
    1453       25648 :     if (conn->ssl_in_use)
    1454             :     {
    1455         148 :         if (conn->ssl)
    1456             :         {
    1457             :             /*
    1458             :              * We can't destroy everything SSL-related here due to the
    1459             :              * possible later calls to OpenSSL routines which may need our
    1460             :              * thread callbacks, so set a flag here and check at the end.
    1461             :              */
    1462             : 
    1463         148 :             SSL_shutdown(conn->ssl);
    1464         148 :             SSL_free(conn->ssl);
    1465         148 :             conn->ssl = NULL;
    1466         148 :             conn->ssl_in_use = false;
    1467             : 
    1468         148 :             destroy_needed = true;
    1469             :         }
    1470             : 
    1471         148 :         if (conn->peer)
    1472             :         {
    1473         128 :             X509_free(conn->peer);
    1474         128 :             conn->peer = NULL;
    1475             :         }
    1476             : 
    1477             : #ifdef USE_SSL_ENGINE
    1478         148 :         if (conn->engine)
    1479             :         {
    1480           0 :             ENGINE_finish(conn->engine);
    1481           0 :             ENGINE_free(conn->engine);
    1482           0 :             conn->engine = NULL;
    1483             :         }
    1484             : #endif
    1485             :     }
    1486             :     else
    1487             :     {
    1488             :         /*
    1489             :          * In the non-SSL case, just remove the crypto callbacks if the
    1490             :          * connection has then loaded.  This code path has no dependency on
    1491             :          * any pending SSL calls.
    1492             :          */
    1493       25500 :         if (conn->crypto_loaded)
    1494           0 :             destroy_needed = true;
    1495             :     }
    1496             : 
    1497             :     /*
    1498             :      * This will remove our crypto locking hooks if this is the last
    1499             :      * connection using libcrypto which means we must wait to call it until
    1500             :      * after all the potential SSL calls have been made, otherwise we can end
    1501             :      * up with a race condition and possible deadlocks.
    1502             :      *
    1503             :      * See comments above destroy_ssl_system().
    1504             :      */
    1505       25648 :     if (destroy_needed)
    1506             :     {
    1507         148 :         destroy_ssl_system();
    1508         148 :         conn->crypto_loaded = false;
    1509             :     }
    1510       25648 : }
    1511             : 
    1512             : 
    1513             : /*
    1514             :  * Obtain reason string for passed SSL errcode
    1515             :  *
    1516             :  * ERR_get_error() is used by caller to get errcode to pass here.
    1517             :  *
    1518             :  * Some caution is needed here since ERR_reason_error_string will
    1519             :  * return NULL if it doesn't recognize the error code.  We don't
    1520             :  * want to return NULL ever.
    1521             :  */
    1522             : static char ssl_nomem[] = "out of memory allocating error description";
    1523             : 
    1524             : #define SSL_ERR_LEN 128
    1525             : 
    1526             : static char *
    1527          28 : SSLerrmessage(unsigned long ecode)
    1528             : {
    1529             :     const char *errreason;
    1530             :     char       *errbuf;
    1531             : 
    1532          28 :     errbuf = malloc(SSL_ERR_LEN);
    1533          28 :     if (!errbuf)
    1534           0 :         return ssl_nomem;
    1535          28 :     if (ecode == 0)
    1536             :     {
    1537           0 :         snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
    1538           0 :         return errbuf;
    1539             :     }
    1540          28 :     errreason = ERR_reason_error_string(ecode);
    1541          28 :     if (errreason != NULL)
    1542             :     {
    1543          28 :         strlcpy(errbuf, errreason, SSL_ERR_LEN);
    1544          28 :         return errbuf;
    1545             :     }
    1546           0 :     snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
    1547           0 :     return errbuf;
    1548             : }
    1549             : 
    1550             : static void
    1551          28 : SSLerrfree(char *buf)
    1552             : {
    1553          28 :     if (buf != ssl_nomem)
    1554          28 :         free(buf);
    1555          28 : }
    1556             : 
    1557             : /* ------------------------------------------------------------ */
    1558             : /*                  SSL information functions                   */
    1559             : /* ------------------------------------------------------------ */
    1560             : 
    1561             : /*
    1562             :  *  Return pointer to OpenSSL object.
    1563             :  */
    1564             : void *
    1565           0 : PQgetssl(PGconn *conn)
    1566             : {
    1567           0 :     if (!conn)
    1568           0 :         return NULL;
    1569           0 :     return conn->ssl;
    1570             : }
    1571             : 
    1572             : void *
    1573           0 : PQsslStruct(PGconn *conn, const char *struct_name)
    1574             : {
    1575           0 :     if (!conn)
    1576           0 :         return NULL;
    1577           0 :     if (strcmp(struct_name, "OpenSSL") == 0)
    1578           0 :         return conn->ssl;
    1579           0 :     return NULL;
    1580             : }
    1581             : 
    1582             : const char *const *
    1583           0 : PQsslAttributeNames(PGconn *conn)
    1584             : {
    1585             :     static const char *const result[] = {
    1586             :         "library",
    1587             :         "key_bits",
    1588             :         "cipher",
    1589             :         "compression",
    1590             :         "protocol",
    1591             :         NULL
    1592             :     };
    1593             : 
    1594           0 :     return result;
    1595             : }
    1596             : 
    1597             : const char *
    1598           0 : PQsslAttribute(PGconn *conn, const char *attribute_name)
    1599             : {
    1600           0 :     if (!conn)
    1601           0 :         return NULL;
    1602           0 :     if (conn->ssl == NULL)
    1603           0 :         return NULL;
    1604             : 
    1605           0 :     if (strcmp(attribute_name, "library") == 0)
    1606           0 :         return "OpenSSL";
    1607             : 
    1608           0 :     if (strcmp(attribute_name, "key_bits") == 0)
    1609             :     {
    1610             :         static char sslbits_str[12];
    1611             :         int         sslbits;
    1612             : 
    1613           0 :         SSL_get_cipher_bits(conn->ssl, &sslbits);
    1614           0 :         snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
    1615           0 :         return sslbits_str;
    1616             :     }
    1617             : 
    1618           0 :     if (strcmp(attribute_name, "cipher") == 0)
    1619           0 :         return SSL_get_cipher(conn->ssl);
    1620             : 
    1621           0 :     if (strcmp(attribute_name, "compression") == 0)
    1622           0 :         return SSL_get_current_compression(conn->ssl) ? "on" : "off";
    1623             : 
    1624           0 :     if (strcmp(attribute_name, "protocol") == 0)
    1625           0 :         return SSL_get_version(conn->ssl);
    1626             : 
    1627           0 :     return NULL;                /* unknown attribute */
    1628             : }
    1629             : 
    1630             : /*
    1631             :  * Private substitute BIO: this does the sending and receiving using
    1632             :  * pqsecure_raw_write() and pqsecure_raw_read() instead, to allow those
    1633             :  * functions to disable SIGPIPE and give better error messages on I/O errors.
    1634             :  *
    1635             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
    1636             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
    1637             :  * XXX OpenSSL 1.0.1e considers many more errcodes than just EINTR as reasons
    1638             :  * to retry; do we need to adopt their logic for that?
    1639             :  */
    1640             : 
    1641             : #ifndef HAVE_BIO_GET_DATA
    1642             : #define BIO_get_data(bio) (bio->ptr)
    1643             : #define BIO_set_data(bio, data) (bio->ptr = data)
    1644             : #endif
    1645             : 
    1646             : static BIO_METHOD *my_bio_methods;
    1647             : 
    1648             : static int
    1649        3642 : my_sock_read(BIO *h, char *buf, int size)
    1650             : {
    1651             :     int         res;
    1652             : 
    1653        3642 :     res = pqsecure_raw_read((PGconn *) BIO_get_data(h), buf, size);
    1654        3642 :     BIO_clear_retry_flags(h);
    1655        3642 :     if (res < 0)
    1656             :     {
    1657             :         /* If we were interrupted, tell caller to retry */
    1658         534 :         switch (SOCK_ERRNO)
    1659             :         {
    1660             : #ifdef EAGAIN
    1661         534 :             case EAGAIN:
    1662             : #endif
    1663             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    1664             :             case EWOULDBLOCK:
    1665             : #endif
    1666             :             case EINTR:
    1667         534 :                 BIO_set_retry_read(h);
    1668         534 :                 break;
    1669             : 
    1670           0 :             default:
    1671           0 :                 break;
    1672             :         }
    1673        3108 :     }
    1674             : 
    1675        3642 :     return res;
    1676             : }
    1677             : 
    1678             : static int
    1679         876 : my_sock_write(BIO *h, const char *buf, int size)
    1680             : {
    1681             :     int         res;
    1682             : 
    1683         876 :     res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
    1684         876 :     BIO_clear_retry_flags(h);
    1685         876 :     if (res <= 0)
    1686             :     {
    1687             :         /* If we were interrupted, tell caller to retry */
    1688           0 :         switch (SOCK_ERRNO)
    1689             :         {
    1690             : #ifdef EAGAIN
    1691           0 :             case EAGAIN:
    1692             : #endif
    1693             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    1694             :             case EWOULDBLOCK:
    1695             : #endif
    1696             :             case EINTR:
    1697           0 :                 BIO_set_retry_write(h);
    1698           0 :                 break;
    1699             : 
    1700           0 :             default:
    1701           0 :                 break;
    1702             :         }
    1703         876 :     }
    1704             : 
    1705         876 :     return res;
    1706             : }
    1707             : 
    1708             : static BIO_METHOD *
    1709         148 : my_BIO_s_socket(void)
    1710             : {
    1711         148 :     if (!my_bio_methods)
    1712             :     {
    1713         148 :         BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
    1714             : #ifdef HAVE_BIO_METH_NEW
    1715             :         int         my_bio_index;
    1716             : 
    1717         148 :         my_bio_index = BIO_get_new_index();
    1718         148 :         if (my_bio_index == -1)
    1719           0 :             return NULL;
    1720         148 :         my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
    1721         148 :         my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
    1722         148 :         if (!my_bio_methods)
    1723           0 :             return NULL;
    1724             : 
    1725             :         /*
    1726             :          * As of this writing, these functions never fail. But check anyway,
    1727             :          * like OpenSSL's own examples do.
    1728             :          */
    1729         296 :         if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
    1730         296 :             !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
    1731         296 :             !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
    1732         296 :             !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
    1733         296 :             !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
    1734         296 :             !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
    1735         296 :             !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
    1736         148 :             !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
    1737             :         {
    1738           0 :             BIO_meth_free(my_bio_methods);
    1739           0 :             my_bio_methods = NULL;
    1740           0 :             return NULL;
    1741             :         }
    1742             : #else
    1743             :         my_bio_methods = malloc(sizeof(BIO_METHOD));
    1744             :         if (!my_bio_methods)
    1745             :             return NULL;
    1746             :         memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
    1747             :         my_bio_methods->bread = my_sock_read;
    1748             :         my_bio_methods->bwrite = my_sock_write;
    1749             : #endif
    1750             :     }
    1751         148 :     return my_bio_methods;
    1752             : }
    1753             : 
    1754             : /* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
    1755             : static int
    1756         148 : my_SSL_set_fd(PGconn *conn, int fd)
    1757             : {
    1758         148 :     int         ret = 0;
    1759             :     BIO        *bio;
    1760             :     BIO_METHOD *bio_method;
    1761             : 
    1762         148 :     bio_method = my_BIO_s_socket();
    1763         148 :     if (bio_method == NULL)
    1764             :     {
    1765           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
    1766           0 :         goto err;
    1767             :     }
    1768         148 :     bio = BIO_new(bio_method);
    1769         148 :     if (bio == NULL)
    1770             :     {
    1771           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
    1772           0 :         goto err;
    1773             :     }
    1774         148 :     BIO_set_data(bio, conn);
    1775             : 
    1776         148 :     SSL_set_bio(conn->ssl, bio, bio);
    1777         148 :     BIO_set_fd(bio, fd, BIO_NOCLOSE);
    1778         148 :     ret = 1;
    1779         148 : err:
    1780         148 :     return ret;
    1781             : }
    1782             : 
    1783             : /*
    1784             :  * This is the default handler to return a client cert password from
    1785             :  * conn->sslpassword. Apps may install it explicitly if they want to
    1786             :  * prevent openssl from ever prompting on stdin.
    1787             :  */
    1788             : int
    1789           4 : PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
    1790             : {
    1791           4 :     if (conn->sslpassword)
    1792             :     {
    1793           4 :         if (strlen(conn->sslpassword) + 1 > size)
    1794           0 :             fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
    1795           4 :         strncpy(buf, conn->sslpassword, size);
    1796           4 :         buf[size - 1] = '\0';
    1797           4 :         return strlen(buf);
    1798             :     }
    1799             :     else
    1800             :     {
    1801           0 :         buf[0] = '\0';
    1802           0 :         return 0;
    1803             :     }
    1804             : }
    1805             : 
    1806             : PQsslKeyPassHook_OpenSSL_type
    1807           0 : PQgetSSLKeyPassHook_OpenSSL(void)
    1808             : {
    1809           0 :     return PQsslKeyPassHook;
    1810             : }
    1811             : 
    1812             : void
    1813           0 : PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
    1814             : {
    1815           0 :     PQsslKeyPassHook = hook;
    1816           0 : }
    1817             : 
    1818             : /*
    1819             :  * Supply a password to decrypt a client certificate.
    1820             :  *
    1821             :  * This must match OpenSSL type pem_password_cb.
    1822             :  */
    1823             : static int
    1824           4 : PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1825             : {
    1826           4 :     PGconn     *conn = userdata;
    1827             : 
    1828           4 :     if (PQsslKeyPassHook)
    1829           0 :         return PQsslKeyPassHook(buf, size, conn);
    1830             :     else
    1831           4 :         return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
    1832             : }
    1833             : 
    1834             : /*
    1835             :  * Convert TLS protocol version string to OpenSSL values
    1836             :  *
    1837             :  * If a version is passed that is not supported by the current OpenSSL version,
    1838             :  * then we return -1. If a non-negative value is returned, subsequent code can
    1839             :  * assume it is working with a supported version.
    1840             :  *
    1841             :  * Note: this is rather similar to the backend routine in be-secure-openssl.c,
    1842             :  * so make sure to update both routines if changing this one.
    1843             :  */
    1844             : static int
    1845         156 : ssl_protocol_version_to_openssl(const char *protocol)
    1846             : {
    1847         156 :     if (pg_strcasecmp("TLSv1", protocol) == 0)
    1848           0 :         return TLS1_VERSION;
    1849             : 
    1850             : #ifdef TLS1_1_VERSION
    1851         156 :     if (pg_strcasecmp("TLSv1.1", protocol) == 0)
    1852           0 :         return TLS1_1_VERSION;
    1853             : #endif
    1854             : 
    1855             : #ifdef TLS1_2_VERSION
    1856         156 :     if (pg_strcasecmp("TLSv1.2", protocol) == 0)
    1857         156 :         return TLS1_2_VERSION;
    1858             : #endif
    1859             : 
    1860             : #ifdef TLS1_3_VERSION
    1861           0 :     if (pg_strcasecmp("TLSv1.3", protocol) == 0)
    1862           0 :         return TLS1_3_VERSION;
    1863             : #endif
    1864             : 
    1865           0 :     return -1;
    1866             : }

Generated by: LCOV version 1.14