LCOV - code coverage report
Current view: top level - src/backend/libpq - be-secure-openssl.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13devel Lines: 282 448 62.9 %
Date: 2019-09-19 23:07:04 Functions: 27 29 93.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * be-secure-openssl.c
       4             :  *    functions for OpenSSL support in the backend.
       5             :  *
       6             :  *
       7             :  * Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
       8             :  * Portions Copyright (c) 1994, Regents of the University of California
       9             :  *
      10             :  *
      11             :  * IDENTIFICATION
      12             :  *    src/backend/libpq/be-secure-openssl.c
      13             :  *
      14             :  *-------------------------------------------------------------------------
      15             :  */
      16             : 
      17             : #include "postgres.h"
      18             : 
      19             : #include <sys/stat.h>
      20             : #include <signal.h>
      21             : #include <fcntl.h>
      22             : #include <ctype.h>
      23             : #include <sys/socket.h>
      24             : #include <unistd.h>
      25             : #include <netdb.h>
      26             : #include <netinet/in.h>
      27             : #ifdef HAVE_NETINET_TCP_H
      28             : #include <netinet/tcp.h>
      29             : #include <arpa/inet.h>
      30             : #endif
      31             : 
      32             : #include <openssl/ssl.h>
      33             : #include <openssl/dh.h>
      34             : #include <openssl/conf.h>
      35             : #ifndef OPENSSL_NO_ECDH
      36             : #include <openssl/ec.h>
      37             : #endif
      38             : 
      39             : #include "libpq/libpq.h"
      40             : #include "miscadmin.h"
      41             : #include "pgstat.h"
      42             : #include "storage/fd.h"
      43             : #include "storage/latch.h"
      44             : #include "tcop/tcopprot.h"
      45             : #include "utils/memutils.h"
      46             : 
      47             : 
      48             : static int  my_sock_read(BIO *h, char *buf, int size);
      49             : static int  my_sock_write(BIO *h, const char *buf, int size);
      50             : static BIO_METHOD *my_BIO_s_socket(void);
      51             : static int  my_SSL_set_fd(Port *port, int fd);
      52             : 
      53             : static DH  *load_dh_file(char *filename, bool isServerStart);
      54             : static DH  *load_dh_buffer(const char *, size_t);
      55             : static int  ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      56             : static int  dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata);
      57             : static int  verify_cb(int, X509_STORE_CTX *);
      58             : static void info_cb(const SSL *ssl, int type, int args);
      59             : static bool initialize_dh(SSL_CTX *context, bool isServerStart);
      60             : static bool initialize_ecdh(SSL_CTX *context, bool isServerStart);
      61             : static const char *SSLerrmessage(unsigned long ecode);
      62             : 
      63             : static char *X509_NAME_to_cstring(X509_NAME *name);
      64             : 
      65             : static SSL_CTX *SSL_context = NULL;
      66             : static bool SSL_initialized = false;
      67             : static bool dummy_ssl_passwd_cb_called = false;
      68             : static bool ssl_is_server_start;
      69             : 
      70             : static int  ssl_protocol_version_to_openssl(int v, const char *guc_name,
      71             :                                             int loglevel);
      72             : #ifndef SSL_CTX_set_min_proto_version
      73             : static int  SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version);
      74             : static int  SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version);
      75             : #endif
      76             : 
      77             : 
      78             : /* ------------------------------------------------------------ */
      79             : /*                       Public interface                       */
      80             : /* ------------------------------------------------------------ */
      81             : 
      82             : int
      83          20 : be_tls_init(bool isServerStart)
      84             : {
      85          20 :     STACK_OF(X509_NAME) *root_cert_list = NULL;
      86             :     SSL_CTX    *context;
      87             : 
      88             :     /* This stuff need be done only once. */
      89          20 :     if (!SSL_initialized)
      90             :     {
      91             : #ifdef HAVE_OPENSSL_INIT_SSL
      92          20 :         OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
      93             : #else
      94             :         OPENSSL_config(NULL);
      95             :         SSL_library_init();
      96             :         SSL_load_error_strings();
      97             : #endif
      98          20 :         SSL_initialized = true;
      99             :     }
     100             : 
     101             :     /*
     102             :      * We use SSLv23_method() because it can negotiate use of the highest
     103             :      * mutually supported protocol version, while alternatives like
     104             :      * TLSv1_2_method() permit only one specific version.  Note that we don't
     105             :      * actually allow SSL v2 or v3, only TLS protocols (see below).
     106             :      */
     107          20 :     context = SSL_CTX_new(SSLv23_method());
     108          20 :     if (!context)
     109             :     {
     110           0 :         ereport(isServerStart ? FATAL : LOG,
     111             :                 (errmsg("could not create SSL context: %s",
     112             :                         SSLerrmessage(ERR_get_error()))));
     113           0 :         goto error;
     114             :     }
     115             : 
     116             :     /*
     117             :      * Disable OpenSSL's moving-write-buffer sanity check, because it causes
     118             :      * unnecessary failures in nonblocking send cases.
     119             :      */
     120          20 :     SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
     121             : 
     122             :     /*
     123             :      * Set password callback
     124             :      */
     125          20 :     if (isServerStart)
     126             :     {
     127          20 :         if (ssl_passphrase_command[0])
     128           4 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
     129             :     }
     130             :     else
     131             :     {
     132           0 :         if (ssl_passphrase_command[0] && ssl_passphrase_command_supports_reload)
     133           0 :             SSL_CTX_set_default_passwd_cb(context, ssl_external_passwd_cb);
     134             :         else
     135             : 
     136             :             /*
     137             :              * If reloading and no external command is configured, override
     138             :              * OpenSSL's default handling of passphrase-protected files,
     139             :              * because we don't want to prompt for a passphrase in an
     140             :              * already-running server.
     141             :              */
     142           0 :             SSL_CTX_set_default_passwd_cb(context, dummy_ssl_passwd_cb);
     143             :     }
     144             :     /* used by the callback */
     145          20 :     ssl_is_server_start = isServerStart;
     146             : 
     147             :     /*
     148             :      * Load and verify server's certificate and private key
     149             :      */
     150          20 :     if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
     151             :     {
     152           0 :         ereport(isServerStart ? FATAL : LOG,
     153             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     154             :                  errmsg("could not load server certificate file \"%s\": %s",
     155             :                         ssl_cert_file, SSLerrmessage(ERR_get_error()))));
     156           0 :         goto error;
     157             :     }
     158             : 
     159          20 :     if (!check_ssl_key_file_permissions(ssl_key_file, isServerStart))
     160           0 :         goto error;
     161             : 
     162             :     /*
     163             :      * OK, try to load the private key file.
     164             :      */
     165          20 :     dummy_ssl_passwd_cb_called = false;
     166             : 
     167          20 :     if (SSL_CTX_use_PrivateKey_file(context,
     168             :                                     ssl_key_file,
     169             :                                     SSL_FILETYPE_PEM) != 1)
     170             :     {
     171           2 :         if (dummy_ssl_passwd_cb_called)
     172           0 :             ereport(isServerStart ? FATAL : LOG,
     173             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     174             :                      errmsg("private key file \"%s\" cannot be reloaded because it requires a passphrase",
     175             :                             ssl_key_file)));
     176             :         else
     177           2 :             ereport(isServerStart ? FATAL : LOG,
     178             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     179             :                      errmsg("could not load private key file \"%s\": %s",
     180             :                             ssl_key_file, SSLerrmessage(ERR_get_error()))));
     181           0 :         goto error;
     182             :     }
     183             : 
     184          18 :     if (SSL_CTX_check_private_key(context) != 1)
     185             :     {
     186           0 :         ereport(isServerStart ? FATAL : LOG,
     187             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     188             :                  errmsg("check of private key failed: %s",
     189             :                         SSLerrmessage(ERR_get_error()))));
     190           0 :         goto error;
     191             :     }
     192             : 
     193          18 :     if (ssl_min_protocol_version)
     194             :     {
     195          18 :         int         ssl_ver = ssl_protocol_version_to_openssl(ssl_min_protocol_version,
     196             :                                                               "ssl_min_protocol_version",
     197             :                                                               isServerStart ? FATAL : LOG);
     198             : 
     199          18 :         if (ssl_ver == -1)
     200           0 :             goto error;
     201          18 :         SSL_CTX_set_min_proto_version(context, ssl_ver);
     202             :     }
     203             : 
     204          18 :     if (ssl_max_protocol_version)
     205             :     {
     206           0 :         int         ssl_ver = ssl_protocol_version_to_openssl(ssl_max_protocol_version,
     207             :                                                               "ssl_max_protocol_version",
     208             :                                                               isServerStart ? FATAL : LOG);
     209             : 
     210           0 :         if (ssl_ver == -1)
     211           0 :             goto error;
     212           0 :         SSL_CTX_set_max_proto_version(context, ssl_ver);
     213             :     }
     214             : 
     215             :     /* disallow SSL session tickets */
     216             : #ifdef SSL_OP_NO_TICKET         /* added in OpenSSL 0.9.8f */
     217          18 :     SSL_CTX_set_options(context, SSL_OP_NO_TICKET);
     218             : #endif
     219             : 
     220             :     /* disallow SSL session caching, too */
     221          18 :     SSL_CTX_set_session_cache_mode(context, SSL_SESS_CACHE_OFF);
     222             : 
     223             :     /* set up ephemeral DH and ECDH keys */
     224          18 :     if (!initialize_dh(context, isServerStart))
     225           0 :         goto error;
     226          18 :     if (!initialize_ecdh(context, isServerStart))
     227           0 :         goto error;
     228             : 
     229             :     /* set up the allowed cipher list */
     230          18 :     if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
     231             :     {
     232           0 :         ereport(isServerStart ? FATAL : LOG,
     233             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     234             :                  errmsg("could not set the cipher list (no valid ciphers available)")));
     235           0 :         goto error;
     236             :     }
     237             : 
     238             :     /* Let server choose order */
     239          18 :     if (SSLPreferServerCiphers)
     240          18 :         SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
     241             : 
     242             :     /*
     243             :      * Load CA store, so we can verify client certificates if needed.
     244             :      */
     245          18 :     if (ssl_ca_file[0])
     246             :     {
     247          32 :         if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
     248          16 :             (root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
     249             :         {
     250           0 :             ereport(isServerStart ? FATAL : LOG,
     251             :                     (errcode(ERRCODE_CONFIG_FILE_ERROR),
     252             :                      errmsg("could not load root certificate file \"%s\": %s",
     253             :                             ssl_ca_file, SSLerrmessage(ERR_get_error()))));
     254           0 :             goto error;
     255             :         }
     256             :     }
     257             : 
     258             :     /*----------
     259             :      * Load the Certificate Revocation List (CRL).
     260             :      * http://searchsecurity.techtarget.com/sDefinition/0,,sid14_gci803160,00.html
     261             :      *----------
     262             :      */
     263          18 :     if (ssl_crl_file[0])
     264             :     {
     265          16 :         X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
     266             : 
     267          16 :         if (cvstore)
     268             :         {
     269             :             /* Set the flags to check against the complete CRL chain */
     270          16 :             if (X509_STORE_load_locations(cvstore, ssl_crl_file, NULL) == 1)
     271             :             {
     272             :                 /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
     273             : #ifdef X509_V_FLAG_CRL_CHECK
     274          16 :                 X509_STORE_set_flags(cvstore,
     275             :                                      X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
     276             : #else
     277             :                 ereport(LOG,
     278             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     279             :                          errmsg("SSL certificate revocation list file \"%s\" ignored",
     280             :                                 ssl_crl_file),
     281             :                          errdetail("SSL library does not support certificate revocation lists.")));
     282             : #endif
     283             :             }
     284             :             else
     285             :             {
     286           0 :                 ereport(isServerStart ? FATAL : LOG,
     287             :                         (errcode(ERRCODE_CONFIG_FILE_ERROR),
     288             :                          errmsg("could not load SSL certificate revocation list file \"%s\": %s",
     289             :                                 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
     290           0 :                 goto error;
     291             :             }
     292             :         }
     293             :     }
     294             : 
     295          18 :     if (ssl_ca_file[0])
     296             :     {
     297             :         /*
     298             :          * Always ask for SSL client cert, but don't fail if it's not
     299             :          * presented.  We might fail such connections later, depending on what
     300             :          * we find in pg_hba.conf.
     301             :          */
     302          16 :         SSL_CTX_set_verify(context,
     303             :                            (SSL_VERIFY_PEER |
     304             :                             SSL_VERIFY_CLIENT_ONCE),
     305             :                            verify_cb);
     306             : 
     307             :         /*
     308             :          * Tell OpenSSL to send the list of root certs we trust to clients in
     309             :          * CertificateRequests.  This lets a client with a keystore select the
     310             :          * appropriate client certificate to send to us.
     311             :          */
     312          16 :         SSL_CTX_set_client_CA_list(context, root_cert_list);
     313             :     }
     314             : 
     315             :     /*
     316             :      * Success!  Replace any existing SSL_context.
     317             :      */
     318          18 :     if (SSL_context)
     319           0 :         SSL_CTX_free(SSL_context);
     320             : 
     321          18 :     SSL_context = context;
     322             : 
     323             :     /*
     324             :      * Set flag to remember whether CA store has been loaded into SSL_context.
     325             :      */
     326          18 :     if (ssl_ca_file[0])
     327          16 :         ssl_loaded_verify_locations = true;
     328             :     else
     329           2 :         ssl_loaded_verify_locations = false;
     330             : 
     331          18 :     return 0;
     332             : 
     333             : error:
     334           0 :     if (context)
     335           0 :         SSL_CTX_free(context);
     336           0 :     return -1;
     337             : }
     338             : 
     339             : void
     340          48 : be_tls_destroy(void)
     341             : {
     342          48 :     if (SSL_context)
     343           0 :         SSL_CTX_free(SSL_context);
     344          48 :     SSL_context = NULL;
     345          48 :     ssl_loaded_verify_locations = false;
     346          48 : }
     347             : 
     348             : int
     349          84 : be_tls_open_server(Port *port)
     350             : {
     351             :     int         r;
     352             :     int         err;
     353             :     int         waitfor;
     354             :     unsigned long ecode;
     355             : 
     356             :     Assert(!port->ssl);
     357             :     Assert(!port->peer);
     358             : 
     359          84 :     if (!SSL_context)
     360             :     {
     361           0 :         ereport(COMMERROR,
     362             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     363             :                  errmsg("could not initialize SSL connection: SSL context not set up")));
     364           0 :         return -1;
     365             :     }
     366             : 
     367          84 :     if (!(port->ssl = SSL_new(SSL_context)))
     368             :     {
     369           0 :         ereport(COMMERROR,
     370             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     371             :                  errmsg("could not initialize SSL connection: %s",
     372             :                         SSLerrmessage(ERR_get_error()))));
     373           0 :         return -1;
     374             :     }
     375          84 :     if (!my_SSL_set_fd(port, port->sock))
     376             :     {
     377           0 :         ereport(COMMERROR,
     378             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
     379             :                  errmsg("could not set SSL socket: %s",
     380             :                         SSLerrmessage(ERR_get_error()))));
     381           0 :         return -1;
     382             :     }
     383          84 :     port->ssl_in_use = true;
     384             : 
     385             : aloop:
     386             : 
     387             :     /*
     388             :      * Prepare to call SSL_get_error() by clearing thread's OpenSSL error
     389             :      * queue.  In general, the current thread's error queue must be empty
     390             :      * before the TLS/SSL I/O operation is attempted, or SSL_get_error() will
     391             :      * not work reliably.  An extension may have failed to clear the
     392             :      * per-thread error queue following another call to an OpenSSL I/O
     393             :      * routine.
     394             :      */
     395         138 :     ERR_clear_error();
     396         138 :     r = SSL_accept(port->ssl);
     397         136 :     if (r <= 0)
     398             :     {
     399          74 :         err = SSL_get_error(port->ssl, r);
     400             : 
     401             :         /*
     402             :          * Other clients of OpenSSL in the backend may fail to call
     403             :          * ERR_get_error(), but we always do, so as to not cause problems for
     404             :          * OpenSSL clients that don't call ERR_clear_error() defensively.  Be
     405             :          * sure that this happens by calling now. SSL_get_error() relies on
     406             :          * the OpenSSL per-thread error queue being intact, so this is the
     407             :          * earliest possible point ERR_get_error() may be called.
     408             :          */
     409          74 :         ecode = ERR_get_error();
     410          74 :         switch (err)
     411             :         {
     412             :             case SSL_ERROR_WANT_READ:
     413             :             case SSL_ERROR_WANT_WRITE:
     414             :                 /* not allowed during connection establishment */
     415             :                 Assert(!port->noblock);
     416             : 
     417             :                 /*
     418             :                  * No need to care about timeouts/interrupts here. At this
     419             :                  * point authentication_timeout still employs
     420             :                  * StartupPacketTimeoutHandler() which directly exits.
     421             :                  */
     422          54 :                 if (err == SSL_ERROR_WANT_READ)
     423          54 :                     waitfor = WL_SOCKET_READABLE | WL_EXIT_ON_PM_DEATH;
     424             :                 else
     425           0 :                     waitfor = WL_SOCKET_WRITEABLE | WL_EXIT_ON_PM_DEATH;
     426             : 
     427          54 :                 (void) WaitLatchOrSocket(MyLatch, waitfor, port->sock, 0,
     428             :                                          WAIT_EVENT_SSL_OPEN_SERVER);
     429          54 :                 goto aloop;
     430             :             case SSL_ERROR_SYSCALL:
     431           6 :                 if (r < 0)
     432           6 :                     ereport(COMMERROR,
     433             :                             (errcode_for_socket_access(),
     434             :                              errmsg("could not accept SSL connection: %m")));
     435             :                 else
     436           0 :                     ereport(COMMERROR,
     437             :                             (errcode(ERRCODE_PROTOCOL_VIOLATION),
     438             :                              errmsg("could not accept SSL connection: EOF detected")));
     439           6 :                 break;
     440             :             case SSL_ERROR_SSL:
     441          14 :                 ereport(COMMERROR,
     442             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     443             :                          errmsg("could not accept SSL connection: %s",
     444             :                                 SSLerrmessage(ecode))));
     445          14 :                 break;
     446             :             case SSL_ERROR_ZERO_RETURN:
     447           0 :                 ereport(COMMERROR,
     448             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     449             :                          errmsg("could not accept SSL connection: EOF detected")));
     450           0 :                 break;
     451             :             default:
     452           0 :                 ereport(COMMERROR,
     453             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     454             :                          errmsg("unrecognized SSL error code: %d",
     455             :                                 err)));
     456           0 :                 break;
     457             :         }
     458          20 :         return -1;
     459             :     }
     460             : 
     461             :     /* Get client certificate, if available. */
     462          62 :     port->peer = SSL_get_peer_certificate(port->ssl);
     463             : 
     464             :     /* and extract the Common Name from it. */
     465          62 :     port->peer_cn = NULL;
     466          62 :     port->peer_cert_valid = false;
     467          62 :     if (port->peer != NULL)
     468             :     {
     469             :         int         len;
     470             : 
     471          14 :         len = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
     472             :                                         NID_commonName, NULL, 0);
     473          14 :         if (len != -1)
     474             :         {
     475             :             char       *peer_cn;
     476             : 
     477          14 :             peer_cn = MemoryContextAlloc(TopMemoryContext, len + 1);
     478          14 :             r = X509_NAME_get_text_by_NID(X509_get_subject_name(port->peer),
     479             :                                           NID_commonName, peer_cn, len + 1);
     480          14 :             peer_cn[len] = '\0';
     481          14 :             if (r != len)
     482             :             {
     483             :                 /* shouldn't happen */
     484           0 :                 pfree(peer_cn);
     485           0 :                 return -1;
     486             :             }
     487             : 
     488             :             /*
     489             :              * Reject embedded NULLs in certificate common name to prevent
     490             :              * attacks like CVE-2009-4034.
     491             :              */
     492          14 :             if (len != strlen(peer_cn))
     493             :             {
     494           0 :                 ereport(COMMERROR,
     495             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     496             :                          errmsg("SSL certificate's common name contains embedded null")));
     497           0 :                 pfree(peer_cn);
     498           0 :                 return -1;
     499             :             }
     500             : 
     501          14 :             port->peer_cn = peer_cn;
     502             :         }
     503          14 :         port->peer_cert_valid = true;
     504             :     }
     505             : 
     506             :     /* set up debugging/info callback */
     507          62 :     SSL_CTX_set_info_callback(SSL_context, info_cb);
     508             : 
     509          62 :     return 0;
     510             : }
     511             : 
     512             : void
     513          84 : be_tls_close(Port *port)
     514             : {
     515          84 :     if (port->ssl)
     516             :     {
     517          84 :         SSL_shutdown(port->ssl);
     518          84 :         SSL_free(port->ssl);
     519          84 :         port->ssl = NULL;
     520          84 :         port->ssl_in_use = false;
     521             :     }
     522             : 
     523          84 :     if (port->peer)
     524             :     {
     525          14 :         X509_free(port->peer);
     526          14 :         port->peer = NULL;
     527             :     }
     528             : 
     529          84 :     if (port->peer_cn)
     530             :     {
     531          14 :         pfree(port->peer_cn);
     532          14 :         port->peer_cn = NULL;
     533             :     }
     534          84 : }
     535             : 
     536             : ssize_t
     537         206 : be_tls_read(Port *port, void *ptr, size_t len, int *waitfor)
     538             : {
     539             :     ssize_t     n;
     540             :     int         err;
     541             :     unsigned long ecode;
     542             : 
     543         206 :     errno = 0;
     544         206 :     ERR_clear_error();
     545         206 :     n = SSL_read(port->ssl, ptr, len);
     546         206 :     err = SSL_get_error(port->ssl, n);
     547         206 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     548         206 :     switch (err)
     549             :     {
     550             :         case SSL_ERROR_NONE:
     551             :             /* a-ok */
     552         160 :             break;
     553             :         case SSL_ERROR_WANT_READ:
     554          40 :             *waitfor = WL_SOCKET_READABLE;
     555          40 :             errno = EWOULDBLOCK;
     556          40 :             n = -1;
     557          40 :             break;
     558             :         case SSL_ERROR_WANT_WRITE:
     559           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     560           0 :             errno = EWOULDBLOCK;
     561           0 :             n = -1;
     562           0 :             break;
     563             :         case SSL_ERROR_SYSCALL:
     564             :             /* leave it to caller to ereport the value of errno */
     565           0 :             if (n != -1)
     566             :             {
     567           0 :                 errno = ECONNRESET;
     568           0 :                 n = -1;
     569             :             }
     570           0 :             break;
     571             :         case SSL_ERROR_SSL:
     572           0 :             ereport(COMMERROR,
     573             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     574             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     575           0 :             errno = ECONNRESET;
     576           0 :             n = -1;
     577           0 :             break;
     578             :         case SSL_ERROR_ZERO_RETURN:
     579             :             /* connection was cleanly shut down by peer */
     580           6 :             n = 0;
     581           6 :             break;
     582             :         default:
     583           0 :             ereport(COMMERROR,
     584             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     585             :                      errmsg("unrecognized SSL error code: %d",
     586             :                             err)));
     587           0 :             errno = ECONNRESET;
     588           0 :             n = -1;
     589           0 :             break;
     590             :     }
     591             : 
     592         206 :     return n;
     593             : }
     594             : 
     595             : ssize_t
     596         110 : be_tls_write(Port *port, void *ptr, size_t len, int *waitfor)
     597             : {
     598             :     ssize_t     n;
     599             :     int         err;
     600             :     unsigned long ecode;
     601             : 
     602         110 :     errno = 0;
     603         110 :     ERR_clear_error();
     604         110 :     n = SSL_write(port->ssl, ptr, len);
     605         110 :     err = SSL_get_error(port->ssl, n);
     606         110 :     ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
     607         110 :     switch (err)
     608             :     {
     609             :         case SSL_ERROR_NONE:
     610             :             /* a-ok */
     611         110 :             break;
     612             :         case SSL_ERROR_WANT_READ:
     613           0 :             *waitfor = WL_SOCKET_READABLE;
     614           0 :             errno = EWOULDBLOCK;
     615           0 :             n = -1;
     616           0 :             break;
     617             :         case SSL_ERROR_WANT_WRITE:
     618           0 :             *waitfor = WL_SOCKET_WRITEABLE;
     619           0 :             errno = EWOULDBLOCK;
     620           0 :             n = -1;
     621           0 :             break;
     622             :         case SSL_ERROR_SYSCALL:
     623             :             /* leave it to caller to ereport the value of errno */
     624           0 :             if (n != -1)
     625             :             {
     626           0 :                 errno = ECONNRESET;
     627           0 :                 n = -1;
     628             :             }
     629           0 :             break;
     630             :         case SSL_ERROR_SSL:
     631           0 :             ereport(COMMERROR,
     632             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     633             :                      errmsg("SSL error: %s", SSLerrmessage(ecode))));
     634           0 :             errno = ECONNRESET;
     635           0 :             n = -1;
     636           0 :             break;
     637             :         case SSL_ERROR_ZERO_RETURN:
     638             : 
     639             :             /*
     640             :              * the SSL connection was closed, leave it to the caller to
     641             :              * ereport it
     642             :              */
     643           0 :             errno = ECONNRESET;
     644           0 :             n = -1;
     645           0 :             break;
     646             :         default:
     647           0 :             ereport(COMMERROR,
     648             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     649             :                      errmsg("unrecognized SSL error code: %d",
     650             :                             err)));
     651           0 :             errno = ECONNRESET;
     652           0 :             n = -1;
     653           0 :             break;
     654             :     }
     655             : 
     656         110 :     return n;
     657             : }
     658             : 
     659             : /* ------------------------------------------------------------ */
     660             : /*                      Internal functions                      */
     661             : /* ------------------------------------------------------------ */
     662             : 
     663             : /*
     664             :  * Private substitute BIO: this does the sending and receiving using send() and
     665             :  * recv() instead. This is so that we can enable and disable interrupts
     666             :  * just while calling recv(). We cannot have interrupts occurring while
     667             :  * the bulk of OpenSSL runs, because it uses malloc() and possibly other
     668             :  * non-reentrant libc facilities. We also need to call send() and recv()
     669             :  * directly so it gets passed through the socket/signals layer on Win32.
     670             :  *
     671             :  * These functions are closely modelled on the standard socket BIO in OpenSSL;
     672             :  * see sock_read() and sock_write() in OpenSSL's crypto/bio/bss_sock.c.
     673             :  * XXX OpenSSL 1.0.1e considers many more errcodes than just EINTR as reasons
     674             :  * to retry; do we need to adopt their logic for that?
     675             :  */
     676             : 
     677             : #ifndef HAVE_BIO_GET_DATA
     678             : #define BIO_get_data(bio) (bio->ptr)
     679             : #define BIO_set_data(bio, data) (bio->ptr = data)
     680             : #endif
     681             : 
     682             : static BIO_METHOD *my_bio_methods = NULL;
     683             : 
     684             : static int
     685        1156 : my_sock_read(BIO *h, char *buf, int size)
     686             : {
     687        1156 :     int         res = 0;
     688             : 
     689        1156 :     if (buf != NULL)
     690             :     {
     691        1156 :         res = secure_raw_read(((Port *) BIO_get_data(h)), buf, size);
     692        1156 :         BIO_clear_retry_flags(h);
     693        1156 :         if (res <= 0)
     694             :         {
     695             :             /* If we were interrupted, tell caller to retry */
     696         100 :             if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     697             :             {
     698          94 :                 BIO_set_retry_read(h);
     699             :             }
     700             :         }
     701             :     }
     702             : 
     703        1156 :     return res;
     704             : }
     705             : 
     706             : static int
     707         316 : my_sock_write(BIO *h, const char *buf, int size)
     708             : {
     709         316 :     int         res = 0;
     710             : 
     711         316 :     res = secure_raw_write(((Port *) BIO_get_data(h)), buf, size);
     712         314 :     BIO_clear_retry_flags(h);
     713         314 :     if (res <= 0)
     714             :     {
     715             :         /* If we were interrupted, tell caller to retry */
     716           0 :         if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
     717             :         {
     718           0 :             BIO_set_retry_write(h);
     719             :         }
     720             :     }
     721             : 
     722         314 :     return res;
     723             : }
     724             : 
     725             : static BIO_METHOD *
     726          84 : my_BIO_s_socket(void)
     727             : {
     728          84 :     if (!my_bio_methods)
     729             :     {
     730          84 :         BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
     731             : #ifdef HAVE_BIO_METH_NEW
     732             :         int         my_bio_index;
     733             : 
     734          84 :         my_bio_index = BIO_get_new_index();
     735          84 :         if (my_bio_index == -1)
     736           0 :             return NULL;
     737          84 :         my_bio_methods = BIO_meth_new(my_bio_index, "PostgreSQL backend socket");
     738          84 :         if (!my_bio_methods)
     739           0 :             return NULL;
     740         168 :         if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
     741         168 :             !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
     742         168 :             !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
     743         168 :             !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
     744         168 :             !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
     745         168 :             !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
     746         168 :             !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
     747          84 :             !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
     748             :         {
     749           0 :             BIO_meth_free(my_bio_methods);
     750           0 :             my_bio_methods = NULL;
     751           0 :             return NULL;
     752             :         }
     753             : #else
     754             :         my_bio_methods = malloc(sizeof(BIO_METHOD));
     755             :         if (!my_bio_methods)
     756             :             return NULL;
     757             :         memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
     758             :         my_bio_methods->bread = my_sock_read;
     759             :         my_bio_methods->bwrite = my_sock_write;
     760             : #endif
     761             :     }
     762          84 :     return my_bio_methods;
     763             : }
     764             : 
     765             : /* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
     766             : static int
     767          84 : my_SSL_set_fd(Port *port, int fd)
     768             : {
     769          84 :     int         ret = 0;
     770             :     BIO        *bio;
     771             :     BIO_METHOD *bio_method;
     772             : 
     773          84 :     bio_method = my_BIO_s_socket();
     774          84 :     if (bio_method == NULL)
     775             :     {
     776           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     777           0 :         goto err;
     778             :     }
     779          84 :     bio = BIO_new(bio_method);
     780             : 
     781          84 :     if (bio == NULL)
     782             :     {
     783           0 :         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
     784           0 :         goto err;
     785             :     }
     786          84 :     BIO_set_data(bio, port);
     787             : 
     788          84 :     BIO_set_fd(bio, fd, BIO_NOCLOSE);
     789          84 :     SSL_set_bio(port->ssl, bio, bio);
     790          84 :     ret = 1;
     791             : err:
     792          84 :     return ret;
     793             : }
     794             : 
     795             : /*
     796             :  *  Load precomputed DH parameters.
     797             :  *
     798             :  *  To prevent "downgrade" attacks, we perform a number of checks
     799             :  *  to verify that the DBA-generated DH parameters file contains
     800             :  *  what we expect it to contain.
     801             :  */
     802             : static DH  *
     803           0 : load_dh_file(char *filename, bool isServerStart)
     804             : {
     805             :     FILE       *fp;
     806           0 :     DH         *dh = NULL;
     807             :     int         codes;
     808             : 
     809             :     /* attempt to open file.  It's not an error if it doesn't exist. */
     810           0 :     if ((fp = AllocateFile(filename, "r")) == NULL)
     811             :     {
     812           0 :         ereport(isServerStart ? FATAL : LOG,
     813             :                 (errcode_for_file_access(),
     814             :                  errmsg("could not open DH parameters file \"%s\": %m",
     815             :                         filename)));
     816           0 :         return NULL;
     817             :     }
     818             : 
     819           0 :     dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
     820           0 :     FreeFile(fp);
     821             : 
     822           0 :     if (dh == NULL)
     823             :     {
     824           0 :         ereport(isServerStart ? FATAL : LOG,
     825             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     826             :                  errmsg("could not load DH parameters file: %s",
     827             :                         SSLerrmessage(ERR_get_error()))));
     828           0 :         return NULL;
     829             :     }
     830             : 
     831             :     /* make sure the DH parameters are usable */
     832           0 :     if (DH_check(dh, &codes) == 0)
     833             :     {
     834           0 :         ereport(isServerStart ? FATAL : LOG,
     835             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     836             :                  errmsg("invalid DH parameters: %s",
     837             :                         SSLerrmessage(ERR_get_error()))));
     838           0 :         return NULL;
     839             :     }
     840           0 :     if (codes & DH_CHECK_P_NOT_PRIME)
     841             :     {
     842           0 :         ereport(isServerStart ? FATAL : LOG,
     843             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     844             :                  errmsg("invalid DH parameters: p is not prime")));
     845           0 :         return NULL;
     846             :     }
     847           0 :     if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
     848           0 :         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
     849             :     {
     850           0 :         ereport(isServerStart ? FATAL : LOG,
     851             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
     852             :                  errmsg("invalid DH parameters: neither suitable generator or safe prime")));
     853           0 :         return NULL;
     854             :     }
     855             : 
     856           0 :     return dh;
     857             : }
     858             : 
     859             : /*
     860             :  *  Load hardcoded DH parameters.
     861             :  *
     862             :  *  To prevent problems if the DH parameters files don't even
     863             :  *  exist, we can load DH parameters hardcoded into this file.
     864             :  */
     865             : static DH  *
     866          18 : load_dh_buffer(const char *buffer, size_t len)
     867             : {
     868             :     BIO        *bio;
     869          18 :     DH         *dh = NULL;
     870             : 
     871          18 :     bio = BIO_new_mem_buf(unconstify(char *, buffer), len);
     872          18 :     if (bio == NULL)
     873           0 :         return NULL;
     874          18 :     dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
     875          18 :     if (dh == NULL)
     876           0 :         ereport(DEBUG2,
     877             :                 (errmsg_internal("DH load buffer: %s",
     878             :                                  SSLerrmessage(ERR_get_error()))));
     879          18 :     BIO_free(bio);
     880             : 
     881          18 :     return dh;
     882             : }
     883             : 
     884             : /*
     885             :  *  Passphrase collection callback using ssl_passphrase_command
     886             :  */
     887             : static int
     888           4 : ssl_external_passwd_cb(char *buf, int size, int rwflag, void *userdata)
     889             : {
     890             :     /* same prompt as OpenSSL uses internally */
     891           4 :     const char *prompt = "Enter PEM pass phrase:";
     892             : 
     893             :     Assert(rwflag == 0);
     894             : 
     895           4 :     return run_ssl_passphrase_command(prompt, ssl_is_server_start, buf, size);
     896             : }
     897             : 
     898             : /*
     899             :  * Dummy passphrase callback
     900             :  *
     901             :  * If OpenSSL is told to use a passphrase-protected server key, by default
     902             :  * it will issue a prompt on /dev/tty and try to read a key from there.
     903             :  * That's no good during a postmaster SIGHUP cycle, not to mention SSL context
     904             :  * reload in an EXEC_BACKEND postmaster child.  So override it with this dummy
     905             :  * function that just returns an empty passphrase, guaranteeing failure.
     906             :  */
     907             : static int
     908           0 : dummy_ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata)
     909             : {
     910             :     /* Set flag to change the error message we'll report */
     911           0 :     dummy_ssl_passwd_cb_called = true;
     912             :     /* And return empty string */
     913             :     Assert(size > 0);
     914           0 :     buf[0] = '\0';
     915           0 :     return 0;
     916             : }
     917             : 
     918             : /*
     919             :  *  Certificate verification callback
     920             :  *
     921             :  *  This callback allows us to log intermediate problems during
     922             :  *  verification, but for now we'll see if the final error message
     923             :  *  contains enough information.
     924             :  *
     925             :  *  This callback also allows us to override the default acceptance
     926             :  *  criteria (e.g., accepting self-signed or expired certs), but
     927             :  *  for now we accept the default checks.
     928             :  */
     929             : static int
     930          44 : verify_cb(int ok, X509_STORE_CTX *ctx)
     931             : {
     932          44 :     return ok;
     933             : }
     934             : 
     935             : /*
     936             :  *  This callback is used to copy SSL information messages
     937             :  *  into the PostgreSQL log.
     938             :  */
     939             : static void
     940          68 : info_cb(const SSL *ssl, int type, int args)
     941             : {
     942          68 :     switch (type)
     943             :     {
     944             :         case SSL_CB_HANDSHAKE_START:
     945           0 :             ereport(DEBUG4,
     946             :                     (errmsg_internal("SSL: handshake start")));
     947           0 :             break;
     948             :         case SSL_CB_HANDSHAKE_DONE:
     949           0 :             ereport(DEBUG4,
     950             :                     (errmsg_internal("SSL: handshake done")));
     951           0 :             break;
     952             :         case SSL_CB_ACCEPT_LOOP:
     953           0 :             ereport(DEBUG4,
     954             :                     (errmsg_internal("SSL: accept loop")));
     955           0 :             break;
     956             :         case SSL_CB_ACCEPT_EXIT:
     957           0 :             ereport(DEBUG4,
     958             :                     (errmsg_internal("SSL: accept exit (%d)", args)));
     959           0 :             break;
     960             :         case SSL_CB_CONNECT_LOOP:
     961           0 :             ereport(DEBUG4,
     962             :                     (errmsg_internal("SSL: connect loop")));
     963           0 :             break;
     964             :         case SSL_CB_CONNECT_EXIT:
     965           0 :             ereport(DEBUG4,
     966             :                     (errmsg_internal("SSL: connect exit (%d)", args)));
     967           0 :             break;
     968             :         case SSL_CB_READ_ALERT:
     969           6 :             ereport(DEBUG4,
     970             :                     (errmsg_internal("SSL: read alert (0x%04x)", args)));
     971           6 :             break;
     972             :         case SSL_CB_WRITE_ALERT:
     973          62 :             ereport(DEBUG4,
     974             :                     (errmsg_internal("SSL: write alert (0x%04x)", args)));
     975          62 :             break;
     976             :     }
     977          68 : }
     978             : 
     979             : /*
     980             :  * Set DH parameters for generating ephemeral DH keys.  The
     981             :  * DH parameters can take a long time to compute, so they must be
     982             :  * precomputed.
     983             :  *
     984             :  * Since few sites will bother to create a parameter file, we also
     985             :  * provide a fallback to the parameters provided by the OpenSSL
     986             :  * project.
     987             :  *
     988             :  * These values can be static (once loaded or computed) since the
     989             :  * OpenSSL library can efficiently generate random keys from the
     990             :  * information provided.
     991             :  */
     992             : static bool
     993          18 : initialize_dh(SSL_CTX *context, bool isServerStart)
     994             : {
     995          18 :     DH         *dh = NULL;
     996             : 
     997          18 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE);
     998             : 
     999          18 :     if (ssl_dh_params_file[0])
    1000           0 :         dh = load_dh_file(ssl_dh_params_file, isServerStart);
    1001          18 :     if (!dh)
    1002          18 :         dh = load_dh_buffer(FILE_DH2048, sizeof(FILE_DH2048));
    1003          18 :     if (!dh)
    1004             :     {
    1005           0 :         ereport(isServerStart ? FATAL : LOG,
    1006             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1007             :                  (errmsg("DH: could not load DH parameters"))));
    1008           0 :         return false;
    1009             :     }
    1010             : 
    1011          18 :     if (SSL_CTX_set_tmp_dh(context, dh) != 1)
    1012             :     {
    1013           0 :         ereport(isServerStart ? FATAL : LOG,
    1014             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1015             :                  (errmsg("DH: could not set DH parameters: %s",
    1016             :                          SSLerrmessage(ERR_get_error())))));
    1017           0 :         return false;
    1018             :     }
    1019          18 :     return true;
    1020             : }
    1021             : 
    1022             : /*
    1023             :  * Set ECDH parameters for generating ephemeral Elliptic Curve DH
    1024             :  * keys.  This is much simpler than the DH parameters, as we just
    1025             :  * need to provide the name of the curve to OpenSSL.
    1026             :  */
    1027             : static bool
    1028          18 : initialize_ecdh(SSL_CTX *context, bool isServerStart)
    1029             : {
    1030             : #ifndef OPENSSL_NO_ECDH
    1031             :     EC_KEY     *ecdh;
    1032             :     int         nid;
    1033             : 
    1034          18 :     nid = OBJ_sn2nid(SSLECDHCurve);
    1035          18 :     if (!nid)
    1036             :     {
    1037           0 :         ereport(isServerStart ? FATAL : LOG,
    1038             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1039             :                  errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
    1040           0 :         return false;
    1041             :     }
    1042             : 
    1043          18 :     ecdh = EC_KEY_new_by_curve_name(nid);
    1044          18 :     if (!ecdh)
    1045             :     {
    1046           0 :         ereport(isServerStart ? FATAL : LOG,
    1047             :                 (errcode(ERRCODE_CONFIG_FILE_ERROR),
    1048             :                  errmsg("ECDH: could not create key")));
    1049           0 :         return false;
    1050             :     }
    1051             : 
    1052          18 :     SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
    1053          18 :     SSL_CTX_set_tmp_ecdh(context, ecdh);
    1054          18 :     EC_KEY_free(ecdh);
    1055             : #endif
    1056             : 
    1057          18 :     return true;
    1058             : }
    1059             : 
    1060             : /*
    1061             :  * Obtain reason string for passed SSL errcode
    1062             :  *
    1063             :  * ERR_get_error() is used by caller to get errcode to pass here.
    1064             :  *
    1065             :  * Some caution is needed here since ERR_reason_error_string will
    1066             :  * return NULL if it doesn't recognize the error code.  We don't
    1067             :  * want to return NULL ever.
    1068             :  */
    1069             : static const char *
    1070          16 : SSLerrmessage(unsigned long ecode)
    1071             : {
    1072             :     const char *errreason;
    1073             :     static char errbuf[36];
    1074             : 
    1075          16 :     if (ecode == 0)
    1076           0 :         return _("no SSL error reported");
    1077          16 :     errreason = ERR_reason_error_string(ecode);
    1078          16 :     if (errreason != NULL)
    1079          16 :         return errreason;
    1080           0 :     snprintf(errbuf, sizeof(errbuf), _("SSL error code %lu"), ecode);
    1081           0 :     return errbuf;
    1082             : }
    1083             : 
    1084             : int
    1085         100 : be_tls_get_cipher_bits(Port *port)
    1086             : {
    1087             :     int         bits;
    1088             : 
    1089         100 :     if (port->ssl)
    1090             :     {
    1091         100 :         SSL_get_cipher_bits(port->ssl, &bits);
    1092         100 :         return bits;
    1093             :     }
    1094             :     else
    1095           0 :         return 0;
    1096             : }
    1097             : 
    1098             : bool
    1099         100 : be_tls_get_compression(Port *port)
    1100             : {
    1101         100 :     if (port->ssl)
    1102         100 :         return (SSL_get_current_compression(port->ssl) != NULL);
    1103             :     else
    1104           0 :         return false;
    1105             : }
    1106             : 
    1107             : const char *
    1108         100 : be_tls_get_version(Port *port)
    1109             : {
    1110         100 :     if (port->ssl)
    1111         100 :         return SSL_get_version(port->ssl);
    1112             :     else
    1113           0 :         return NULL;
    1114             : }
    1115             : 
    1116             : const char *
    1117         100 : be_tls_get_cipher(Port *port)
    1118             : {
    1119         100 :     if (port->ssl)
    1120         100 :         return SSL_get_cipher(port->ssl);
    1121             :     else
    1122           0 :         return NULL;
    1123             : }
    1124             : 
    1125             : void
    1126          50 : be_tls_get_peer_subject_name(Port *port, char *ptr, size_t len)
    1127             : {
    1128          50 :     if (port->peer)
    1129          10 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_subject_name(port->peer)), len);
    1130             :     else
    1131          40 :         ptr[0] = '\0';
    1132          50 : }
    1133             : 
    1134             : void
    1135          50 : be_tls_get_peer_issuer_name(Port *port, char *ptr, size_t len)
    1136             : {
    1137          50 :     if (port->peer)
    1138          10 :         strlcpy(ptr, X509_NAME_to_cstring(X509_get_issuer_name(port->peer)), len);
    1139             :     else
    1140          40 :         ptr[0] = '\0';
    1141          50 : }
    1142             : 
    1143             : void
    1144          50 : be_tls_get_peer_serial(Port *port, char *ptr, size_t len)
    1145             : {
    1146          50 :     if (port->peer)
    1147             :     {
    1148             :         ASN1_INTEGER *serial;
    1149             :         BIGNUM     *b;
    1150             :         char       *decimal;
    1151             : 
    1152          10 :         serial = X509_get_serialNumber(port->peer);
    1153          10 :         b = ASN1_INTEGER_to_BN(serial, NULL);
    1154          10 :         decimal = BN_bn2dec(b);
    1155             : 
    1156          10 :         BN_free(b);
    1157          10 :         strlcpy(ptr, decimal, len);
    1158          10 :         OPENSSL_free(decimal);
    1159             :     }
    1160             :     else
    1161          40 :         ptr[0] = '\0';
    1162          50 : }
    1163             : 
    1164             : #ifdef HAVE_X509_GET_SIGNATURE_NID
    1165             : char *
    1166           2 : be_tls_get_certificate_hash(Port *port, size_t *len)
    1167             : {
    1168             :     X509       *server_cert;
    1169             :     char       *cert_hash;
    1170           2 :     const EVP_MD *algo_type = NULL;
    1171             :     unsigned char hash[EVP_MAX_MD_SIZE];    /* size for SHA-512 */
    1172             :     unsigned int hash_size;
    1173             :     int         algo_nid;
    1174             : 
    1175           2 :     *len = 0;
    1176           2 :     server_cert = SSL_get_certificate(port->ssl);
    1177           2 :     if (server_cert == NULL)
    1178           0 :         return NULL;
    1179             : 
    1180             :     /*
    1181             :      * Get the signature algorithm of the certificate to determine the hash
    1182             :      * algorithm to use for the result.
    1183             :      */
    1184           2 :     if (!OBJ_find_sigid_algs(X509_get_signature_nid(server_cert),
    1185             :                              &algo_nid, NULL))
    1186           0 :         elog(ERROR, "could not determine server certificate signature algorithm");
    1187             : 
    1188             :     /*
    1189             :      * The TLS server's certificate bytes need to be hashed with SHA-256 if
    1190             :      * its signature algorithm is MD5 or SHA-1 as per RFC 5929
    1191             :      * (https://tools.ietf.org/html/rfc5929#section-4.1).  If something else
    1192             :      * is used, the same hash as the signature algorithm is used.
    1193             :      */
    1194           2 :     switch (algo_nid)
    1195             :     {
    1196             :         case NID_md5:
    1197             :         case NID_sha1:
    1198           0 :             algo_type = EVP_sha256();
    1199           0 :             break;
    1200             :         default:
    1201           2 :             algo_type = EVP_get_digestbynid(algo_nid);
    1202           2 :             if (algo_type == NULL)
    1203           0 :                 elog(ERROR, "could not find digest for NID %s",
    1204             :                      OBJ_nid2sn(algo_nid));
    1205           2 :             break;
    1206             :     }
    1207             : 
    1208             :     /* generate and save the certificate hash */
    1209           2 :     if (!X509_digest(server_cert, algo_type, hash, &hash_size))
    1210           0 :         elog(ERROR, "could not generate server certificate hash");
    1211             : 
    1212           2 :     cert_hash = palloc(hash_size);
    1213           2 :     memcpy(cert_hash, hash, hash_size);
    1214           2 :     *len = hash_size;
    1215             : 
    1216           2 :     return cert_hash;
    1217             : }
    1218             : #endif
    1219             : 
    1220             : /*
    1221             :  * Convert an X509 subject name to a cstring.
    1222             :  *
    1223             :  */
    1224             : static char *
    1225          20 : X509_NAME_to_cstring(X509_NAME *name)
    1226             : {
    1227          20 :     BIO        *membuf = BIO_new(BIO_s_mem());
    1228             :     int         i,
    1229             :                 nid,
    1230          20 :                 count = X509_NAME_entry_count(name);
    1231             :     X509_NAME_ENTRY *e;
    1232             :     ASN1_STRING *v;
    1233             :     const char *field_name;
    1234             :     size_t      size;
    1235             :     char        nullterm;
    1236             :     char       *sp;
    1237             :     char       *dp;
    1238             :     char       *result;
    1239             : 
    1240          20 :     (void) BIO_set_close(membuf, BIO_CLOSE);
    1241          40 :     for (i = 0; i < count; i++)
    1242             :     {
    1243          20 :         e = X509_NAME_get_entry(name, i);
    1244          20 :         nid = OBJ_obj2nid(X509_NAME_ENTRY_get_object(e));
    1245          20 :         v = X509_NAME_ENTRY_get_data(e);
    1246          20 :         field_name = OBJ_nid2sn(nid);
    1247          20 :         if (!field_name)
    1248           0 :             field_name = OBJ_nid2ln(nid);
    1249          20 :         BIO_printf(membuf, "/%s=", field_name);
    1250          20 :         ASN1_STRING_print_ex(membuf, v,
    1251             :                              ((ASN1_STRFLGS_RFC2253 & ~ASN1_STRFLGS_ESC_MSB)
    1252             :                               | ASN1_STRFLGS_UTF8_CONVERT));
    1253             :     }
    1254             : 
    1255             :     /* ensure null termination of the BIO's content */
    1256          20 :     nullterm = '\0';
    1257          20 :     BIO_write(membuf, &nullterm, 1);
    1258          20 :     size = BIO_get_mem_data(membuf, &sp);
    1259          20 :     dp = pg_any_to_server(sp, size - 1, PG_UTF8);
    1260             : 
    1261          20 :     result = pstrdup(dp);
    1262          20 :     if (dp != sp)
    1263           0 :         pfree(dp);
    1264          20 :     BIO_free(membuf);
    1265             : 
    1266          20 :     return result;
    1267             : }
    1268             : 
    1269             : /*
    1270             :  * Convert TLS protocol version GUC enum to OpenSSL values
    1271             :  *
    1272             :  * This is a straightforward one-to-one mapping, but doing it this way makes
    1273             :  * guc.c independent of OpenSSL availability and version.
    1274             :  *
    1275             :  * If a version is passed that is not supported by the current OpenSSL
    1276             :  * version, then we log with the given loglevel and return (if we return) -1.
    1277             :  * If a nonnegative value is returned, subsequent code can assume it's working
    1278             :  * with a supported version.
    1279             :  */
    1280             : static int
    1281          18 : ssl_protocol_version_to_openssl(int v, const char *guc_name, int loglevel)
    1282             : {
    1283          18 :     switch (v)
    1284             :     {
    1285             :         case PG_TLS_ANY:
    1286           0 :             return 0;
    1287             :         case PG_TLS1_VERSION:
    1288          18 :             return TLS1_VERSION;
    1289             :         case PG_TLS1_1_VERSION:
    1290             : #ifdef TLS1_1_VERSION
    1291           0 :             return TLS1_1_VERSION;
    1292             : #else
    1293             :             break;
    1294             : #endif
    1295             :         case PG_TLS1_2_VERSION:
    1296             : #ifdef TLS1_2_VERSION
    1297           0 :             return TLS1_2_VERSION;
    1298             : #else
    1299             :             break;
    1300             : #endif
    1301             :         case PG_TLS1_3_VERSION:
    1302             : #ifdef TLS1_3_VERSION
    1303             :             return TLS1_3_VERSION;
    1304             : #else
    1305           0 :             break;
    1306             : #endif
    1307             :     }
    1308             : 
    1309           0 :     ereport(loglevel,
    1310             :             (errmsg("%s setting %s not supported by this build",
    1311             :                     guc_name,
    1312             :                     GetConfigOption(guc_name, false, false))));
    1313           0 :     return -1;
    1314             : }
    1315             : 
    1316             : /*
    1317             :  * Replacements for APIs present in newer versions of OpenSSL
    1318             :  */
    1319             : #ifndef SSL_CTX_set_min_proto_version
    1320             : 
    1321             : /*
    1322             :  * OpenSSL versions that support TLS 1.3 shouldn't get here because they
    1323             :  * already have these functions.  So we don't have to keep updating the below
    1324             :  * code for every new TLS version, and eventually it can go away.  But let's
    1325             :  * just check this to make sure ...
    1326             :  */
    1327             : #ifdef TLS1_3_VERSION
    1328             : #error OpenSSL version mismatch
    1329             : #endif
    1330             : 
    1331             : static int
    1332             : SSL_CTX_set_min_proto_version(SSL_CTX *ctx, int version)
    1333             : {
    1334             :     int         ssl_options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
    1335             : 
    1336             :     if (version > TLS1_VERSION)
    1337             :         ssl_options |= SSL_OP_NO_TLSv1;
    1338             : #ifdef TLS1_1_VERSION
    1339             :     if (version > TLS1_1_VERSION)
    1340             :         ssl_options |= SSL_OP_NO_TLSv1_1;
    1341             : #endif
    1342             : #ifdef TLS1_2_VERSION
    1343             :     if (version > TLS1_2_VERSION)
    1344             :         ssl_options |= SSL_OP_NO_TLSv1_2;
    1345             : #endif
    1346             : 
    1347             :     SSL_CTX_set_options(ctx, ssl_options);
    1348             : 
    1349             :     return 1;                   /* success */
    1350             : }
    1351             : 
    1352             : static int
    1353             : SSL_CTX_set_max_proto_version(SSL_CTX *ctx, int version)
    1354             : {
    1355             :     int         ssl_options = 0;
    1356             : 
    1357             :     AssertArg(version != 0);
    1358             : 
    1359             : #ifdef TLS1_1_VERSION
    1360             :     if (version < TLS1_1_VERSION)
    1361             :         ssl_options |= SSL_OP_NO_TLSv1_1;
    1362             : #endif
    1363             : #ifdef TLS1_2_VERSION
    1364             :     if (version < TLS1_2_VERSION)
    1365             :         ssl_options |= SSL_OP_NO_TLSv1_2;
    1366             : #endif
    1367             : 
    1368             :     SSL_CTX_set_options(ctx, ssl_options);
    1369             : 
    1370             :     return 1;                   /* success */
    1371             : }
    1372             : 
    1373             : #endif                          /* !SSL_CTX_set_min_proto_version */

Generated by: LCOV version 1.13