LCOV - code coverage report
Current view: top level - src/interfaces/libpq - fe-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 390 692 56.4 %
Date: 2025-04-24 12:15:10 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         260 :         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         568 : pgtls_read(PGconn *conn, void *ptr, size_t len)
     119             : {
     120             :     ssize_t     n;
     121         568 :     int         result_errno = 0;
     122             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     123             :     int         err;
     124             :     unsigned long ecode;
     125             : 
     126         568 : 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         568 :     SOCK_ERRNO_SET(0);
     138         568 :     ERR_clear_error();
     139         568 :     n = SSL_read(conn->ssl, ptr, len);
     140         568 :     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         568 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     151         568 :     switch (err)
     152             :     {
     153         388 :         case SSL_ERROR_NONE:
     154         388 :             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         388 :             break;
     163         168 :         case SSL_ERROR_WANT_READ:
     164         168 :             n = 0;
     165         168 :             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         568 :     SOCK_ERRNO_SET(result_errno);
     229             : 
     230         568 :     return n;
     231             : }
     232             : 
     233             : bool
     234         654 : pgtls_read_pending(PGconn *conn)
     235             : {
     236         654 :     return SSL_pending(conn->ssl) > 0;
     237             : }
     238             : 
     239             : ssize_t
     240         566 : pgtls_write(PGconn *conn, const void *ptr, size_t len)
     241             : {
     242             :     ssize_t     n;
     243         566 :     int         result_errno = 0;
     244             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     245             :     int         err;
     246             :     unsigned long ecode;
     247             : 
     248         566 :     SOCK_ERRNO_SET(0);
     249         566 :     ERR_clear_error();
     250         566 :     n = SSL_write(conn->ssl, ptr, len);
     251         566 :     err = SSL_get_error(conn->ssl, n);
     252         566 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     253         566 :     switch (err)
     254             :     {
     255         566 :         case SSL_ERROR_NONE:
     256         566 :             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         566 :             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         566 :     SOCK_ERRNO_SET(result_errno);
     335             : 
     336         566 :     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         570 : verify_cb(int ok, X509_STORE_CTX *ctx)
     431             : {
     432         570 :     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         208 : cert_cb(SSL *ssl, void *arg)
     447             : {
     448         208 :     PGconn     *conn = arg;
     449             : 
     450         208 :     conn->ssl_cert_requested = true;
     451             : 
     452             :     /* Do we have a certificate loaded to send back? */
     453         208 :     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         208 :     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             :                                                                      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             : static void
     698          10 : SSL_CTX_keylog_cb(const SSL *ssl, const char *line)
     699             : {
     700             :     int         fd;
     701             :     mode_t      old_umask;
     702             :     ssize_t     rc;
     703          10 :     PGconn     *conn = SSL_get_app_data(ssl);
     704             : 
     705          10 :     if (conn == NULL)
     706           0 :         return;
     707             : 
     708          10 :     old_umask = umask(077);
     709          10 :     fd = open(conn->sslkeylogfile, O_WRONLY | O_APPEND | O_CREAT, 0600);
     710          10 :     umask(old_umask);
     711             : 
     712          10 :     if (fd == -1)
     713             :     {
     714           0 :         libpq_append_conn_error(conn, "could not open ssl keylog file \"%s\": %s",
     715           0 :                                 conn->sslkeylogfile, pg_strerror(errno));
     716           0 :         return;
     717             :     }
     718             : 
     719             :     /* line is guaranteed by OpenSSL to be NUL terminated */
     720          10 :     rc = write(fd, line, strlen(line));
     721          10 :     if (rc < 0)
     722           0 :         libpq_append_conn_error(conn, "could not write to ssl keylog file \"%s\": %s",
     723           0 :                                 conn->sslkeylogfile, pg_strerror(errno));
     724             :     else
     725          10 :         rc = write(fd, "\n", 1);
     726             :     (void) rc;                  /* silence compiler warnings */
     727          10 :     close(fd);
     728             : }
     729             : #endif
     730             : 
     731             : /*
     732             :  *  Create per-connection SSL object, and load the client certificate,
     733             :  *  private key, and trusted CA certs.
     734             :  *
     735             :  *  Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
     736             :  */
     737             : static int
     738         260 : initialize_SSL(PGconn *conn)
     739             : {
     740             :     SSL_CTX    *SSL_context;
     741             :     struct stat buf;
     742             :     char        homedir[MAXPGPATH];
     743             :     char        fnbuf[MAXPGPATH];
     744             :     char        sebuf[PG_STRERROR_R_BUFLEN];
     745             :     bool        have_homedir;
     746             :     bool        have_cert;
     747             :     bool        have_rootcert;
     748             : 
     749             :     /*
     750             :      * We'll need the home directory if any of the relevant parameters are
     751             :      * defaulted.  If pqGetHomeDirectory fails, act as though none of the
     752             :      * files could be found.
     753             :      */
     754         260 :     if (!(conn->sslcert && strlen(conn->sslcert) > 0) ||
     755         234 :         !(conn->sslkey && strlen(conn->sslkey) > 0) ||
     756         218 :         !(conn->sslrootcert && strlen(conn->sslrootcert) > 0) ||
     757         218 :         !((conn->sslcrl && strlen(conn->sslcrl) > 0) ||
     758           8 :           (conn->sslcrldir && strlen(conn->sslcrldir) > 0)))
     759          46 :         have_homedir = pqGetHomeDirectory(homedir, sizeof(homedir));
     760             :     else                        /* won't need it */
     761         214 :         have_homedir = false;
     762             : 
     763             :     /*
     764             :      * Create a new SSL_CTX object.
     765             :      *
     766             :      * We used to share a single SSL_CTX between all connections, but it was
     767             :      * complicated if connections used different certificates. So now we
     768             :      * create a separate context for each connection, and accept the overhead.
     769             :      */
     770         260 :     SSL_context = SSL_CTX_new(SSLv23_method());
     771         260 :     if (!SSL_context)
     772             :     {
     773           0 :         char       *err = SSLerrmessage(ERR_get_error());
     774             : 
     775           0 :         libpq_append_conn_error(conn, "could not create SSL context: %s", err);
     776           0 :         SSLerrfree(err);
     777           0 :         return -1;
     778             :     }
     779             : 
     780             :     /*
     781             :      * Delegate the client cert password prompt to the libpq wrapper callback
     782             :      * if any is defined.
     783             :      *
     784             :      * If the application hasn't installed its own and the sslpassword
     785             :      * parameter is non-null, we install ours now to make sure we supply
     786             :      * PGconn->sslpassword to OpenSSL instead of letting it prompt on stdin.
     787             :      *
     788             :      * This will replace OpenSSL's default PEM_def_callback (which prompts on
     789             :      * stdin), but we're only setting it for this SSL context so it's
     790             :      * harmless.
     791             :      */
     792         260 :     if (PQsslKeyPassHook
     793         260 :         || (conn->sslpassword && strlen(conn->sslpassword) > 0))
     794             :     {
     795           6 :         SSL_CTX_set_default_passwd_cb(SSL_context, PQssl_passwd_cb);
     796           6 :         SSL_CTX_set_default_passwd_cb_userdata(SSL_context, conn);
     797             :     }
     798             : 
     799             : #ifdef HAVE_SSL_CTX_SET_CERT_CB
     800             :     /* Set up a certificate selection callback. */
     801         260 :     SSL_CTX_set_cert_cb(SSL_context, cert_cb, conn);
     802             : #endif
     803             : 
     804             :     /* Disable old protocol versions */
     805         260 :     SSL_CTX_set_options(SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
     806             : 
     807             :     /* Set the minimum and maximum protocol versions if necessary */
     808         260 :     if (conn->ssl_min_protocol_version &&
     809         260 :         strlen(conn->ssl_min_protocol_version) != 0)
     810             :     {
     811             :         int         ssl_min_ver;
     812             : 
     813         260 :         ssl_min_ver = ssl_protocol_version_to_openssl(conn->ssl_min_protocol_version);
     814             : 
     815         260 :         if (ssl_min_ver == -1)
     816             :         {
     817           0 :             libpq_append_conn_error(conn, "invalid value \"%s\" for minimum SSL protocol version",
     818             :                                     conn->ssl_min_protocol_version);
     819           0 :             SSL_CTX_free(SSL_context);
     820           0 :             return -1;
     821             :         }
     822             : 
     823         260 :         if (!SSL_CTX_set_min_proto_version(SSL_context, ssl_min_ver))
     824             :         {
     825           0 :             char       *err = SSLerrmessage(ERR_get_error());
     826             : 
     827           0 :             libpq_append_conn_error(conn, "could not set minimum SSL protocol version: %s", err);
     828           0 :             SSLerrfree(err);
     829           0 :             SSL_CTX_free(SSL_context);
     830           0 :             return -1;
     831             :         }
     832             :     }
     833             : 
     834         260 :     if (conn->ssl_max_protocol_version &&
     835           4 :         strlen(conn->ssl_max_protocol_version) != 0)
     836             :     {
     837             :         int         ssl_max_ver;
     838             : 
     839           4 :         ssl_max_ver = ssl_protocol_version_to_openssl(conn->ssl_max_protocol_version);
     840             : 
     841           4 :         if (ssl_max_ver == -1)
     842             :         {
     843           0 :             libpq_append_conn_error(conn, "invalid value \"%s\" for maximum SSL protocol version",
     844             :                                     conn->ssl_max_protocol_version);
     845           0 :             SSL_CTX_free(SSL_context);
     846           0 :             return -1;
     847             :         }
     848             : 
     849           4 :         if (!SSL_CTX_set_max_proto_version(SSL_context, ssl_max_ver))
     850             :         {
     851           0 :             char       *err = SSLerrmessage(ERR_get_error());
     852             : 
     853           0 :             libpq_append_conn_error(conn, "could not set maximum SSL protocol version: %s", err);
     854           0 :             SSLerrfree(err);
     855           0 :             SSL_CTX_free(SSL_context);
     856           0 :             return -1;
     857             :         }
     858             :     }
     859             : 
     860             :     /*
     861             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     862             :      * unnecessary failures in nonblocking send cases.
     863             :      */
     864         260 :     SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     865             : 
     866             :     /*
     867             :      * If the root cert file exists, load it so we can perform certificate
     868             :      * verification. If sslmode is "verify-full" we will also do further
     869             :      * verification after the connection has been completed.
     870             :      */
     871         260 :     if (conn->sslrootcert && strlen(conn->sslrootcert) > 0)
     872         234 :         strlcpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
     873          26 :     else if (have_homedir)
     874          26 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
     875             :     else
     876           0 :         fnbuf[0] = '\0';
     877             : 
     878         260 :     if (strcmp(fnbuf, "system") == 0)
     879             :     {
     880             :         /*
     881             :          * The "system" sentinel value indicates that we should load whatever
     882             :          * root certificates are installed for use by OpenSSL; these locations
     883             :          * differ by platform. Note that the default system locations may be
     884             :          * further overridden by the SSL_CERT_DIR and SSL_CERT_FILE
     885             :          * environment variables.
     886             :          */
     887           6 :         if (SSL_CTX_set_default_verify_paths(SSL_context) != 1)
     888             :         {
     889           0 :             char       *err = SSLerrmessage(ERR_get_error());
     890             : 
     891           0 :             libpq_append_conn_error(conn, "could not load system root certificate paths: %s",
     892             :                                     err);
     893           0 :             SSLerrfree(err);
     894           0 :             SSL_CTX_free(SSL_context);
     895           0 :             return -1;
     896             :         }
     897           6 :         have_rootcert = true;
     898             :     }
     899         508 :     else if (fnbuf[0] != '\0' &&
     900         254 :              stat(fnbuf, &buf) == 0)
     901         200 :     {
     902             :         X509_STORE *cvstore;
     903             : 
     904         200 :         if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
     905             :         {
     906           0 :             char       *err = SSLerrmessage(ERR_get_error());
     907             : 
     908           0 :             libpq_append_conn_error(conn, "could not read root certificate file \"%s\": %s",
     909             :                                     fnbuf, err);
     910           0 :             SSLerrfree(err);
     911           0 :             SSL_CTX_free(SSL_context);
     912           0 :             return -1;
     913             :         }
     914             : 
     915         200 :         if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
     916             :         {
     917         200 :             char       *fname = NULL;
     918         200 :             char       *dname = NULL;
     919             : 
     920         200 :             if (conn->sslcrl && strlen(conn->sslcrl) > 0)
     921         196 :                 fname = conn->sslcrl;
     922         200 :             if (conn->sslcrldir && strlen(conn->sslcrldir) > 0)
     923         200 :                 dname = conn->sslcrldir;
     924             : 
     925             :             /* defaults to use the default CRL file */
     926         200 :             if (!fname && !dname && have_homedir)
     927             :             {
     928           0 :                 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
     929           0 :                 fname = fnbuf;
     930             :             }
     931             : 
     932             :             /* Set the flags to check against the complete CRL chain */
     933         400 :             if ((fname || dname) &&
     934         200 :                 X509_STORE_load_locations(cvstore, fname, dname) == 1)
     935             :             {
     936          10 :                 X509_STORE_set_flags(cvstore,
     937             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     938             :             }
     939             : 
     940             :             /* if not found, silently ignore;  we do not require CRL */
     941         200 :             ERR_clear_error();
     942             :         }
     943         200 :         have_rootcert = true;
     944             :     }
     945             :     else
     946             :     {
     947             :         /*
     948             :          * stat() failed; assume root file doesn't exist.  If sslmode is
     949             :          * verify-ca or verify-full, this is an error.  Otherwise, continue
     950             :          * without performing any server cert verification.
     951             :          */
     952          54 :         if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
     953             :         {
     954             :             /*
     955             :              * The only way to reach here with an empty filename is if
     956             :              * pqGetHomeDirectory failed.  That's a sufficiently unusual case
     957             :              * that it seems worth having a specialized error message for it.
     958             :              */
     959           4 :             if (fnbuf[0] == '\0')
     960           0 :                 libpq_append_conn_error(conn, "could not get home directory to locate root certificate file\n"
     961             :                                         "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.");
     962             :             else
     963           4 :                 libpq_append_conn_error(conn, "root certificate file \"%s\" does not exist\n"
     964             :                                         "Either provide the file, use the system's trusted roots with sslrootcert=system, or change sslmode to disable server certificate verification.", fnbuf);
     965           4 :             SSL_CTX_free(SSL_context);
     966           4 :             return -1;
     967             :         }
     968          50 :         have_rootcert = false;
     969             :     }
     970             : 
     971             :     /* Read the client certificate file */
     972         256 :     if (conn->sslcert && strlen(conn->sslcert) > 0)
     973         230 :         strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
     974          26 :     else if (have_homedir)
     975          26 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
     976             :     else
     977           0 :         fnbuf[0] = '\0';
     978             : 
     979         256 :     if (conn->sslcertmode[0] == 'd') /* disable */
     980             :     {
     981             :         /* don't send a client cert even if we have one */
     982           6 :         have_cert = false;
     983             :     }
     984         250 :     else if (fnbuf[0] == '\0')
     985             :     {
     986             :         /* no home directory, proceed without a client cert */
     987           0 :         have_cert = false;
     988             :     }
     989         250 :     else if (stat(fnbuf, &buf) != 0)
     990             :     {
     991             :         /*
     992             :          * If file is not present, just go on without a client cert; server
     993             :          * might or might not accept the connection.  Any other error,
     994             :          * however, is grounds for complaint.
     995             :          */
     996         174 :         if (errno != ENOENT && errno != ENOTDIR)
     997             :         {
     998           0 :             libpq_append_conn_error(conn, "could not open certificate file \"%s\": %s",
     999           0 :                                     fnbuf, strerror_r(errno, sebuf, sizeof(sebuf)));
    1000           0 :             SSL_CTX_free(SSL_context);
    1001           0 :             return -1;
    1002             :         }
    1003         174 :         have_cert = false;
    1004             :     }
    1005             :     else
    1006             :     {
    1007             :         /*
    1008             :          * Cert file exists, so load it. Since OpenSSL doesn't provide the
    1009             :          * equivalent of "SSL_use_certificate_chain_file", we have to load it
    1010             :          * into the SSL context, rather than the SSL object.
    1011             :          */
    1012          76 :         if (SSL_CTX_use_certificate_chain_file(SSL_context, fnbuf) != 1)
    1013             :         {
    1014           0 :             char       *err = SSLerrmessage(ERR_get_error());
    1015             : 
    1016           0 :             libpq_append_conn_error(conn, "could not read certificate file \"%s\": %s",
    1017             :                                     fnbuf, err);
    1018           0 :             SSLerrfree(err);
    1019           0 :             SSL_CTX_free(SSL_context);
    1020           0 :             return -1;
    1021             :         }
    1022             : 
    1023             :         /* need to load the associated private key, too */
    1024          76 :         have_cert = true;
    1025             :     }
    1026             : 
    1027             :     /*
    1028             :      * The SSL context is now loaded with the correct root and client
    1029             :      * certificates. Create a connection-specific SSL object. The private key
    1030             :      * is loaded directly into the SSL object. (We could load the private key
    1031             :      * into the context, too, but we have done it this way historically, and
    1032             :      * it doesn't really matter.)
    1033             :      */
    1034         512 :     if (!(conn->ssl = SSL_new(SSL_context)) ||
    1035         512 :         !SSL_set_app_data(conn->ssl, conn) ||
    1036         256 :         !ssl_set_pgconn_bio(conn))
    1037             :     {
    1038           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1039             : 
    1040           0 :         libpq_append_conn_error(conn, "could not establish SSL connection: %s", err);
    1041           0 :         SSLerrfree(err);
    1042           0 :         SSL_CTX_free(SSL_context);
    1043           0 :         return -1;
    1044             :     }
    1045         256 :     conn->ssl_in_use = true;
    1046             : 
    1047         256 :     if (conn->sslkeylogfile && strlen(conn->sslkeylogfile) > 0)
    1048             :     {
    1049             : #ifdef HAVE_SSL_CTX_SET_KEYLOG_CALLBACK
    1050           2 :         SSL_CTX_set_keylog_callback(SSL_context, SSL_CTX_keylog_cb);
    1051             : #else
    1052             : #ifdef LIBRESSL_VERSION_NUMBER
    1053             :         fprintf(stderr, libpq_gettext("WARNING: sslkeylogfile support requires OpenSSL\n"));
    1054             : #else
    1055             :         fprintf(stderr, libpq_gettext("WARNING: libpq was not built with sslkeylogfile support\n"));
    1056             : #endif
    1057             : #endif
    1058             :     }
    1059             : 
    1060             : 
    1061             :     /*
    1062             :      * SSL contexts are reference counted by OpenSSL. We can free it as soon
    1063             :      * as we have created the SSL object, and it will stick around for as long
    1064             :      * as it's actually needed.
    1065             :      */
    1066         256 :     SSL_CTX_free(SSL_context);
    1067         256 :     SSL_context = NULL;
    1068             : 
    1069             :     /*
    1070             :      * Set Server Name Indication (SNI), if enabled by connection parameters.
    1071             :      * Per RFC 6066, do not set it if the host is a literal IP address (IPv4
    1072             :      * or IPv6).
    1073             :      */
    1074         256 :     if (conn->sslsni && conn->sslsni[0] == '1')
    1075             :     {
    1076         256 :         const char *host = conn->connhost[conn->whichhost].host;
    1077             : 
    1078         256 :         if (host && host[0] &&
    1079         256 :             !(strspn(host, "0123456789.") == strlen(host) ||
    1080         236 :               strchr(host, ':')))
    1081             :         {
    1082         222 :             if (SSL_set_tlsext_host_name(conn->ssl, host) != 1)
    1083             :             {
    1084           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1085             : 
    1086           0 :                 libpq_append_conn_error(conn, "could not set SSL Server Name Indication (SNI): %s", err);
    1087           0 :                 SSLerrfree(err);
    1088           0 :                 return -1;
    1089             :             }
    1090             :         }
    1091             :     }
    1092             : 
    1093             :     /* Set ALPN */
    1094             :     {
    1095             :         int         retval;
    1096             : 
    1097         256 :         retval = SSL_set_alpn_protos(conn->ssl, alpn_protos, sizeof(alpn_protos));
    1098             : 
    1099         256 :         if (retval != 0)
    1100             :         {
    1101           0 :             char       *err = SSLerrmessage(ERR_get_error());
    1102             : 
    1103           0 :             libpq_append_conn_error(conn, "could not set SSL ALPN extension: %s", err);
    1104           0 :             SSLerrfree(err);
    1105           0 :             return -1;
    1106             :         }
    1107             :     }
    1108             : 
    1109             :     /*
    1110             :      * Read the SSL key. If a key is specified, treat it as an engine:key
    1111             :      * combination if there is colon present - we don't support files with
    1112             :      * colon in the name. The exception is if the second character is a colon,
    1113             :      * in which case it can be a Windows filename with drive specification.
    1114             :      */
    1115         256 :     if (have_cert && conn->sslkey && strlen(conn->sslkey) > 0)
    1116             :     {
    1117             : #ifdef USE_SSL_ENGINE
    1118          76 :         if (strchr(conn->sslkey, ':')
    1119             : #ifdef WIN32
    1120             :             && conn->sslkey[1] != ':'
    1121             : #endif
    1122             :             )
    1123             :         {
    1124             :             /* Colon, but not in second character, treat as engine:key */
    1125           0 :             char       *engine_str = strdup(conn->sslkey);
    1126             :             char       *engine_colon;
    1127             :             EVP_PKEY   *pkey;
    1128             : 
    1129           0 :             if (engine_str == NULL)
    1130             :             {
    1131           0 :                 libpq_append_conn_error(conn, "out of memory");
    1132           0 :                 return -1;
    1133             :             }
    1134             : 
    1135             :             /* cannot return NULL because we already checked before strdup */
    1136           0 :             engine_colon = strchr(engine_str, ':');
    1137             : 
    1138           0 :             *engine_colon = '\0';   /* engine_str now has engine name */
    1139           0 :             engine_colon++;     /* engine_colon now has key name */
    1140             : 
    1141           0 :             conn->engine = ENGINE_by_id(engine_str);
    1142           0 :             if (conn->engine == NULL)
    1143             :             {
    1144           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1145             : 
    1146           0 :                 libpq_append_conn_error(conn, "could not load SSL engine \"%s\": %s",
    1147             :                                         engine_str, err);
    1148           0 :                 SSLerrfree(err);
    1149           0 :                 free(engine_str);
    1150           0 :                 return -1;
    1151             :             }
    1152             : 
    1153           0 :             if (ENGINE_init(conn->engine) == 0)
    1154             :             {
    1155           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1156             : 
    1157           0 :                 libpq_append_conn_error(conn, "could not initialize SSL engine \"%s\": %s",
    1158             :                                         engine_str, err);
    1159           0 :                 SSLerrfree(err);
    1160           0 :                 ENGINE_free(conn->engine);
    1161           0 :                 conn->engine = NULL;
    1162           0 :                 free(engine_str);
    1163           0 :                 return -1;
    1164             :             }
    1165             : 
    1166           0 :             pkey = ENGINE_load_private_key(conn->engine, engine_colon,
    1167             :                                            NULL, NULL);
    1168           0 :             if (pkey == NULL)
    1169             :             {
    1170           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1171             : 
    1172           0 :                 libpq_append_conn_error(conn, "could not read private SSL key \"%s\" from engine \"%s\": %s",
    1173             :                                         engine_colon, engine_str, err);
    1174           0 :                 SSLerrfree(err);
    1175           0 :                 ENGINE_finish(conn->engine);
    1176           0 :                 ENGINE_free(conn->engine);
    1177           0 :                 conn->engine = NULL;
    1178           0 :                 free(engine_str);
    1179           0 :                 return -1;
    1180             :             }
    1181           0 :             if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
    1182             :             {
    1183           0 :                 char       *err = SSLerrmessage(ERR_get_error());
    1184             : 
    1185           0 :                 libpq_append_conn_error(conn, "could not load private SSL key \"%s\" from engine \"%s\": %s",
    1186             :                                         engine_colon, engine_str, err);
    1187           0 :                 SSLerrfree(err);
    1188           0 :                 ENGINE_finish(conn->engine);
    1189           0 :                 ENGINE_free(conn->engine);
    1190           0 :                 conn->engine = NULL;
    1191           0 :                 free(engine_str);
    1192           0 :                 return -1;
    1193             :             }
    1194             : 
    1195           0 :             free(engine_str);
    1196             : 
    1197           0 :             fnbuf[0] = '\0';    /* indicate we're not going to load from a
    1198             :                                  * file */
    1199             :         }
    1200             :         else
    1201             : #endif                          /* USE_SSL_ENGINE */
    1202             :         {
    1203             :             /* PGSSLKEY is not an engine, treat it as a filename */
    1204          76 :             strlcpy(fnbuf, conn->sslkey, sizeof(fnbuf));
    1205             :         }
    1206             :     }
    1207         180 :     else if (have_homedir)
    1208             :     {
    1209             :         /* No PGSSLKEY specified, load default file */
    1210          42 :         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
    1211             :     }
    1212             :     else
    1213         138 :         fnbuf[0] = '\0';
    1214             : 
    1215         256 :     if (have_cert && fnbuf[0] != '\0')
    1216             :     {
    1217             :         /* read the client key from file */
    1218             : 
    1219          76 :         if (stat(fnbuf, &buf) != 0)
    1220             :         {
    1221           0 :             if (errno == ENOENT)
    1222           0 :                 libpq_append_conn_error(conn, "certificate present, but not private key file \"%s\"",
    1223             :                                         fnbuf);
    1224             :             else
    1225           0 :                 libpq_append_conn_error(conn, "could not stat private key file \"%s\": %m",
    1226             :                                         fnbuf);
    1227           0 :             return -1;
    1228             :         }
    1229             : 
    1230             :         /* Key file must be a regular file */
    1231          76 :         if (!S_ISREG(buf.st_mode))
    1232             :         {
    1233           0 :             libpq_append_conn_error(conn, "private key file \"%s\" is not a regular file",
    1234             :                                     fnbuf);
    1235           0 :             return -1;
    1236             :         }
    1237             : 
    1238             :         /*
    1239             :          * Refuse to load world-readable key files.  We accept root-owned
    1240             :          * files with mode 0640 or less, so that we can access system-wide
    1241             :          * certificates if we have a supplementary group membership that
    1242             :          * allows us to read 'em.  For files with non-root ownership, require
    1243             :          * mode 0600 or less.  We need not check the file's ownership exactly;
    1244             :          * if we're able to read it despite it having such restrictive
    1245             :          * permissions, it must have the right ownership.
    1246             :          *
    1247             :          * Note: be very careful about tightening these rules.  Some people
    1248             :          * expect, for example, that a client process running as root should
    1249             :          * be able to use a non-root-owned key file.
    1250             :          *
    1251             :          * Note that roughly similar checks are performed in
    1252             :          * src/backend/libpq/be-secure-common.c so any changes here may need
    1253             :          * to be made there as well.  However, this code caters for the case
    1254             :          * of current user == root, while that code does not.
    1255             :          *
    1256             :          * Ideally we would do similar permissions checks on Windows, but it
    1257             :          * is not clear how that would work since Unix-style permissions may
    1258             :          * not be available.
    1259             :          */
    1260             : #if !defined(WIN32) && !defined(__CYGWIN__)
    1261         152 :         if (buf.st_uid == 0 ?
    1262           0 :             buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO) :
    1263          76 :             buf.st_mode & (S_IRWXG | S_IRWXO))
    1264             :         {
    1265           2 :             libpq_append_conn_error(conn,
    1266             :                                     "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",
    1267             :                                     fnbuf);
    1268           2 :             return -1;
    1269             :         }
    1270             : #endif
    1271             : 
    1272          74 :         if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
    1273             :         {
    1274           6 :             char       *err = SSLerrmessage(ERR_get_error());
    1275             : 
    1276             :             /*
    1277             :              * We'll try to load the file in DER (binary ASN.1) format, and if
    1278             :              * that fails too, report the original error. This could mask
    1279             :              * issues where there's something wrong with a DER-format cert,
    1280             :              * but we'd have to duplicate openssl's format detection to be
    1281             :              * smarter than this. We can't just probe for a leading -----BEGIN
    1282             :              * because PEM can have leading non-matching lines and blanks.
    1283             :              * OpenSSL doesn't expose its get_name(...) and its PEM routines
    1284             :              * don't differentiate between failure modes in enough detail to
    1285             :              * let us tell the difference between "not PEM, try DER" and
    1286             :              * "wrong password".
    1287             :              */
    1288           6 :             if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_ASN1) != 1)
    1289             :             {
    1290           2 :                 libpq_append_conn_error(conn, "could not load private key file \"%s\": %s",
    1291             :                                         fnbuf, err);
    1292           2 :                 SSLerrfree(err);
    1293           2 :                 return -1;
    1294             :             }
    1295             : 
    1296           4 :             SSLerrfree(err);
    1297             :         }
    1298             :     }
    1299             : 
    1300             :     /* verify that the cert and key go together */
    1301         324 :     if (have_cert &&
    1302          72 :         SSL_check_private_key(conn->ssl) != 1)
    1303             :     {
    1304           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1305             : 
    1306           0 :         libpq_append_conn_error(conn, "certificate does not match private key file \"%s\": %s",
    1307             :                                 fnbuf, err);
    1308           0 :         SSLerrfree(err);
    1309           0 :         return -1;
    1310             :     }
    1311             : 
    1312             :     /*
    1313             :      * If a root cert was loaded, also set our certificate verification
    1314             :      * callback.
    1315             :      */
    1316         252 :     if (have_rootcert)
    1317         202 :         SSL_set_verify(conn->ssl, SSL_VERIFY_PEER, verify_cb);
    1318             : 
    1319             :     /*
    1320             :      * Set compression option if necessary.
    1321             :      */
    1322         252 :     if (conn->sslcompression && conn->sslcompression[0] == '0')
    1323         252 :         SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
    1324             :     else
    1325           0 :         SSL_clear_options(conn->ssl, SSL_OP_NO_COMPRESSION);
    1326             : 
    1327         252 :     return 0;
    1328             : }
    1329             : 
    1330             : /*
    1331             :  *  Attempt to negotiate SSL connection.
    1332             :  */
    1333             : static PostgresPollingStatusType
    1334         506 : open_client_SSL(PGconn *conn)
    1335             : {
    1336             :     int         r;
    1337             : 
    1338         506 :     SOCK_ERRNO_SET(0);
    1339         506 :     ERR_clear_error();
    1340         506 :     r = SSL_connect(conn->ssl);
    1341         506 :     if (r <= 0)
    1342             :     {
    1343         278 :         int         save_errno = SOCK_ERRNO;
    1344         278 :         int         err = SSL_get_error(conn->ssl, r);
    1345             :         unsigned long ecode;
    1346             : 
    1347         278 :         ecode = ERR_get_error();
    1348         278 :         switch (err)
    1349             :         {
    1350         254 :             case SSL_ERROR_WANT_READ:
    1351         254 :                 return PGRES_POLLING_READING;
    1352             : 
    1353           0 :             case SSL_ERROR_WANT_WRITE:
    1354           0 :                 return PGRES_POLLING_WRITING;
    1355             : 
    1356           4 :             case SSL_ERROR_SYSCALL:
    1357             :                 {
    1358             :                     char        sebuf[PG_STRERROR_R_BUFLEN];
    1359             :                     unsigned long vcode;
    1360             : 
    1361           4 :                     vcode = SSL_get_verify_result(conn->ssl);
    1362             : 
    1363             :                     /*
    1364             :                      * If we get an X509 error here for failing to load the
    1365             :                      * local issuer cert, without an error in the socket layer
    1366             :                      * it means that verification failed due to a missing
    1367             :                      * system CA pool without it being a protocol error. We
    1368             :                      * inspect the sslrootcert setting to ensure that the user
    1369             :                      * was using the system CA pool. For other errors, log
    1370             :                      * them using the normal SYSCALL logging.
    1371             :                      */
    1372           4 :                     if (save_errno == 0 &&
    1373           0 :                         vcode == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY &&
    1374           0 :                         strcmp(conn->sslrootcert, "system") == 0)
    1375           0 :                         libpq_append_conn_error(conn, "SSL error: certificate verify failed: %s",
    1376             :                                                 X509_verify_cert_error_string(vcode));
    1377           4 :                     else if (r == -1 && save_errno != 0)
    1378           0 :                         libpq_append_conn_error(conn, "SSL SYSCALL error: %s",
    1379             :                                                 SOCK_STRERROR(save_errno, sebuf, sizeof(sebuf)));
    1380             :                     else
    1381           4 :                         libpq_append_conn_error(conn, "SSL SYSCALL error: EOF detected");
    1382           4 :                     pgtls_close(conn);
    1383           4 :                     return PGRES_POLLING_FAILED;
    1384             :                 }
    1385          20 :             case SSL_ERROR_SSL:
    1386             :                 {
    1387          20 :                     char       *err = SSLerrmessage(ecode);
    1388             : 
    1389          20 :                     libpq_append_conn_error(conn, "SSL error: %s", err);
    1390          20 :                     SSLerrfree(err);
    1391          20 :                     switch (ERR_GET_REASON(ecode))
    1392             :                     {
    1393             :                             /*
    1394             :                              * UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
    1395             :                              * TLSV1_ALERT_PROTOCOL_VERSION have been observed
    1396             :                              * when trying to communicate with an old OpenSSL
    1397             :                              * library, or when the client and server specify
    1398             :                              * disjoint protocol ranges.
    1399             :                              * NO_PROTOCOLS_AVAILABLE occurs if there's a
    1400             :                              * local misconfiguration (which can happen
    1401             :                              * despite our checks, if openssl.cnf injects a
    1402             :                              * limit we didn't account for).  It's not very
    1403             :                              * clear what would make OpenSSL return the other
    1404             :                              * codes listed here, but a hint about protocol
    1405             :                              * versions seems like it's appropriate for all.
    1406             :                              */
    1407           2 :                         case SSL_R_NO_PROTOCOLS_AVAILABLE:
    1408             :                         case SSL_R_UNSUPPORTED_PROTOCOL:
    1409             :                         case SSL_R_BAD_PROTOCOL_VERSION_NUMBER:
    1410             :                         case SSL_R_UNKNOWN_PROTOCOL:
    1411             :                         case SSL_R_UNKNOWN_SSL_VERSION:
    1412             :                         case SSL_R_UNSUPPORTED_SSL_VERSION:
    1413             :                         case SSL_R_WRONG_SSL_VERSION:
    1414             :                         case SSL_R_WRONG_VERSION_NUMBER:
    1415             :                         case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
    1416             : #ifdef SSL_R_VERSION_TOO_HIGH
    1417             :                         case SSL_R_VERSION_TOO_HIGH:
    1418             :                         case SSL_R_VERSION_TOO_LOW:
    1419             : #endif
    1420           4 :                             libpq_append_conn_error(conn, "This may indicate that the server does not support any SSL protocol version between %s and %s.",
    1421           2 :                                                     conn->ssl_min_protocol_version ?
    1422             :                                                     conn->ssl_min_protocol_version :
    1423             :                                                     MIN_OPENSSL_TLS_VERSION,
    1424           2 :                                                     conn->ssl_max_protocol_version ?
    1425             :                                                     conn->ssl_max_protocol_version :
    1426             :                                                     MAX_OPENSSL_TLS_VERSION);
    1427           2 :                             break;
    1428          18 :                         default:
    1429          18 :                             break;
    1430             :                     }
    1431          20 :                     pgtls_close(conn);
    1432          20 :                     return PGRES_POLLING_FAILED;
    1433             :                 }
    1434             : 
    1435           0 :             default:
    1436           0 :                 libpq_append_conn_error(conn, "unrecognized SSL error code: %d", err);
    1437           0 :                 pgtls_close(conn);
    1438           0 :                 return PGRES_POLLING_FAILED;
    1439             :         }
    1440             :     }
    1441             : 
    1442             :     /* ALPN is mandatory with direct SSL connections */
    1443         228 :     if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
    1444             :     {
    1445             :         const unsigned char *selected;
    1446             :         unsigned int len;
    1447             : 
    1448           6 :         SSL_get0_alpn_selected(conn->ssl, &selected, &len);
    1449             : 
    1450           6 :         if (selected == NULL)
    1451             :         {
    1452           0 :             libpq_append_conn_error(conn, "direct SSL connection was established without ALPN protocol negotiation extension");
    1453           0 :             pgtls_close(conn);
    1454           0 :             return PGRES_POLLING_FAILED;
    1455             :         }
    1456             : 
    1457             :         /*
    1458             :          * We only support one protocol so that's what the negotiation should
    1459             :          * always choose, but doesn't hurt to check.
    1460             :          */
    1461           6 :         if (len != strlen(PG_ALPN_PROTOCOL) ||
    1462           6 :             memcmp(selected, PG_ALPN_PROTOCOL, strlen(PG_ALPN_PROTOCOL)) != 0)
    1463             :         {
    1464           0 :             libpq_append_conn_error(conn, "SSL connection was established with unexpected ALPN protocol");
    1465           0 :             pgtls_close(conn);
    1466           0 :             return PGRES_POLLING_FAILED;
    1467             :         }
    1468             :     }
    1469             : 
    1470             :     /*
    1471             :      * We already checked the server certificate in initialize_SSL() using
    1472             :      * SSL_CTX_set_verify(), if root.crt exists.
    1473             :      */
    1474             : 
    1475             :     /* get server certificate */
    1476         228 :     conn->peer = SSL_get_peer_certificate(conn->ssl);
    1477         228 :     if (conn->peer == NULL)
    1478             :     {
    1479           0 :         char       *err = SSLerrmessage(ERR_get_error());
    1480             : 
    1481           0 :         libpq_append_conn_error(conn, "certificate could not be obtained: %s", err);
    1482           0 :         SSLerrfree(err);
    1483           0 :         pgtls_close(conn);
    1484           0 :         return PGRES_POLLING_FAILED;
    1485             :     }
    1486             : 
    1487         228 :     if (!pq_verify_peer_name_matches_certificate(conn))
    1488             :     {
    1489          26 :         pgtls_close(conn);
    1490          26 :         return PGRES_POLLING_FAILED;
    1491             :     }
    1492             : 
    1493             :     /* SSL handshake is complete */
    1494         202 :     return PGRES_POLLING_OK;
    1495             : }
    1496             : 
    1497             : void
    1498       54318 : pgtls_close(PGconn *conn)
    1499             : {
    1500       54318 :     if (conn->ssl_in_use)
    1501             :     {
    1502         256 :         if (conn->ssl)
    1503             :         {
    1504             :             /*
    1505             :              * We can't destroy everything SSL-related here due to the
    1506             :              * possible later calls to OpenSSL routines which may need our
    1507             :              * thread callbacks, so set a flag here and check at the end.
    1508             :              */
    1509             : 
    1510         256 :             SSL_shutdown(conn->ssl);
    1511         256 :             SSL_free(conn->ssl);
    1512         256 :             conn->ssl = NULL;
    1513         256 :             conn->ssl_in_use = false;
    1514         256 :             conn->ssl_handshake_started = false;
    1515             :         }
    1516             : 
    1517         256 :         if (conn->peer)
    1518             :         {
    1519         228 :             X509_free(conn->peer);
    1520         228 :             conn->peer = NULL;
    1521             :         }
    1522             : 
    1523             : #ifdef USE_SSL_ENGINE
    1524         256 :         if (conn->engine)
    1525             :         {
    1526           0 :             ENGINE_finish(conn->engine);
    1527           0 :             ENGINE_free(conn->engine);
    1528           0 :             conn->engine = NULL;
    1529             :         }
    1530             : #endif
    1531             :     }
    1532       54318 : }
    1533             : 
    1534             : 
    1535             : /*
    1536             :  * Obtain reason string for passed SSL errcode
    1537             :  *
    1538             :  * ERR_get_error() is used by caller to get errcode to pass here.
    1539             :  * The result must be freed after use, using SSLerrfree.
    1540             :  *
    1541             :  * Some caution is needed here since ERR_reason_error_string will return NULL
    1542             :  * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code
    1543             :  * represents a system errno value.  We don't want to return NULL ever.
    1544             :  */
    1545             : static char ssl_nomem[] = "out of memory allocating error description";
    1546             : 
    1547             : #define SSL_ERR_LEN 128
    1548             : 
    1549             : static char *
    1550          38 : SSLerrmessage(unsigned long ecode)
    1551             : {
    1552             :     const char *errreason;
    1553             :     char       *errbuf;
    1554             : 
    1555          38 :     errbuf = malloc(SSL_ERR_LEN);
    1556          38 :     if (!errbuf)
    1557           0 :         return ssl_nomem;
    1558          38 :     if (ecode == 0)
    1559             :     {
    1560           0 :         snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
    1561           0 :         return errbuf;
    1562             :     }
    1563          38 :     errreason = ERR_reason_error_string(ecode);
    1564          38 :     if (errreason != NULL)
    1565             :     {
    1566          38 :         strlcpy(errbuf, errreason, SSL_ERR_LEN);
    1567          38 :         return errbuf;
    1568             :     }
    1569             : 
    1570             :     /*
    1571             :      * Server aborted the connection with TLS "no_application_protocol" alert.
    1572             :      * The ERR_reason_error_string() function doesn't give any error string
    1573             :      * for that for some reason, so do it ourselves.  See
    1574             :      * https://github.com/openssl/openssl/issues/24300.  This is available in
    1575             :      * OpenSSL 1.1.0 and later, as well as in LibreSSL 3.4.3 (OpenBSD 7.0) and
    1576             :      * later.
    1577             :      */
    1578             : #ifdef SSL_AD_NO_APPLICATION_PROTOCOL
    1579           0 :     if (ERR_GET_LIB(ecode) == ERR_LIB_SSL &&
    1580           0 :         ERR_GET_REASON(ecode) == SSL_AD_REASON_OFFSET + SSL_AD_NO_APPLICATION_PROTOCOL)
    1581             :     {
    1582           0 :         snprintf(errbuf, SSL_ERR_LEN, "no application protocol");
    1583           0 :         return errbuf;
    1584             :     }
    1585             : #endif
    1586             : 
    1587             :     /*
    1588             :      * In OpenSSL 3.0.0 and later, ERR_reason_error_string does not map system
    1589             :      * errno values anymore.  (See OpenSSL source code for the explanation.)
    1590             :      * We can cover that shortcoming with this bit of code.  Older OpenSSL
    1591             :      * versions don't have the ERR_SYSTEM_ERROR macro, but that's okay because
    1592             :      * they don't have the shortcoming either.
    1593             :      */
    1594             : #ifdef ERR_SYSTEM_ERROR
    1595             :     if (ERR_SYSTEM_ERROR(ecode))
    1596             :     {
    1597             :         strerror_r(ERR_GET_REASON(ecode), errbuf, SSL_ERR_LEN);
    1598             :         return errbuf;
    1599             :     }
    1600             : #endif
    1601             : 
    1602             :     /* No choice but to report the numeric ecode */
    1603           0 :     snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
    1604           0 :     return errbuf;
    1605             : }
    1606             : 
    1607             : static void
    1608          38 : SSLerrfree(char *buf)
    1609             : {
    1610          38 :     if (buf != ssl_nomem)
    1611          38 :         free(buf);
    1612          38 : }
    1613             : 
    1614             : /* ------------------------------------------------------------ */
    1615             : /*                  SSL information functions                   */
    1616             : /* ------------------------------------------------------------ */
    1617             : 
    1618             : /*
    1619             :  *  Return pointer to OpenSSL object.
    1620             :  */
    1621             : void *
    1622           0 : PQgetssl(PGconn *conn)
    1623             : {
    1624           0 :     if (!conn)
    1625           0 :         return NULL;
    1626           0 :     return conn->ssl;
    1627             : }
    1628             : 
    1629             : void *
    1630           0 : PQsslStruct(PGconn *conn, const char *struct_name)
    1631             : {
    1632           0 :     if (!conn)
    1633           0 :         return NULL;
    1634           0 :     if (strcmp(struct_name, "OpenSSL") == 0)
    1635           0 :         return conn->ssl;
    1636           0 :     return NULL;
    1637             : }
    1638             : 
    1639             : const char *const *
    1640           0 : PQsslAttributeNames(PGconn *conn)
    1641             : {
    1642             :     static const char *const openssl_attrs[] = {
    1643             :         "library",
    1644             :         "key_bits",
    1645             :         "cipher",
    1646             :         "compression",
    1647             :         "protocol",
    1648             :         "alpn",
    1649             :         NULL
    1650             :     };
    1651             :     static const char *const empty_attrs[] = {NULL};
    1652             : 
    1653           0 :     if (!conn)
    1654             :     {
    1655             :         /* Return attributes of default SSL library */
    1656           0 :         return openssl_attrs;
    1657             :     }
    1658             : 
    1659             :     /* No attrs for unencrypted connection */
    1660           0 :     if (conn->ssl == NULL)
    1661           0 :         return empty_attrs;
    1662             : 
    1663           0 :     return openssl_attrs;
    1664             : }
    1665             : 
    1666             : const char *
    1667           2 : PQsslAttribute(PGconn *conn, const char *attribute_name)
    1668             : {
    1669           2 :     if (!conn)
    1670             :     {
    1671             :         /* PQsslAttribute(NULL, "library") reports the default SSL library */
    1672           2 :         if (strcmp(attribute_name, "library") == 0)
    1673           2 :             return "OpenSSL";
    1674           0 :         return NULL;
    1675             :     }
    1676             : 
    1677             :     /* All attributes read as NULL for a non-encrypted connection */
    1678           0 :     if (conn->ssl == NULL)
    1679           0 :         return NULL;
    1680             : 
    1681           0 :     if (strcmp(attribute_name, "library") == 0)
    1682           0 :         return "OpenSSL";
    1683             : 
    1684           0 :     if (strcmp(attribute_name, "key_bits") == 0)
    1685             :     {
    1686             :         static char sslbits_str[12];
    1687             :         int         sslbits;
    1688             : 
    1689           0 :         SSL_get_cipher_bits(conn->ssl, &sslbits);
    1690           0 :         snprintf(sslbits_str, sizeof(sslbits_str), "%d", sslbits);
    1691           0 :         return sslbits_str;
    1692             :     }
    1693             : 
    1694           0 :     if (strcmp(attribute_name, "cipher") == 0)
    1695           0 :         return SSL_get_cipher(conn->ssl);
    1696             : 
    1697           0 :     if (strcmp(attribute_name, "compression") == 0)
    1698           0 :         return SSL_get_current_compression(conn->ssl) ? "on" : "off";
    1699             : 
    1700           0 :     if (strcmp(attribute_name, "protocol") == 0)
    1701           0 :         return SSL_get_version(conn->ssl);
    1702             : 
    1703           0 :     if (strcmp(attribute_name, "alpn") == 0)
    1704             :     {
    1705             :         const unsigned char *data;
    1706             :         unsigned int len;
    1707             :         static char alpn_str[256];  /* alpn doesn't support longer than 255
    1708             :                                      * bytes */
    1709             : 
    1710           0 :         SSL_get0_alpn_selected(conn->ssl, &data, &len);
    1711           0 :         if (data == NULL || len == 0 || len > sizeof(alpn_str) - 1)
    1712           0 :             return "";
    1713           0 :         memcpy(alpn_str, data, len);
    1714           0 :         alpn_str[len] = 0;
    1715           0 :         return alpn_str;
    1716             :     }
    1717             : 
    1718           0 :     return NULL;                /* unknown attribute */
    1719             : }
    1720             : 
    1721             : /*
    1722             :  * Private substitute BIO: this does the sending and receiving using
    1723             :  * pqsecure_raw_write() and pqsecure_raw_read() instead, to allow those
    1724             :  * functions to disable SIGPIPE and give better error messages on I/O errors.
    1725             :  *
    1726             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
    1727             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
    1728             :  */
    1729             : 
    1730             : /* protected by ssl_config_mutex */
    1731             : static BIO_METHOD *pgconn_bio_method_ptr;
    1732             : 
    1733             : static int
    1734        4560 : pgconn_bio_read(BIO *h, char *buf, int size)
    1735             : {
    1736        4560 :     PGconn     *conn = (PGconn *) BIO_get_data(h);
    1737             :     int         res;
    1738             : 
    1739        4560 :     res = pqsecure_raw_read(conn, buf, size);
    1740        4560 :     BIO_clear_retry_flags(h);
    1741        4560 :     conn->last_read_was_eof = res == 0;
    1742        4560 :     if (res < 0)
    1743             :     {
    1744             :         /* If we were interrupted, tell caller to retry */
    1745         422 :         switch (SOCK_ERRNO)
    1746             :         {
    1747             : #ifdef EAGAIN
    1748         422 :             case EAGAIN:
    1749             : #endif
    1750             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    1751             :             case EWOULDBLOCK:
    1752             : #endif
    1753             :             case EINTR:
    1754         422 :                 BIO_set_retry_read(h);
    1755         422 :                 break;
    1756             : 
    1757           0 :             default:
    1758           0 :                 break;
    1759             :         }
    1760        4138 :     }
    1761             : 
    1762        4560 :     if (res > 0)
    1763        4134 :         conn->ssl_handshake_started = true;
    1764             : 
    1765        4560 :     return res;
    1766             : }
    1767             : 
    1768             : static int
    1769        1280 : pgconn_bio_write(BIO *h, const char *buf, int size)
    1770             : {
    1771             :     int         res;
    1772             : 
    1773        1280 :     res = pqsecure_raw_write((PGconn *) BIO_get_data(h), buf, size);
    1774        1280 :     BIO_clear_retry_flags(h);
    1775        1280 :     if (res < 0)
    1776             :     {
    1777             :         /* If we were interrupted, tell caller to retry */
    1778           0 :         switch (SOCK_ERRNO)
    1779             :         {
    1780             : #ifdef EAGAIN
    1781           0 :             case EAGAIN:
    1782             : #endif
    1783             : #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
    1784             :             case EWOULDBLOCK:
    1785             : #endif
    1786             :             case EINTR:
    1787           0 :                 BIO_set_retry_write(h);
    1788           0 :                 break;
    1789             : 
    1790           0 :             default:
    1791           0 :                 break;
    1792             :         }
    1793        1280 :     }
    1794             : 
    1795        1280 :     return res;
    1796             : }
    1797             : 
    1798             : static long
    1799        1218 : pgconn_bio_ctrl(BIO *h, int cmd, long num, void *ptr)
    1800             : {
    1801             :     long        res;
    1802        1218 :     PGconn     *conn = (PGconn *) BIO_get_data(h);
    1803             : 
    1804        1218 :     switch (cmd)
    1805             :     {
    1806           0 :         case BIO_CTRL_EOF:
    1807             : 
    1808             :             /*
    1809             :              * This should not be needed. pgconn_bio_read already has a way to
    1810             :              * signal EOF to OpenSSL. However, OpenSSL made an undocumented,
    1811             :              * backwards-incompatible change and now expects EOF via BIO_ctrl.
    1812             :              * See https://github.com/openssl/openssl/issues/8208
    1813             :              */
    1814           0 :             res = conn->last_read_was_eof;
    1815           0 :             break;
    1816         714 :         case BIO_CTRL_FLUSH:
    1817             :             /* libssl expects all BIOs to support BIO_flush. */
    1818         714 :             res = 1;
    1819         714 :             break;
    1820         504 :         default:
    1821         504 :             res = 0;
    1822         504 :             break;
    1823             :     }
    1824             : 
    1825        1218 :     return res;
    1826             : }
    1827             : 
    1828             : static BIO_METHOD *
    1829         256 : pgconn_bio_method(void)
    1830             : {
    1831             :     BIO_METHOD *res;
    1832             : 
    1833         256 :     if (pthread_mutex_lock(&ssl_config_mutex))
    1834           0 :         return NULL;
    1835             : 
    1836         256 :     res = pgconn_bio_method_ptr;
    1837             : 
    1838         256 :     if (!pgconn_bio_method_ptr)
    1839             :     {
    1840             :         int         my_bio_index;
    1841             : 
    1842         256 :         my_bio_index = BIO_get_new_index();
    1843         256 :         if (my_bio_index == -1)
    1844           0 :             goto err;
    1845         256 :         my_bio_index |= BIO_TYPE_SOURCE_SINK;
    1846         256 :         res = BIO_meth_new(my_bio_index, "libpq socket");
    1847         256 :         if (!res)
    1848           0 :             goto err;
    1849             : 
    1850             :         /*
    1851             :          * As of this writing, these functions never fail. But check anyway,
    1852             :          * like OpenSSL's own examples do.
    1853             :          */
    1854         512 :         if (!BIO_meth_set_write(res, pgconn_bio_write) ||
    1855         512 :             !BIO_meth_set_read(res, pgconn_bio_read) ||
    1856         256 :             !BIO_meth_set_ctrl(res, pgconn_bio_ctrl))
    1857             :         {
    1858           0 :             goto err;
    1859             :         }
    1860             :     }
    1861             : 
    1862         256 :     pgconn_bio_method_ptr = res;
    1863         256 :     pthread_mutex_unlock(&ssl_config_mutex);
    1864         256 :     return res;
    1865             : 
    1866           0 : err:
    1867           0 :     if (res)
    1868           0 :         BIO_meth_free(res);
    1869           0 :     pthread_mutex_unlock(&ssl_config_mutex);
    1870           0 :     return NULL;
    1871             : }
    1872             : 
    1873             : static int
    1874         256 : ssl_set_pgconn_bio(PGconn *conn)
    1875             : {
    1876             :     BIO        *bio;
    1877             :     BIO_METHOD *bio_method;
    1878             : 
    1879         256 :     bio_method = pgconn_bio_method();
    1880         256 :     if (bio_method == NULL)
    1881           0 :         return 0;
    1882             : 
    1883         256 :     bio = BIO_new(bio_method);
    1884         256 :     if (bio == NULL)
    1885           0 :         return 0;
    1886             : 
    1887         256 :     BIO_set_data(bio, conn);
    1888         256 :     BIO_set_init(bio, 1);
    1889             : 
    1890         256 :     SSL_set_bio(conn->ssl, bio, bio);
    1891         256 :     return 1;
    1892             : }
    1893             : 
    1894             : /*
    1895             :  * This is the default handler to return a client cert password from
    1896             :  * conn->sslpassword. Apps may install it explicitly if they want to
    1897             :  * prevent openssl from ever prompting on stdin.
    1898             :  */
    1899             : int
    1900           4 : PQdefaultSSLKeyPassHook_OpenSSL(char *buf, int size, PGconn *conn)
    1901             : {
    1902           4 :     if (conn && conn->sslpassword)
    1903             :     {
    1904           4 :         if (strlen(conn->sslpassword) + 1 > size)
    1905           0 :             fprintf(stderr, libpq_gettext("WARNING: sslpassword truncated\n"));
    1906           4 :         strncpy(buf, conn->sslpassword, size);
    1907           4 :         buf[size - 1] = '\0';
    1908           4 :         return strlen(buf);
    1909             :     }
    1910             :     else
    1911             :     {
    1912           0 :         buf[0] = '\0';
    1913           0 :         return 0;
    1914             :     }
    1915             : }
    1916             : 
    1917             : PQsslKeyPassHook_OpenSSL_type
    1918           0 : PQgetSSLKeyPassHook_OpenSSL(void)
    1919             : {
    1920           0 :     return PQsslKeyPassHook;
    1921             : }
    1922             : 
    1923             : void
    1924           0 : PQsetSSLKeyPassHook_OpenSSL(PQsslKeyPassHook_OpenSSL_type hook)
    1925             : {
    1926           0 :     PQsslKeyPassHook = hook;
    1927           0 : }
    1928             : 
    1929             : /*
    1930             :  * Supply a password to decrypt a client certificate.
    1931             :  *
    1932             :  * This must match OpenSSL type pem_password_cb.
    1933             :  */
    1934             : static int
    1935           4 : PQssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
    1936             : {
    1937           4 :     PGconn     *conn = userdata;
    1938             : 
    1939           4 :     if (PQsslKeyPassHook)
    1940           0 :         return PQsslKeyPassHook(buf, size, conn);
    1941             :     else
    1942           4 :         return PQdefaultSSLKeyPassHook_OpenSSL(buf, size, conn);
    1943             : }
    1944             : 
    1945             : /*
    1946             :  * Convert TLS protocol version string to OpenSSL values
    1947             :  *
    1948             :  * If a version is passed that is not supported by the current OpenSSL version,
    1949             :  * then we return -1. If a non-negative value is returned, subsequent code can
    1950             :  * assume it is working with a supported version.
    1951             :  *
    1952             :  * Note: this is rather similar to the backend routine in be-secure-openssl.c,
    1953             :  * so make sure to update both routines if changing this one.
    1954             :  */
    1955             : static int
    1956         264 : ssl_protocol_version_to_openssl(const char *protocol)
    1957             : {
    1958         264 :     if (pg_strcasecmp("TLSv1", protocol) == 0)
    1959           0 :         return TLS1_VERSION;
    1960             : 
    1961             : #ifdef TLS1_1_VERSION
    1962         264 :     if (pg_strcasecmp("TLSv1.1", protocol) == 0)
    1963           0 :         return TLS1_1_VERSION;
    1964             : #endif
    1965             : 
    1966             : #ifdef TLS1_2_VERSION
    1967         264 :     if (pg_strcasecmp("TLSv1.2", protocol) == 0)
    1968         264 :         return TLS1_2_VERSION;
    1969             : #endif
    1970             : 
    1971             : #ifdef TLS1_3_VERSION
    1972           0 :     if (pg_strcasecmp("TLSv1.3", protocol) == 0)
    1973           0 :         return TLS1_3_VERSION;
    1974             : #endif
    1975             : 
    1976           0 :     return -1;
    1977             : }

Generated by: LCOV version 1.14