LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 19devel Lines: 385 690 55.8 %
Date: 2025-07-31 00:18:02 Functions: 26 31 83.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.16