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

Generated by: LCOV version 1.13