Rebased from an OpenBSD patch.

--- a/src/client.c
+++ b/src/client.c
@@ -795,7 +795,7 @@ NOEXPORT void print_cipher(CLI *c) { /* print negotiated cipher */
 NOEXPORT void transfer(CLI *c) {
     int timeout; /* s_poll_wait timeout in seconds */
     int pending; /* either processed on unprocessed TLS data */
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
     int has_pending=0, prev_has_pending;
 #endif
     int watchdog=0; /* a counter to detect an infinite loop */
@@ -842,7 +842,7 @@ NOEXPORT void transfer(CLI *c) {
 
         /****************************** wait for an event */
         pending=SSL_pending(c->ssl);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
         /* only attempt to process SSL_has_pending() data once */
         prev_has_pending=has_pending;
         has_pending=SSL_has_pending(c->ssl);
@@ -1265,7 +1265,7 @@ NOEXPORT void transfer(CLI *c) {
             s_log(LOG_ERR,
                 "please report the problem to Michal.Trojnara@stunnel.org");
             stunnel_info(LOG_ERR);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
             s_log(LOG_ERR, "protocol=%s, SSL_pending=%d, SSL_has_pending=%d",
                 SSL_get_version(c->ssl),
                 SSL_pending(c->ssl), SSL_has_pending(c->ssl));
--- a/src/common.h
+++ b/src/common.h
@@ -467,7 +467,7 @@ extern char *sys_errlist[];
 #define OPENSSL_NO_TLS1_2
 #endif /* OpenSSL older than 1.0.1 || defined(OPENSSL_NO_TLS1) */
 
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 #ifndef OPENSSL_NO_SSL2
 #define OPENSSL_NO_SSL2
 #endif /* !defined(OPENSSL_NO_SSL2) */
@@ -514,7 +514,7 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
 /* not defined in public headers before OpenSSL 0.9.8 */
 STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
 #endif /* !defined(OPENSSL_NO_COMP) */
-#if OPENSSL_VERSION_NUMBER>=0x10101000L
+#if OPENSSL_VERSION_NUMBER>=0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 #include <openssl/store.h>
 #include <openssl/storeerr.h>
 #endif /* OPENSSL_VERSION_NUMBER>=0x10101000L */
--- a/src/ctx.c
+++ b/src/ctx.c
@@ -46,7 +46,7 @@
 
 SERVICE_OPTIONS *current_section=NULL;
 
-#if OPENSSL_VERSION_NUMBER<0x10101000L
+#if OPENSSL_VERSION_NUMBER<0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
 /* try an empty passphrase first */
 static char cached_passwd[PEM_BUFSIZE]="";
 static int cached_len=0;
@@ -90,7 +90,7 @@ NOEXPORT unsigned psk_server_callback(SSL *, const char *,
     unsigned char *, unsigned);
 #endif /* !defined(OPENSSL_NO_PSK) */
 
-#if OPENSSL_VERSION_NUMBER>=0x10101000L
+#if OPENSSL_VERSION_NUMBER>=0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int load_objects(SERVICE_OPTIONS *, int, int);
 NOEXPORT int load_objects_from_store(SSL_CTX *, const char *, int, int);
 #else /* OpenSSL 1.1.1 or later */
@@ -111,7 +111,7 @@ NOEXPORT int load_key_engine(SERVICE_OPTIONS *);
 NOEXPORT int ui_retry(void);
 
 /* session tickets */
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int generate_session_ticket_cb(SSL *, void *);
 NOEXPORT int decrypt_session_ticket_cb(SSL *, SSL_SESSION *,
     const unsigned char *, size_t, SSL_TICKET_STATUS, void *);
@@ -126,7 +126,7 @@ NOEXPORT int ssl_tlsext_ticket_key_cb(SSL *, unsigned char *,
 NOEXPORT int sess_new_cb(SSL *, SSL_SESSION *);
 NOEXPORT void new_chain(CLI *);
 NOEXPORT void session_cache_save(CLI *, SSL_SESSION *);
-#if OPENSSL_VERSION_NUMBER<0x10101000L
+#if OPENSSL_VERSION_NUMBER<0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *);
 #endif
 NOEXPORT SSL_SESSION *sess_get_cb(SSL *,
@@ -155,7 +155,7 @@ NOEXPORT char *get_tls13_cipher_list(STACK_OF(SSL_CIPHER) *);
 
 /**************************************** initialize section->ctx */
 
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 typedef long unsigned SSL_OPTIONS_TYPE;
 #else
 typedef long SSL_OPTIONS_TYPE;
@@ -208,7 +208,7 @@ int context_init(SERVICE_OPTIONS *section) { /* init TLS context */
     }
     current_section=section; /* setup current section for callbacks */
 
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
     /* set the security level */
     if(section->security_level>=0) {
         /* set the user-specified value */
@@ -309,7 +309,7 @@ int context_init(SERVICE_OPTIONS *section) { /* init TLS context */
 #endif
 
     /* setup session tickets */
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
     SSL_CTX_set_session_ticket_cb(section->ctx, generate_session_ticket_cb,
         decrypt_session_ticket_cb, NULL);
 #endif /* OpenSSL 1.1.1 or later */
@@ -608,7 +608,7 @@ NOEXPORT int ecdh_init(SERVICE_OPTIONS *section) {
 /**************************************** initialize OpenSSL CONF */
 
 NOEXPORT int conf_init(SERVICE_OPTIONS *section) {
-#if OPENSSL_VERSION_NUMBER>=0x10002000L
+#if OPENSSL_VERSION_NUMBER>=0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
     SSL_CONF_CTX *cctx;
     NAME_LIST *curr;
     char *cmd, *param;
@@ -713,7 +713,7 @@ NOEXPORT int auth_init(SERVICE_OPTIONS *section) {
         key_needed=load_key_engine(section);
     }
 #endif
-#if OPENSSL_VERSION_NUMBER>=0x10101000L
+#if OPENSSL_VERSION_NUMBER>=0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
     if(load_objects(section, cert_needed, key_needed))
         return 1; /* FAILED */
 #else /* OpenSSL 1.1.1 or later */
@@ -840,7 +840,7 @@ PSK_KEYS *psk_find(const PSK_TABLE *table, const char *identity) {
 
 #endif /* !defined(OPENSSL_NO_PSK) */
 
-#if OPENSSL_VERSION_NUMBER<0x10101000L
+#if OPENSSL_VERSION_NUMBER<0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
 
 NOEXPORT int pkcs12_extension(const char *filename) {
     const char *ext=strrchr(filename, '.');
@@ -1121,7 +1121,7 @@ NOEXPORT int load_key_engine(SERVICE_OPTIONS *section) {
 
 #endif /* !defined(OPENSSL_NO_ENGINE) */
 
-#if OPENSSL_VERSION_NUMBER>=0x10101000L
+#if OPENSSL_VERSION_NUMBER>=0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 
 NOEXPORT int load_objects(SERVICE_OPTIONS *section, int cert_needed, int key_needed) {
 
@@ -1374,7 +1374,7 @@ NOEXPORT int ui_retry(void) {
 
 /**************************************** session tickets */
 
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 
 typedef struct {
     void *session_authenticated;
@@ -1655,7 +1655,7 @@ NOEXPORT void session_cache_save(CLI *c, SSL_SESSION *sess) {
     CRYPTO_THREAD_unlock(stunnel_locks[LOCK_SESSION]);
 }
 
-#if OPENSSL_VERSION_NUMBER<0x10101000L
+#if OPENSSL_VERSION_NUMBER<0x10101000L || defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT SSL_SESSION *SSL_SESSION_dup(SSL_SESSION *src) {
     int der_len;
     unsigned char *der_data;
@@ -1884,7 +1884,7 @@ NOEXPORT void info_callback(const SSL *ssl, int where, int ret) {
     CLI *c;
     SSL_CTX *ctx;
     const char *state_string;
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
     OSSL_HANDSHAKE_STATE state=SSL_get_state(ssl);
 #else
     int state=SSL_get_state((SSL *)ssl);
@@ -1933,7 +1933,10 @@ NOEXPORT void info_callback(const SSL *ssl, int where, int ret) {
         if(state==TLS_ST_SR_CLNT_HELLO) {
 #else
         if(state==SSL3_ST_SR_CLNT_HELLO_A
-                || state==SSL23_ST_SR_CLNT_HELLO_A) {
+#if !defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER < 0x4000000fL
+                || state==SSL23_ST_SR_CLNT_HELLO_A
+#endif
+        ) {
 #endif
             /* client hello received after initial handshake,
              * this means renegotiation -> mark it */
--- a/src/prototypes.h
+++ b/src/prototypes.h
@@ -72,7 +72,7 @@ typedef struct servername_list_struct SERVERNAME_LIST;
     typedef HANDLE THREAD_ID;
 #endif
 
-#if OPENSSL_VERSION_NUMBER<0x10100004L
+#if OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
 
 #ifdef USE_OS_THREADS
 
@@ -810,7 +810,7 @@ extern CLI *thread_head;
 
 extern CRYPTO_RWLOCK *stunnel_locks[STUNNEL_LOCKS];
 
-#if OPENSSL_VERSION_NUMBER<0x10100004L
+#if OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
 /* Emulate the OpenSSL 1.1 locking API for older OpenSSL versions */
 CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void);
 int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *);
--- a/src/ssl.c
+++ b/src/ssl.c
@@ -38,7 +38,7 @@
 #include "prototypes.h"
 
     /* global OpenSSL initialization: compression, engine, entropy */
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT void cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
         int idx, long argl, void *argp);
 #else /* OPENSSL_VERSION_NUMBER>=0x10100000L */
@@ -48,7 +48,7 @@ NOEXPORT int cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
 #if OPENSSL_VERSION_NUMBER>=0x30000000L
 NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
     void **from_d, int idx, long argl, void *argp);
-#elif OPENSSL_VERSION_NUMBER>=0x10100000L
+#elif OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
     void *from_d, int idx, long argl, void *argp);
 #else
@@ -108,7 +108,7 @@ int fips_available(void) { /* either FIPS provider or container is available */
 
 /* initialize libcrypto before invoking API functions that require it */
 void crypto_init(void) {
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
     OPENSSL_INIT_SETTINGS *conf;
 #endif /* OPENSSL_VERSION_NUMBER>=0x10100000L */
 #ifdef USE_WIN32
@@ -158,7 +158,7 @@ void crypto_init(void) {
 #endif /* USE_WIN32 */
 
     /* initialize OpenSSL */
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
     conf=OPENSSL_INIT_new();
 #ifdef USE_WIN32
     path=str_printf("%s\\config\\openssl.cnf", stunnel_dir);
@@ -241,7 +241,7 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) {
 #endif
 #endif
 
-#if OPENSSL_VERSION_NUMBER>=0x10100000L
+#if OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT void cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
         int idx, long argl, void *argp) {
 #else /* OPENSSL_VERSION_NUMBER>=0x10100000L */
@@ -255,7 +255,7 @@ NOEXPORT int cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
         (char *)argp);
     if(!CRYPTO_set_ex_data(ad, idx, (void *)(-1)))
         sslerror("CRYPTO_set_ex_data");
-#if OPENSSL_VERSION_NUMBER<0x10100000L
+#if OPENSSL_VERSION_NUMBER<0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
     return 1; /* success */
 #endif /* OPENSSL_VERSION_NUMBER<0x10100000L */
 }
@@ -263,7 +263,7 @@ NOEXPORT int cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
 #if OPENSSL_VERSION_NUMBER>=0x30000000L
 NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
         void **from_d, int idx, long argl, void *argp) {
-#elif OPENSSL_VERSION_NUMBER>=0x10100000L
+#elif OPENSSL_VERSION_NUMBER>=0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from,
         void *from_d, int idx, long argl, void *argp) {
 #else
--- a/src/sthreads.c
+++ b/src/sthreads.c
@@ -123,7 +123,7 @@ NOEXPORT void thread_id_init(void) {
 /**************************************** locking */
 
 /* we only need to initialize locking with OpenSSL older than 1.1.0 */
-#if OPENSSL_VERSION_NUMBER<0x10100004L
+#if OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
 
 #ifdef USE_PTHREAD
 
@@ -283,7 +283,7 @@ NOEXPORT int s_atomic_add(int *val, int amount, CRYPTO_RWLOCK *lock) {
 
 CRYPTO_RWLOCK *stunnel_locks[STUNNEL_LOCKS];
 
-#if OPENSSL_VERSION_NUMBER<0x10100004L
+#if OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER)
 
 #ifdef USE_OS_THREADS
 
@@ -391,7 +391,8 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) {
 
 NOEXPORT void locking_init(void) {
     size_t i;
-#if defined(USE_OS_THREADS) && OPENSSL_VERSION_NUMBER<0x10100004L
+#if defined(USE_OS_THREADS) && \
+	(OPENSSL_VERSION_NUMBER<0x10100004L || defined(LIBRESSL_VERSION_NUMBER))
     size_t num;
 
     /* initialize the OpenSSL static locking */
--- a/src/str.c
+++ b/src/str.c
@@ -98,7 +98,7 @@ NOEXPORT LEAK_ENTRY leak_hash_table[LEAK_TABLE_SIZE],
     *leak_results[LEAK_TABLE_SIZE];
 NOEXPORT int leak_result_num=0;
 
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 DEFINE_STACK_OF(LEAK_ENTRY)
 #endif /* OpenSSL version >= 1.1.1 */
 
@@ -112,7 +112,7 @@ NOEXPORT ALLOC_LIST *get_alloc_list_ptr(void *, const char *, int);
 NOEXPORT void str_leak_debug(const ALLOC_LIST *, int);
 
 NOEXPORT LEAK_ENTRY *leak_search(const ALLOC_LIST *);
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int leak_cmp(const LEAK_ENTRY *const *, const LEAK_ENTRY *const *);
 #endif /* OpenSSL version >= 1.1.1 */
 NOEXPORT void leak_report(void);
@@ -574,7 +574,7 @@ NOEXPORT LEAK_ENTRY *leak_search(const ALLOC_LIST *alloc_list) {
 void leak_table_utilization(void) {
     int i, utilization=0;
     int64_t grand_total=0;
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
     STACK_OF(LEAK_ENTRY) *stats;
 #endif /* OpenSSL version >= 1.1.1 */
 
@@ -591,7 +591,7 @@ void leak_table_utilization(void) {
     s_log(LOG_DEBUG, "Leak detection table utilization: %d/%d (%05.2f%%)",
         utilization, LEAK_TABLE_SIZE, 100.0*utilization/LEAK_TABLE_SIZE);
 
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
     /* log up to 5 most frequently used heap allocations */
     stats=sk_LEAK_ENTRY_new_reserve(leak_cmp, utilization);
     for(i=0; i<LEAK_TABLE_SIZE; ++i)
@@ -608,7 +608,7 @@ void leak_table_utilization(void) {
 #endif /* OpenSSL version >= 1.1.1 */
 }
 
-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
+#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
 NOEXPORT int leak_cmp(const LEAK_ENTRY *const *a, const LEAK_ENTRY *const *b) {
     int64_t d = (*a)->total - (*b)->total;
     if(d>0)
--- a/src/verify.c
+++ b/src/verify.c
@@ -392,7 +392,7 @@ NOEXPORT int cert_check_local(X509_STORE_CTX *callback_ctx) {
     cert=X509_STORE_CTX_get_current_cert(callback_ctx);
     subject=X509_get_subject_name(cert);
 
-#if OPENSSL_VERSION_NUMBER<0x10100006L
+#if OPENSSL_VERSION_NUMBER<0x10100006L || defined(LIBRESSL_VERSION_NUMBER)
 #define X509_STORE_CTX_get1_certs X509_STORE_get1_certs
 #endif
     /* modern API allows retrieving multiple matching certificates */
