40 #ifdef HAVE_NETINET_TCP_H
41 #include <netinet/tcp.h>
48 #ifdef ENABLE_THREAD_SAFETY
56 #include <openssl/ssl.h>
57 #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
58 #include <openssl/conf.h>
61 #include <openssl/engine.h>
63 #include <openssl/x509v3.h>
66 static int verify_cb(
int ok, X509_STORE_CTX *ctx);
92 #ifdef ENABLE_THREAD_SAFETY
93 static long ssl_open_connections = 0;
99 static long win32_ssl_create_mutex = 0;
115 #ifdef ENABLE_THREAD_SAFETY
121 if (ssl_open_connections != 0)
136 if (conn->ssl ==
NULL)
138 #ifdef ENABLE_THREAD_SAFETY
142 #ifdef ENABLE_THREAD_SAFETY
152 !SSL_set_app_data(conn->ssl, conn) ||
161 #ifdef ENABLE_THREAD_SAFETY
168 conn->ssl_in_use =
true;
170 #ifdef ENABLE_THREAD_SAFETY
195 return SSL_pending(conn->ssl);
209 int result_errno = 0;
226 n = SSL_read(conn->ssl, ptr, len);
227 err = SSL_get_error(conn->ssl, n);
237 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
245 "SSL_read failed but did not provide error information\n");
250 case SSL_ERROR_WANT_READ:
253 case SSL_ERROR_WANT_WRITE:
262 case SSL_ERROR_SYSCALL:
266 if (result_errno == EPIPE ||
270 "server closed the connection unexpectedly\n"
271 "\tThis probably means the server terminated abnormally\n"
272 "\tbefore or while processing the request.\n"));
277 sebuf,
sizeof(sebuf)));
300 case SSL_ERROR_ZERO_RETURN:
308 libpq_gettext(
"SSL connection has been closed unexpectedly\n"));
339 int result_errno = 0;
346 n = SSL_write(conn->ssl, ptr, len);
347 err = SSL_get_error(conn->ssl, n);
348 ecode = (err != SSL_ERROR_NONE || n < 0) ? ERR_get_error() : 0;
356 "SSL_write failed but did not provide error information\n");
361 case SSL_ERROR_WANT_READ:
369 case SSL_ERROR_WANT_WRITE:
372 case SSL_ERROR_SYSCALL:
376 if (result_errno == EPIPE || result_errno ==
ECONNRESET)
379 "server closed the connection unexpectedly\n"
380 "\tThis probably means the server terminated abnormally\n"
381 "\tbefore or while processing the request.\n"));
386 sebuf,
sizeof(sebuf)));
409 case SSL_ERROR_ZERO_RETURN:
417 libpq_gettext(
"SSL connection has been closed unexpectedly\n"));
477 int lenpat = strlen(pattern);
478 int lenstr = strlen(
string);
490 if (
pg_strcasecmp(pattern + 1,
string + lenstr - lenpat + 1) != 0)
498 if (strchr(
string,
'.') <
string + lenstr - lenpat)
526 unsigned char *namedata;
532 if (name_entry ==
NULL)
545 namedata = ASN1_STRING_data(name_entry);
546 len = ASN1_STRING_length(name_entry);
554 memcpy(name, namedata, len);
561 if (len != strlen(name))
565 libpq_gettext(
"SSL certificate's name contains embedded null\n"));
596 int names_examined = 0;
597 bool found_match =
false;
598 bool got_error =
false;
599 char *first_name =
NULL;
601 STACK_OF(GENERAL_NAME) *peer_san;
609 if (strcmp(conn->
sslmode,
"verify-full") != 0)
616 libpq_gettext(
"host name must be specified for a verified SSL connection\n"));
624 peer_san = (STACK_OF(GENERAL_NAME) *)
625 X509_get_ext_d2i(conn->peer, NID_subject_alt_name,
NULL,
NULL);
629 int san_len = sk_GENERAL_NAME_num(peer_san);
631 for (i = 0; i < san_len; i++)
633 const GENERAL_NAME *
name = sk_GENERAL_NAME_value(peer_san, i);
635 if (name->type == GEN_DNS)
651 first_name = alt_name;
656 if (found_match || got_error)
659 sk_GENERAL_NAME_free(peer_san);
669 if (names_examined == 0)
671 X509_NAME *subject_name;
673 subject_name = X509_get_subject_name(conn->peer);
674 if (subject_name !=
NULL)
678 cn_index = X509_NAME_get_index_by_NID(subject_name,
685 X509_NAME_ENTRY_get_data(
686 X509_NAME_get_entry(subject_name, cn_index)),
697 if (!found_match && !got_error)
705 if (names_examined > 1)
708 libpq_ngettext(
"server certificate for \"%s\" (and %d other name) does not match host name \"%s\"\n",
709 "server certificate for \"%s\" (and %d other names) does not match host name \"%s\"\n",
711 first_name, names_examined - 1, conn->
pghost);
713 else if (names_examined == 1)
716 libpq_gettext(
"server certificate for \"%s\" does not match host name \"%s\"\n"),
717 first_name, conn->
pghost);
722 libpq_gettext(
"could not get server's host name from server certificate\n"));
730 return found_match && !got_error;
733 #ifdef ENABLE_THREAD_SAFETY
739 pq_threadidcallback(
void)
752 pq_lockingcallback(
int mode,
int n,
const char *file,
int line)
754 if (mode & CRYPTO_LOCK)
757 PGTHREAD_ERROR(
"failed to lock mutex");
762 PGTHREAD_ERROR(
"failed to unlock mutex");
786 #ifdef ENABLE_THREAD_SAFETY
789 if (ssl_config_mutex ==
NULL)
791 while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
793 if (ssl_config_mutex ==
NULL)
798 InterlockedExchange(&win32_ssl_create_mutex, 0);
810 if (pq_lockarray ==
NULL)
820 for (i = 0; i < CRYPTO_num_locks(); i++)
832 if (ssl_open_connections++ == 0)
838 if (CRYPTO_get_id_callback() ==
NULL)
839 CRYPTO_set_id_callback(pq_threadidcallback);
840 if (CRYPTO_get_locking_callback() ==
NULL)
841 CRYPTO_set_locking_callback(pq_lockingcallback);
850 #if SSLEAY_VERSION_NUMBER >= 0x00907000L
851 OPENSSL_config(
NULL);
854 SSL_load_error_strings();
872 #ifdef ENABLE_THREAD_SAFETY
879 SSL_CTX_set_options(
SSL_context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
885 SSL_CTX_set_mode(
SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
888 #ifdef ENABLE_THREAD_SAFETY
908 #ifdef ENABLE_THREAD_SAFETY
914 --ssl_open_connections;
922 if (CRYPTO_get_locking_callback() == pq_lockingcallback)
923 CRYPTO_set_locking_callback(
NULL);
924 if (CRYPTO_get_id_callback() == pq_threadidcallback)
925 CRYPTO_set_id_callback(
NULL);
962 EVP_PKEY *pkey =
NULL;
975 have_homedir =
false;
980 else if (have_homedir)
981 snprintf(fnbuf,
sizeof(fnbuf),
"%s/%s", homedir, USER_CERT_FILE);
985 if (fnbuf[0] ==
'\0')
990 else if (stat(fnbuf, &buf) != 0)
997 if (errno != ENOENT && errno != ENOTDIR)
1000 libpq_gettext(
"could not open certificate file \"%s\": %s\n"),
1001 fnbuf,
pqStrerror(errno, sebuf,
sizeof(sebuf)));
1024 #ifdef ENABLE_THREAD_SAFETY
1034 if (SSL_CTX_use_certificate_chain_file(
SSL_context, fnbuf) != 1)
1039 libpq_gettext(
"could not read certificate file \"%s\": %s\n"),
1043 #ifdef ENABLE_THREAD_SAFETY
1049 if (SSL_use_certificate_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
1054 libpq_gettext(
"could not read certificate file \"%s\": %s\n"),
1057 #ifdef ENABLE_THREAD_SAFETY
1066 #ifdef ENABLE_THREAD_SAFETY
1077 if (have_cert && conn->
sslkey && strlen(conn->
sslkey) > 0)
1079 #ifdef USE_SSL_ENGINE
1080 if (strchr(conn->
sslkey,
':')
1082 && conn->
sslkey[1] !=
':'
1087 char *engine_str = strdup(conn->
sslkey);
1090 if (engine_str ==
NULL)
1098 engine_colon = strchr(engine_str,
':');
1100 *engine_colon =
'\0';
1103 conn->engine = ENGINE_by_id(engine_str);
1104 if (conn->engine ==
NULL)
1116 if (ENGINE_init(conn->engine) == 0)
1121 libpq_gettext(
"could not initialize SSL engine \"%s\": %s\n"),
1124 ENGINE_free(conn->engine);
1125 conn->engine =
NULL;
1130 pkey = ENGINE_load_private_key(conn->engine, engine_colon,
1137 libpq_gettext(
"could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
1138 engine_colon, engine_str, err);
1140 ENGINE_finish(conn->engine);
1141 ENGINE_free(conn->engine);
1142 conn->engine =
NULL;
1146 if (SSL_use_PrivateKey(conn->ssl, pkey) != 1)
1151 libpq_gettext(
"could not load private SSL key \"%s\" from engine \"%s\": %s\n"),
1152 engine_colon, engine_str, err);
1154 ENGINE_finish(conn->engine);
1155 ENGINE_free(conn->engine);
1156 conn->engine =
NULL;
1173 else if (have_homedir)
1176 snprintf(fnbuf,
sizeof(fnbuf),
"%s/%s", homedir, USER_KEY_FILE);
1181 if (have_cert && fnbuf[0] !=
'\0')
1185 if (stat(fnbuf, &buf) != 0)
1188 libpq_gettext(
"certificate present, but not private key file \"%s\"\n"),
1196 libpq_gettext(
"private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
1202 if (SSL_use_PrivateKey_file(conn->ssl, fnbuf, SSL_FILETYPE_PEM) != 1)
1207 libpq_gettext(
"could not load private key file \"%s\": %s\n"),
1216 SSL_check_private_key(conn->ssl) != 1)
1221 libpq_gettext(
"certificate does not match private key file \"%s\": %s\n"),
1234 else if (have_homedir)
1235 snprintf(fnbuf,
sizeof(fnbuf),
"%s/%s", homedir, ROOT_CERT_FILE);
1239 if (fnbuf[0] !=
'\0' &&
1240 stat(fnbuf, &buf) == 0)
1242 X509_STORE *cvstore;
1244 #ifdef ENABLE_THREAD_SAFETY
1259 libpq_gettext(
"could not read root certificate file \"%s\": %s\n"),
1262 #ifdef ENABLE_THREAD_SAFETY
1272 else if (have_homedir)
1273 snprintf(fnbuf,
sizeof(fnbuf),
"%s/%s", homedir, ROOT_CRL_FILE);
1278 if (fnbuf[0] !=
'\0' &&
1279 X509_STORE_load_locations(cvstore, fnbuf,
NULL) == 1)
1282 #ifdef X509_V_FLAG_CRL_CHECK
1283 X509_STORE_set_flags(cvstore,
1284 X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1289 libpq_gettext(
"SSL library does not support CRL certificates (file \"%s\")\n"),
1292 #ifdef ENABLE_THREAD_SAFETY
1300 #ifdef ENABLE_THREAD_SAFETY
1304 SSL_set_verify(conn->ssl, SSL_VERIFY_PEER,
verify_cb);
1320 if (fnbuf[0] ==
'\0')
1322 libpq_gettext(
"could not get home directory to locate root certificate file\n"
1323 "Either provide the file or change sslmode to disable server certificate verification.\n"));
1326 libpq_gettext(
"root certificate file \"%s\" does not exist\n"
1327 "Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
1336 #ifdef SSL_OP_NO_COMPRESSION
1339 SSL_set_options(conn->ssl, SSL_OP_NO_COMPRESSION);
1355 r = SSL_connect(conn->ssl);
1358 int err = SSL_get_error(conn->ssl, r);
1359 unsigned long ecode;
1361 ecode = ERR_get_error();
1364 case SSL_ERROR_WANT_READ:
1367 case SSL_ERROR_WANT_WRITE:
1370 case SSL_ERROR_SYSCALL:
1411 conn->peer = SSL_get_peer_certificate(conn->ssl);
1412 if (conn->peer ==
NULL)
1442 bool destroy_needed =
false;
1451 destroy_needed =
true;
1453 SSL_shutdown(conn->ssl);
1454 SSL_free(conn->ssl);
1456 conn->ssl_in_use =
false;
1461 X509_free(conn->peer);
1465 #ifdef USE_SSL_ENGINE
1468 ENGINE_finish(conn->engine);
1469 ENGINE_free(conn->engine);
1470 conn->engine =
NULL;
1496 static char ssl_nomem[] =
"out of memory allocating error description";
1498 #define SSL_ERR_LEN 128
1503 const char *errreason;
1514 errreason = ERR_reason_error_string(ecode);
1515 if (errreason !=
NULL)
1527 if (buf != ssl_nomem)
1540 return conn->ssl_in_use;
1559 if (strcmp(struct_name,
"OpenSSL") == 0)
1567 static const char *
const result[] = {
1584 if (conn->ssl ==
NULL)
1587 if (strcmp(attribute_name,
"library") == 0)
1590 if (strcmp(attribute_name,
"key_bits") == 0)
1592 static char sslbits_str[10];
1595 SSL_get_cipher_bits(conn->ssl, &sslbits);
1596 snprintf(sslbits_str,
sizeof(sslbits_str),
"%d", sslbits);
1600 if (strcmp(attribute_name,
"cipher") == 0)
1601 return SSL_get_cipher(conn->ssl);
1603 if (strcmp(attribute_name,
"compression") == 0)
1606 if (strcmp(attribute_name,
"protocol") == 0)
1607 return SSL_get_version(conn->ssl);
1632 BIO_clear_retry_flags(h);
1641 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1645 BIO_set_retry_read(h);
1662 BIO_clear_retry_flags(h);
1671 #if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
1675 BIO_set_retry_write(h);
1689 if (!my_bio_initialized)
1691 memcpy(&my_bio_methods, BIO_s_socket(),
sizeof(BIO_METHOD));
1694 my_bio_initialized =
true;
1709 SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
1715 SSL_set_bio(conn->ssl, bio, bio);
1716 BIO_set_fd(bio, fd, BIO_NOCLOSE);
static bool pq_init_ssl_lib
static bool verify_peer_name_matches_certificate(PGconn *)
CRITICAL_SECTION * pthread_mutex_t
void * PQgetssl(PGconn *conn)
static int my_sock_write(BIO *h, const char *buf, int size)
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
const char * PQsslAttribute(PGconn *conn, const char *attribute_name)
static PostgresPollingStatusType open_client_SSL(PGconn *)
void * PQsslStruct(PGconn *conn, const char *struct_name)
char * pqStrerror(int errnum, char *strerrbuf, size_t buflen)
int pthread_mutex_init(pthread_mutex_t *mp, void *attr)
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
int pg_strcasecmp(const char *s1, const char *s2)
ssize_t pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
static BIO_METHOD my_bio_methods
PostgresPollingStatusType pgtls_open_client(PGconn *conn)
static int fd(const char *x, int i)
static bool my_bio_initialized
int pthread_mutex_lock(pthread_mutex_t *mp)
#define libpq_ngettext(s, p, n)
bool pgtls_read_pending(PGconn *conn)
static int initialize_SSL(PGconn *conn)
#define SOCK_ERRNO_SET(e)
const char *const * PQsslAttributeNames(PGconn *conn)
static int verify_cb(int ok, X509_STORE_CTX *ctx)
static int my_sock_read(BIO *h, char *buf, int size)
static int my_SSL_set_fd(PGconn *conn, int fd)
static void SSLerrfree(char *buf)
void pgtls_close(PGconn *conn)
ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len)
ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len)
int pthread_mutex_unlock(pthread_mutex_t *mp)
#define SSL_get_current_compression(x)
static SSL_CTX * SSL_context
static bool pq_init_crypto_lib
PQExpBufferData errorMessage
size_t strlcpy(char *dst, const char *src, size_t siz)
ssize_t pqsecure_raw_write(PGconn *conn, const void *ptr, size_t len)
PostgresPollingStatusType
static char * SSLerrmessage(unsigned long ecode)
static int verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name, char **store_name)
bool pqGetHomeDirectory(char *buf, int bufsize)
int PQsslInUse(PGconn *conn)
const char * strerror(int errnum)
void pgtls_init_library(bool do_ssl, int do_crypto)
static void destroy_ssl_system(void)
static BIO_METHOD * my_BIO_s_socket(void)
int pgtls_init(PGconn *conn)
static int wildcard_certificate_match(const char *pattern, const char *string)