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

Generated by: LCOV version 1.14