[squid-dev] [PATCH] Bug 4662 adding --with-libressl build option

Amos Jeffries squid3 at treenet.co.nz
Sun Jan 29 11:26:31 UTC 2017


This is I think all we need to do code-wise to resolve the Bug 4662
issues with LibreSSL being incompatible with OpenSSL 1.1.

The libraries cannot both be linked either way. If both --with-* options
are provided LibreSSL currently overrides OpenSSL. I picked that
preference order because AFAICS the LibreSSL has the lower overall
security footprint while providing the same (or better) needed
functionality.


NP: If there are no objections I would like to fast-track this and apply
in ~3 days (allowing for today being a sunday) for a slightly late
4.0.18 beta.

Amos

-------------- next part --------------
=== modified file 'configure.ac'
--- configure.ac	2017-01-13 05:14:03 +0000
+++ configure.ac	2017-01-28 05:53:00 +0000
@@ -1246,20 +1246,89 @@
   if test "x$LIBGNUTLS_LIBS" != "x" ; then
     CXXFLAGS="$LIBGNUTLS_CFLAGS $CXXFLAGS"
     SSLLIB="$LIBGNUTLS_PATH $LIBGNUTLS_LIBS $SSLLIB"
     AC_DEFINE(USE_GNUTLS,1,[GnuTLS support is available])
   else
     with_gnutls=no
   fi
 fi
 AC_MSG_NOTICE([GnuTLS library support: ${with_gnutls:=auto} ${LIBGNUTLS_PATH} ${LIBGNUTLS_LIBS}])
 
+dnl User may specify LibreSSL is needed from a non-standard location
+AC_ARG_WITH(libressl,
+  AS_HELP_STRING([--with-libressl=PATH],
+                 [Compile with the LibreSSL libraries. The path to
+                  the LibreSSL development libraries and headers
+                  installation can be specified if outside of the
+                  system standard directories]), [ 
+case "$with_libressl" in
+  yes|no)
+    : # Nothing special to do here
+    ;;
+  *)
+    if test ! -d "$withval" ; then
+      AC_MSG_ERROR([--with-libressl path does not point to a directory])
+    fi
+    LIBLIBRESSL_PATH="-L$with_libressl/lib"
+    CPPFLAGS="-I$with_libressl/include $CPPFLAGS"
+    with_libressl=yes
+  esac
+])
+AH_TEMPLATE(USE_LIBRESSL,[LibreSSL support is available])
+## LibreSSL is default disable due to licensing issues on some OS
+if test "x$with_libressl" = "xyes"; then
+
+  AC_CHECK_HEADERS( \
+    openssl/bio.h \
+    openssl/err.h \
+    openssl/md5.h \
+    openssl/opensslv.h \
+    openssl/ssl.h \
+    openssl/x509v3.h \
+    openssl/engine.h \
+    openssl/txt_db.h \
+  )
+
+  # User may have provided a custom location for LibreSSL. Otherwise...
+  SQUID_STATE_SAVE(squid_libressl_state)
+  LIBS="$LIBS $LIBLIBRESSL_PATH"
+
+  # auto-detect using pkg-config
+  PKG_CHECK_MODULES([LIBLIBRESSL],[libressl],,[
+    ## For some OS pkg-config is broken or unavailable.
+    ## Detect libraries the hard way.
+
+    AC_CHECK_LIB(crypto,[CRYPTO_new_ex_data],[LIBLIBRESSL_LIBS="-lcrypto $LIBLIBRESSL_LIBS"],[
+      AC_MSG_ERROR([library 'crypto' is required for LibreSSL])
+    ])
+    AC_CHECK_LIB(ssl,[SSL_library_init],[LIBLIBRESSL_LIBS="-lssl $LIBLIBRESSL_LIBS"],[
+      AC_MSG_ERROR([library 'ssl' is required for LibreSSL])
+    ])
+  ])
+
+  SQUID_STATE_ROLLBACK(squid_libressl_state) #de-pollute LIBS
+
+  if test "x$with_libressl" = "xyes" -a "x$LIBLIBRESSL_LIBS" = "x"; then
+    AC_MSG_ERROR([Required LibreSSL library not found])
+  fi
+  if test "x$LIBLIBRESSL_LIBS" != "x"; then
+    CXXFLAGS="$LIBLIBRESSL_CFLAGS $CXXFLAGS"
+    SSLLIB="$LIBLIBRESSL_PATH $LIBLIBRESSL_LIBS $SSLLIB"
+    AC_DEFINE(USE_LIBRESSL,1,[LibreSSL support is available])
+    AC_DEFINE(HAVE_LEGACY_OPENSSL_API,1,[LibreSSL provides the pre- OpenSSL 1.1 API])
+  fi
+fi
+AC_MSG_NOTICE([LibreSSL library support: ${with_libressl:=no} ${LIBLIBRESSL_PATH} ${LIBLIBRESSL_LIBS}])
+AM_CONDITIONAL(ENABLE_SSL,[ test "x$with_libressl" = "xyes" ])
+AC_SUBST(SSLLIB)
+
+if test "x$with_libressl" != "xyes"; then
 dnl User may specify OpenSSL is needed from a non-standard location
 AC_ARG_WITH(openssl,
   AS_HELP_STRING([--with-openssl=PATH],
                  [Compile with the OpenSSL libraries. The path to
                   the OpenSSL development libraries and headers
                   installation can be specified if outside of the
                   system standard directories]), [ 
 case "$with_openssl" in
   yes|no)
     : # Nothing special to do here
@@ -1322,28 +1391,30 @@
   if test "x$LIBOPENSSL_LIBS" != "x"; then
     CXXFLAGS="$LIBOPENSSL_CFLAGS $CXXFLAGS"
     SSLLIB="$LIBOPENSSL_PATH $LIBOPENSSL_LIBS $SSLLIB"
     AC_DEFINE(USE_OPENSSL,1,[OpenSSL support is available])
 
     # check for other specific broken implementations
     SQUID_CHECK_OPENSSL_GETCERTIFICATE_WORKS
     SQUID_CHECK_OPENSSL_CONST_SSL_METHOD
     SQUID_CHECK_OPENSSL_TXTDB
     SQUID_CHECK_OPENSSL_HELLO_OVERWRITE_HACK
+    AC_DEFINE(HAVE_LEGACY_OPENSSL_API,(OPENSSL_VERSION_NUMBER < 0x10100000L),[Whether OpenSSL provides the pre-1.1 API])
   fi
   if test "x$SSLLIB" = "x"; then
     AC_MSG_ERROR([Required OpenSSL library not found])
   fi
 fi
 AC_MSG_NOTICE([OpenSSL library support: ${with_openssl:=no} ${LIBOPENSSL_PATH} ${LIBOPENSSL_LIBS}])
 AM_CONDITIONAL(ENABLE_SSL,[ test "x$with_openssl" = "xyes" ])
 AC_SUBST(SSLLIB)
+fi
 
 dnl User may specify MIT Kerberos is needed from a non-standard location
 AC_ARG_WITH(mit-krb5,
   AS_HELP_STRING([--without-mit-krb5],
 		 [Compile without MIT Kerberos support.]), [
 case "$with_mit_krb5" in
   yes|no)
     : # Nothing special to do here
     ;;
   *)

=== modified file 'src/AccessLogEntry.cc'
--- src/AccessLogEntry.cc	2017-01-01 00:12:22 +0000
+++ src/AccessLogEntry.cc	2017-01-23 00:58:31 +0000
@@ -5,27 +5,27 @@
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "AccessLogEntry.h"
 #include "HttpReply.h"
 #include "HttpRequest.h"
 #include "SquidConfig.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 
 AccessLogEntry::SslDetails::SslDetails(): user(NULL), bumpMode(::Ssl::bumpEnd)
 {
 }
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 void
 AccessLogEntry::getLogClientIp(char *buf, size_t bufsz) const
 {
     Ip::Address log_ip;
 
 #if FOLLOW_X_FORWARDED_FOR
     if (Config.onoff.log_uses_indirect_client && request)
         log_ip = request->indirect_client_addr;
     else

=== modified file 'src/AccessLogEntry.h'
--- src/AccessLogEntry.h	2017-01-01 00:12:22 +0000
+++ src/AccessLogEntry.h	2017-01-23 00:58:31 +0000
@@ -18,21 +18,21 @@
 #include "HttpHeader.h"
 #include "icp_opcode.h"
 #include "ip/Address.h"
 #include "LogTags.h"
 #include "MessageSizes.h"
 #include "Notes.h"
 #include "sbuf/SBuf.h"
 #if ICAP_CLIENT
 #include "adaptation/icap/Elements.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/gadgets.h"
 #endif
 
 /* forward decls */
 class HttpReply;
 class HttpRequest;
 class CustomLog;
 
 class AccessLogEntry: public RefCountable
 {
@@ -112,21 +112,21 @@
      * \todo Inner class declarations should be moved outside
      */
     class HtcpDetails
     {
     public:
         HtcpDetails() : opcode(NULL) {};
 
         const char *opcode;
     } htcp;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// logging information specific to the SSL protocol
     class SslDetails
     {
     public:
         SslDetails();
 
         const char *user; ///< emailAddress from the SSL client certificate
         int bumpMode; ///< whether and how the request was SslBumped
     } ssl;
 #endif
@@ -139,39 +139,39 @@
     class CacheDetails
     {
 
     public:
         CacheDetails() : caddr(),
             highOffset(0),
             objectSize(0),
             code(LOG_TAG_NONE),
             rfc931 (NULL),
             extuser(NULL),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             ssluser(NULL),
 #endif
             port(NULL)
         {
             caddr.setNoAddr();
             memset(&start_time, 0, sizeof(start_time));
             memset(&trTime, 0, sizeof(start_time));
         }
 
         Ip::Address caddr;
         int64_t highOffset;
         int64_t objectSize;
         LogTags code;
         struct timeval start_time; ///< The time the master transaction started
         struct timeval trTime; ///< The response time
         const char *rfc931;
         const char *extuser;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
         const char *ssluser;
         Security::CertPointer sslClientCert; ///< cert received from the client
 #endif
         AnyP::PortCfgPointer port;
 
     } cache;
 
     /** \brief This subclass holds log info for various headers in raw format
      * \todo shuffle this to the relevant protocol section.

=== modified file 'src/AclRegs.cc'
--- src/AclRegs.cc	2017-01-01 00:12:22 +0000
+++ src/AclRegs.cc	2017-01-23 00:58:31 +0000
@@ -16,21 +16,21 @@
 #if USE_ADAPTATION
 #include "acl/AdaptationService.h"
 #include "acl/AdaptationServiceData.h"
 #endif
 #include "acl/AllOf.h"
 #include "acl/AnyOf.h"
 #if USE_SQUID_EUI
 #include "acl/Arp.h"
 #include "acl/Eui64.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "acl/AtStep.h"
 #include "acl/AtStepData.h"
 #endif
 #include "acl/Asn.h"
 #include "acl/Browser.h"
 #include "acl/Checklist.h"
 #include "acl/ConnectionsEncrypted.h"
 #include "acl/Data.h"
 #include "acl/DestinationAsn.h"
 #include "acl/DestinationDomain.h"
@@ -65,31 +65,31 @@
 #include "acl/RegexData.h"
 #include "acl/ReplyHeaderStrategy.h"
 #include "acl/ReplyMimeType.h"
 #include "acl/RequestHeaderStrategy.h"
 #include "acl/RequestMimeType.h"
 #include "acl/SourceAsn.h"
 #include "acl/SourceDomain.h"
 #include "acl/SourceIp.h"
 #include "acl/SquidError.h"
 #include "acl/SquidErrorData.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "acl/Certificate.h"
 #include "acl/CertificateData.h"
 #include "acl/ServerName.h"
 #include "acl/SslError.h"
 #include "acl/SslErrorData.h"
 #endif
 #include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "acl/StringData.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "acl/ServerCertificate.h"
 #endif
 #include "acl/Tag.h"
 #include "acl/Time.h"
 #include "acl/TimeData.h"
 #include "acl/Url.h"
 #include "acl/UrlLogin.h"
 #include "acl/UrlPath.h"
 #include "acl/UrlPort.h"
 #include "acl/UserData.h"
@@ -161,21 +161,21 @@
 ACL::Prototype ACLUrl::RegistryProtoype(&ACLUrl::RegistryEntry_, "url_regex");
 ACLStrategised<char const *> ACLUrl::RegistryEntry_(new ACLRegexData, ACLUrlStrategy::Instance(), "url_regex");
 ACL::Prototype ACLUrlLogin::RegistryProtoype(&ACLUrlLogin::RegistryEntry_, "urllogin");
 ACLStrategised<char const *> ACLUrlLogin::RegistryEntry_(new ACLRegexData, ACLUrlLoginStrategy::Instance(), "urllogin");
 ACL::Prototype ACLUrlPath::LegacyRegistryProtoype(&ACLUrlPath::RegistryEntry_, "pattern");
 ACL::Prototype ACLUrlPath::RegistryProtoype(&ACLUrlPath::RegistryEntry_, "urlpath_regex");
 ACLStrategised<char const *> ACLUrlPath::RegistryEntry_(new ACLRegexData, ACLUrlPathStrategy::Instance(), "urlpath_regex");
 ACL::Prototype ACLUrlPort::RegistryProtoype(&ACLUrlPort::RegistryEntry_, "port");
 ACLStrategised<int> ACLUrlPort::RegistryEntry_(new ACLIntRange, ACLUrlPortStrategy::Instance(), "port");
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 ACL::Prototype ACLSslError::RegistryProtoype(&ACLSslError::RegistryEntry_, "ssl_error");
 ACLStrategised<const Security::CertErrors *> ACLSslError::RegistryEntry_(new ACLSslErrorData, ACLSslErrorStrategy::Instance(), "ssl_error");
 ACL::Prototype ACLCertificate::UserRegistryProtoype(&ACLCertificate::UserRegistryEntry_, "user_cert");
 ACLStrategised<X509 *> ACLCertificate::UserRegistryEntry_(new ACLCertificateData (Ssl::GetX509UserAttribute, "*"), ACLCertificateStrategy::Instance(), "user_cert");
 ACL::Prototype ACLCertificate::CARegistryProtoype(&ACLCertificate::CARegistryEntry_, "ca_cert");
 ACLStrategised<X509 *> ACLCertificate::CARegistryEntry_(new ACLCertificateData (Ssl::GetX509CAAttribute, "*"), ACLCertificateStrategy::Instance(), "ca_cert");
 ACL::Prototype ACLServerCertificate::X509FingerprintRegistryProtoype(&ACLServerCertificate::X509FingerprintRegistryEntry_, "server_cert_fingerprint");
 ACLStrategised<X509 *> ACLServerCertificate::X509FingerprintRegistryEntry_(new ACLCertificateData(Ssl::GetX509Fingerprint, "-sha1", true), ACLServerCertificateStrategy::Instance(), "server_cert_fingerprint");
 
 ACL::Prototype ACLAtStep::RegistryProtoype(&ACLAtStep::RegistryEntry_, "at_step");

=== modified file 'src/ClientRequestContext.h'
--- src/ClientRequestContext.h	2017-01-01 00:12:22 +0000
+++ src/ClientRequestContext.h	2017-01-23 00:58:31 +0000
@@ -41,21 +41,21 @@
     void clientRedirectStart();
     void clientRedirectDone(const Helper::Reply &reply);
     void clientStoreIdStart();
     void clientStoreIdDone(const Helper::Reply &reply);
     void checkNoCache();
     void checkNoCacheDone(const allow_t &answer);
 #if USE_ADAPTATION
 
     void adaptationAccessCheck();
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /**
      * Initiates and start the acl checklist to check if the a CONNECT
      * request must be bumped.
      \retval true if the acl check scheduled, false if no ssl-bump required
      */
     bool sslBumpAccessCheck();
     /// The callback function for ssl-bump access check list
     void sslBumpAccessCheckDone(const allow_t &answer);
 #endif
 
@@ -69,19 +69,19 @@
     bool adapted_http_access_done;
 #if USE_ADAPTATION
     bool adaptation_acl_check_done;
 #endif
     bool redirect_done;
     bool store_id_done;
     bool no_cache_done;
     bool interpreted_req_hdrs;
     bool tosToClientDone;
     bool nfmarkToClientDone;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     bool sslBumpCheckDone;
 #endif
     ErrorState *error; ///< saved error page for centralized/delayed processing
     bool readNextRequest; ///< whether Squid should read after error handling
 };
 
 #endif /* SQUID_CLIENTREQUESTCONTEXT_H */
 

=== modified file 'src/FwdState.cc'
--- src/FwdState.cc	2017-01-01 00:12:22 +0000
+++ src/FwdState.cc	2017-01-23 01:06:29 +0000
@@ -46,21 +46,21 @@
 #include "PeerPoolMgr.h"
 #include "PeerSelectState.h"
 #include "security/BlindPeerConnector.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "ssl/PeekingPeerConnector.h"
 #include "Store.h"
 #include "StoreClient.h"
 #include "urn.h"
 #include "whois.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/cert_validate_message.h"
 #include "ssl/Config.h"
 #include "ssl/ErrorDetail.h"
 #include "ssl/helper.h"
 #include "ssl/ServerBump.h"
 #include "ssl/support.h"
 #else
 #include "security/EncryptorAnswer.h"
 #endif
 
@@ -244,21 +244,21 @@
     entry->mem_obj->checkUrlChecksum();
 #endif
 
     if (entry->store_status == STORE_PENDING) {
         if (entry->isEmpty()) {
             if (!err) // we quit (e.g., fd closed) before an error or content
                 fail(new ErrorState(ERR_READ_ERROR, Http::scBadGateway, request));
             assert(err);
             errorAppendEntry(entry, err);
             err = NULL;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             if (request->flags.sslPeek && request->clientConnectionManager.valid()) {
                 CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
                              ConnStateData::httpsPeeked, Comm::ConnectionPointer(NULL));
             }
 #endif
         } else {
             EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
             entry->complete();
             entry->releaseRequest();
         }
@@ -691,21 +691,21 @@
         const bool needTlsToPeer = peerWantsTls && !userWillTlsToPeerForUs;
         const bool needTlsToOrigin = !p && request->url.getScheme() == AnyP::PROTO_HTTPS;
         if (needTlsToPeer || needTlsToOrigin || request->flags.sslPeek) {
             HttpRequest::Pointer requestPointer = request;
             AsyncCall::Pointer callback = asyncCall(17,4,
                                                     "FwdState::ConnectedToPeer",
                                                     FwdStatePeerAnswerDialer(&FwdState::connectedToPeer, this));
             // Use positive timeout when less than one second is left.
             const time_t sslNegotiationTimeout = max(static_cast<time_t>(1), timeLeft());
             Security::PeerConnector *connector = nullptr;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             if (request->flags.sslPeek)
                 connector = new Ssl::PeekingPeerConnector(requestPointer, serverConnection(), clientConn, callback, al, sslNegotiationTimeout);
             else
 #endif
                 connector = new Security::BlindPeerConnector(requestPointer, serverConnection(), callback, al, sslNegotiationTimeout);
             AsyncJob::Start(connector); // will call our callback
             return;
         }
     }
 
@@ -963,21 +963,21 @@
     /* Bug 2537: The TOS forward part of QOS only applies to patched Linux kernels. */
     if (Ip::Qos::TheConfig.isHitTosActive()) {
         if (Comm::IsConnOpen(clientConn)) {
             fde * clientFde = &fd_table[clientConn->fd]; // XXX: move the fd_table access into Ip::Qos
             /* Get the TOS value for the packet */
             Ip::Qos::getTosFromServer(serverConnection(), clientFde);
         }
     }
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (request->flags.sslPeek) {
         CallJobHere1(17, 4, request->clientConnectionManager, ConnStateData,
                      ConnStateData::httpsPeeked, serverConnection());
         unregister(serverConn); // async call owns it now
         complete(); // destroys us
         return;
     }
 #endif
 
     if (serverConnection()->getPeer() != NULL) {

=== modified file 'src/FwdState.h'
--- src/FwdState.h	2017-01-01 00:12:22 +0000
+++ src/FwdState.h	2017-01-23 01:03:54 +0000
@@ -10,34 +10,34 @@
 #define SQUID_FORWARD_H
 
 #include "base/RefCount.h"
 #include "comm.h"
 #include "comm/Connection.h"
 #include "err_type.h"
 #include "fde.h"
 #include "http/StatusCode.h"
 #include "ip/Address.h"
 #include "security/forward.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 /* forward decls */
 
 class AccessLogEntry;
 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
 class PconnPool;
 typedef RefCount<PconnPool> PconnPoolPointer;
 class ErrorState;
 class HttpRequest;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 namespace Ssl
 {
 class ErrorDetail;
 class CertValidationResponse;
 };
 #endif
 
 /**
  * Returns the TOS value that we should be setting on the connection
  * to the server, based on the ACL.

=== modified file 'src/HttpHeader.cc'
--- src/HttpHeader.cc	2017-01-25 22:29:03 +0000
+++ src/HttpHeader.cc	2017-01-29 04:25:08 +0000
@@ -72,21 +72,21 @@
 
 /* header accounting */
 // NP: keep in sync with enum http_hdr_owner_type
 static HttpHeaderStat HttpHeaderStats[] = {
     HttpHeaderStat(/*hoNone*/ "all", NULL),
 #if USE_HTCP
     HttpHeaderStat(/*hoHtcpReply*/ "HTCP reply", &ReplyHeadersMask),
 #endif
     HttpHeaderStat(/*hoRequest*/ "request", &RequestHeadersMask),
     HttpHeaderStat(/*hoReply*/ "reply", &ReplyHeadersMask)
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /* hoErrorDetail */
 #endif
     /* hoEnd */
 };
 static int HttpHeaderStatCount = countof(HttpHeaderStats);
 
 static int HeaderEntryParsedCount = 0;
 
 /*
  * forward declarations and local routines

=== modified file 'src/HttpHeader.h'
--- src/HttpHeader.h	2017-01-01 00:12:22 +0000
+++ src/HttpHeader.h	2017-01-23 00:58:31 +0000
@@ -27,21 +27,21 @@
 class Packable;
 
 /** Possible owners of http header */
 typedef enum {
     hoNone =0,
 #if USE_HTCP
     hoHtcpReply,
 #endif
     hoRequest,
     hoReply,
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     hoErrorDetail,
 #endif
     hoEnd
 } http_hdr_owner_type;
 
 /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
 typedef ssize_t HttpHeaderPos;
 
 /* use this and only this to initialize HttpHeaderPos */
 #define HttpHeaderInitPos (-1)

=== modified file 'src/HttpHeaderTools.cc'
--- src/HttpHeaderTools.cc	2017-01-01 00:12:22 +0000
+++ src/HttpHeaderTools.cc	2017-01-23 00:58:31 +0000
@@ -24,21 +24,21 @@
 #include "HttpHdrContRange.h"
 #include "HttpHeader.h"
 #include "HttpHeaderFieldInfo.h"
 #include "HttpHeaderTools.h"
 #include "HttpRequest.h"
 #include "MemBuf.h"
 #include "SquidConfig.h"
 #include "Store.h"
 #include "StrList.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #include <algorithm>
 #include <cerrno>
 #include <string>
 
 static void httpHeaderPutStrvf(HttpHeader * hdr, Http::HdrType id, const char *fmt, va_list vargs);
 static void httpHdrAdd(HttpHeader *heads, HttpRequest *request, const AccessLogEntryPointer &al, HeaderWithAclList &headersAdd);
 

=== modified file 'src/SquidConfig.h'
--- src/SquidConfig.h	2017-01-01 00:12:22 +0000
+++ src/SquidConfig.h	2017-01-23 02:17:49 +0000
@@ -13,26 +13,26 @@
 #include "base/RefCount.h"
 #include "base/YesNoNone.h"
 #include "ClientDelayConfig.h"
 #include "DelayConfig.h"
 #include "helper/ChildConfig.h"
 #include "HttpHeaderTools.h"
 #include "ip/Address.h"
 #include "Notes.h"
 #include "security/forward.h"
 #include "SquidTime.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 #include "store/forward.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 class sslproxy_cert_sign;
 class sslproxy_cert_adapt;
 #endif
 
 namespace Mgr
 {
 class ActionPasswordList;
 } // namespace Mgr
 class CachePeer;
 class CustomLog;
@@ -182,21 +182,21 @@
 
     struct {
         wordlist *redirect;
         wordlist *store_id;
 #if USE_UNLINKD
 
         char *unlinkd;
 #endif
 
         char *diskd;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
         char *ssl_password;
 #endif
 
     } Program;
 
     Helper::ChildConfig redirectChildren;
     Helper::ChildConfig storeIdChildren;
 
     struct {
@@ -325,21 +325,21 @@
         int tproxy_uses_indirect_client;
 #endif
 #endif /* FOLLOW_X_FORWARDED_FOR */
 
         int WIN32_IpAddrChangeMonitor;
         int memory_cache_first;
         int memory_cache_disk;
         int hostStrictVerify;
         int client_dst_passthru;
         int dns_mdns;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         bool logTlsServerHelloDetails;
 #endif
     } onoff;
 
     int64_t collapsed_forwarding_shared_entries_limit;
 
     int pipeline_max_prefetch;
 
     int forward_max_tries;
     int connect_retries;
@@ -368,21 +368,21 @@
         acl_access *redirector;
         acl_access *store_id;
         acl_access *reply;
         Acl::Address *outgoing_address;
 #if USE_HTCP
 
         acl_access *htcp;
         acl_access *htcp_clr;
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         acl_access *ssl_bump;
 #endif
 #if FOLLOW_X_FORWARDED_FOR
         acl_access *followXFF;
 #endif /* FOLLOW_X_FORWARDED_FOR */
 
         /// acceptible PROXY protocol clients
         acl_access *proxyProtocol;
 
         /// spoof_client_ip squid.conf acl.
@@ -471,21 +471,21 @@
 #if USE_CACHE_DIGESTS
 
     struct {
         int bits_per_entry;
         time_t rebuild_period;
         time_t rewrite_period;
         size_t swapout_chunk_size;
         int rebuild_chunk_percentage;
     } digest;
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
     struct {
         int unclean_shutdown;
         char *ssl_engine;
         int session_ttl;
         size_t sessionCacheSize;
         char *certSignHash;
     } SSL;
 #endif
 
@@ -494,21 +494,21 @@
         int high_pf;
         size_t high_memory;
     } warnings;
     char *store_dir_select_algorithm;
     int sleep_after_fork;   /* microseconds */
     time_t minimum_expiry_time; /* seconds */
     external_acl *externalAclHelperList;
 
     struct {
         Security::ContextPointer sslContext;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         char *foreignIntermediateCertsPath;
         acl_access *cert_error;
         sslproxy_cert_sign *cert_sign;
         sslproxy_cert_adapt *cert_adapt;
 #endif
     } ssl_client;
 
     char *accept_filter;
     int umask;
     int max_filedescriptors;

=== modified file 'src/acl/AtStep.cc'
--- src/acl/AtStep.cc	2017-01-01 00:12:22 +0000
+++ src/acl/AtStep.cc	2017-01-23 00:58:31 +0000
@@ -1,21 +1,21 @@
 /*
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/AtStep.h"
 #include "acl/AtStepData.h"
 #include "acl/Checklist.h"
 #include "client_side.h"
 #include "http/Stream.h"
 #include "ssl/ServerBump.h"
 
 int
 ACLAtStepStrategy::match (ACLData<Ssl::BumpStep> * &data, ACLFilledChecklist *checklist, ACLFlags &)
@@ -29,12 +29,12 @@
 }
 
 ACLAtStepStrategy *
 ACLAtStepStrategy::Instance()
 {
     return &Instance_;
 }
 
 ACLAtStepStrategy ACLAtStepStrategy::Instance_;
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/acl/AtStep.h'
--- src/acl/AtStep.h	2017-01-01 00:12:22 +0000
+++ src/acl/AtStep.h	2017-01-23 00:58:31 +0000
@@ -2,21 +2,21 @@
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_ACLATSTEP_H
 #define SQUID_ACLATSTEP_H
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/Strategised.h"
 #include "acl/Strategy.h"
 #include "ssl/support.h"
 
 /// \ingroup ACLAPI
 class ACLAtStepStrategy : public ACLStrategy<Ssl::BumpStep>
 {
 
 public:
@@ -34,14 +34,14 @@
 };
 
 class ACLAtStep
 {
 
 private:
     static ACL::Prototype RegistryProtoype;
     static ACLStrategised<Ssl::BumpStep> RegistryEntry_;
 };
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 #endif /* SQUID_ACLATSTEP_H */
 

=== modified file 'src/acl/AtStepData.cc'
--- src/acl/AtStepData.cc	2017-01-01 00:12:22 +0000
+++ src/acl/AtStepData.cc	2017-01-23 00:58:31 +0000
@@ -1,21 +1,21 @@
 /*
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/AtStepData.h"
 #include "acl/Checklist.h"
 #include "cache_cf.h"
 #include "ConfigParser.h"
 #include "Debug.h"
 #include "wordlist.h"
 
 ACLAtStepData::ACLAtStepData()
 {}
@@ -73,12 +73,12 @@
 {
     return values.empty();
 }
 
 ACLAtStepData *
 ACLAtStepData::clone() const
 {
     return new ACLAtStepData(*this);
 }
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/acl/AtStepData.h'
--- src/acl/AtStepData.h	2017-01-01 00:12:22 +0000
+++ src/acl/AtStepData.h	2017-01-23 00:58:31 +0000
@@ -2,21 +2,21 @@
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_ACLATSTEPDATA_H
 #define SQUID_ACLATSTEPDATA_H
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/Acl.h"
 #include "acl/Data.h"
 #include "ssl/support.h"
 
 #include <list>
 
 class ACLAtStepData : public ACLData<Ssl::BumpStep>
 {
     MEMPROXY_CLASS(ACLAtStepData);
@@ -28,14 +28,14 @@
     virtual ~ACLAtStepData();
     bool match(Ssl::BumpStep);
     virtual SBufList dump() const;
     void parse();
     bool empty() const;
     virtual ACLAtStepData *clone() const;
 
     std::list<Ssl::BumpStep> values;
 };
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 #endif /* SQUID_ACLSSL_ERRORDATA_H */
 

=== modified file 'src/acl/Certificate.cc'
--- src/acl/Certificate.cc	2017-01-01 00:12:22 +0000
+++ src/acl/Certificate.cc	2017-01-23 00:58:31 +0000
@@ -6,21 +6,21 @@
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 /* DEBUG: section 28    Access Control */
 
 #include "squid.h"
 
 /* MS Visual Studio Projects are monolithic, so we need the following
  * #if to exclude the SSL code from compile process when not needed.
  */
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/Certificate.h"
 #include "acl/CertificateData.h"
 #include "acl/Checklist.h"
 #include "client_side.h"
 #include "fde.h"
 #include "globals.h"
 #include "http/Stream.h"
 #include "HttpRequest.h"
 
@@ -37,12 +37,12 @@
 }
 
 ACLCertificateStrategy *
 ACLCertificateStrategy::Instance()
 {
     return &Instance_;
 }
 
 ACLCertificateStrategy ACLCertificateStrategy::Instance_;
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/acl/FilledChecklist.cc'
--- src/acl/FilledChecklist.cc	2017-01-01 00:12:22 +0000
+++ src/acl/FilledChecklist.cc	2017-01-23 00:58:31 +0000
@@ -26,21 +26,21 @@
 ACLFilledChecklist::ACLFilledChecklist() :
     dst_rdns(NULL),
     request (NULL),
     reply (NULL),
 #if USE_AUTH
     auth_user_request (NULL),
 #endif
 #if SQUID_SNMP
     snmp_community(NULL),
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     sslErrors(NULL),
 #endif
     requestErrorType(ERR_MAX),
     conn_(NULL),
     fd_(-1),
     destinationDomainChecked_(false),
     sourceDomainChecked_(false)
 {
     my_addr.setEmpty();
     src_addr.setEmpty();
@@ -53,21 +53,21 @@
     assert (!asyncInProgress());
 
     safe_free(dst_rdns); // created by xstrdup().
 
     HTTPMSGUNLOCK(request);
 
     HTTPMSGUNLOCK(reply);
 
     cbdataReferenceDone(conn_);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     cbdataReferenceDone(sslErrors);
 #endif
 
     debugs(28, 4, HERE << "ACLFilledChecklist destroyed " << this);
 }
 
 static void
 showDebugWarning(const char *msg)
 {
     static uint16_t count = 0;
@@ -196,21 +196,21 @@
 ACLFilledChecklist::ACLFilledChecklist(const acl_access *A, HttpRequest *http_request, const char *ident):
     dst_rdns(NULL),
     request(NULL),
     reply(NULL),
 #if USE_AUTH
     auth_user_request(NULL),
 #endif
 #if SQUID_SNMP
     snmp_community(NULL),
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     sslErrors(NULL),
 #endif
     requestErrorType(ERR_MAX),
     conn_(NULL),
     fd_(-1),
     destinationDomainChecked_(false),
     sourceDomainChecked_(false)
 {
     my_addr.setEmpty();
     src_addr.setEmpty();

=== modified file 'src/acl/ServerCertificate.cc'
--- src/acl/ServerCertificate.cc	2017-01-01 00:12:22 +0000
+++ src/acl/ServerCertificate.cc	2017-01-23 00:58:31 +0000
@@ -1,21 +1,21 @@
 /*
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/CertificateData.h"
 #include "acl/Checklist.h"
 #include "acl/ServerCertificate.h"
 #include "client_side.h"
 #include "fde.h"
 #include "http/Stream.h"
 #include "ssl/ServerBump.h"
 
 int
@@ -34,12 +34,12 @@
 }
 
 ACLServerCertificateStrategy *
 ACLServerCertificateStrategy::Instance()
 {
     return &Instance_;
 }
 
 ACLServerCertificateStrategy ACLServerCertificateStrategy::Instance_;
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/adaptation/ServiceConfig.cc'
--- src/adaptation/ServiceConfig.cc	2017-01-01 00:12:22 +0000
+++ src/adaptation/ServiceConfig.cc	2017-01-29 10:58:00 +0000
@@ -136,29 +136,30 @@
         } else if (strcmp(name, "max-conn") == 0)
             grokked = grokLong(maxConn, name, value);
         else if (strcmp(name, "on-overload") == 0) {
             grokked = grokOnOverload(onOverload, value);
             onOverloadSet = true;
         } else if (strcmp(name, "connection-encryption") == 0) {
             bool encrypt;
             grokked = grokBool(encrypt, name, value);
             connectionEncryption.configure(encrypt);
         } else if (strncmp(name, "ssl", 3) == 0 || strncmp(name, "tls-", 4) == 0) {
-#if !USE_OPENSSL
-            debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: adaptation option '" << name << "' requires --with-openssl. ICAP service option ignored.");
-#else
+#if USE_OPENSSL || USE_LIBRESSL
             // name prefix is "ssl" or "tls-"
             std::string tmp = name + (name[0] == 's' ? 3 : 4);
             tmp += "=";
             tmp += value;
             secure.parse(tmp.c_str());
             grokked = true;
+#else
+            debugs(3, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: adaptation option '" << name <<
+                   "' requires --with-openssl or --with-libressl. ICAP service option ignored.");
 #endif
         } else
             grokked = grokExtension(name, value);
 
         if (!grokked)
             return false;
     }
 
     // set default on-overload value if needed
     if (!onOverloadSet)
@@ -238,21 +239,21 @@
             have_port = true;
         } else if ((e = strchr(s, '/')) != NULL) {
             have_port = false;
         } else {
             return false;
         }
         len = e - s;
     }
 
     host.limitInit(s, len);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (secure.sslDomain.isEmpty())
         secure.sslDomain.assign(host.rawBuf(), host.size());
 #endif
     s = e;
 
     port = -1;
     if (have_port) {
         ++s;
 
         if ((e = strchr(s, '/')) != NULL) {

=== modified file 'src/adaptation/icap/History.h'
--- src/adaptation/icap/History.h	2017-01-01 00:12:22 +0000
+++ src/adaptation/icap/History.h	2017-01-23 00:58:31 +0000
@@ -30,21 +30,21 @@
     /// record the start of an ICAP processing interval
     void start(const char *context);
     /// note the end of an ICAP processing interval
     void stop(const char *context);
 
     /// the total time of all ICAP processing intervals
     /// \param[out] total time taken for all ICAP processing
     void processingTime(struct timeval &total) const;
 
     String rfc931; ///< the username from ident
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     String ssluser; ///< the username from SSL
 #endif
     LogTags logType; ///< the squid request status (TCP_MISS etc)
 
     String log_uri; ///< the request uri
     size_t req_sz; ///< the request size
 
 private:
     void currentTime(struct timeval &) const; ///< time since current start or zero
 

=== modified file 'src/adaptation/icap/ModXact.cc'
--- src/adaptation/icap/ModXact.cc	2017-01-01 00:12:22 +0000
+++ src/adaptation/icap/ModXact.cc	2017-01-23 00:58:31 +0000
@@ -1335,21 +1335,21 @@
 
     if (adapted_reply_) {
         al.reply = adapted_reply_;
         HTTPMSGLOCK(al.reply);
     } else
         al.reply = NULL;
 
     if (h->rfc931.size())
         al.cache.rfc931 = h->rfc931.termedBuf();
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (h->ssluser.size())
         al.cache.ssluser = h->ssluser.termedBuf();
 #endif
     al.cache.code = h->logType;
 
     const HttpMsg *virgin_msg = dynamic_cast<HttpReply*>(virgin.header);
     if (!virgin_msg)
         virgin_msg = virgin_request_;
     assert(virgin_msg != virgin.cause);
     al.http.clientRequestSz.header = virgin_msg->hdr_sz;

=== modified file 'src/adaptation/icap/Xaction.cc'
--- src/adaptation/icap/Xaction.cc	2017-01-01 00:12:22 +0000
+++ src/adaptation/icap/Xaction.cc	2017-01-23 02:18:49 +0000
@@ -706,21 +706,21 @@
     return false;
 }
 
 bool
 Ssl::IcapPeerConnector::initialize(Security::SessionPointer &serverSession)
 {
     if (!Security::PeerConnector::initialize(serverSession))
         return false;
 
     assert(!icapService->cfg().secure.sslDomain.isEmpty());
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     SBuf *host = new SBuf(icapService->cfg().secure.sslDomain);
     SSL_set_ex_data(serverSession.get(), ssl_ex_index_server, host);
 
     ACLFilledChecklist *check = static_cast<ACLFilledChecklist *>(SSL_get_ex_data(serverSession.get(), ssl_ex_index_cert_error_check));
     if (check)
         check->dst_peer_name = *host;
 #endif
 
     Security::SetSessionResumeData(serverSession, icapService->sslSession);
     return true;

=== modified file 'src/anyp/PortCfg.cc'
--- src/anyp/PortCfg.cc	2017-01-01 00:12:22 +0000
+++ src/anyp/PortCfg.cc	2017-01-23 01:09:37 +0000
@@ -4,21 +4,21 @@
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "anyp/PortCfg.h"
 #include "comm.h"
 #include "fatal.h"
 #include "security/PeerOptions.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #include <cstring>
 #include <limits>
 
 AnyP::PortCfgPointer HttpPortList;
 AnyP::PortCfgPointer FtpPortList;
 
 int NHttpSockets = 0;
@@ -33,21 +33,21 @@
     flags(),
     allow_direct(false),
     vhost(false),
     actAsOrigin(false),
     ignore_cc(false),
     connection_auth_disabled(false),
     ftp_track_dirs(false),
     vport(0),
     disable_pmtu_discovery(0),
     listenConn()
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     ,
     clientca(NULL),
     sslContextSessionId(NULL),
     generateHostCertificates(true),
     dynamicCertMemCacheSize(4*1024*1024), // 4 MB
     signingCert(),
     signPkey(),
     certsToChain(),
     untrustedSigningCert(),
     untrustedSignPkey(),
@@ -60,21 +60,21 @@
 AnyP::PortCfg::~PortCfg()
 {
     if (Comm::IsConnOpen(listenConn)) {
         listenConn->close();
         listenConn = NULL;
     }
 
     safe_free(name);
     safe_free(defaultsite);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     safe_free(clientca);
     safe_free(sslContextSessionId);
 #endif
 }
 
 AnyP::PortCfgPointer
 AnyP::PortCfg::clone() const
 {
     AnyP::PortCfgPointer b = new AnyP::PortCfg();
     b->s = s;
@@ -87,38 +87,38 @@
     b->flags = flags;
     b->allow_direct = allow_direct;
     b->vhost = vhost;
     b->vport = vport;
     b->connection_auth_disabled = connection_auth_disabled;
     b->ftp_track_dirs = ftp_track_dirs;
     b->disable_pmtu_discovery = disable_pmtu_discovery;
     b->tcp_keepalive = tcp_keepalive;
     b->secure = secure;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (clientca)
         b->clientca = xstrdup(clientca);
     if (sslContextSessionId)
         b->sslContextSessionId = xstrdup(sslContextSessionId);
 
 #if 0
     // TODO: AYJ: 2015-01-15: for now SSL does not clone the context object.
     // cloning should only be done before the PortCfg is post-configure initialized and opened
     Security::ContextPointer sslContext;
 #endif
 
 #endif /*0*/
 
     return b;
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 void
 AnyP::PortCfg::configureSslServerContext()
 {
     if (!secure.certs.empty()) {
         Security::KeyData &keys = secure.certs.front();
         Ssl::readCertChainAndPrivateKeyFromFiles(signingCert, signPkey, certsToChain, keys.certFile.c_str(), keys.privateKeyFile.c_str());
     }
 
     if (!signingCert) {
         char buf[128];

=== modified file 'src/anyp/PortCfg.h'
--- src/anyp/PortCfg.h	2017-01-01 00:12:22 +0000
+++ src/anyp/PortCfg.h	2017-01-23 01:10:05 +0000
@@ -9,34 +9,34 @@
 #ifndef SQUID_ANYP_PORTCFG_H
 #define SQUID_ANYP_PORTCFG_H
 
 #include "anyp/forward.h"
 #include "anyp/ProtocolVersion.h"
 #include "anyp/TrafficMode.h"
 #include "comm/Connection.h"
 #include "sbuf/SBuf.h"
 #include "security/ServerOptions.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/gadgets.h"
 #endif
 
 namespace AnyP
 {
 
 class PortCfg : public RefCountable
 {
 public:
     PortCfg();
     ~PortCfg();
     AnyP::PortCfgPointer clone() const;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// creates, configures, and validates SSL context and related port options
     void configureSslServerContext();
 #endif
 
     PortCfgPointer next;
 
     Ip::Address s;
     AnyP::ProtocolVersion transport; ///< transport protocol and version received by this port
     char *name;                /* visible name */
     char *defaultsite;         /* default web site */
@@ -65,21 +65,21 @@
     /**
      * The listening socket details.
      * If Comm::ConnIsOpen() we are actively listening for client requests.
      * use listenConn->close() to stop.
      */
     Comm::ConnectionPointer listenConn;
 
     /// TLS configuration options for this listening port
     Security::ServerOptions secure;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     char *clientca;
     char *sslContextSessionId; ///< "session id context" for secure.staticSslContext
     bool generateHostCertificates; ///< dynamically make host cert for sslBump
     size_t dynamicCertMemCacheSize; ///< max size of generated certificates memory cache
 
     Security::CertPointer signingCert; ///< x509 certificate for signing generated certificates
     Ssl::EVP_PKEY_Pointer signPkey; ///< private key for sighing generated certificates
     Ssl::X509_STACK_Pointer certsToChain; ///<  x509 certificates to send with the generated cert
     Security::CertPointer untrustedSigningCert; ///< x509 certificate for signing untrusted generated certificates
     Ssl::EVP_PKEY_Pointer untrustedSignPkey; ///< private key for signing untrusted generated certificates

=== modified file 'src/cache_cf.cc'
--- src/cache_cf.cc	2017-01-01 00:12:22 +0000
+++ src/cache_cf.cc	2017-01-29 11:05:36 +0000
@@ -68,21 +68,21 @@
 #include "wccp2.h"
 #if USE_ADAPTATION
 #include "adaptation/Config.h"
 #endif
 #if ICAP_CLIENT
 #include "adaptation/icap/Config.h"
 #endif
 #if USE_ECAP
 #include "adaptation/ecap/Config.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/Config.h"
 #include "ssl/support.h"
 #endif
 #if USE_SQUID_ESI
 #include "esi/Parser.h"
 #endif
 #if SQUID_SNMP
 #include "snmp.h"
 #endif
 
@@ -94,21 +94,21 @@
 #if HAVE_PWD_H
 #include <pwd.h>
 #endif
 #if HAVE_GRP_H
 #include <grp.h>
 #endif
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/gadgets.h"
 #endif
 
 #if USE_ADAPTATION
 static void parse_adaptation_service_set_type();
 static void parse_adaptation_service_chain_type();
 static void parse_adaptation_access_type();
 #endif
 
 #if ICAP_CLIENT
@@ -160,21 +160,21 @@
 static uint64_t parseTimeUnits(const char *unit,  bool allowMsec);
 static void parseTimeLine(time_msec_t * tptr, const char *units, bool allowMsec, bool expectMoreArguments);
 static void parse_u_short(unsigned short * var);
 static void parse_string(char **);
 static void default_all(void);
 static void defaults_if_none(void);
 static void defaults_postscriptum(void);
 static int parse_line(char *);
 static void parse_obsolete(const char *);
 static void parseBytesLine(size_t * bptr, const char *units);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static void parseBytesOptionValue(size_t * bptr, const char *units, char const * value);
 #endif
 static void parseBytesLineSigned(ssize_t * bptr, const char *units);
 static size_t parseBytesUnits(const char *unit);
 static void free_all(void);
 void requirePathnameExists(const char *name, const char *path);
 static OBJH dump_config;
 #if USE_HTTP_VIOLATIONS
 static void free_HeaderManglers(HeaderManglers **pm);
 static void dump_http_header_access(StoreEntry * entry, const char *name, const HeaderManglers *manglers);
@@ -201,31 +201,31 @@
 #if CURRENTLY_UNUSED
 static int check_null_IpAddress_list(const Ip::Address_list *);
 #endif /* CURRENTLY_UNUSED */
 #endif /* USE_WCCPv2 */
 
 static void parsePortCfg(AnyP::PortCfgPointer *, const char *protocol);
 #define parse_PortCfg(l) parsePortCfg((l), token)
 static void dump_PortCfg(StoreEntry *, const char *, const AnyP::PortCfgPointer &);
 #define free_PortCfg(h)  *(h)=NULL
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static void parse_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign);
 static void dump_sslproxy_cert_sign(StoreEntry *entry, const char *name, sslproxy_cert_sign *cert_sign);
 static void free_sslproxy_cert_sign(sslproxy_cert_sign **cert_sign);
 static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt);
 static void dump_sslproxy_cert_adapt(StoreEntry *entry, const char *name, sslproxy_cert_adapt *cert_adapt);
 static void free_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt);
 static void parse_sslproxy_ssl_bump(acl_access **ssl_bump);
 static void dump_sslproxy_ssl_bump(StoreEntry *entry, const char *name, acl_access *ssl_bump);
 static void free_sslproxy_ssl_bump(acl_access **ssl_bump);
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 static void parse_ftp_epsv(acl_access **ftp_epsv);
 static void dump_ftp_epsv(StoreEntry *entry, const char *name, acl_access *ftp_epsv);
 static void free_ftp_epsv(acl_access **ftp_epsv);
 
 static void parse_b_size_t(size_t * var);
 static void parse_b_int64_t(int64_t * var);
 
 static void parse_CpuAffinityMap(CpuAffinityMap **const cpuAffinityMap);
 static void dump_CpuAffinityMap(StoreEntry *const entry, const char *const name, const CpuAffinityMap *const cpuAffinityMap);
@@ -855,36 +855,36 @@
 
         if (NULL == grp) {
             fatalf("getgrnam failed to find groupid for effective group '%s'",
                    Config.effectiveGroup);
             return;
         }
 
         Config2.effectiveGroupID = grp->gr_gid;
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Config.ssl_client.foreignIntermediateCertsPath)
         Ssl::loadSquidUntrusted(Config.ssl_client.foreignIntermediateCertsPath);
 #endif
 
     if (Security::ProxyOutgoingConfig.encryptTransport) {
         debugs(3, DBG_IMPORTANT, "Initializing https:// proxy context");
         Config.ssl_client.sslContext = Security::ProxyOutgoingConfig.createClientContext(false);
         if (!Config.ssl_client.sslContext) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             fatal("ERROR: Could not initialize https:// proxy context");
 #else
-            debugs(3, DBG_IMPORTANT, "ERROR: proxying https:// currently still requires --with-openssl");
+            debugs(3, DBG_IMPORTANT, "ERROR: proxying https:// currently still requires --with-openssl or --with-libressl");
 #endif
         }
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         Ssl::useSquidUntrusted(Config.ssl_client.sslContext.get());
 #endif
     }
 
     for (CachePeer *p = Config.peers; p != NULL; p = p->next) {
 
         // default value for ssldomain= is the peer host/IP
         if (p->secure.sslDomain.isEmpty())
             p->secure.sslDomain = p->host;
 
@@ -892,21 +892,21 @@
             debugs(3, DBG_IMPORTANT, "Initializing cache_peer " << p->name << " TLS context");
             p->sslContext = p->secure.createClientContext(true);
             if (!p->sslContext) {
                 debugs(3, DBG_CRITICAL, "ERROR: Could not initialize cache_peer " << p->name << " TLS context");
                 self_destruct();
                 return;
             }
         }
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
         if (!s->secure.encryptTransport)
             continue;
         debugs(3, DBG_IMPORTANT, "Initializing " << AnyP::UriScheme(s->transport.protocol) << "_port " << s->s << " TLS context");
         s->configureSslServerContext();
     }
 #endif
 
     // prevent infinite fetch loops in the request parser
     // due to buffer full but not enough data recived to finish parse
@@ -2263,24 +2263,24 @@
             safe_free(p->name);
 
             if (token[5])
                 p->name = xstrdup(token + 5);
         } else if (!strncmp(token, "forceddomain=", 13)) {
             safe_free(p->domain);
             if (token[13])
                 p->domain = xstrdup(token + 13);
 
         } else if (strncmp(token, "ssl", 3) == 0) {
-#if !USE_OPENSSL
-            debugs(0, DBG_CRITICAL, "WARNING: cache_peer option '" << token << "' requires --with-openssl");
-#else
+#if USE_OPENSSL || USE_LIBRESSL
             p->secure.parse(token+3);
+#else
+            debugs(0, DBG_CRITICAL, "WARNING: cache_peer option '" << token << "' requires --with-openssl or --with-libressl");
 #endif
         } else if (strncmp(token, "tls-", 4) == 0) {
             p->secure.parse(token+4);
         } else if (strncmp(token, "tls", 3) == 0) {
             p->secure.parse(token+3);
         } else if (strcmp(token, "front-end-https") == 0) {
             p->front_end_https = 1;
         } else if (strcmp(token, "front-end-https=on") == 0) {
             p->front_end_https = 1;
         } else if (strcmp(token, "front-end-https=auto") == 0) {
@@ -3647,21 +3647,21 @@
         t = strchr(t, ',');
         if (t) {
             ++t;
             s->tcp_keepalive.interval = xatoui(t,',');
             t = strchr(t, ',');
         }
         if (t) {
             ++t;
             s->tcp_keepalive.timeout = xatoui(t);
         }
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     } else if (strcmp(token, "sslBump") == 0) {
         debugs(3, DBG_PARSE_NOTE(1), "WARNING: '" << token << "' is deprecated " <<
                "in " << cfg_directive << ". Use 'ssl-bump' instead.");
         s->flags.tunnelSslBumping = true;
     } else if (strcmp(token, "ssl-bump") == 0) {
         s->flags.tunnelSslBumping = true;
     } else if (strncmp(token, "cert=", 5) == 0) {
         s->secure.parse(token);
     } else if (strncmp(token, "key=", 4) == 0) {
         s->secure.parse(token);
@@ -3750,30 +3750,30 @@
 
     AnyP::PortCfgPointer s = new AnyP::PortCfg();
     s->transport = parsePortProtocol(protoName); // default; protocol=... overwrites
     parsePortSpecification(s, token);
 
     /* parse options ... */
     while ((token = ConfigParser::NextToken())) {
         parse_port_option(s, token);
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // if clientca has been defined but not cafile, then use it to verify
     // but if cafile has been defined, only use that to verify
     if (s->clientca && !s->secure.caFiles.size())
         s->secure.caFiles.emplace_back(SBuf(s->clientca));
 #endif
 
     if (s->transport.protocol == AnyP::PROTO_HTTPS) {
         s->secure.encryptTransport = true;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         /* ssl-bump on https_port configuration requires either tproxy or intercept, and vice versa */
         const bool hijacked = s->flags.isIntercepted();
         if (s->flags.tunnelSslBumping && !hijacked) {
             debugs(3, DBG_CRITICAL, "FATAL: ssl-bump on https_port requires tproxy/intercept which is missing.");
             self_destruct();
             return;
         }
         if (hijacked && !s->flags.tunnelSslBumping) {
             debugs(3, DBG_CRITICAL, "FATAL: tproxy/intercept on https_port requires ssl-bump which is missing.");
             self_destruct();
@@ -3888,28 +3888,28 @@
         storeAppendPrintf(e, " ipv4");
 
     if (s->tcp_keepalive.enabled) {
         if (s->tcp_keepalive.idle || s->tcp_keepalive.interval || s->tcp_keepalive.timeout) {
             storeAppendPrintf(e, " tcpkeepalive=%d,%d,%d", s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
         } else {
             storeAppendPrintf(e, " tcpkeepalive");
         }
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (s->flags.tunnelSslBumping)
         storeAppendPrintf(e, " ssl-bump");
 #endif
 
     s->secure.dumpCfg(e, "tls-");
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (s->sslContextSessionId)
         storeAppendPrintf(e, " sslcontext=%s", s->sslContextSessionId);
 
     if (!s->generateHostCertificates)
         storeAppendPrintf(e, " generate-host-certificates=off");
 
     if (s->dynamicCertMemCacheSize != 4*1024*1024) // 4MB default
         storeAppendPrintf(e, "dynamic_cert_mem_cache_size=%" PRIuSIZE "%s\n", s->dynamicCertMemCacheSize, B_BYTES_STR);
 #endif
 }
@@ -3921,21 +3921,21 @@
         dump_generic_port(e, n, p);
         storeAppendPrintf(e, "\n");
     }
 }
 
 void
 configFreeMemory(void)
 {
     free_all();
     Config.ssl_client.sslContext.reset();
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::unloadSquidUntrusted();
 #endif
 }
 
 void
 requirePathnameExists(const char *name, const char *path)
 {
 
     struct stat sb;
     char pathbuf[BUFSIZ];
@@ -4425,21 +4425,21 @@
     storeAppendPrintf(entry, "\n");
 }
 
 static void free_icap_service_failure_limit(Adaptation::Icap::Config *cfg)
 {
     cfg->oldest_service_failure = 0;
     cfg->service_failure_limit = 0;
 }
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static void parse_sslproxy_cert_adapt(sslproxy_cert_adapt **cert_adapt)
 {
     char *al;
     sslproxy_cert_adapt *ca = (sslproxy_cert_adapt *) xcalloc(1, sizeof(sslproxy_cert_adapt));
     if ((al = ConfigParser::NextToken()) == NULL) {
         xfree(ca);
         self_destruct();
         return;
     }
 

=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2017-01-07 03:00:43 +0000
+++ src/cf.data.pre	2017-01-23 02:20:02 +0000
@@ -936,21 +936,21 @@
 	Some example key values:
 
 		user=John%20Smith
 		user="John Smith"
 		user="J. \"Bob\" Smith"
 DOC_END
 
 NAME: acl
 TYPE: acl
 LOC: Config.aclList
-IF USE_OPENSSL
+IF USE_OPENSSL||USE_LIBRESSL
 DEFAULT: ssl::certHasExpired ssl_error X509_V_ERR_CERT_HAS_EXPIRED
 DEFAULT: ssl::certNotYetValid ssl_error X509_V_ERR_CERT_NOT_YET_VALID
 DEFAULT: ssl::certDomainMismatch ssl_error SQUID_X509_V_ERR_DOMAIN_MISMATCH
 DEFAULT: ssl::certUntrusted ssl_error X509_V_ERR_INVALID_CA X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY X509_V_ERR_CERT_UNTRUSTED
 DEFAULT: ssl::certSelfSigned ssl_error X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
 ENDIF
 DEFAULT: all src all
 DEFAULT: manager url_regex -i ^cache_object:// +i ^https?://[^/]+/squid-internal-mgr/
 DEFAULT: localhost src 127.0.0.1/32 ::1
 DEFAULT: to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
@@ -1219,21 +1219,21 @@
 
 	acl aclname adaptation_service service ...
 	  # Matches the name of any icap_service, ecap_service,
 	  # adaptation_service_set, or adaptation_service_chain that Squid
 	  # has used (or attempted to use) for the master transaction.
 	  # This ACL must be defined after the corresponding adaptation
 	  # service is named in squid.conf. This ACL is usable with
 	  # adaptation_meta because it starts matching immediately after
 	  # the service has been selected for adaptation.
 
-IF USE_OPENSSL
+IF USE_OPENSSL||USE_LIBRESSL
 	acl aclname ssl_error errorname
 	  # match against SSL certificate validation error [fast]
 	  #
 	  # For valid error names see in @DEFAULT_ERROR_DIR@/templates/error-details.txt
 	  # template file.
 	  #
 	  # The following can be used as shortcuts for certificate properties:
 	  #  [ssl::]certHasExpired: the "not after" field is in the past
 	  #  [ssl::]certNotYetValid: the "not before" field is in the future
 	  #  [ssl::]certUntrusted: The certificate issuer is not to be trusted.
@@ -2171,21 +2171,21 @@
 	visible on the internal address.
 
 NOCOMMENT_START
 
 # Squid normally listens to port 3128
 http_port @DEFAULT_HTTP_PORT@
 NOCOMMENT_END
 DOC_END
 
 NAME: https_port
-IFDEF: USE_GNUTLS||USE_OPENSSL
+IFDEF: USE_GNUTLS||USE_OPENSSL||USE_LIBRESSL
 TYPE: PortCfg
 DEFAULT: none
 LOC: HttpPortList
 DOC_START
 	Usage:  [ip:]port [mode] cert=certificate.pem [options]
 
 	The socket address where Squid will listen for client requests made
 	over TLS or SSL connections. Commonly referred to as HTTPS.
 
 	This is most useful for situations where you are running squid in
@@ -2583,21 +2583,21 @@
 	
 	see host_verify_strict for details on the verification process.
 DOC_END
 
 COMMENT_START
  TLS OPTIONS
  -----------------------------------------------------------------------------
 COMMENT_END
 
 NAME: tls_outgoing_options
-IFDEF: USE_GNUTLS||USE_OPENSSL
+IFDEF: USE_GNUTLS||USE_OPENSSL||USE_LIBRESSL
 TYPE: securePeerOptions
 DEFAULT: min-version=1.0
 LOC: Security::ProxyOutgoingConfig
 DOC_START
 	disable		Do not support https:// URLs.
 	
 	cert=/path/to/client/certificate
 			A client TLS certificate to use when connecting.
 	
 	key=/path/to/client/private_key
@@ -2667,97 +2667,97 @@
 			certificate. If not specified the peer hostname will be
 			used.
 DOC_END
 
 COMMENT_START
  SSL OPTIONS
  -----------------------------------------------------------------------------
 COMMENT_END
 
 NAME: ssl_unclean_shutdown
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 TYPE: onoff
 DEFAULT: off
 LOC: Config.SSL.unclean_shutdown
 DOC_START
 	Some browsers (especially MSIE) bugs out on SSL shutdown
 	messages.
 DOC_END
 
 NAME: ssl_engine
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 TYPE: string
 LOC: Config.SSL.ssl_engine
 DEFAULT: none
 DOC_START
 	The OpenSSL engine to use. You will need to set this if you
 	would like to use hardware SSL acceleration for example.
 DOC_END
 
 NAME: sslproxy_session_ttl
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: 300
 LOC: Config.SSL.session_ttl
 TYPE: int
 DOC_START
 	Sets the timeout value for SSL sessions
 DOC_END
 
 NAME: sslproxy_session_cache_size
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: 2 MB
 LOC: Config.SSL.sessionCacheSize
 TYPE: b_size_t
 DOC_START
         Sets the cache size to use for ssl session
 DOC_END
 
 NAME: sslproxy_foreign_intermediate_certs
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 LOC: Config.ssl_client.foreignIntermediateCertsPath
 TYPE: string
 DOC_START
 	Many origin servers fail to send their full server certificate
 	chain for verification, assuming the client already has or can
 	easily locate any missing intermediate certificates.
 
 	Squid uses the certificates from the specified file to fill in
 	these missing chains when trying to validate origin server
 	certificate chains.
 
 	The file is expected to contain zero or more PEM-encoded
 	intermediate certificates. These certificates are not treated
 	as trusted root certificates, and any self-signed certificate in
 	this file will be ignored.
 DOC_END
 
 NAME: sslproxy_cert_sign_hash
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 LOC: Config.SSL.certSignHash
 TYPE: string
 DOC_START
 	Sets the hashing algorithm to use when signing generated certificates.
 	Valid algorithm names depend on the OpenSSL library used. The following
 	names are usually available: sha1, sha256, sha512, and md5. Please see
 	your OpenSSL library manual for the available hashes. By default, Squids
 	that support this option use sha256 hashes.
 
 	Squid does not forcefully purge cached certificates that were generated
 	with an algorithm other than the currently configured one. They remain
 	in the cache, subject to the regular cache eviction policy, and become
 	useful if the algorithm changes again.
 DOC_END
 
 NAME: ssl_bump
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 TYPE: sslproxy_ssl_bump
 LOC: Config.accessList.ssl_bump
 DEFAULT_DOC: Become a TCP tunnel without decrypting proxied traffic.
 DEFAULT: none
 DOC_START
 	This option is consulted when a CONNECT request is received on
 	an http_port (or a new connection is intercepted at an
 	https_port), provided that port was configured with an ssl-bump
 	flag. The subsequent data on the connection is either treated as
 	HTTPS and decrypted OR tunneled at TCP level without decryption,
@@ -2828,21 +2828,21 @@
 	# Example: Bump all TLS connections except those originating from
 	# localhost or those going to example.com.
 
 	acl broken_sites ssl::server_name .example.com
 	ssl_bump splice localhost
 	ssl_bump splice broken_sites
 	ssl_bump bump all
 DOC_END
 
 NAME: sslproxy_cert_error
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 DEFAULT_DOC: Server certificate errors terminate the transaction.
 LOC: Config.ssl_client.cert_error
 TYPE: acl_access
 DOC_START
 	Use this ACL to bypass server certificate validation errors.
 
 	For example, the following lines will bypass all validation errors
 	when talking to servers for example.com. All other
 	validation errors will result in ERR_SECURE_CONNECT_FAIL error.
@@ -2863,21 +2863,21 @@
 
 	SECURITY WARNING:
 		Bypassing validation errors is dangerous because an
 		error usually implies that the server cannot be trusted
 		and the connection may be insecure.
 
 	See also: sslproxy_flags and DONT_VERIFY_PEER.
 DOC_END
 
 NAME: sslproxy_cert_sign
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 POSTSCRIPTUM: signUntrusted ssl::certUntrusted
 POSTSCRIPTUM: signSelf ssl::certSelfSigned
 POSTSCRIPTUM: signTrusted all
 TYPE: sslproxy_cert_sign
 LOC: Config.ssl_client.cert_sign
 DOC_START
 
         sslproxy_cert_sign <signing algorithm> acl ...
 
@@ -2909,21 +2909,21 @@
 
 	WARNING: SQUID_X509_V_ERR_DOMAIN_MISMATCH and ssl:certDomainMismatch can
 	be used with sslproxy_cert_adapt, but if and only if Squid is bumping a
 	CONNECT request that carries a domain name. In all other cases (CONNECT
 	to an IP address or an intercepted SSL connection), Squid cannot detect
 	the domain mismatch at certificate generation time when
 	bump-server-first is used.
 DOC_END
 
 NAME: sslproxy_cert_adapt
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 TYPE: sslproxy_cert_adapt
 LOC: Config.ssl_client.cert_adapt
 DOC_START
 	
 	sslproxy_cert_adapt <adaptation algorithm> acl ...
 
 	The following certificate adaptation algorithms are supported:
 
 	   setValidAfter
@@ -2952,21 +2952,21 @@
 
 	WARNING: SQUID_X509_V_ERR_DOMAIN_MISMATCH and ssl:certDomainMismatch can
 	be used with sslproxy_cert_adapt, but if and only if Squid is bumping a
 	CONNECT request that carries a domain name. In all other cases (CONNECT
 	to an IP address or an intercepted SSL connection), Squid cannot detect
 	the domain mismatch at certificate generation time when
 	bump-server-first is used.
 DOC_END
 
 NAME: sslpassword_program
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 LOC: Config.Program.ssl_password
 TYPE: string
 DOC_START
 	Specify a program used for entering SSL key passphrases
 	when using encrypted SSL certificate keys. If not specified
 	keys must either be unencrypted, or Squid started with the -N
 	option to allow it to query interactively for the passphrase.
 
 	The key file name is given as argument to the program allowing
@@ -3025,37 +3025,37 @@
 	Sets the maximum number of queued requests.
 	If the queued requests exceed queue size for more than 3 minutes
 	squid aborts its operation.
 	The default value is set to 2*numberofchildren.
 	
 	You must have at least one ssl_crtd process.
 DOC_END
 
 NAME: sslcrtvalidator_program
 TYPE: eol
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: none
 LOC: Ssl::TheConfig.ssl_crt_validator
 DOC_START
 	Specify the location and options of the executable for ssl_crt_validator
 	process.
 
 	Usage:  sslcrtvalidator_program [ttl=n] [cache=n] path ...
 
 	Options:
 	  ttl=n         TTL in seconds for cached results. The default is 60 secs
 	  cache=n       limit the result cache size. The default value is 2048
 DOC_END
 
 NAME: sslcrtvalidator_children
 TYPE: HelperChildConfig
-IFDEF: USE_OPENSSL
+IFDEF: USE_OPENSSL||USE_LIBRESSL
 DEFAULT: 32 startup=5 idle=1 concurrency=1
 LOC: Ssl::TheConfig.ssl_crt_validator_Children
 DOC_START
 	The maximum number of processes spawn to service SSL server.
 	The maximum this may be safely set to is 32.
 	
 	The startup= and idle= options allow some measure of skew in your
 	tuning.
 	
 		startup=N

=== modified file 'src/cf_gen_defines'
--- src/cf_gen_defines	2017-01-01 00:12:22 +0000
+++ src/cf_gen_defines	2017-01-23 02:21:25 +0000
@@ -27,25 +27,27 @@
 	define["HAVE_MSTATS&&HAVE_GNUMALLOC_H"]="GNU Malloc with mstats()"
 	define["ICAP_CLIENT"]="--enable-icap-client"
 	define["SO_MARK&&USE_LIBCAP"]="Packet MARK (Linux)"
 	define["SQUID_SNMP"]="--enable-snmp"
 	define["USE_ADAPTATION"]="--enable-ecap or --enable-icap-client"
 	define["USE_AUTH"]="--enable-auth"
 	define["USE_CACHE_DIGESTS"]="--enable-cache-digests"
 	define["USE_DELAY_POOLS"]="--enable-delay-pools"
 	define["USE_ECAP"]="--enable-ecap"
 	define["USE_ERR_LOCALES"]="--enable-auto-locale"
-	define["USE_GNUTLS||USE_OPENSSL"]="--with-gnutls or --with-openssl"
+	define["USE_GNUTLS||USE_OPENSSL||USE_LIBRESSL"]="--with-gnutls or --with-openssl or --with-libressl"
 	define["USE_HTCP"]="--enable-htcp"
 	define["USE_HTTP_VIOLATIONS"]="--enable-http-violations"
 	define["USE_ICMP"]="--enable-icmp"
 	define["USE_IDENT"]="--enable-ident-lookups"
+	define["USE_LIBRESSL"]="--with-libressl"
+	define["USE_OPENSSL||USE_LIBRESSL"]="--with-openssl or --with-libressl"
 	define["USE_LOADABLE_MODULES"]="--enable-loadable-modules"
 	define["USE_OPENSSL"]="--with-openssl"
 	define["USE_QOS_TOS"]="--enable-zph-qos"
 	define["USE_SQUID_ESI"]="--enable-esi"
 	define["USE_SQUID_EUI"]="--enable-eui"
 	define["USE_SSL_CRTD"]="--enable-ssl-crtd"
 	define["USE_UNLINKD"]="--enable-unlinkd"
 	define["USE_WCCP"]="--enable-wccp"
 	define["USE_WCCPv2"]="--enable-wccpv2"
 }

=== modified file 'src/client_side.cc'
--- src/client_side.cc	2017-01-25 03:18:03 +0000
+++ src/client_side.cc	2017-01-29 04:25:08 +0000
@@ -114,21 +114,21 @@
 #include "TimeOrTag.h"
 #include "tools.h"
 #include "URL.h"
 
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
 #if USE_DELAY_POOLS
 #include "ClientInfo.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/bio.h"
 #include "ssl/context_storage.h"
 #include "ssl/gadgets.h"
 #include "ssl/helper.h"
 #include "ssl/ProxyCerts.h"
 #include "ssl/ServerBump.h"
 #include "ssl/support.h"
 #endif
 
 // for tvSubUsec() which should be in SquidTime.h
@@ -163,21 +163,21 @@
 
 private:
     AnyP::PortCfgPointer portCfg;   ///< from HttpPortList
     Ipc::FdNoteId portTypeNote;    ///< Type of IPC socket being opened
     Subscription::Pointer sub; ///< The handler to be subscribed for this connetion listener
 };
 
 static void clientListenerConnectionOpened(AnyP::PortCfgPointer &s, const Ipc::FdNoteId portTypeNote, const Subscription::Pointer &sub);
 
 static IOACB httpAccept;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static IOACB httpsAccept;
 #endif
 static CTCB clientLifetimeTimeout;
 #if USE_IDENT
 static IDCB clientIdentDone;
 #endif
 static int clientIsContentLengthValid(HttpRequest * r);
 static int clientIsRequestBodyTooLargeForPolicy(int64_t bodyLength);
 
 static void clientUpdateStatHistCounters(const LogTags &logType, int svc_time);
@@ -411,22 +411,21 @@
     al->cache.code = logType;
 
     tvSub(al->cache.trTime, al->cache.start_time, current_time);
 
     if (request)
         prepareLogWithRequestDetails(request, al);
 
     if (getConn() != NULL && getConn()->clientConnection != NULL && getConn()->clientConnection->rfc931[0])
         al->cache.rfc931 = getConn()->clientConnection->rfc931;
 
-#if USE_OPENSSL && 0
-
+#if 0 // USE_OPENSSL || USE_LIBRESSL
     /* This is broken. Fails if the connection has been closed. Needs
      * to snarf the ssl details some place earlier..
      */
     if (getConn() != NULL)
         al->cache.ssluser = sslGetUserEmail(fd_table[getConn()->fd].ssl);
 
 #endif
 
     /* Add notes (if we have a request to annotate) */
     if (request) {
@@ -620,21 +619,21 @@
         debugs(33, DBG_IMPORTANT, "BUG: ConnStateData did not close " << clientConnection);
 
     if (!flags.swanSang)
         debugs(33, DBG_IMPORTANT, "BUG: ConnStateData was not destroyed properly; " << clientConnection);
 
     if (bodyPipe != NULL)
         stopProducingFor(bodyPipe, false);
 
     delete bodyParser; // TODO: pool
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     delete sslServerBump;
 #endif
 }
 
 /**
  * clientSetKeepaliveFlag() sets request->flags.proxyKeepalive.
  * This is the client-side persistent connection flag.  We need
  * to set this relatively early in the request processing
  * to handle hacks for broken servers and clients.
  */
@@ -1473,21 +1472,21 @@
 {
     // From HTTP p.o.v., we do not have to close after every error detected
     // at the client-side, but many such errors do require closure and the
     // client-side code is bad at handling errors so we play it safe.
     if (request)
         request->flags.proxyKeepalive = false;
     flags.readMore = false;
     debugs(33,4, HERE << "Will close after error: " << clientConnection);
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 bool ConnStateData::serveDelayedError(Http::Stream *context)
 {
     ClientHttpRequest *http = context->http;
 
     if (!sslServerBump)
         return false;
 
     assert(sslServerBump->entry);
     // Did we create an error entry while processing CONNECT?
     if (!sslServerBump->entry->isEmpty()) {
@@ -1557,21 +1556,21 @@
                 repContext->setReplyToError(request->method, err);
                 assert(context->http->out.offset == 0);
                 context->pullData();
                 return true;
             }
         }
     }
 
     return false;
 }
-#endif // USE_OPENSSL
+#endif // USE_OPENSSL || USE_LIBRESSL
 
 /**
  * Check on_unsupported_protocol checklist and return true if tunnel mode selected
  * or false otherwise
  */
 bool
 clientTunnelOnError(ConnStateData *conn, Http::StreamPointer &context, HttpRequest::Pointer &request, const HttpRequestMethod& method, err_type requestError)
 {
     if (conn->mayTunnelUnsupportedProto()) {
         ACLFilledChecklist checklist(Config.accessList.on_unsupported_protocol, request.getRaw(), nullptr);
@@ -1744,21 +1743,21 @@
         return;
     }
 
     clientSetKeepaliveFlag(http);
     // Let tunneling code be fully responsible for CONNECT requests
     if (http->request->method == Http::METHOD_CONNECT) {
         context->mayUseConnection(true);
         conn->flags.readMore = false;
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (conn->switchedToHttps() && conn->serveDelayedError(context)) {
         clientProcessRequestFinished(conn, request);
         return;
     }
 #endif
 
     /* Do we expect a request-body? */
     expectBody = chunked || request->content_length > 0;
     if (!context->mayUseConnection() && expectBody) {
         request->body_pipe = conn->expectRequestBody(
@@ -1817,21 +1816,21 @@
  * \return true  when there are available position(s) in the pipeline queue for another request.
  * \return false when the pipeline queue is full or disabled.
  */
 bool
 ConnStateData::concurrentRequestQueueFilled() const
 {
     const int existingRequestCount = pipeline.count();
 
     // default to the configured pipeline size.
     // add 1 because the head of pipeline is counted in concurrent requests and not prefetch queue
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     const int internalRequest = (transparent() && sslBumpMode == Ssl::bumpSplice) ? 1 : 0;
 #else
     const int internalRequest = 0;
 #endif
     const int concurrentRequestLimit = pipelinePrefetchMax() + 1 + internalRequest;
 
     // when queue filled already we cant add more.
     if (existingRequestCount >= concurrentRequestLimit) {
         debugs(33, 3, clientConnection << " max concurrent requests reached (" << concurrentRequestLimit << ")");
         debugs(33, 5, clientConnection << " deferring new request until one is done");
@@ -2172,21 +2171,21 @@
         }
     }
 
     /* XXX where to 'finish' the parsing pass? */
     return parsed_req;
 }
 
 void
 ConnStateData::afterClientRead()
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (parsingTlsHandshake) {
         parseTlsHandshake();
         return;
     }
 #endif
 
     /* Process next request */
     if (pipeline.empty())
         fd_note(clientConnection->fd, "Reading next request");
 
@@ -2394,25 +2393,25 @@
     debugs(33, DBG_IMPORTANT, "\t" << http->uri);
     http->logType.err.timedout = true;
     if (Comm::IsConnOpen(io.conn))
         io.conn->close();
 }
 
 ConnStateData::ConnStateData(const MasterXaction::Pointer &xact) :
     AsyncJob("ConnStateData"), // kids overwrite
     Server(xact),
     bodyParser(nullptr),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     sslBumpMode(Ssl::bumpEnd),
 #endif
     needProxyProtocolHeader_(false),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     switchedToHttps_(false),
     parsingTlsHandshake(false),
     sslServerBump(NULL),
     signAlgorithm(Ssl::algSignTrusted),
 #endif
     stoppedSending_(NULL),
     stoppedReceiving_(NULL)
 {
     flags.readMore = true; // kids may overwrite
     flags.swanSang = false;
@@ -2550,21 +2549,21 @@
     if (s->tcp_keepalive.enabled)
         commSetTcpKeepalive(params.conn->fd, s->tcp_keepalive.idle, s->tcp_keepalive.interval, s->tcp_keepalive.timeout);
 
     ++incoming_sockets_accepted;
 
     // Socket is ready, setup the connection manager to start using it
     auto *srv = Http::NewServer(xact);
     AsyncJob::Start(srv); // usually async-calls readSomeData()
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 /** Create SSL connection structure and update fd_table */
 static bool
 httpsCreate(const Comm::ConnectionPointer &conn, const Security::ContextPointer &ctx)
 {
     if (Ssl::CreateServer(ctx, conn, "client https start")) {
         debugs(33, 5, "will negotate SSL on " << conn);
         return true;
     }
 
@@ -2640,21 +2639,21 @@
     Security::SessionPointer session(fd_table[fd].ssl);
     if (Security::SessionIsResumed(session)) {
         debugs(83, 2, "Session " << SSL_get_session(session.get()) <<
                " reused on FD " << fd << " (" << fd_table[fd].ipaddr <<
                ":" << (int)fd_table[fd].remote_port << ")");
     } else {
         if (Debug::Enabled(83, 4)) {
             /* Write out the SSL session details.. actually the call below, but
              * OpenSSL headers do strange typecasts confusing GCC.. */
             /* PEM_write_SSL_SESSION(debug_log, SSL_get_session(ssl)); */
-#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00908000L
+#if USE_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x00908000L
             PEM_ASN1_write(reinterpret_cast<i2d_of_void *>(i2d_SSL_SESSION),
                            PEM_STRING_SSL_SESSION, debug_log,
                            reinterpret_cast<char *>(SSL_get_session(session.get())),
                            nullptr, nullptr, 0, nullptr, nullptr);
 
 #elif (ALLOW_ALWAYS_SSL_SESSION_DETAIL == 1)
 
             /* When using gcc 3.3.x and OpenSSL 0.9.7x sometimes a compile error can occur here.
             * This is caused by an unpredicatble gcc behaviour on a cast of the first argument
             * of PEM_ASN1_write(). For this reason this code section is disabled. To enable it,
@@ -3321,21 +3320,21 @@
         debugs(33, 5, HERE << "Error while bumping: " << sslConnectHostOrIp);
 
         //  copy error detail from bump-server-first request to CONNECT request
         if (!pipeline.empty() && pipeline.front()->http != nullptr && pipeline.front()->http->request)
             pipeline.front()->http->request->detailError(sslServerBump->request->errType, sslServerBump->request->errDetail);
     }
 
     getSslContextStart();
 }
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 bool
 ConnStateData::initiateTunneledRequest(HttpRequest::Pointer const &cause, Http::MethodType const method, const char *reason, const SBuf &payload)
 {
     // fake a CONNECT request to force connState to tunnel
     SBuf connectHost;
     unsigned short connectPort = 0;
 
     if (pinning.serverConnection != nullptr) {
         static char ip[MAX_IPSTRLEN];
@@ -3362,21 +3361,21 @@
 
 bool
 ConnStateData::fakeAConnectRequest(const char *reason, const SBuf &payload)
 {
     debugs(33, 2, "fake a CONNECT request to force connState to tunnel for " << reason);
 
     SBuf connectHost;
     assert(transparent());
     const unsigned short connectPort = clientConnection->local.port();
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (serverBump() && !serverBump()->clientSni.isEmpty())
         connectHost.assign(serverBump()->clientSni);
     else
 #endif
     {
         static char ip[MAX_IPSTRLEN];
         connectHost.assign(clientConnection->local.toStr(ip, sizeof(ip)));
     }
 
     ClientHttpRequest *http = buildFakeRequest(Http::METHOD_CONNECT, connectHost, connectPort, payload);
@@ -3484,21 +3483,21 @@
 {
     for (AnyP::PortCfgPointer s = HttpPortList; s != NULL; s = s->next) {
         const SBuf &scheme = AnyP::UriScheme(s->transport.protocol).image();
 
         if (MAXTCPLISTENPORTS == NHttpSockets) {
             debugs(1, DBG_IMPORTANT, "WARNING: You have too many '" << scheme << "_port' lines.");
             debugs(1, DBG_IMPORTANT, "         The limit is " << MAXTCPLISTENPORTS << " HTTP ports.");
             continue;
         }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (s->flags.tunnelSslBumping) {
             if (!Config.accessList.ssl_bump) {
                 debugs(33, DBG_IMPORTANT, "WARNING: No ssl_bump configured. Disabling ssl-bump on " << scheme << "_port " << s->s);
                 s->flags.tunnelSslBumping = false;
             }
             if (!s->secure.staticContext && !s->generateHostCertificates) {
                 debugs(1, DBG_IMPORTANT, "Will not bump SSL at " << scheme << "_port " << s->s << " due to TLS initialization failure.");
                 s->flags.tunnelSslBumping = false;
                 if (s->transport.protocol == AnyP::PROTO_HTTP)
                     s->secure.encryptTransport = false;
@@ -3527,21 +3526,21 @@
         typedef CommCbFunPtrCallT<CommAcceptCbPtrFun> AcceptCall;
         if (s->transport.protocol == AnyP::PROTO_HTTP) {
             // setup the subscriptions such that new connections accepted by listenConn are handled by HTTP
             RefCount<AcceptCall> subCall = commCbCall(5, 5, "httpAccept", CommAcceptCbPtrFun(httpAccept, CommAcceptCbParams(NULL)));
             Subscription::Pointer sub = new CallSubscription<AcceptCall>(subCall);
 
             AsyncCall::Pointer listenCall = asyncCall(33,2, "clientListenerConnectionOpened",
                                             ListeningStartedDialer(&clientListenerConnectionOpened, s, Ipc::fdnHttpSocket, sub));
             Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->listenConn, Ipc::fdnHttpSocket, listenCall);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         } else if (s->transport.protocol == AnyP::PROTO_HTTPS) {
             // setup the subscriptions such that new connections accepted by listenConn are handled by HTTPS
             RefCount<AcceptCall> subCall = commCbCall(5, 5, "httpsAccept", CommAcceptCbPtrFun(httpsAccept, CommAcceptCbParams(NULL)));
             Subscription::Pointer sub = new CallSubscription<AcceptCall>(subCall);
 
             AsyncCall::Pointer listenCall = asyncCall(33, 2, "clientListenerConnectionOpened",
                                             ListeningStartedDialer(&clientListenerConnectionOpened,
                                                     s, Ipc::fdnHttpsSocket, sub));
             Ipc::StartListening(SOCK_STREAM, IPPROTO_TCP, s->listenConn, Ipc::fdnHttpsSocket, listenCall);
 #endif
@@ -3937,21 +3936,21 @@
 
 void
 ConnStateData::stopPinnedConnectionMonitoring()
 {
     if (pinning.readHandler != NULL) {
         Comm::ReadCancel(pinning.serverConnection->fd, pinning.readHandler);
         pinning.readHandler = NULL;
     }
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 bool
 ConnStateData::handleIdleClientPinnedTlsRead()
 {
     // A ready-for-reading connection means that the TLS server either closed
     // the connection, sent us some unexpected HTTP data, or started TLS
     // renegotiations. We should close the connection except for the last case.
 
     Must(pinning.serverConnection != nullptr);
     auto ssl = fd_table[pinning.serverConnection->fd].ssl.get();
     if (!ssl)
@@ -3989,21 +3988,21 @@
 void
 ConnStateData::clientPinnedConnectionRead(const CommIoCbParams &io)
 {
     pinning.readHandler = NULL; // Comm unregisters handlers before calling
 
     if (io.flag == Comm::ERR_CLOSING)
         return; // close handler will clean up
 
     Must(pinning.serverConnection == io.conn);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (handleIdleClientPinnedTlsRead())
         return;
 #endif
 
     const bool clientIsIdle = pipeline.empty();
 
     debugs(33, 3, "idle pinned " << pinning.serverConnection << " read " <<
            io.size << (clientIsIdle ? " with idle client" : ""));
 
     pinning.serverConnection->close();
@@ -4107,18 +4106,18 @@
     http.req_sz = inBuf.length();
     char const *uri = "error:transaction-end-before-headers";
     http.uri = xstrdup(uri);
     setLogUri(&http, uri);
 }
 
 bool
 ConnStateData::mayTunnelUnsupportedProto()
 {
     return Config.accessList.on_unsupported_protocol
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
            &&
            ((port->flags.isIntercepted() && port->flags.tunnelSslBumping)
             || (serverBump() && pinning.serverConnection))
 #endif
            ;
 }
 

=== modified file 'src/client_side.h'
--- src/client_side.h	2017-01-01 00:12:22 +0000
+++ src/client_side.h	2017-01-23 02:23:01 +0000
@@ -16,29 +16,29 @@
 #include "comm.h"
 #include "helper/forward.h"
 #include "http/forward.h"
 #include "HttpControlMsg.h"
 #include "ipc/FdNotes.h"
 #include "sbuf/SBuf.h"
 #include "servers/Server.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "security/Handshake.h"
 #include "ssl/support.h"
 #endif
 
 class ClientHttpRequest;
 class HttpHdrRangeSpec;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 namespace Ssl
 {
 class ServerBump;
 }
 #endif
 
 /**
  * Legacy Server code managing a connection to a client.
  *
  * NP: presents AsyncJob API but does not operate autonomously as a Job.
@@ -192,21 +192,21 @@
     virtual bool doneAll() const { return BodyProducer::doneAll() && false;}
     virtual void swanSong();
 
     /// Changes state so that we close the connection and quit after serving
     /// the client-side-detected error response instead of getting stuck.
     void quitAfterError(HttpRequest *request); // meant to be private
 
     /// The caller assumes responsibility for connection closure detection.
     void stopPinnedConnectionMonitoring();
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// the second part of old httpsAccept, waiting for future HttpsServer home
     void postHttpsAccept();
 
     /// Initializes and starts a peek-and-splice negotiation with the SSL client
     void startPeekAndSplice();
 
     /// Called when a peek-and-splice step finished. For example after
     /// server SSL certificates received and fake server SSL certificates
     /// generated
     void doPeekAndSpliceStep();
@@ -300,21 +300,21 @@
     virtual void endingShutdown();
 
 protected:
     void startDechunkingRequest();
     void finishDechunkingRequest(bool withSuccess);
     void abortChunkedRequestBody(const err_type error);
     err_type handleChunkedRequestBody();
 
     void startPinnedConnectionMonitoring();
     void clientPinnedConnectionRead(const CommIoCbParams &io);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// Handles a ready-for-reading TLS squid-to-server connection that
     /// we thought was idle.
     /// \return false if and only if the connection should be closed.
     bool handleIdleClientPinnedTlsRead();
 #endif
 
     /// parse input buffer prefix into a single transfer protocol request
     /// return NULL to request more header bytes (after checking any limits)
     /// use abortRequestParsing() to handle parsing errors w/o creating request
     virtual Http::Stream *parseOneRequest() = 0;
@@ -351,21 +351,21 @@
     bool needProxyProtocolHeader_;
 
 #if USE_AUTH
     /// some user details that can be used to perform authentication on this connection
     Auth::UserRequest::Pointer auth_;
 #endif
 
     /// the parser state for current HTTP/1.x input buffer processing
     Http1::RequestParserPointer parser_;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     bool switchedToHttps_;
     bool parsingTlsHandshake; ///< whether we are getting/parsing TLS Hello bytes
 
     /// The SSL server host name appears in CONNECT request or the server ip address for the intercepted requests
     String sslConnectHostOrIp; ///< The SSL server host name as passed in the CONNECT request
     SBuf sslCommonName_; ///< CN name for SSL certificate generation
     String sslBumpCertKey; ///< Key to use to store/retrieve generated certificate
 
     /// HTTPS server cert. fetching state for bump-ssl-server-first
     Ssl::ServerBump *sslServerBump;

=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc	2017-01-11 18:17:47 +0000
+++ src/client_side_request.cc	2017-01-23 02:23:24 +0000
@@ -60,21 +60,21 @@
 #endif
 #if USE_ADAPTATION
 #include "adaptation/AccessCheck.h"
 #include "adaptation/Answer.h"
 #include "adaptation/Iterator.h"
 #include "adaptation/Service.h"
 #if ICAP_CLIENT
 #include "adaptation/icap/History.h"
 #endif
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/ServerBump.h"
 #include "ssl/support.h"
 #endif
 
 #if LINGERING_CLOSE
 #define comm_close comm_lingering_close
 #endif
 
 static const char *const crlf = "\r\n";
 
@@ -82,21 +82,21 @@
 static void clientFollowXForwardedForCheck(allow_t answer, void *data);
 #endif /* FOLLOW_X_FORWARDED_FOR */
 
 ErrorState *clientBuildError(err_type, Http::StatusCode, char const *url, Ip::Address &, HttpRequest *);
 
 CBDATA_CLASS_INIT(ClientRequestContext);
 
 /* Local functions */
 /* other */
 static void clientAccessCheckDoneWrapper(allow_t, void *);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static void sslBumpAccessCheckDoneWrapper(allow_t, void *);
 #endif
 static int clientHierarchical(ClientHttpRequest * http);
 static void clientInterpretRequestHeaders(ClientHttpRequest * http);
 static HLPCB clientRedirectDoneWrapper;
 static HLPCB clientStoreIdDoneWrapper;
 static void checkNoCacheDoneWrapper(allow_t, void *);
 SQUIDCEXTERN CSR clientGetMoreData;
 SQUIDCEXTERN CSS clientReplyStatus;
 SQUIDCEXTERN CSD clientReplyDetach;
@@ -126,21 +126,21 @@
     adapted_http_access_done(false),
 #if USE_ADAPTATION
     adaptation_acl_check_done(false),
 #endif
     redirect_done(false),
     store_id_done(false),
     no_cache_done(false),
     interpreted_req_hdrs(false),
     tosToClientDone(false),
     nfmarkToClientDone(false),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     sslBumpCheckDone(false),
 #endif
     error(NULL),
     readNextRequest(false)
 {
     debugs(85, 3, "ClientRequestContext constructed, this=" << this);
 }
 
 CBDATA_CLASS_INIT(ClientHttpRequest);
 
@@ -151,37 +151,37 @@
     request(NULL),
     uri(NULL),
     log_uri(NULL),
     req_sz(0),
     logType(LOG_TAG_NONE),
     calloutContext(NULL),
     maxReplyBodySize_(0),
     entry_(NULL),
     loggingEntry_(NULL),
     conn_(NULL)
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     , sslBumpNeed_(Ssl::bumpEnd)
 #endif
 #if USE_ADAPTATION
     , request_satisfaction_mode(false)
     , request_satisfaction_offset(0)
 #endif
 {
     setConn(aConn);
     al = new AccessLogEntry;
     al->cache.start_time = current_time;
     if (aConn) {
         al->tcpClient = clientConnection = aConn->clientConnection;
         al->cache.port = aConn->port;
         al->cache.caddr = aConn->log_addr;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (aConn->clientConnection != NULL && aConn->clientConnection->isOpen()) {
             if (auto ssl = fd_table[aConn->clientConnection->fd].ssl.get())
                 al->cache.sslClientCert.resetWithoutLocking(SSL_get_peer_certificate(ssl));
         }
 #endif
     }
     dlinkAdd(this, &active, &ClientActiveRequests);
 }
 
 /*
@@ -846,21 +846,21 @@
 void
 ClientHttpRequest::noteAdaptationAclCheckDone(Adaptation::ServiceGroupPointer g)
 {
     debugs(93,3,HERE << this << " adaptationAclCheckDone called");
 
 #if ICAP_CLIENT
     Adaptation::Icap::History::Pointer ih = request->icapHistory();
     if (ih != NULL) {
         if (getConn() != NULL && getConn()->clientConnection != NULL) {
             ih->rfc931 = getConn()->clientConnection->rfc931;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             if (getConn()->clientConnection->isOpen()) {
                 ih->ssluser = sslGetUserEmail(fd_table[getConn()->clientConnection->fd].ssl.get());
             }
 #endif
         }
         ih->log_uri = log_uri;
         ih->req_sz = req_sz;
     }
 #endif
 
@@ -1399,21 +1399,21 @@
 ClientRequestContext::checkNoCacheDone(const allow_t &answer)
 {
     acl_checklist = NULL;
     if (answer == ACCESS_DENIED) {
         http->request->flags.noCache = true; // dont read reply from cache
         http->request->flags.cachable = false; // dont store reply into cache
     }
     http->doCallouts();
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 bool
 ClientRequestContext::sslBumpAccessCheck()
 {
     if (!http->getConn()) {
         http->al->ssl.bumpMode = Ssl::bumpEnd; // SslBump does not apply; log -
         return false;
     }
 
     if (http->request->flags.forceTunnel) {
         debugs(85, 5, "not needed; already decided to tunnel " << http->getConn());
@@ -1493,21 +1493,21 @@
  * and forward them to the appropriate location. All other requests, request
  * them.
  */
 void
 ClientHttpRequest::processRequest()
 {
     debugs(85, 4, request->method << ' ' << uri);
 
     const bool untouchedConnect = request->method == Http::METHOD_CONNECT && !redirect.status;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (untouchedConnect && sslBumpNeeded()) {
         assert(!request->flags.forceTunnel);
         sslBumpStart();
         return;
     }
 #endif
 
     if (untouchedConnect || request->flags.forceTunnel) {
         getConn()->stopReading(); // tunnels read for themselves
         tunnelStart(this);
@@ -1525,21 +1525,21 @@
     debugs(85, 4, logType.c_str() << " for '" << uri << "'");
 
     /* no one should have touched this */
     assert(out.offset == 0);
     /* Use the Stream Luke */
     clientStreamNode *node = (clientStreamNode *)client_stream.tail->data;
     clientStreamRead(node, this, node->readBuffer);
     PROF_stop(httpStart);
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 void
 ClientHttpRequest::sslBumpNeed(Ssl::BumpMode mode)
 {
     debugs(83, 3, HERE << "sslBump required: "<< Ssl::bumpMode(mode));
     sslBumpNeed_ = mode;
 }
 
 // called when comm_write has completed
 static void
@@ -1779,37 +1779,37 @@
         if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConnection)) {
             ACLFilledChecklist ch(NULL, request, NULL);
             ch.src_addr = request->client_addr;
             ch.my_addr = request->my_addr;
             nfmark_t mark = aclMapNfmark(Ip::Qos::TheConfig.nfmarkToClient, &ch);
             if (mark)
                 Ip::Qos::setSockNfmark(getConn()->clientConnection, mark);
         }
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // We need to check for SslBump even if the calloutContext->error is set
     // because bumping may require delaying the error until after CONNECT.
     if (!calloutContext->sslBumpCheckDone) {
         calloutContext->sslBumpCheckDone = true;
         if (calloutContext->sslBumpAccessCheck())
             return;
         /* else no ssl bump required*/
     }
 #endif
 
     if (calloutContext->error) {
         // XXX: prformance regression. c_str() reallocates
         SBuf storeUriBuf(request->storeId());
         const char *storeUri = storeUriBuf.c_str();
         StoreEntry *e = storeCreateEntry(storeUri, storeUri, request->flags, request->method);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (sslBumpNeeded()) {
             // We have to serve an error, so bump the client first.
             sslBumpNeed(Ssl::bumpClientFirst);
             // set final error but delay sending until we bump
             Ssl::ServerBump *srvBump = new Ssl::ServerBump(request, e, Ssl::bumpClientFirst);
             errorAppendEntry(e, calloutContext->error);
             calloutContext->error = NULL;
             getConn()->setServerBump(srvBump);
             e->unlock("ClientHttpRequest::doCallouts+sslBumpNeeded");
         } else

=== modified file 'src/client_side_request.h'
--- src/client_side_request.h	2017-01-11 18:17:47 +0000
+++ src/client_side_request.h	2017-01-23 00:58:31 +0000
@@ -133,21 +133,21 @@
     }
     virtual void callException(const std::exception &ex);
 #endif
 
 private:
     int64_t maxReplyBodySize_;
     StoreEntry *entry_;
     StoreEntry *loggingEntry_;
     ConnStateData * conn_;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// whether (and how) the request needs to be bumped
     Ssl::BumpMode sslBumpNeed_;
 
 public:
     /// returns raw sslBump mode value
     Ssl::BumpMode sslBumpNeed() const { return sslBumpNeed_; }
     /// returns true if and only if the request needs to be bumped
     bool sslBumpNeeded() const { return sslBumpNeed_ == Ssl::bumpServerFirst || sslBumpNeed_ == Ssl::bumpClientFirst || sslBumpNeed_ == Ssl::bumpBump || sslBumpNeed_ == Ssl::bumpPeek || sslBumpNeed_ == Ssl::bumpStare; }
     /// set the sslBumpNeeded state
     void sslBumpNeed(Ssl::BumpMode mode);

=== modified file 'src/comm.cc'
--- src/comm.cc	2017-01-01 00:12:22 +0000
+++ src/comm.cc	2017-01-23 01:20:37 +0000
@@ -30,21 +30,21 @@
 #include "ip/QosConfig.h"
 #include "ip/tools.h"
 #include "pconn.h"
 #include "profiler/Profiler.h"
 #include "sbuf/SBuf.h"
 #include "SquidConfig.h"
 #include "StatCounters.h"
 #include "StoreIOBuffer.h"
 #include "tools.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #include <cerrno>
 #include <cmath>
 #if _SQUID_CYGWIN_
 #include <sys/ioctl.h>
 #endif
 #ifdef HAVE_NETINET_TCP_H
 #include <netinet/tcp.h>
@@ -95,21 +95,21 @@
  *
  * This is a magical routine that empties the read buffers.
  * Under some platforms (Linux) if a buffer has data in it before
  * you call close(), the socket will hang and take quite a while
  * to timeout.
  */
 static void
 comm_empty_os_read_buffers(int fd)
 {
 #if _SQUID_LINUX_
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // Bug 4146: SSL-Bump BIO does not release sockets on close.
     if (fd_table[fd].ssl)
         return;
 #endif
 
     /* prevent those nasty RST packets */
     char buf[SQUID_TCP_SO_RCVBUF];
     if (fd_table[fd].flags.nonblocking && fd_table[fd].type != FD_MSGHDR) {
         while (FD_READ_METHOD(fd, buf, SQUID_TCP_SO_RCVBUF) > 0) {};
     }
@@ -757,21 +757,21 @@
     debugs(5, 3, "commLingerTimeout: FD " << params.fd);
     comm_close(params.fd);
 }
 
 /*
  * Inspired by apache
  */
 void
 comm_lingering_close(int fd)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (fd_table[fd].ssl)
         ssl_shutdown_method(fd_table[fd].ssl);
 #endif
 
     if (shutdown(fd, 1) < 0) {
         comm_close(fd);
         return;
     }
 
     fd_note(fd, "lingering close");
@@ -818,21 +818,21 @@
     L.l_onoff = 1;
     L.l_linger = 0;
 
     if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) {
         int xerrno = errno;
         debugs(50, DBG_CRITICAL, "ERROR: Closing FD " << fd << " with TCP RST: " << xstrerr(xerrno));
     }
     comm_close(fd);
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 void
 commStartSslClose(const FdeCbParams &params)
 {
     assert(fd_table[params.fd].ssl);
     ssl_shutdown_method(fd_table[params.fd].ssl.get());
 }
 #endif
 
 void
 comm_close_complete(const FdeCbParams &params)
@@ -883,21 +883,21 @@
         // XXX: do we need to run close(fd) or fd_close(fd) here?
         return;
     }
 
     assert(F->type != FD_FILE);
 
     PROF_start(comm_close);
 
     F->flags.close_request = true;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (F->ssl) {
         AsyncCall::Pointer startCall=commCbCall(5,4, "commStartSslClose",
                                                 FdeCbPtrFun(commStartSslClose, NULL));
         FdeCbParams &startParams = GetCommParams<FdeCbParams>(startCall);
         startParams.fd = fd;
         ScheduleCallHere(startCall);
     }
 #endif
 
     // a half-closed fd may lack a reader, so we stop monitoring explicitly

=== modified file 'src/errorpage.cc'
--- src/errorpage.cc	2017-01-01 00:12:22 +0000
+++ src/errorpage.cc	2017-01-23 00:58:31 +0000
@@ -26,21 +26,21 @@
 #include "rfc1738.h"
 #include "SquidConfig.h"
 #include "Store.h"
 #include "tools.h"
 #include "URL.h"
 #include "wordlist.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
 #include "SquidTime.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/ErrorDetailManager.h"
 #endif
 
 /**
  \defgroup ErrorPageInternal Error Page Internals
  \ingroup ErrorPageAPI
  *
  \section Abstract Abstract:
  *   These routines are used to generate error messages to be
  *   sent to clients.  The error type is used to select between
@@ -200,21 +200,21 @@
 
     error_stylesheet.reset();
 
     // look for and load stylesheet into global MemBuf for it.
     if (Config.errorStylesheet) {
         ErrorPageFile tmpl("StylesSheet", ERR_MAX);
         tmpl.loadFromFile(Config.errorStylesheet);
         error_stylesheet.appendf("%s",tmpl.text());
     }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::errorDetailInitialize();
 #endif
 }
 
 void
 errorClean(void)
 {
     if (error_text) {
         int i;
 
@@ -224,21 +224,21 @@
         safe_free(error_text);
     }
 
     while (!ErrorDynamicPages.empty()) {
         errorDynamicPageInfoDestroy(ErrorDynamicPages.back());
         ErrorDynamicPages.pop_back();
     }
 
     error_page_count = 0;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::errorDetailClean();
 #endif
 }
 
 /// \ingroup ErrorPageInternal
 static const char *
 errorFindHardText(err_type type)
 {
     int i;
 
@@ -571,21 +571,21 @@
     xerrno(0),
     port(0),
     dnsError(),
     ttl(0),
     src_addr(),
     redirect_url(NULL),
     callback(NULL),
     callback_data(NULL),
     request_hdrs(NULL),
     err_msg(NULL),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     detail(NULL),
 #endif
     detailCode(ERR_DETAIL_NONE)
 {
     memset(&ftp, 0, sizeof(ftp));
 
     if (page_id >= ERR_MAX && ErrorDynamicPages[page_id - ERR_MAX]->page_redirect != Http::scNone)
         httpStatus = ErrorDynamicPages[page_id - ERR_MAX]->page_redirect;
 
     if (req != NULL) {
@@ -684,21 +684,21 @@
     safe_free(ftp.request);
     safe_free(ftp.reply);
 #if USE_AUTH
     auth_user_request = NULL;
 #endif
     safe_free(err_msg);
 #if USE_ERR_LOCALES
     if (err_language != Config.errorDefaultLanguage)
 #endif
         safe_free(err_language);
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     delete detail;
 #endif
 }
 
 int
 ErrorState::Dump(MemBuf * mb)
 {
     MemBuf str;
     char ntoabuf[MAX_IPSTRLEN];
 
@@ -802,21 +802,21 @@
         break;
 
     case 'c':
         if (building_deny_info_url) break;
         p = errorPageName(type);
         break;
 
     case 'D':
         if (!allowRecursion)
             p = "%D";  // if recursion is not allowed, do not convert
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         // currently only SSL error details implemented
         else if (detail) {
             detail->useRequest(request);
             const String &errDetail = detail->toString();
             if (errDetail.size() > 0) {
                 MemBuf *detail_mb  = ConvertText(errDetail.termedBuf(), false);
                 mb.append(detail_mb->content(), detail_mb->contentSize());
                 delete detail_mb;
                 do_quote = 0;
             }
@@ -1047,21 +1047,21 @@
         break;
 
     case 'W':
         if (building_deny_info_url) break;
         if (Config.adminEmail && Config.onoff.emailErrData)
             Dump(&mb);
         no_urlescape = 1;
         break;
 
     case 'x':
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (detail)
             mb.appendf("%s", detail->errorName());
         else
 #endif
             if (!building_deny_info_url)
                 p = "[Unknown Error Code]";
         break;
 
     case 'z':
         if (building_deny_info_url) break;
@@ -1198,21 +1198,21 @@
         }
 
         rep->body.setMb(content);
         /* do not memBufClean() or delete the content, it was absorbed by httpBody */
     }
 
     // Make sure error codes get back to the client side for logging and
     // error tracking.
     if (request) {
         int edc = ERR_DETAIL_NONE; // error detail code
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (detail)
             edc = detail->errorNo();
         else
 #endif
             if (detailCode)
                 edc = detailCode;
             else
                 edc = xerrno;
         request->detailError(type, edc);
     }

=== modified file 'src/errorpage.h'
--- src/errorpage.h	2017-01-01 00:12:22 +0000
+++ src/errorpage.h	2017-01-23 00:58:31 +0000
@@ -13,21 +13,21 @@
 
 #include "cbdata.h"
 #include "comm/forward.h"
 #include "err_detail_type.h"
 #include "err_type.h"
 #include "http/StatusCode.h"
 #include "ip/Address.h"
 #include "SquidString.h"
 /* auth/UserRequest.h is empty unless USE_AUTH is defined */
 #include "auth/UserRequest.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/ErrorDetail.h"
 #endif
 
 /// error page callback
 typedef void ERCB(int fd, void *, size_t);
 
 /**
  \defgroup ErrorPageAPI Error Pages API
  \ingroup Components
  \section ErrorPageStringCodes Error Page % codes for text insertion.
@@ -160,21 +160,21 @@
         wordlist *server_msg;
         char *request;
         char *reply;
         char *cwd_msg;
         MemBuf *listing;
     } ftp;
 
     char *request_hdrs;
     char *err_msg; /* Preformatted error message from the cache */
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::ErrorDetail *detail;
 #endif
     /// type-specific detail about the transaction error;
     /// overwrites xerrno; overwritten by detail, if any.
     int detailCode;
 };
 
 /**
  \ingroup ErrorPageAPI
  *

=== modified file 'src/external_acl.cc'
--- src/external_acl.cc	2017-01-11 19:06:57 +0000
+++ src/external_acl.cc	2017-01-23 01:20:09 +0000
@@ -30,21 +30,21 @@
 #include "MemBuf.h"
 #include "mgr/Registration.h"
 #include "rfc1738.h"
 #include "SquidConfig.h"
 #include "SquidString.h"
 #include "SquidTime.h"
 #include "Store.h"
 #include "tools.h"
 #include "URL.h"
 #include "wordlist.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/ServerBump.h"
 #include "ssl/support.h"
 #endif
 #if USE_AUTH
 #include "auth/Acl.h"
 #include "auth/Gadgets.h"
 #include "auth/UserRequest.h"
 #endif
 #if USE_IDENT
 #include "ident/AclIdent.h"
@@ -278,21 +278,21 @@
 
         *fmt = new Format::Token;
         // these tokens are whitespace delimited
         (*fmt)->space = true;
 
         // set the default encoding to match the protocol= config
         // this will be overridden by explicit %macro attributes
         (*fmt)->quote = a->quote;
 
         // compatibility for old tokens incompatible with Format::Token syntax
-#if USE_OPENSSL // dont bother if we dont have to.
+#if USE_OPENSSL || USE_LIBRESSL // dont bother if we dont have to.
         if (strncmp(token, "%USER_CERT_", 11) == 0) {
             (*fmt)->type = Format::LFT_EXT_ACL_USER_CERT;
             (*fmt)->data.string = xstrdup(token + 11);
             (*fmt)->data.header.header = (*fmt)->data.string;
         } else if (strncmp(token, "%USER_CA_CERT_", 14) == 0) {
             (*fmt)->type = Format::LFT_EXT_ACL_USER_CA_CERT;
             (*fmt)->data.string = xstrdup(token + 14);
             (*fmt)->data.header.header = (*fmt)->data.string;
         } else if (strncmp(token, "%CA_CERT_", 9) == 0) {
             debugs(82, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: external_acl_type %CA_CERT_* code is obsolete. Use %USER_CA_CERT_* instead");

=== modified file 'src/format/ByteCode.h'
--- src/format/ByteCode.h	2017-01-01 00:12:22 +0000
+++ src/format/ByteCode.h	2017-01-23 02:23:34 +0000
@@ -203,21 +203,21 @@
     LFT_ICAP_REP_HEADER_ELEM,
     LFT_ICAP_REP_ALL_HEADERS,
 
     LFT_ICAP_TR_RESPONSE_TIME,
     LFT_ICAP_IO_TIME,
     LFT_ICAP_OUTCOME,
     LFT_ICAP_STATUS_CODE,
 #endif
     LFT_CREDENTIALS,
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     LFT_SSL_BUMP_MODE,
     LFT_SSL_USER_CERT_SUBJECT,
     LFT_SSL_USER_CERT_ISSUER,
     LFT_SSL_CLIENT_SNI,
     LFT_SSL_SERVER_CERT_SUBJECT,
     LFT_SSL_SERVER_CERT_ISSUER,
     LFT_SSL_SERVER_CERT_ERRORS,
     LFT_TLS_CLIENT_NEGOTIATED_VERSION,
     LFT_TLS_SERVER_NEGOTIATED_VERSION,
     LFT_TLS_CLIENT_NEGOTIATED_CIPHER,
@@ -225,21 +225,21 @@
     LFT_TLS_CLIENT_RECEIVED_HELLO_VERSION,
     LFT_TLS_SERVER_RECEIVED_HELLO_VERSION,
     LFT_TLS_CLIENT_SUPPORTED_VERSION,
     LFT_TLS_SERVER_SUPPORTED_VERSION,
 #endif
 
     LFT_NOTE,
     LFT_PERCENT,            /* special string cases for escaped chars */
 
     // TODO assign better bytecode names and Token strings for these
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     LFT_EXT_ACL_USER_CERT_RAW,
     LFT_EXT_ACL_USER_CERTCHAIN_RAW,
     LFT_EXT_ACL_USER_CERT,
     LFT_EXT_ACL_USER_CA_CERT,
 #endif
     LFT_EXT_ACL_CLIENT_EUI48,
     LFT_EXT_ACL_CLIENT_EUI64,
     LFT_EXT_ACL_NAME,
     LFT_EXT_ACL_DATA
 

=== modified file 'src/format/Format.cc'
--- src/format/Format.cc	2017-01-15 17:35:43 +0000
+++ src/format/Format.cc	2017-01-23 02:23:45 +0000
@@ -20,21 +20,21 @@
 #include "http/Stream.h"
 #include "HttpRequest.h"
 #include "MemBuf.h"
 #include "rfc1738.h"
 #include "security/CertError.h"
 #include "security/NegotiationHistory.h"
 #include "SquidTime.h"
 #include "Store.h"
 #include "tools.h"
 #include "URL.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/ErrorDetail.h"
 #include "ssl/ServerBump.h"
 #endif
 
 /// Convert a string to NULL pointer if it is ""
 #define strOrNull(s) ((s)==NULL||(s)[0]=='\0'?NULL:(s))
 
 const SBuf Format::Dash("-");
 
 Format::Format::Format(const char *n) :
@@ -314,21 +314,21 @@
             *p = *str;
             ++p;
             ++str;
             break;
         }
     }
 
     *p = '\0';
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static char *
 sslErrorName(Security::ErrorCode err, char *buf, size_t size)
 {
     snprintf(buf, size, "SSL_ERR=%d", err);
     return buf;
 }
 #endif
 
 /// XXX: Misnamed. TODO: Split <h (and this function) to distinguish received
 /// headers from sent headers rather than failing to distinguish requests from responses.
@@ -906,22 +906,21 @@
             if (al->request && al->request->auth_user_request != NULL)
                 out = strOrNull(al->request->auth_user_request->username());
 #endif
             if (!out && al->request && al->request->extacl_user.size()) {
                 if (const char *t = al->request->extacl_user.termedBuf())
                     out = t;
             }
 
             if (!out)
                 out = strOrNull(al->cache.extuser);
-
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             if (!out)
                 out = strOrNull(al->cache.ssluser);
 #endif
             if (!out)
                 out = strOrNull(al->cache.rfc931);
             break;
 
         case LFT_USER_LOGIN:
 #if USE_AUTH
             if (al->request && al->request->auth_user_request != NULL)
@@ -982,21 +981,21 @@
         case LFT_SQUID_STATUS:
             out = al->cache.code.c_str();
             break;
 
         case LFT_SQUID_ERROR:
             if (al->request && al->request->errType != ERR_NONE)
                 out = errorPageName(al->request->errType);
             break;
 
         case LFT_SQUID_ERROR_DETAIL:
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
             if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
                 if (! (out = Ssl::GetErrorName(al->request->errDetail)))
                     out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
             } else
 #endif
                 if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
                     if (al->request->errDetail > ERR_DETAIL_START && al->request->errDetail < ERR_DETAIL_MAX)
                         out = errorDetailName(al->request->errDetail);
                     else {
                         if (al->request->errDetail >= ERR_DETAIL_EXCEPTION_START)
@@ -1223,21 +1222,21 @@
 
             quote = 1;
 
             break;
 
         case LFT_SEQUENCE_NUMBER:
             outoff = logSequenceNumber;
             dooff = 1;
             break;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         case LFT_SSL_BUMP_MODE: {
             const Ssl::BumpMode mode = static_cast<Ssl::BumpMode>(al->ssl.bumpMode);
             // for Ssl::bumpEnd, Ssl::bumpMode() returns NULL and we log '-'
             out = Ssl::bumpMode(mode);
         }
         break;
 
         case LFT_EXT_ACL_USER_CERT_RAW:
             if (al->request) {
                 ConnStateData *conn = al->request->clientConnectionManager.get();

=== modified file 'src/format/Token.cc'
--- src/format/Token.cc	2017-01-01 00:12:22 +0000
+++ src/format/Token.cc	2017-01-23 02:24:13 +0000
@@ -160,21 +160,21 @@
     TokenTableEntry("MYPORT", LFT_LOCAL_LISTENING_PORT),
     TokenTableEntry("PATH", LFT_CLIENT_REQ_URLPATH),
     TokenTableEntry("PORT", LFT_CLIENT_REQ_URLPORT),
     TokenTableEntry("PROTO", LFT_CLIENT_REQ_URLSCHEME),
     TokenTableEntry("SRCEUI48", LFT_EXT_ACL_CLIENT_EUI48),
     TokenTableEntry("SRCEUI64", LFT_EXT_ACL_CLIENT_EUI64),
     TokenTableEntry("SRCPORT", LFT_CLIENT_PORT),
     TokenTableEntry("SRC", LFT_CLIENT_IP_ADDRESS), // keep after longer SRC* tokens
     TokenTableEntry("TAG", LFT_TAG),
     TokenTableEntry("URI", LFT_CLIENT_REQ_URI),
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     TokenTableEntry("USER_CERTCHAIN", LFT_EXT_ACL_USER_CERTCHAIN_RAW),
     TokenTableEntry("USER_CERT", LFT_EXT_ACL_USER_CERT_RAW),
 #endif
     TokenTableEntry(NULL, LFT_NONE)        /* this must be last */
 };
 
 #if USE_ADAPTATION
 static TokenTableEntry TokenTableAdapt[] = {
     TokenTableEntry("all_trs", LFT_ADAPTATION_ALL_XACT_TIMES),
     TokenTableEntry("sum_trs", LFT_ADAPTATION_SUM_XACT_TIMES),
@@ -202,21 +202,21 @@
 
     TokenTableEntry("tr",  LFT_ICAP_TR_RESPONSE_TIME),
     TokenTableEntry("tio", LFT_ICAP_IO_TIME),
     TokenTableEntry("to",  LFT_ICAP_OUTCOME),
     TokenTableEntry("Hs",  LFT_ICAP_STATUS_CODE),
 
     TokenTableEntry(NULL, LFT_NONE)           /* this must be last */
 };
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 // SSL (ssl::) tokens
 static TokenTableEntry TokenTableSsl[] = {
     TokenTableEntry("bump_mode", LFT_SSL_BUMP_MODE),
     TokenTableEntry(">cert_subject", LFT_SSL_USER_CERT_SUBJECT),
     TokenTableEntry(">cert_issuer", LFT_SSL_USER_CERT_ISSUER),
     TokenTableEntry(">sni", LFT_SSL_CLIENT_SNI),
     TokenTableEntry("<cert_subject", LFT_SSL_SERVER_CERT_SUBJECT),
     TokenTableEntry("<cert_issuer", LFT_SSL_SERVER_CERT_ISSUER),
     TokenTableEntry("<cert_errors", LFT_SSL_SERVER_CERT_ERRORS),
     TokenTableEntry(">negotiated_version", LFT_TLS_CLIENT_NEGOTIATED_VERSION),
@@ -237,21 +237,21 @@
 Format::Token::Init()
 {
     // TODO standard log tokens
 
 #if USE_ADAPTATION
     TheConfig.registerTokens(String("adapt"),::Format::TokenTableAdapt);
 #endif
 #if ICAP_CLIENT
     TheConfig.registerTokens(String("icap"),::Format::TokenTableIcap);
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     TheConfig.registerTokens(String("ssl"),::Format::TokenTableSsl);
 #endif
 }
 
 /// Scans a token table to see if the next token exists there
 /// returns a pointer to next unparsed byte and updates type member if found
 const char *
 Format::Token::scanForToken(TokenTableEntry const table[], const char *cur)
 {
     for (TokenTableEntry const *lte = table; lte->configTag != NULL; ++lte) {
@@ -605,21 +605,21 @@
         debugs(46, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: The \">v\" formatting code is deprecated. Use the \">rv\" instead.");
         type = LFT_REQUEST_VERSION;
         break;
 
 #if !USE_SQUID_EUI
     case LFT_CLIENT_EUI:
         debugs(46, DBG_CRITICAL, "WARNING: The \">eui\" formatting code requires EUI features which are disabled in this Squid.");
         break;
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     case LFT_TLS_SERVER_NEGOTIATED_VERSION:
     case LFT_TLS_SERVER_RECEIVED_HELLO_VERSION:
     case LFT_TLS_SERVER_SUPPORTED_VERSION:
         Config.onoff.logTlsServerHelloDetails = true;
         break;
 #endif
 
     case LFT_REQUEST_URLGROUP_OLD_2X:
         debugs(46, DBG_PARSE_NOTE(DBG_IMPORTANT), "WARNING: The \"rG\" formatting code is deprecated. Use \"note{urlgroup}\" instead.");
         type = LFT_NOTE;

=== modified file 'src/log/FormatSquidIcap.cc'
--- src/log/FormatSquidIcap.cc	2017-01-01 00:12:22 +0000
+++ src/log/FormatSquidIcap.cc	2017-01-23 00:58:31 +0000
@@ -38,21 +38,21 @@
     }
 
 #if USE_AUTH
     if (al->request != NULL && al->request->auth_user_request != NULL)
         user = ::Format::QuoteUrlEncodeUsername(al->request->auth_user_request->username());
 #endif
 
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.extuser);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.ssluser);
 #endif
 
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
     if (user && !*user)
         safe_free(user);
 

=== modified file 'src/log/FormatSquidNative.cc'
--- src/log/FormatSquidNative.cc	2017-01-01 00:12:22 +0000
+++ src/log/FormatSquidNative.cc	2017-01-23 00:58:31 +0000
@@ -27,21 +27,21 @@
     const char *user = NULL;
 
 #if USE_AUTH
     if (al->request && al->request->auth_user_request != NULL)
         user = ::Format::QuoteUrlEncodeUsername(al->request->auth_user_request->username());
 #endif
 
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.extuser);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.ssluser);
 #endif
 
     if (!user)
         user = ::Format::QuoteUrlEncodeUsername(al->cache.rfc931);
 
     if (user && !*user)
         safe_free(user);
 

=== modified file 'src/main.cc'
--- src/main.cc	2017-01-01 00:12:22 +0000
+++ src/main.cc	2017-01-23 01:18:24 +0000
@@ -91,21 +91,21 @@
 #endif
 #if USE_DELAY_POOLS
 #include "ClientDelayConfig.h"
 #endif
 #if USE_DELAY_POOLS
 #include "DelayPools.h"
 #endif
 #if USE_LOADABLE_MODULES
 #include "LoadableModules.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/context_storage.h"
 #include "ssl/helper.h"
 #endif
 #if ICAP_CLIENT
 #include "adaptation/icap/Config.h"
 #endif
 #if USE_ECAP
 #include "adaptation/ecap/Config.h"
 #endif
 #if USE_ADAPTATION
@@ -854,21 +854,21 @@
 
     // Initiate asynchronous closing sequence
     serverConnectionsClose();
     icpClosePorts();
 #if USE_HTCP
     htcpClosePorts();
 #endif
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Shutdown();
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Ssl::CertValidationHelper::GetInstance())
         Ssl::CertValidationHelper::GetInstance()->Shutdown();
     Ssl::TheGlobalContextStorage.reconfigureStart();
 #endif
     redirectShutdown();
 #if USE_AUTH
     authenticateReset();
 #endif
     externalAclShutdown();
     storeDirCloseSwapLogs();
@@ -949,21 +949,21 @@
 #endif
 
 #if ICAP_CLIENT
     icapLogOpen();
 #endif
     storeLogOpen();
     Dns::Init();
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Init();
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Ssl::CertValidationHelper::GetInstance())
         Ssl::CertValidationHelper::GetInstance()->Init();
 #endif
 
     redirectInit();
 #if USE_AUTH
     authenticateInit(&Auth::TheConfig.schemes);
 #endif
     externalAclInit();
 
@@ -1160,21 +1160,21 @@
     fqdncache_init();
 
     parseEtcHosts();
 
     Dns::Init();
 
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Init();
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Ssl::CertValidationHelper::GetInstance())
         Ssl::CertValidationHelper::GetInstance()->Init();
 #endif
 
     redirectInit();
 #if USE_AUTH
     authenticateInit(&Auth::TheConfig.schemes);
 #endif
     externalAclInit();
 
@@ -2002,21 +2002,21 @@
      */
 
 #if USE_WIN32_SERVICE
     WIN32_svcstatusupdate(SERVICE_STOP_PENDING, 10000);
 #endif
 
     debugs(1, DBG_IMPORTANT, "Shutting down...");
 #if USE_SSL_CRTD
     Ssl::Helper::GetInstance()->Shutdown();
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Ssl::CertValidationHelper::GetInstance())
         Ssl::CertValidationHelper::GetInstance()->Shutdown();
 #endif
     redirectShutdown();
     externalAclShutdown();
     icpClosePorts();
 #if USE_HTCP
     htcpClosePorts();
 #endif
 #if SQUID_SNMP

=== modified file 'src/redirect.cc'
--- src/redirect.cc	2017-01-01 00:12:22 +0000
+++ src/redirect.cc	2017-01-23 00:58:31 +0000
@@ -24,21 +24,21 @@
 #include "HttpRequest.h"
 #include "mgr/Registration.h"
 #include "redirect.h"
 #include "rfc1738.h"
 #include "sbuf/SBuf.h"
 #include "SquidConfig.h"
 #include "Store.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 /// url maximum lengh + extra informations passed to redirector
 #define MAX_REDIRECTOR_REQUEST_STRLEN (MAX_URL + 1024)
 
 class RedirectStateData
 {
     CBDATA_CLASS(RedirectStateData);
 

=== modified file 'src/security/BlindPeerConnector.cc'
--- src/security/BlindPeerConnector.cc	2017-01-01 00:12:22 +0000
+++ src/security/BlindPeerConnector.cc	2017-01-23 02:32:47 +0000
@@ -34,21 +34,21 @@
 {
     if (!Security::PeerConnector::initialize(serverSession))
         return false;
 
     if (const CachePeer *peer = serverConnection()->getPeer()) {
         assert(peer);
 
         // NP: domain may be a raw-IP but it is now always set
         assert(!peer->secure.sslDomain.isEmpty());
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         // const loss is okay here, ssl_ex_index_server is only read and not assigned a destructor
         SBuf *host = new SBuf(peer->secure.sslDomain);
         SSL_set_ex_data(serverSession.get(), ssl_ex_index_server, host);
 
         Security::SetSessionResumeData(serverSession, peer->sslSession);
     } else {
         SBuf *hostName = new SBuf(request->url.host());
         SSL_set_ex_data(serverSession.get(), ssl_ex_index_server, (void*)hostName);
 #endif
     }

=== modified file 'src/security/Context.h'
--- src/security/Context.h	2017-01-01 00:12:22 +0000
+++ src/security/Context.h	2017-01-23 02:32:41 +0000
@@ -5,34 +5,34 @@
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SRC_SECURITY_CONTEXT_H
 #define SQUID_SRC_SECURITY_CONTEXT_H
 
 #include "security/forward.h"
 #include "security/LockingPointer.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #if HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
 
 #elif USE_GNUTLS
 #if HAVE_GNUTLS_GNUTLS_H
 #include <gnutls/gnutls.h>
 #endif
 #endif
 
 namespace Security {
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 CtoCpp1(SSL_CTX_free, SSL_CTX *);
 #if defined(CRYPTO_LOCK_SSL_CTX) // OpenSSL 1.0
 inline int SSL_CTX_up_ref(SSL_CTX *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_SSL_CTX); return 0;}
 #endif
 typedef Security::LockingPointer<SSL_CTX, SSL_CTX_free_cpp, HardFun<int, SSL_CTX *, SSL_CTX_up_ref> > ContextPointer;
 
 #elif USE_GNUTLS
 CtoCpp1(gnutls_certificate_free_credentials, gnutls_certificate_credentials_t);
 typedef Security::LockingPointer<struct gnutls_certificate_credentials_st, gnutls_certificate_free_credentials_cpp> ContextPointer;
 

=== modified file 'src/security/Handshake.cc'
--- src/security/Handshake.cc	2017-01-01 00:12:22 +0000
+++ src/security/Handshake.cc	2017-01-23 02:32:34 +0000
@@ -3,21 +3,21 @@
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 /* DEBUG: section 83    SSL-Bump Server/Peer negotiation */
 
 #include "squid.h"
 #include "security/Handshake.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #include <unordered_set>
 
 namespace Security {
 /*
  * The types below represent various SSL and TLS protocol elements. Most names
  * are based on RFC 5264 and RFC 6066 terminology. Objects of these explicit
  * types are stored or passed around. Other protocol elements are simply parsed
@@ -531,21 +531,21 @@
     catch (const Parser::BinaryTokenizer::InsufficientInput &) {
         debugs(83, 5, "need more data");
         return false;
     }
     return false; // unreached
 }
 
 void
 Security::HandshakeParser::ParseCertificate(const SBuf &raw, Security::CertPointer &pCert)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     auto x509Start = reinterpret_cast<const unsigned char *>(raw.rawContent());
     auto x509Pos = x509Start;
     X509 *x509 = d2i_X509(nullptr, &x509Pos, raw.length());
     pCert.resetWithoutLocking(x509);
     Must(x509); // successfully parsed
     Must(x509Pos == x509Start + raw.length()); // no leftovers
 #endif
 }
 
 void
@@ -563,21 +563,21 @@
         debugs(83, 7, "parsed " << serverCertificates.size() << " certificates so far");
     }
 
 }
 
 /// A helper function to create a set of all supported TLS extensions
 static
 Security::Extensions
 Security::SupportedExtensions()
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
     // optimize lookup speed by reserving the number of values x3, approximately
     Security::Extensions extensions(64);
 
     // Keep this list ordered and up to date by running something like
     // egrep '# *define TLSEXT_TYPE_' /usr/include/openssl/tls1.h
     // TODO: Teach OpenSSL to return the list of extensions it supports.
 #if defined(TLSEXT_TYPE_server_name) // 0
     extensions.insert(TLSEXT_TYPE_server_name);
 #endif

=== modified file 'src/security/LockingPointer.h'
--- src/security/LockingPointer.h	2017-01-01 00:12:22 +0000
+++ src/security/LockingPointer.h	2017-01-23 02:32:23 +0000
@@ -4,34 +4,34 @@
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SRC_SECURITY_LOCKINGPOINTER_H
 #define SQUID_SRC_SECURITY_LOCKINGPOINTER_H
 
 #include "base/HardFun.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #if HAVE_OPENSSL_CRYPTO_H
 #include <openssl/crypto.h>
 #endif
 
 // Macro to be used to define the C++ wrapper function of a sk_*_pop_free
 // openssl family functions. The C++ function suffixed with the _free_wrapper
 // extension
 #define sk_free_wrapper(sk_object, argument, freefunction) \
         extern "C++" inline void sk_object ## _free_wrapper(argument a) { \
             sk_object ## _pop_free(a, freefunction); \
         }
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 // Macro to be used to define the C++ equivalent function of an extern "C"
 // function. The C++ function suffixed with the _cpp extension
 #define CtoCpp1(function, argument) \
         extern "C++" inline void function ## _cpp(argument a) { \
             function(a); \
         }
 
 namespace Security
 {

=== modified file 'src/security/NegotiationHistory.cc'
--- src/security/NegotiationHistory.cc	2017-01-01 00:12:22 +0000
+++ src/security/NegotiationHistory.cc	2017-01-23 02:32:00 +0000
@@ -3,44 +3,44 @@
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "MemBuf.h"
 #include "security/NegotiationHistory.h"
 #include "SquidConfig.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/bio.h"
 #include "ssl/support.h"
 #endif
 
 Security::NegotiationHistory::NegotiationHistory()
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     : cipher(nullptr)
 #endif
 {
 }
 
 const char *
 Security::NegotiationHistory::printTlsVersion(AnyP::ProtocolVersion const &v) const
 {
     if (v.protocol != AnyP::PROTO_SSL && v.protocol != AnyP::PROTO_TLS)
         return nullptr;
 
     static char buf[512];
     snprintf(buf, sizeof(buf), "%s/%d.%d", AnyP::ProtocolType_str[v.protocol], v.major, v.minor);
     return buf;
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 static AnyP::ProtocolVersion
 toProtocolVersion(const int v)
 {
     switch(v) {
 #if defined(TLS1_2_VERSION)
     case TLS1_2_VERSION:
         return AnyP::ProtocolVersion(AnyP::PROTO_TLS, 1, 2);
 #endif
 #if defined(TLS1_1_VERSION)
     case TLS1_1_VERSION:
@@ -60,21 +60,21 @@
 #endif
     default:
         return AnyP::ProtocolVersion();
     }
 }
 #endif
 
 void
 Security::NegotiationHistory::retrieveNegotiatedInfo(const Security::SessionPointer &session)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if ((cipher = SSL_get_current_cipher(session.get()))) {
         // Set the negotiated version only if the cipher negotiated
         // else probably the negotiation is not completed and version
         // is not the final negotiated version
         version_ = toProtocolVersion(SSL_version(session.get()));
     }
 
     if (Debug::Enabled(83, 5)) {
         BIO *b = SSL_get_rbio(session.get());
         Ssl::Bio *bio = static_cast<Ssl::Bio *>(BIO_get_data(b));
@@ -90,20 +90,20 @@
 {
     if (details) {
         helloVersion_ = details->tlsVersion;
         supportedVersion_ = details->tlsSupportedVersion;
     }
 }
 
 const char *
 Security::NegotiationHistory::cipherName() const
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (!cipher)
         return nullptr;
 
     return SSL_CIPHER_get_name(cipher);
 #else
     return nullptr;
 #endif
 }
 

=== modified file 'src/security/NegotiationHistory.h'
--- src/security/NegotiationHistory.h	2017-01-01 00:12:22 +0000
+++ src/security/NegotiationHistory.h	2017-01-23 02:31:34 +0000
@@ -33,19 +33,19 @@
     const char *helloVersion() const {return printTlsVersion(helloVersion_);}
     /// String representation of the maximum supported TLS version
     /// by remote peer
     const char *supportedVersion() const {return printTlsVersion(supportedVersion_);}
 private:
     /// String representation of the TLS version 'v'
     const char *printTlsVersion(AnyP::ProtocolVersion const &v) const;
     AnyP::ProtocolVersion helloVersion_; ///< The TLS version of the hello message
     AnyP::ProtocolVersion supportedVersion_; ///< The maximum supported TLS version
     AnyP::ProtocolVersion version_; ///< The negotiated TLS version
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     const SSL_CIPHER *cipher; ///< The negotiated cipher
 #endif
 };
 
 } // namespace Security
 
 #endif /* SQUID_SRC_SECURITY_NEGOTIATIONHISTORY_H */
 

=== modified file 'src/security/PeerConnector.cc'
--- src/security/PeerConnector.cc	2017-01-01 00:12:22 +0000
+++ src/security/PeerConnector.cc	2017-01-23 02:31:26 +0000
@@ -12,21 +12,21 @@
 #include "acl/FilledChecklist.h"
 #include "comm/Loops.h"
 #include "Downloader.h"
 #include "errorpage.h"
 #include "fde.h"
 #include "http/Stream.h"
 #include "HttpRequest.h"
 #include "security/NegotiationHistory.h"
 #include "security/PeerConnector.h"
 #include "SquidConfig.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/bio.h"
 #include "ssl/cert_validate_message.h"
 #include "ssl/Config.h"
 #include "ssl/helper.h"
 #endif
 
 CBDATA_NAMESPACED_CLASS_INIT(Security, PeerConnector);
 
 Security::PeerConnector::PeerConnector(const Comm::ConnectionPointer &aServerConn, AsyncCall::Pointer &aCallback, const AccessLogEntryPointer &alp, const time_t timeout) :
     AsyncJob("Security::PeerConnector"),
@@ -92,21 +92,21 @@
     // watch for external connection closures
     typedef CommCbMemFunT<Security::PeerConnector, CommCloseCbParams> Dialer;
     closeHandler = JobCallback(9, 5, Dialer, this, Security::PeerConnector::commCloseHandler);
     comm_add_close_handler(fd, closeHandler);
     return true;
 }
 
 bool
 Security::PeerConnector::initialize(Security::SessionPointer &serverSession)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Security::ContextPointer ctx(getTlsContext());
     assert(ctx);
 
     if (!Ssl::CreateClient(ctx, serverConnection(), "server https start")) {
         const auto xerrno = errno;
         const auto ssl_error = ERR_get_error();
         ErrorState *anErr = new ErrorState(ERR_SOCKET_FAILURE, Http::scInternalServerError, request.getRaw());
         anErr->xerrno = xerrno;
         debugs(83, DBG_IMPORTANT, "Error allocating TLS handle: " << Security::ErrorString(ssl_error));
         noteNegotiationDone(anErr);
@@ -152,61 +152,61 @@
 
 void
 Security::PeerConnector::recordNegotiationDetails()
 {
     const int fd = serverConnection()->fd;
     Security::SessionPointer session(fd_table[fd].ssl);
 
     // retrieve TLS server negotiated information if any
     serverConnection()->tlsNegotiations()->retrieveNegotiatedInfo(session);
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // retrieve TLS parsed extra info
     BIO *b = SSL_get_rbio(session.get());
     Ssl::ServerBio *bio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     if (const Security::TlsDetails::Pointer &details = bio->receivedHelloDetails())
         serverConnection()->tlsNegotiations()->retrieveParsedInfo(details);
 #endif
 }
 
 void
 Security::PeerConnector::negotiate()
 {
     if (!Comm::IsConnOpen(serverConnection()))
         return;
 
     const int fd = serverConnection()->fd;
     if (fd_table[fd].closing())
         return;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     const int result = SSL_connect(fd_table[fd].ssl.get());
 #else
     const int result = -1;
 #endif
     if (result <= 0) {
         handleNegotiateError(result);
         return; // we might be gone by now
     }
 
     recordNegotiationDetails();
 
     if (!sslFinalized())
         return;
 
     callBack();
 }
 
 bool
 Security::PeerConnector::sslFinalized()
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (Ssl::TheConfig.ssl_crt_validator && useCertValidator_) {
         const int fd = serverConnection()->fd;
         Security::SessionPointer session(fd_table[fd].ssl);
 
         Ssl::CertValidationRequest validationRequest;
         // WARNING: Currently we do not use any locking for any of the
         // members of the Ssl::CertValidationRequest class. In this code the
         // Ssl::CertValidationRequest object used only to pass data to
         // Ssl::CertValidationHelper::submit method.
         validationRequest.ssl = session.get();
@@ -233,21 +233,21 @@
             serverConn->close();
             return true;
         }
     }
 #endif
 
     noteNegotiationDone(NULL);
     return true;
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 void
 Security::PeerConnector::sslCrtvdHandleReply(Ssl::CertValidationResponse::Pointer validationResponse)
 {
     Must(validationResponse != NULL);
 
     Ssl::ErrorDetail *errDetails = NULL;
     bool validatorFailed = false;
     if (!Comm::IsConnOpen(serverConnection())) {
         return;
     }
@@ -283,21 +283,21 @@
         /*anErr->xerrno= Should preserved*/
     }
 
     noteNegotiationDone(anErr);
     bail(anErr);
     serverConn->close();
     return;
 }
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 /// Checks errors in the cert. validator response against sslproxy_cert_error.
 /// The first honored error, if any, is returned via errDetails parameter.
 /// The method returns all seen errors except SSL_ERROR_NONE as Security::CertErrors.
 Security::CertErrors *
 Security::PeerConnector::sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &resp, Ssl::ErrorDetail *& errDetails)
 {
     ACLFilledChecklist *check = NULL;
     if (acl_access *acl = ::Config.ssl_client.cert_error) {
         check = new ACLFilledChecklist(acl, request.getRaw(), dash_str);
         check->al = al;
@@ -353,21 +353,21 @@
 Security::PeerConnector::NegotiateSsl(int, void *data)
 {
     PeerConnector *pc = static_cast<Security::PeerConnector *>(data);
     // Use job calls to add done() checks and other job logic/protections.
     CallJobHere(83, 7, pc, Security::PeerConnector, negotiate);
 }
 
 void
 Security::PeerConnector::handleNegotiateError(const int ret)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     const int fd = serverConnection()->fd;
     unsigned long ssl_lib_error = SSL_ERROR_NONE;
     Security::SessionPointer session(fd_table[fd].ssl);
     const int ssl_error = SSL_get_error(session.get(), ret);
 
     switch (ssl_error) {
     case SSL_ERROR_WANT_READ:
         noteWantRead();
         return;
 
@@ -388,21 +388,21 @@
     // Log connection details, if any
     recordNegotiationDetails();
     noteNegotiationError(ret, ssl_error, ssl_lib_error);
 #endif
 }
 
 void
 Security::PeerConnector::noteWantRead()
 {
     const int fd = serverConnection()->fd;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Security::SessionPointer session(fd_table[fd].ssl);
     BIO *b = SSL_get_rbio(session.get());
     Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     if (srvBio->holdRead()) {
         if (srvBio->gotHello()) {
             if (checkForMissingCertificates())
                 return; // Wait to download certificates before proceed.
 
             srvBio->holdRead(false);
             // schedule a negotiateSSl to allow openSSL parse received data
@@ -425,21 +425,21 @@
 Security::PeerConnector::noteWantWrite()
 {
     const int fd = serverConnection()->fd;
     Comm::SetSelect(fd, COMM_SELECT_WRITE, &NegotiateSsl, this, 0);
     return;
 }
 
 void
 Security::PeerConnector::noteNegotiationError(const int ret, const int ssl_error, const int ssl_lib_error)
 {
-#if USE_OPENSSL // not used unless OpenSSL enabled.
+#if USE_OPENSSL || USE_LIBRESSL // not used unless OpenSSL or LibreSSL enabled.
 #if defined(EPROTO)
     int sysErrNo = EPROTO;
 #else
     int sysErrNo = EACCES;
 #endif
 
     // store/report errno when ssl_error is SSL_ERROR_SYSCALL, ssl_lib_error is 0, and ret is -1
     if (ssl_error == SSL_ERROR_SYSCALL && ret == -1 && ssl_lib_error == 0)
         sysErrNo = errno;
 
@@ -540,21 +540,21 @@
         buf.appendf("%s",stopReason);
     }
     if (serverConn != NULL)
         buf.appendf(" FD %d", serverConn->fd);
     buf.appendf(" %s%u]", id.prefix(), id.value);
     buf.terminate();
 
     return buf.content();
 }
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 /// CallDialer to allow use Downloader objects within PeerConnector class.
 class PeerConnectorCertDownloaderDialer: public Downloader::CbDialer
 {
 public:
     typedef void (Security::PeerConnector::*Method)(SBuf &object, int status);
 
     PeerConnectorCertDownloaderDialer(Method method, Security::PeerConnector *pc):
         method_(method),
         peerConnector_(pc) {}
 
@@ -641,12 +641,12 @@
         Ssl::missingChainCertificatesUrls(urlsOfMissingCerts, certs);
         if (urlsOfMissingCerts.size()) {
             startCertDownloading(urlsOfMissingCerts.front());
             urlsOfMissingCerts.pop();
             return true;
         }
     }
 
     return false;
 }
-#endif //USE_OPENSSL
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/security/PeerConnector.h'
--- src/security/PeerConnector.h	2017-01-01 00:12:22 +0000
+++ src/security/PeerConnector.h	2017-01-23 02:30:18 +0000
@@ -9,21 +9,21 @@
 #ifndef SQUID_SRC_SECURITY_PEERCONNECTOR_H
 #define SQUID_SRC_SECURITY_PEERCONNECTOR_H
 
 #include "acl/Acl.h"
 #include "base/AsyncCbdataCalls.h"
 #include "base/AsyncJob.h"
 #include "CommCalls.h"
 #include "http/forward.h"
 #include "security/EncryptorAnswer.h"
 #include "security/forward.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #include <iosfwd>
 #include <queue>
 
 class ErrorState;
 class AccessLogEntry;
 typedef RefCount<AccessLogEntry> AccessLogEntryPointer;
 
@@ -119,21 +119,21 @@
     /// be transferred to/from server or on error. In the first case
     /// setups the appropriate Comm::SetSelect handler. In second case
     /// fill an error and report to the PeerConnector caller.
     void handleNegotiateError(const int result);
 
     /// Called when the openSSL SSL_connect fnction request more data from
     /// the remote SSL server. Sets the read timeout and sets the
     /// Squid COMM_SELECT_READ handler.
     void noteWantRead();
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// Run the certificates list sent by the SSL server and check if there
     /// are missing certificates. Adds to the urlOfMissingCerts list the
     /// URLS of missing certificates if this information provided by the
     /// issued certificates with Authority Info Access extension.
     bool checkForMissingCertificates();
 
     /// Start downloading procedure for the given URL.
     void startCertDownloading(SBuf &url);
 
     /// Called by Downloader after a certificate object downloaded.
@@ -176,21 +176,21 @@
     void recordNegotiationDetails();
 
     HttpRequestPointer request; ///< peer connection trigger or cause
     Comm::ConnectionPointer serverConn; ///< TCP connection to the peer
     AccessLogEntryPointer al; ///< info for the future access.log entry
     AsyncCall::Pointer callback; ///< we call this with the results
 private:
     PeerConnector(const PeerConnector &); // not implemented
     PeerConnector &operator =(const PeerConnector &); // not implemented
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     /// Process response from cert validator helper
     void sslCrtvdHandleReply(Ssl::CertValidationResponsePointer);
 
     /// Check SSL errors returned from cert validator against sslproxy_cert_error access list
     Security::CertErrors *sslCrtvdCheckForErrors(Ssl::CertValidationResponse const &, Ssl::ErrorDetail *&);
 #endif
 
     /// A wrapper function for negotiateSsl for use with Comm::SetSelect
     static void NegotiateSsl(int fd, void *data);
 

=== modified file 'src/security/PeerOptions.cc'
--- src/security/PeerOptions.cc	2017-01-01 00:12:22 +0000
+++ src/security/PeerOptions.cc	2017-01-28 05:51:21 +0000
@@ -7,22 +7,21 @@
  */
 
 #include "squid.h"
 #include "base/Packable.h"
 #include "Debug.h"
 #include "fatal.h"
 #include "globals.h"
 #include "parser/Tokenizer.h"
 #include "Parsing.h"
 #include "security/PeerOptions.h"
-
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 Security::PeerOptions Security::ProxyOutgoingConfig;
 
 Security::PeerOptions::PeerOptions(const Security::PeerOptions &p) :
     sslOptions(p.sslOptions),
     caDir(p.caDir),
     crlFile(p.crlFile),
     sslCipher(p.sslCipher),
@@ -71,22 +70,22 @@
         tlsMinVersion = SBuf(token + 12);
     } else if (strncmp(token, "options=", 8) == 0) {
         sslOptions = SBuf(token + 8);
         parsedOptions = parseOptions();
     } else if (strncmp(token, "cipher=", 7) == 0) {
         sslCipher = SBuf(token + 7);
     } else if (strncmp(token, "cafile=", 7) == 0) {
         caFiles.emplace_back(SBuf(token + 7));
     } else if (strncmp(token, "capath=", 7) == 0) {
         caDir = SBuf(token + 7);
-#if !USE_OPENSSL
-        debugs(3, DBG_PARSE_NOTE(1), "WARNING: capath= option requires --with-openssl.");
+#if !USE_OPENSSL && !USE_LIBRESSL
+        debugs(3, DBG_PARSE_NOTE(1), "WARNING: capath= option requires --with-openssl or --with-libressl.");
 #endif
     } else if (strncmp(token, "crlfile=", 8) == 0) {
         crlFile = SBuf(token + 8);
         loadCrlFile();
     } else if (strncmp(token, "flags=", 6) == 0) {
         if (parsedFlags != 0) {
             debugs(3, DBG_PARSE_NOTE(1), "WARNING: Overwriting flags=" << sslFlags << " with " << SBuf(token + 6));
         }
         sslFlags = SBuf(token + 6);
         parsedFlags = parseFlags();
@@ -212,27 +211,27 @@
             sslOptions.append(add, strlen(add));
         }
         sslVersion = 0; // prevent sslOptions being repeatedly appended
     }
 }
 
 Security::ContextPointer
 Security::PeerOptions::createBlankContext() const
 {
     Security::ContextPointer ctx;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::Initialize();
 
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
-    SSL_CTX *t = SSL_CTX_new(TLS_client_method());
-#else
+#if HAVE_LEGACY_OPENSSL_API
     SSL_CTX *t = SSL_CTX_new(SSLv23_client_method());
+#else
+    SSL_CTX *t = SSL_CTX_new(TLS_client_method());
 #endif
     if (!t) {
         const auto x = ERR_get_error();
         fatalf("Failed to allocate TLS client context: %s\n", Security::ErrorString(x));
     }
     ctx.resetWithoutLocking(t);
 
 #elif USE_GNUTLS
     // Initialize for X.509 certificate exchange
     gnutls_certificate_credentials_t t;
@@ -249,21 +248,21 @@
     return ctx;
 }
 
 Security::ContextPointer
 Security::PeerOptions::createClientContext(bool setOptions)
 {
     updateTlsVersionLimits();
 
     Security::ContextPointer t(createBlankContext());
     if (t) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         // XXX: temporary performance regression. c_str() data copies and prevents this being a const method
         Ssl::InitClientContext(t, *this, (setOptions ? parsedOptions : 0), parsedFlags);
 #endif
         updateContextNpn(t);
         updateContextCa(t);
         updateContextCrl(t);
     }
 
     return t;
 }
@@ -523,21 +522,21 @@
 
 /// Load a CRLs list stored in the file whose /path/name is in crlFile
 /// replaces any CRL loaded previously
 void
 Security::PeerOptions::loadCrlFile()
 {
     parsedCrl.clear();
     if (crlFile.isEmpty())
         return;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     BIO *in = BIO_new_file(crlFile.c_str(), "r");
     if (!in) {
         debugs(83, 2, "WARNING: Failed to open CRL file " << crlFile);
         return;
     }
 
     while (X509_CRL *crl = PEM_read_bio_X509_CRL(in,NULL,NULL,NULL)) {
         parsedCrl.emplace_back(Security::CrlPointer(crl));
     }
     BIO_free(in);
@@ -565,42 +564,42 @@
     SSL_CTX_set_next_proto_select_cb(ctx.get(), &ssl_next_proto_cb, nullptr);
 #endif
 
     // NOTE: GnuTLS does not support the obsolete NPN extension.
     //       it does support ALPN per-session, not per-context.
 }
 
 static const char *
 loadSystemTrustedCa(Security::ContextPointer &ctx)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (SSL_CTX_set_default_verify_paths(ctx.get()) == 0)
         return Security::ErrorString(ERR_get_error());
 
 #elif USE_GNUTLS
     auto x = gnutls_certificate_set_x509_system_trust(ctx.get());
     if (x < 0)
         return Security::ErrorString(x);
 
 #endif
     return nullptr;
 }
 
 void
 Security::PeerOptions::updateContextCa(Security::ContextPointer &ctx)
 {
     debugs(83, 8, "Setting CA certificate locations.");
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     const char *path = caDir.isEmpty() ? nullptr : caDir.c_str();
 #endif
     for (auto i : caFiles) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (!SSL_CTX_load_verify_locations(ctx.get(), i.c_str(), path)) {
             const auto x = ERR_get_error();
             debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
                    i << ": " << Security::ErrorString(x));
         }
 #elif USE_GNUTLS
         const auto x = gnutls_certificate_set_x509_trust_file(ctx.get(), i.c_str(), GNUTLS_X509_FMT_PEM);
         if (x < 0) {
             debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting CA certificate location " <<
                    i << ": " << Security::ErrorString(x));
@@ -612,39 +611,39 @@
         return;
 
     if (const char *err = loadSystemTrustedCa(ctx)) {
         debugs(83, DBG_IMPORTANT, "WARNING: Ignoring error setting default trusted CA : " << err);
     }
 }
 
 void
 Security::PeerOptions::updateContextCrl(Security::ContextPointer &ctx)
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     bool verifyCrl = false;
     X509_STORE *st = SSL_CTX_get_cert_store(ctx.get());
     if (parsedCrl.size()) {
         for (auto &i : parsedCrl) {
             if (!X509_STORE_add_crl(st, i.get()))
                 debugs(83, 2, "WARNING: Failed to add CRL");
             else
                 verifyCrl = true;
         }
     }
 
 #if X509_V_FLAG_CRL_CHECK
     if ((parsedFlags & SSL_FLAG_VERIFY_CRL_ALL))
         X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
     else if (verifyCrl || (parsedFlags & SSL_FLAG_VERIFY_CRL))
         X509_STORE_set_flags(st, X509_V_FLAG_CRL_CHECK);
 #endif
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 }
 
 void
 parse_securePeerOptions(Security::PeerOptions *opt)
 {
     while(const char *token = ConfigParser::NextToken())
         opt->parse(token);
 }
 

=== modified file 'src/security/ServerOptions.cc'
--- src/security/ServerOptions.cc	2017-01-01 00:12:22 +0000
+++ src/security/ServerOptions.cc	2017-01-28 07:34:05 +0000
@@ -3,21 +3,21 @@
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 #include "base/Packable.h"
 #include "globals.h"
 #include "security/ServerOptions.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 #if HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
 #endif
 #if HAVE_OPENSSL_X509_H
 #include <openssl/x509.h>
 #endif
 
@@ -82,27 +82,27 @@
 
     // dump the server-only options
     if (!dh.isEmpty())
         p->appendf(" %sdh=" SQUIDSBUFPH, pfx, SQUIDSBUFPRINT(dh));
 }
 
 Security::ContextPointer
 Security::ServerOptions::createBlankContext() const
 {
     Security::ContextPointer ctx;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     Ssl::Initialize();
 
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
-    SSL_CTX *t = SSL_CTX_new(TLS_server_method());
-#else
+#if HAVE_LEGACY_OPENSSL_API
     SSL_CTX *t = SSL_CTX_new(SSLv23_server_method());
+#else
+    SSL_CTX *t = SSL_CTX_new(TLS_server_method());
 #endif
     if (!t) {
         const auto x = ERR_get_error();
         debugs(83, DBG_CRITICAL, "ERROR: Failed to allocate TLS server context: " << Security::ErrorString(x));
     }
     ctx.resetWithoutLocking(t);
 
 #elif USE_GNUTLS
     // Initialize for X.509 certificate exchange
     gnutls_certificate_credentials_t t;
@@ -119,37 +119,37 @@
     return ctx;
 }
 
 bool
 Security::ServerOptions::createStaticServerContext(AnyP::PortCfg &port)
 {
     updateTlsVersionLimits();
 
     Security::ContextPointer t(createBlankContext());
     if (t) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (!Ssl::InitServerContext(t, port))
             return false;
 #endif
     }
 
     staticContext = std::move(t);
     return bool(staticContext);
 }
 
 void
 Security::ServerOptions::loadDhParams()
 {
     if (dhParamsFile.isEmpty())
         return;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     DH *dhp = nullptr;
     if (FILE *in = fopen(dhParamsFile.c_str(), "r")) {
         dhp = PEM_read_DHparams(in, NULL, NULL, NULL);
         fclose(in);
     }
 
     if (!dhp) {
         debugs(83, DBG_IMPORTANT, "WARNING: Failed to read DH parameters '" << dhParamsFile << "'");
         return;
     }
@@ -167,21 +167,28 @@
 #endif
 }
 
 void
 Security::ServerOptions::updateContextEecdh(Security::ContextPointer &ctx)
 {
     // set Elliptic Curve details into the server context
     if (!eecdhCurve.isEmpty()) {
         debugs(83, 9, "Setting Ephemeral ECDH curve to " << eecdhCurve << ".");
 
-#if USE_OPENSSL && OPENSSL_VERSION_NUMBER >= 0x0090800fL && !defined(OPENSSL_NO_ECDH)
+#if USE_OPENSSL && OPENSSL_VERSION_NUMBER < 0x0090800fL
+        debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in " << OPENSSL_VERSION_TEXT);
+
+#elif defined(OPENSSL_NO_ECDH)
+        debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in this build." <<
+               " Please ensure OPENSSL_NO_ECDH is not set.");
+
+#elif USE_OPENSSL || USE_LIBRESSL
         int nid = OBJ_sn2nid(eecdhCurve.c_str());
         if (!nid) {
             debugs(83, DBG_CRITICAL, "ERROR: Unknown EECDH curve '" << eecdhCurve << "'");
             return;
         }
 
         auto ecdh = EC_KEY_new_by_curve_name(nid);
         if (!ecdh) {
             const auto x = ERR_get_error();
             debugs(83, DBG_CRITICAL, "ERROR: Unable to configure Ephemeral ECDH: " << Security::ErrorString(x));
@@ -189,22 +196,22 @@
         }
 
         if (!SSL_CTX_set_tmp_ecdh(ctx.get(), ecdh)) {
             const auto x = ERR_get_error();
             debugs(83, DBG_CRITICAL, "ERROR: Unable to set Ephemeral ECDH: " << Security::ErrorString(x));
         }
         EC_KEY_free(ecdh);
 
 #else
         debugs(83, DBG_CRITICAL, "ERROR: EECDH is not available in this build." <<
-               " Please link against OpenSSL>=0.9.8 and ensure OPENSSL_NO_ECDH is not set.");
+               " Please link against LibreSSL or OpenSSL >= 0.9.8 and ensure OPENSSL_NO_ECDH is not set.");
 #endif
     }
 
     // set DH parameters into the server context
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     if (parsedDhParams) {
         SSL_CTX_set_tmp_dh(ctx.get(), parsedDhParams.get());
     }
 #endif
 }
 

=== modified file 'src/security/Session.cc'
--- src/security/Session.cc	2017-01-01 00:12:22 +0000
+++ src/security/Session.cc	2017-01-23 02:26:58 +0000
@@ -16,55 +16,55 @@
 #include "security/Session.h"
 #include "SquidConfig.h"
 
 #define SSL_SESSION_ID_SIZE 32
 #define SSL_SESSION_MAX_SIZE 10*1024
 
 bool
 Security::SessionIsResumed(const Security::SessionPointer &s)
 {
     bool result = false;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     result = SSL_session_reused(s.get()) == 1;
 #elif USE_GNUTLS
     result = gnutls_session_is_resumed(s.get()) != 0;
 #endif
     debugs(83, 7, "session=" << (void*)s.get() << ", query? answer: " << (result ? 'T' : 'F') );
     return result;
 }
 
 void
 Security::MaybeGetSessionResumeData(const Security::SessionPointer &s, Security::SessionStatePointer &data)
 {
     if (!SessionIsResumed(s)) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         // nil is valid for SSL_get1_session(), it cannot fail.
         data.reset(SSL_get1_session(s.get()));
 #elif USE_GNUTLS
         gnutls_datum_t *tmp = nullptr;
         const auto x = gnutls_session_get_data2(s.get(), tmp);
         if (x != GNUTLS_E_SUCCESS) {
             debugs(83, 3, "session=" << (void*)s.get() << " error: " << Security::ErrorString(x));
         }
         data.reset(tmp);
 #endif
         debugs(83, 5, "session=" << (void*)s.get() << " data=" << (void*)data.get());
     } else {
         debugs(83, 5, "session=" << (void*)s.get() << " data=" << (void*)data.get() << ", do nothing.");
     }
 }
 
 void
 Security::SetSessionResumeData(const Security::SessionPointer &s, const Security::SessionStatePointer &data)
 {
     if (data) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (!SSL_set_session(s.get(), data.get())) {
             const auto ssl_error = ERR_get_error();
             debugs(83, 3, "session=" << (void*)s.get() << " data=" << (void*)data.get() <<
                    " resume error: " << Security::ErrorString(ssl_error));
         }
 #elif USE_GNUTLS
         const auto x = gnutls_session_set_data(s.get(), data->data, data->size);
         if (x != GNUTLS_E_SUCCESS) {
             debugs(83, 3, "session=" << (void*)s.get() << " data=" << (void*)data.get() <<
                    " resume error: " << Security::ErrorString(x));
@@ -88,21 +88,21 @@
         if (s->flags.tunnelSslBumping)
             return true;
     }
 
     return false;
 }
 
 void
 initializeSessionCache()
 {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // Check if the MemMap keys and data are enough big to hold
     // session ids and session data
     assert(SSL_SESSION_ID_SIZE >= MEMMAP_SLOT_KEY_SIZE);
     assert(SSL_SESSION_MAX_SIZE >= MEMMAP_SLOT_DATA_SIZE);
 
     int configuredItems = ::Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot);
     if (IamWorkerProcess() && configuredItems)
         Ssl::SessionCache = new Ipc::MemMap(Ssl::SessionCacheName);
     else {
         Ssl::SessionCache = nullptr;
@@ -130,36 +130,36 @@
 
 private:
     Ipc::MemMap::Owner *owner;
 };
 
 RunnerRegistrationEntry(SharedSessionCacheRr);
 
 void
 SharedSessionCacheRr::useConfig()
 {
-#if USE_OPENSSL // while Ssl:: bits in use
+#if USE_OPENSSL || USE_LIBRESSL // while Ssl:: bits in use
     if (Ssl::SessionCache || !isTlsServer()) //no need to configure ssl session cache.
         return;
 
     Ipc::Mem::RegisteredRunner::useConfig();
     initializeSessionCache();
 #endif
 }
 
 void
 SharedSessionCacheRr::create()
 {
     if (!isTlsServer()) //no need to configure ssl session cache.
         return;
 
-#if USE_OPENSSL // while Ssl:: bits in use
+#if USE_OPENSSL || USE_LIBRESSL // while Ssl:: bits in use
     if (int items = Config.SSL.sessionCacheSize / sizeof(Ipc::MemMap::Slot))
         owner = Ipc::MemMap::Init(Ssl::SessionCacheName, items);
 #endif
 }
 
 SharedSessionCacheRr::~SharedSessionCacheRr()
 {
     // XXX: Enable after testing to reduce at-exit memory "leaks".
     // delete Ssl::SessionCache;
 

=== modified file 'src/security/Session.h'
--- src/security/Session.h	2017-01-01 00:12:22 +0000
+++ src/security/Session.h	2017-01-23 02:26:10 +0000
@@ -6,35 +6,35 @@
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SRC_SECURITY_SESSION_H
 #define SQUID_SRC_SECURITY_SESSION_H
 
 #include "security/LockingPointer.h"
 
 #include <memory>
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #if HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
 #endif
 
 #if USE_GNUTLS
 #if HAVE_GNUTLS_GNUTLS_H
 #include <gnutls/gnutls.h>
 #endif
 #endif
 
 namespace Security {
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 CtoCpp1(SSL_free, SSL *);
 #if defined(CRYPTO_LOCK_SSL) // OpenSSL 1.0
 inline int SSL_up_ref(SSL *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_SSL); return 0;}
 #endif
 typedef Security::LockingPointer<SSL, Security::SSL_free_cpp, HardFun<int, SSL *, SSL_up_ref> > SessionPointer;
 
 typedef std::unique_ptr<SSL_SESSION, HardFun<void, SSL_SESSION*, &SSL_SESSION_free>> SessionStatePointer;
 
 #elif USE_GNUTLS
 // Locks can be implemented attaching locks counter to gnutls_session_t

=== modified file 'src/security/forward.h'
--- src/security/forward.h	2017-01-01 00:12:22 +0000
+++ src/security/forward.h	2017-01-23 02:26:02 +0000
@@ -10,99 +10,99 @@
 #define SQUID_SRC_SECURITY_FORWARD_H
 
 #include "base/CbDataList.h"
 #include "security/Context.h"
 #include "security/Session.h"
 
 #if USE_GNUTLS && HAVE_GNUTLS_X509_H
 #include <gnutls/x509.h>
 #endif
 #include <list>
-#if USE_OPENSSL && HAVE_OPENSSL_ERR_H
+#if (USE_OPENSSL || USE_LIBRESSL) && HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
 #endif
 #include <unordered_set>
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 // Macro to be used to define the C++ wrapper functor of the sk_*_pop_free
 // OpenSSL family of functions. The C++ functor is suffixed with the _free_wrapper
 // extension
 #define sk_dtor_wrapper(sk_object, argument_type, freefunction) \
         struct sk_object ## _free_wrapper { \
             void operator()(argument_type a) { sk_object ## _pop_free(a, freefunction); } \
         }
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 
 /* flags a SSL connection can be configured with */
 #define SSL_FLAG_NO_DEFAULT_CA      (1<<0)
 #define SSL_FLAG_DELAYED_AUTH       (1<<1)
 #define SSL_FLAG_DONT_VERIFY_PEER   (1<<2)
 #define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
 #define SSL_FLAG_NO_SESSION_REUSE   (1<<4)
 #define SSL_FLAG_VERIFY_CRL         (1<<5)
 #define SSL_FLAG_VERIFY_CRL_ALL     (1<<6)
 
 /// Network/connection security abstraction layer
 namespace Security
 {
 
 class CertError;
 /// Holds a list of X.509 certificate errors
 typedef CbDataList<Security::CertError> CertErrors;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 CtoCpp1(X509_free, X509 *)
 #if defined(CRYPTO_LOCK_X509) // OpenSSL 1.0
 inline int X509_up_ref(X509 *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509); return 0;}
 #endif
 typedef Security::LockingPointer<X509, X509_free_cpp, HardFun<int, X509 *, X509_up_ref> > CertPointer;
 #elif USE_GNUTLS
 CtoCpp1(gnutls_x509_crt_deinit, gnutls_x509_crt_t)
 typedef Security::LockingPointer<struct gnutls_x509_crt_int, gnutls_x509_crt_deinit> CertPointer;
 #else
 typedef void * CertPointer;
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 CtoCpp1(X509_CRL_free, X509_CRL *)
 #if defined(CRYPTO_LOCK_X509_CRL) // OpenSSL 1.0
 inline int X509_CRL_up_ref(X509_CRL *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509_CRL); return 0;}
 #endif
 typedef Security::LockingPointer<X509_CRL, X509_CRL_free_cpp, HardFun<int, X509_CRL *, X509_CRL_up_ref> > CrlPointer;
 #elif USE_GNUTLS
 CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t)
 typedef Security::LockingPointer<struct gnutls_x509_crl_int, gnutls_x509_crl_deinit> CrlPointer;
 #else
 typedef void *CrlPointer;
 #endif
 
 typedef std::list<Security::CertPointer> CertList;
 
 typedef std::list<Security::CrlPointer> CertRevokeList;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 CtoCpp1(DH_free, DH *);
 #if defined(CRYPTO_LOCK_DH) // OpenSSL 1.0
 inline int DH_up_ref(DH *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_DH); return 0;}
 #endif
 typedef Security::LockingPointer<DH, DH_free_cpp, HardFun<int, DH *, DH_up_ref> > DhePointer;
 #else
 typedef void *DhePointer;
 #endif
 
 class EncryptorAnswer;
 
 /// Squid defined error code (<0), an error code returned by X.509 API, or SSL_ERROR_NONE
 typedef int ErrorCode;
 
 inline const char *ErrorString(const ErrorCode code) {
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     return ERR_error_string(code, nullptr);
 #elif USE_GNUTLS
     return gnutls_strerror(code);
 #else
     return "[no TLS library]";
 #endif
 }
 
 /// set of Squid defined TLS error codes
 /// \note using std::unordered_set ensures values are unique, with fast lookup

=== modified file 'src/servers/Http1Server.cc'
--- src/servers/Http1Server.cc	2017-01-01 00:12:22 +0000
+++ src/servers/Http1Server.cc	2017-01-23 00:58:31 +0000
@@ -35,21 +35,21 @@
 Http::One::Server::idleTimeout() const
 {
     return Config.Timeout.clientIdlePconn;
 }
 
 void
 Http::One::Server::start()
 {
     ConnStateData::start();
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
     // XXX: Until we create an HttpsServer class, use this hack to allow old
     // client_side.cc code to manipulate ConnStateData object directly
     if (isHttpsServer) {
         postHttpsAccept();
         return;
     }
 #endif
 
     typedef CommCbMemFunT<Server, CommTimeoutCbParams> TimeoutDialer;
     AsyncCall::Pointer timeoutCall =  JobCallback(33, 5,

=== modified file 'src/ssl/PeekingPeerConnector.h'
--- src/ssl/PeekingPeerConnector.h	2017-01-01 00:12:22 +0000
+++ src/ssl/PeekingPeerConnector.h	2017-01-23 02:15:27 +0000
@@ -4,21 +4,21 @@
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SRC_SSL_PEEKINGPEERCONNECTOR_H
 #define SQUID_SRC_SSL_PEEKINGPEERCONNECTOR_H
 
 #include "security/PeerConnector.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 namespace Ssl
 {
 
 /// A PeerConnector for HTTP origin servers. Capable of SslBumping.
 class PeekingPeerConnector: public Security::PeerConnector {
     CBDATA_CLASS(PeekingPeerConnector);
 public:
     PeekingPeerConnector(HttpRequestPointer &aRequest,
                          const Comm::ConnectionPointer &aServerConn,
@@ -74,13 +74,13 @@
 
     Comm::ConnectionPointer clientConn; ///< TCP connection to the client
     AsyncCall::Pointer closeHandler; ///< we call this when the connection closed
     bool splice; ///< whether we are going to splice or not
     bool resumingSession; ///< whether it is an SSL resuming session connection
     bool serverCertificateHandled; ///< whether handleServerCertificate() succeeded
 };
 
 } // namespace Ssl
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 #endif /* SQUID_SRC_SSL_PEEKINGPEERCONNECTOR_H */
 

=== modified file 'src/ssl/ProxyCerts.h'
--- src/ssl/ProxyCerts.h	2017-01-01 00:12:22 +0000
+++ src/ssl/ProxyCerts.h	2017-01-23 00:58:31 +0000
@@ -2,21 +2,21 @@
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SSLPROXYCERTS_H_
 #define SQUID_SSLPROXYCERTS_H_
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "acl/forward.h"
 
 class sslproxy_cert_sign
 {
 public:
     int alg;
     ACLList *aclList;
     sslproxy_cert_sign *next;
 };
 

=== modified file 'src/ssl/bio.cc'
--- src/ssl/bio.cc	2017-01-26 16:22:30 +0000
+++ src/ssl/bio.cc	2017-01-29 04:25:08 +0000
@@ -5,21 +5,21 @@
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 /* DEBUG: section 83    SSL accelerator support */
 
 #include "squid.h"
 #include "ssl/support.h"
 
 /* support.cc says this is needed */
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "comm.h"
 #include "fd.h"
 #include "fde.h"
 #include "globals.h"
 #include "ip/Address.h"
 #include "parser/BinaryTokenizer.h"
 #include "SquidTime.h"
 #include "ssl/bio.h"
 
@@ -36,21 +36,21 @@
 static int squid_bio_write(BIO *h, const char *buf, int num);
 static int squid_bio_read(BIO *h, char *buf, int size);
 static int squid_bio_puts(BIO *h, const char *str);
 //static int squid_bio_gets(BIO *h, char *str, int size);
 static long squid_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int squid_bio_create(BIO *h);
 static int squid_bio_destroy(BIO *data);
 /* SSL callbacks */
 static void squid_ssl_info(const SSL *ssl, int where, int ret);
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
 /// Initialization structure for the BIO table with
 /// Squid-specific methods and BIO method wrappers.
 static BIO_METHOD SquidMethods = {
     BIO_TYPE_SOCKET,
     "squid",
     squid_bio_write,
     squid_bio_read,
     squid_bio_puts,
     NULL, // squid_bio_gets not supported
     squid_bio_ctrl,
@@ -58,21 +58,21 @@
     squid_bio_destroy,
     NULL // squid_callback_ctrl not supported
 };
 #else
 static BIO_METHOD *SquidMethods = NULL;
 #endif
 
 BIO *
 Ssl::Bio::Create(const int fd, Ssl::Bio::Type type)
 {
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     BIO_METHOD *useMethod = &SquidMethods;
 #else
     if (!SquidMethods) {
         SquidMethods = BIO_meth_new(BIO_TYPE_SOCKET, "squid");
         BIO_meth_set_write(SquidMethods, squid_bio_write);
         BIO_meth_set_read(SquidMethods, squid_bio_read);
         BIO_meth_set_puts(SquidMethods, squid_bio_puts);
         BIO_meth_set_gets(SquidMethods, NULL);
         BIO_meth_set_ctrl(SquidMethods, squid_bio_ctrl);
         BIO_meth_set_create(SquidMethods, squid_bio_create);
@@ -555,21 +555,21 @@
 bool
 Ssl::ServerBio::resumingSession()
 {
     return parser_.resumingSession;
 }
 
 /// initializes BIO table after allocation
 static int
 squid_bio_create(BIO *bi)
 {
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     bi->init = 0; // set when we store Bio object and socket fd (BIO_C_SET_FD)
     bi->num = 0;
     bi->flags = 0;
 #else
     // No need to set more, openSSL initialize BIO memory to zero.
 #endif
 
     BIO_set_data(bi, NULL);
     return 1;
 }
@@ -699,21 +699,21 @@
     }
 #endif
 
     if (!details->ciphers.empty()) {
         SBuf strCiphers;
         for (auto cipherId: details->ciphers) {
             unsigned char cbytes[3];
             cbytes[0] = (cipherId >> 8) & 0xFF;
             cbytes[1] = cipherId & 0xFF;
             cbytes[2] = 0;
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
             const SSL_METHOD *method = SSLv23_method();
             const SSL_CIPHER *c = method->get_cipher_by_char(cbytes);
 #else
             const SSL_CIPHER *c = SSL_CIPHER_find(ssl, cbytes);
 #endif
             if (c != NULL) {
                 if (!strCiphers.isEmpty())
                     strCiphers.append(":");
                 strCiphers.append(SSL_CIPHER_get_name(c));
             }
@@ -737,12 +737,12 @@
         if (bumpMode == Ssl::bumpPeek)
             SSL_set_alpn_protos(ssl, (const unsigned char*)details->tlsAppLayerProtoNeg.rawContent(), details->tlsAppLayerProtoNeg.length());
         else {
             static const unsigned char supported_protos[] = {8, 'h','t','t', 'p', '/', '1', '.', '1'};
             SSL_set_alpn_protos(ssl, supported_protos, sizeof(supported_protos));
         }
     }
 #endif
 }
 
-#endif // USE_OPENSSL
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/ssl/bio.h'
--- src/ssl/bio.h	2017-01-26 16:22:30 +0000
+++ src/ssl/bio.h	2017-01-29 04:25:08 +0000
@@ -198,20 +198,20 @@
     /// The size of data stored in rbuf which passed to the openSSL
     size_t rbufConsumePos;
     Security::HandshakeParser parser_; ///< The TLS/SSL messages parser.
 };
 
 } // namespace Ssl
 
 void
 applyTlsDetailsToSSL(SSL *ssl, Security::TlsDetails::Pointer const &details, Ssl::BumpMode bumpMode);
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
 // OpenSSL v1.0 bio compatibility functions
 inline void *BIO_get_data(BIO *table) { return table->ptr; }
 inline void BIO_set_data(BIO *table, void *data) { table->ptr = data; }
 inline int BIO_get_init(BIO *table) { return table->init; }
 inline void BIO_set_init(BIO *table, int init) { table->init = init; }
 #endif
 
 #endif /* SQUID_SSL_BIO_H */
 

=== modified file 'src/ssl/context_storage.h'
--- src/ssl/context_storage.h	2017-01-01 00:12:22 +0000
+++ src/ssl/context_storage.h	2017-01-23 00:58:31 +0000
@@ -2,21 +2,21 @@
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SSL_CONTEXT_STORAGE_H
 #define SQUID_SSL_CONTEXT_STORAGE_H
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "base/LruMap.h"
 #include "CacheManager.h"
 #include "ip/Address.h"
 #include "mgr/Action.h"
 #include "mgr/Command.h"
 #include "security/forward.h"
 #include "SquidTime.h"
 #include "ssl/gadgets.h"
 
@@ -69,14 +69,14 @@
     bool reconfiguring; ///< True if system reconfiguring now.
     /// Storage used on configure or reconfigure.
     std::map<Ip::Address, size_t> configureStorage;
     /// Map for storing all local ip address and their local storages.
     std::map<Ip::Address, LocalContextStorage *> storage;
 };
 
 /// Global cache for store all SSL server certificates.
 extern GlobalContextStorage TheGlobalContextStorage;
 } //namespace Ssl
-#endif // USE_OPENSSL
+#endif // USE_OPENSSL || USE_LIBRESSL
 
 #endif // SQUID_SSL_CONTEXT_STORAGE_H
 

=== modified file 'src/ssl/gadgets.cc'
--- src/ssl/gadgets.cc	2017-01-01 00:12:22 +0000
+++ src/ssl/gadgets.cc	2017-01-28 05:50:58 +0000
@@ -380,21 +380,21 @@
         NonRepudiation,
         KeyEncipherment, // NSS requires for RSA but not EC
         DataEncipherment,
         KeyAgreement,
         KeyCertificateSign,
         CRLSign,
         EncipherOnly,
         DecipherOnly
     };
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     const int mimicAlgo = OBJ_obj2nid(mimicCert.get()->cert_info->key->algor->algorithm);
     const bool rsaPkey = (mimicAlgo == NID_rsaEncryption);
 #else
     EVP_PKEY *certKey = X509_get_pubkey(mimicCert.get());
     const bool rsaPkey = (EVP_PKEY_get0_RSA(certKey) != NULL);
 #endif
 
     int added = 0;
     int nid;
     for (int i = 0; (nid = extensions[i]) != 0; ++i) {

=== modified file 'src/ssl/helper.h'
--- src/ssl/helper.h	2017-01-01 00:12:22 +0000
+++ src/ssl/helper.h	2017-01-23 02:16:57 +0000
@@ -2,21 +2,21 @@
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #ifndef SQUID_SSL_HELPER_H
 #define SQUID_SSL_HELPER_H
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "base/AsyncJobCalls.h"
 #include "base/LruMap.h"
 #include "helper/forward.h"
 #include "security/forward.h"
 #include "ssl/cert_validate_message.h"
 #include "ssl/crtd_message.h"
 
 namespace Ssl
 {
@@ -60,13 +60,13 @@
     ~CertValidationHelper();
 
     helper * ssl_crt_validator; ///< helper for management of ssl_crtd.
 public:
     typedef LruMap<Ssl::CertValidationResponse::Pointer, sizeof(Ssl::CertValidationResponse::Pointer) + sizeof(Ssl::CertValidationResponse)> LruCache;
     static LruCache *HelperCache; ///< cache for cert validation helper
 };
 
 } //namespace Ssl
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 #endif // SQUID_SSL_HELPER_H
 

=== modified file 'src/ssl/support.cc'
--- src/ssl/support.cc	2017-01-24 12:09:25 +0000
+++ src/ssl/support.cc	2017-01-29 04:27:09 +0000
@@ -6,21 +6,21 @@
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 /* DEBUG: section 83    SSL accelerator support */
 
 #include "squid.h"
 
 /* MS Visual Studio Projects are monolithic, so we need the following
  * #if to exclude the SSL code from compile process when not needed.
  */
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "acl/FilledChecklist.h"
 #include "anyp/PortCfg.h"
 #include "fatal.h"
 #include "fd.h"
 #include "fde.h"
 #include "globals.h"
 #include "ipc/MemMap.h"
 #include "security/CertError.h"
 #include "SquidConfig.h"
@@ -89,21 +89,21 @@
 /// \ingroup ServerProtocolSSLInternal
 static void
 ssl_ask_password(SSL_CTX * context, const char * prompt)
 {
     if (Config.Program.ssl_password) {
         SSL_CTX_set_default_passwd_cb(context, ssl_ask_password_cb);
         SSL_CTX_set_default_passwd_cb_userdata(context, (void *)prompt);
     }
 }
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
 static RSA *
 ssl_temp_rsa_cb(SSL * ssl, int anInt, int keylen)
 {
     static RSA *rsa_512 = NULL;
     static RSA *rsa_1024 = NULL;
     RSA *rsa = NULL;
     int newkey = 0;
 
     switch (keylen) {
 
@@ -144,21 +144,21 @@
         debugs(83, DBG_IMPORTANT, "Generated ephemeral RSA key of length " << keylen);
     }
 
     return rsa;
 }
 #endif
 
 static void
 maybeSetupRsaCallback(Security::ContextPointer &ctx)
 {
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     debugs(83, 9, "Setting RSA key generation callback.");
     SSL_CTX_set_tmp_rsa_callback(ctx.get(), ssl_temp_rsa_cb);
 #endif
 }
 
 int Ssl::asn1timeToString(ASN1_TIME *tm, char *buf, int len)
 {
     BIO *bio;
     int write = 0;
     bio = BIO_new(BIO_s_mem());
@@ -228,21 +228,21 @@
     cn[cn_data->length] = '\0';
     debugs(83, 4, "Verifying server domain " << server << " to certificate name/subjectAltName " << cn);
     return matchDomainName(server, (cn[0] == '*' ? cn + 1 : cn), mdnRejectSubsubDomains);
 }
 
 bool Ssl::checkX509ServerValidity(X509 *cert, const char *server)
 {
     return matchX509CommonNames(cert, (void *)server, check_domain);
 }
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
 static inline X509 *X509_STORE_CTX_get0_cert(X509_STORE_CTX *ctx)
 {
     return ctx->cert;
 }
 #endif
 
 /// \ingroup ServerProtocolSSLInternal
 static int
 ssl_verify_cb(int ok, X509_STORE_CTX * ctx)
 {
@@ -372,28 +372,25 @@
         if (!SSL_set_ex_data(ssl, ssl_ex_index_ssl_error_detail, errDetail)) {
             debugs(83, 2, "Failed to set Ssl::ErrorDetail in ssl_verify_cb: Certificate " << buffer);
             delete errDetail;
         }
     }
 
     return ok;
 }
 
 // "dup" function for SSL_get_ex_new_index("cert_err_check")
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
 static int
-ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *,
-                    int, long, void *)
+#if HAVE_LEGACY_OPENSSL_API
+ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *, int, long, void *)
 #else
-static int
-ssl_dupAclChecklist(CRYPTO_EX_DATA *, CRYPTO_EX_DATA *, void *,
-                    int, long, void *)
+ssl_dupAclChecklist(CRYPTO_EX_DATA *, const CRYPTO_EX_DATA *, void *, int, long, void *)
 #endif
 {
     // We do not support duplication of ACLCheckLists.
     // If duplication is needed, we can count copies with cbdata.
     assert(false);
     return 0;
 }
 
 // "free" function for SSL_get_ex_new_index("cert_err_check")
 static void
@@ -1109,21 +1106,21 @@
 
     static char uri[MAX_URL];
     uri[0] = '\0';
 
     for (int i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) {
         ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i);
         if (OBJ_obj2nid(ad->method) == NID_ad_ca_issuers) {
             if (ad->location->type == GEN_URI) {
                 xstrncpy(uri,
                          reinterpret_cast<const char *>(
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
                              ASN1_STRING_data(ad->location->d.uniformResourceIdentifier)
 #else
                              ASN1_STRING_get0_data(ad->location->d.uniformResourceIdentifier)
 #endif
                          ),
                          sizeof(uri));
             }
             break;
         }
     }
@@ -1244,21 +1241,21 @@
     }
     return NULL;
 }
 
 /// add missing issuer certificates to untrustedCerts
 static void
 completeIssuers(X509_STORE_CTX *ctx, STACK_OF(X509) *untrustedCerts)
 {
     debugs(83, 2,  "completing " << sk_X509_num(untrustedCerts) << " OpenSSL untrusted certs using " << SquidUntrustedCerts.size() << " configured untrusted certificates");
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     int depth = ctx->param->depth;
 #else
     const X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(ctx);
     int depth = X509_VERIFY_PARAM_get_depth(param);
 #endif
     X509 *current = X509_STORE_CTX_get0_cert(ctx);
     int i = 0;
     for (i = 0; current && (i < depth); ++i) {
         if (X509_check_issued(current, current)) {
             // either ctx->cert is itself self-signed or untrustedCerts
@@ -1284,40 +1281,40 @@
 untrustedToStoreCtx_cb(X509_STORE_CTX *ctx,void *data)
 {
     debugs(83, 4,  "Try to use pre-downloaded intermediate certificates\n");
 
     SSL *ssl = static_cast<SSL *>(X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx()));
     STACK_OF(X509) *sslUntrustedStack = static_cast <STACK_OF(X509) *>(SSL_get_ex_data(ssl, ssl_ex_index_ssl_untrusted_chain));
 
     // OpenSSL already maintains ctx->untrusted but we cannot modify
     // internal OpenSSL list directly. We have to give OpenSSL our own
     // list, but it must include certificates on the OpenSSL ctx->untrusted
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     STACK_OF(X509) *oldUntrusted = ctx->untrusted;
 #else
     STACK_OF(X509) *oldUntrusted = X509_STORE_CTX_get0_untrusted(ctx);
 #endif
     STACK_OF(X509) *sk = sk_X509_dup(oldUntrusted); // oldUntrusted is always not NULL
 
     for (int i = 0; i < sk_X509_num(sslUntrustedStack); ++i) {
         X509 *cert = sk_X509_value(sslUntrustedStack, i);
         sk_X509_push(sk, cert);
     }
 
     // If the local untrusted certificates internal database is used
     // run completeIssuers to add missing certificates if possible.
     if (SquidUntrustedCerts.size() > 0)
         completeIssuers(ctx, sk);
 
     X509_STORE_CTX_set_chain(ctx, sk); // No locking/unlocking, just sets ctx->untrusted
     int ret = X509_verify_cert(ctx);
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     X509_STORE_CTX_set_chain(ctx, oldUntrusted); // Set back the old untrusted list
 #else
     X509_STORE_CTX_set0_untrusted(ctx, oldUntrusted);
 #endif
     sk_X509_free(sk); // Release sk list
     return ret;
 }
 
 void
 Ssl::useSquidUntrusted(SSL_CTX *sslContext)
@@ -1479,21 +1476,21 @@
 static int
 store_session_cb(SSL *ssl, SSL_SESSION *session)
 {
     if (!Ssl::SessionCache)
         return 0;
 
     debugs(83, 5, "Request to store SSL Session ");
 
     SSL_SESSION_set_timeout(session, Config.SSL.session_ttl);
 
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
     unsigned char *id = session->session_id;
     unsigned int idlen = session->session_id_length;
 #else
     unsigned int idlen;
     const unsigned char *id = SSL_SESSION_get_id(session, &idlen);
 #endif
     unsigned char key[MEMMAP_SLOT_KEY_SIZE];
     // Session ids are of size 32bytes. They should always fit to a
     // MemMap::Slot::key
     assert(idlen <= MEMMAP_SLOT_KEY_SIZE);
@@ -1528,21 +1525,21 @@
     Ssl::SessionCache->closeForReading(pos);
     // TODO:
     // What if we are not able to remove the session?
     // Maybe schedule a job to remove it later?
     // For now we just have an invalid entry in cache until will be expired
     // The openSSL will reject it when we try to use it
     Ssl::SessionCache->free(pos);
 }
 
 static SSL_SESSION *
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+#if HAVE_LEGACY_OPENSSL_API
 get_session_cb(SSL *, unsigned char *sessionID, int len, int *copy)
 #else
 get_session_cb(SSL *, const unsigned char *sessionID, int len, int *copy)
 #endif
 {
     if (!Ssl::SessionCache)
         return NULL;
 
     SSL_SESSION *session = NULL;
     const unsigned int *p;
@@ -1577,12 +1574,12 @@
 Ssl::SetSessionCallbacks(Security::ContextPointer &ctx)
 {
     if (Ssl::SessionCache) {
         SSL_CTX_set_session_cache_mode(ctx.get(), SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL);
         SSL_CTX_sess_set_new_cb(ctx.get(), store_session_cb);
         SSL_CTX_sess_set_remove_cb(ctx.get(), remove_session_cb);
         SSL_CTX_sess_set_get_cb(ctx.get(), get_session_cb);
     }
 }
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/ssl/support.h'
--- src/ssl/support.h	2017-01-01 00:12:22 +0000
+++ src/ssl/support.h	2017-01-23 02:17:13 +0000
@@ -4,21 +4,21 @@
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 /* DEBUG: section 83    SSL accelerator support */
 
 #ifndef SQUID_SSL_SUPPORT_H
 #define SQUID_SSL_SUPPORT_H
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "base/CbDataList.h"
 #include "comm/forward.h"
 #include "sbuf/SBuf.h"
 #include "security/forward.h"
 #include "ssl/gadgets.h"
 
 #if HAVE_OPENSSL_X509V3_H
 #include <openssl/x509v3.h>
 #endif
@@ -370,13 +370,13 @@
 
 #else
 
 /// \ingroup ServerProtocolSSLAPI
 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
 
 #endif /* __cplusplus */
 
 #endif /* _SQUID_WINDOWS_ */
 
-#endif /* USE_OPENSSL */
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 #endif /* SQUID_SSL_SUPPORT_H */
 

=== modified file 'src/stat.cc'
--- src/stat.cc	2017-01-01 00:12:22 +0000
+++ src/stat.cc	2017-01-23 01:15:30 +0000
@@ -45,21 +45,21 @@
 #include "StoreClient.h"
 #include "tools.h"
 // for tvSubDsec() which should be in SquidTime.h
 #include "util.h"
 #if USE_AUTH
 #include "auth/UserRequest.h"
 #endif
 #if USE_DELAY_POOLS
 #include "DelayId.h"
 #endif
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/support.h"
 #endif
 
 /* these are included because they expose stats calls */
 /* TODO: provide a self registration mechanism for those classes
  * to use during static construction
  */
 #include "comm.h"
 #include "StoreSearch.h"
 
@@ -1872,21 +1872,21 @@
             p = http->request->auth_user_request->username();
         else
 #endif
             if (http->request->extacl_user.size() > 0) {
                 p = http->request->extacl_user.termedBuf();
             }
 
         if (!p && conn != NULL && conn->clientConnection->rfc931[0])
             p = conn->clientConnection->rfc931;
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         if (!p && conn != NULL && Comm::IsConnOpen(conn->clientConnection))
             p = sslGetUserEmail(fd_table[conn->clientConnection->fd].ssl.get());
 #endif
 
         if (!p)
             p = dash_str;
 
         storeAppendPrintf(s, "username %s\n", p);
 
 #if USE_DELAY_POOLS

=== modified file 'src/tests/stub_client_side.cc'
--- src/tests/stub_client_side.cc	2017-01-01 00:12:22 +0000
+++ src/tests/stub_client_side.cc	2017-01-23 01:15:19 +0000
@@ -32,21 +32,21 @@
 bool ConnStateData::handleReadData() STUB_RETVAL(false)
 bool ConnStateData::handleRequestBodyData() STUB_RETVAL(false)
 void ConnStateData::pinConnection(const Comm::ConnectionPointer &, HttpRequest *, CachePeer *, bool, bool) STUB
 void ConnStateData::unpinConnection(const bool) STUB
 const Comm::ConnectionPointer ConnStateData::validatePinnedConnection(HttpRequest *, const CachePeer *) STUB_RETVAL(NULL)
 void ConnStateData::clientPinnedConnectionClosed(const CommCloseCbParams &) STUB
 void ConnStateData::connStateClosed(const CommCloseCbParams &) STUB
 void ConnStateData::requestTimeout(const CommTimeoutCbParams &) STUB
 void ConnStateData::swanSong() STUB
 void ConnStateData::quitAfterError(HttpRequest *) STUB
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 void ConnStateData::httpsPeeked(Comm::ConnectionPointer) STUB
 void ConnStateData::getSslContextStart() STUB
 void ConnStateData::getSslContextDone(Security::ContextPointer &, bool) STUB
 void ConnStateData::sslCrtdHandleReplyWrapper(void *, const Helper::Reply &) STUB
 void ConnStateData::sslCrtdHandleReply(const Helper::Reply &) STUB
 void ConnStateData::switchToHttps(HttpRequest *, Ssl::BumpMode) STUB
 void ConnStateData::buildSslCertGenerationParams(Ssl::CertificateProperties &) STUB
 bool ConnStateData::serveDelayedError(Http::Stream *) STUB_RETVAL(false)
 #endif
 

=== modified file 'src/tests/stub_liblog.cc'
--- src/tests/stub_liblog.cc	2017-01-01 00:12:22 +0000
+++ src/tests/stub_liblog.cc	2017-01-23 02:17:30 +0000
@@ -11,21 +11,21 @@
 
 #define STUB_API "log/liblog.la"
 #include "tests/STUB.h"
 
 // XXX: these should be moved to a log/ *.h file
 #include "AccessLogEntry.h"
 /*
 AccessLogEntry::~AccessLogEntry() {STUB}
 void AccessLogEntry::getLogClientIp(char *, size_t) const STUB
 SBuf AccessLogEntry::getLogMethod() const STUB_RETVAL(SBuf())
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 AccessLogEntry::SslDetails::SslDetails() {STUB}
 #endif
 */
 void accessLogLogTo(CustomLog *, AccessLogEntry::Pointer &, ACLChecklist *) STUB
 void accessLogLog(AccessLogEntry::Pointer &, ACLChecklist *) STUB
 void accessLogRotate(void) STUB
 void accessLogClose(void) STUB
 void accessLogInit(void) STUB
 const char *accessLogTime(time_t) STUB_RETVAL(nullptr)
 

=== modified file 'src/tests/stub_libsslsquid.cc'
--- src/tests/stub_libsslsquid.cc	2017-01-01 00:12:22 +0000
+++ src/tests/stub_libsslsquid.cc	2017-01-23 00:58:31 +0000
@@ -1,21 +1,21 @@
 /*
  * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
  * Please see the COPYING and CONTRIBUTORS files for details.
  */
 
 #include "squid.h"
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 
 #include "fatal.h"
 
 /* Stub File for the ssl/libsslsquid.la convenience library */
 
 #define STUB_API "ssl/libsslsquid.la"
 #include "tests/STUB.h"
 
 #include "ssl/Config.h"
 Ssl::Config::Config():

=== modified file 'src/tunnel.cc'
--- src/tunnel.cc	2017-01-01 00:12:22 +0000
+++ src/tunnel.cc	2017-01-23 01:25:26 +0000
@@ -30,21 +30,21 @@
 #include "HttpRequest.h"
 #include "ip/QosConfig.h"
 #include "LogTags.h"
 #include "MemBuf.h"
 #include "PeerSelectState.h"
 #include "sbuf/SBuf.h"
 #include "security/BlindPeerConnector.h"
 #include "SquidConfig.h"
 #include "SquidTime.h"
 #include "StatCounters.h"
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 #include "ssl/bio.h"
 #include "ssl/ServerBump.h"
 #endif
 #include "tools.h"
 #if USE_DELAY_POOLS
 #include "DelayId.h"
 #endif
 
 #include <climits>
 #include <cerrno>
@@ -101,21 +101,21 @@
     bool waitingForConnectResponse() const { return connectRespBuf; }
     /// Whether we are waiting for the CONNECT request/response exchange with the peer.
     bool waitingForConnectExchange() const { return waitingForConnectRequest() || waitingForConnectResponse(); }
 
     /// Whether the client sent a CONNECT request to us.
     bool clientExpectsConnectResponse() const {
         // If we are forcing a tunnel after receiving a client CONNECT, then we
         // have already responded to that CONNECT before tunnel.cc started.
         if (request && request->flags.forceTunnel)
             return false;
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         // We are bumping and we had already send "OK CONNECTED"
         if (http.valid() && http->getConn() && http->getConn()->serverBump() && http->getConn()->serverBump()->step > Ssl::bumpStep1)
             return false;
 #endif
         return !(request != NULL &&
                  (request->flags.interceptTproxy || request->flags.intercepted));
     }
 
     /// Sends "502 Bad Gateway" error response to the client,
     /// if it is waiting for Squid CONNECT response, closing connections.
@@ -1250,21 +1250,21 @@
 
 #if USE_DELAY_POOLS
 void
 TunnelStateData::Connection::setDelayId(DelayId const &newDelay)
 {
     delayId = newDelay;
 }
 
 #endif
 
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
 void
 switchToTunnel(HttpRequest *request, Comm::ConnectionPointer &clientConn, Comm::ConnectionPointer &srvConn)
 {
     debugs(26,5, "Revert to tunnel FD " << clientConn->fd << " with FD " << srvConn->fd);
 
     /* Create state structure. */
     ++statCounter.server.all.requests;
     ++statCounter.server.other.requests;
 
     auto conn = request->clientConnectionManager.get();
@@ -1311,12 +1311,12 @@
     fd_table[srvConn->fd].read_method = &default_read_method;
     fd_table[srvConn->fd].write_method = &default_write_method;
 
     auto ssl = fd_table[srvConn->fd].ssl.get();
     assert(ssl);
     BIO *b = SSL_get_rbio(ssl);
     Ssl::ServerBio *srvBio = static_cast<Ssl::ServerBio *>(BIO_get_data(b));
     tunnelState->preReadServerData = srvBio->rBufData();
     tunnelStartShoveling(tunnelState);
 }
-#endif //USE_OPENSSL
+#endif /* USE_OPENSSL || USE_LIBRESSL */
 

=== modified file 'src/url.cc'
--- src/url.cc	2017-01-01 00:12:22 +0000
+++ src/url.cc	2017-01-23 01:14:24 +0000
@@ -823,21 +823,21 @@
 
     case AnyP::PROTO_WHOIS:
         if (r->method == Http::METHOD_GET)
             rc = 1;
         else if (r->method == Http::METHOD_HEAD)
             rc = 1;
 
         break;
 
     case AnyP::PROTO_HTTPS:
-#if USE_OPENSSL
+#if USE_OPENSSL || USE_LIBRESSL
         rc = 1;
 #else
         /*
         * Squid can't originate an SSL connection, so it should
         * never receive an "https:" URL.  It should always be
         * CONNECT instead.
         */
         rc = 0;
 #endif
         break;



More information about the squid-dev mailing list