/* * Copyright (C) 1996-2023 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_SRC_SECURITY_FORWARD_H #define SQUID_SRC_SECURITY_FORWARD_H #include "base/CbDataList.h" #include "base/forward.h" #include "security/Context.h" #include "security/Session.h" #if USE_GNUTLS && HAVE_GNUTLS_ABSTRACT_H #include #endif #include #include #if USE_OPENSSL #include "compat/openssl.h" #if HAVE_OPENSSL_BN_H #include #endif #if HAVE_OPENSSL_ERR_H #include #endif #if HAVE_OPENSSL_RSA_H #include #endif #endif /* USE_OPENSSL */ #include #if USE_OPENSSL // 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 */ /* 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) #define SSL_FLAG_CONDITIONAL_AUTH (1<<7) /// Network/connection security abstraction layer namespace Security { class CertError; /// Holds a list of X.509 certificate errors typedef CbDataList CertErrors; #if USE_OPENSSL typedef X509 Certificate; #elif USE_GNUTLS typedef struct gnutls_x509_crt_int Certificate; #else typedef class {} Certificate; #endif #if USE_OPENSSL CtoCpp1(X509_free, X509 *); typedef Security::LockingPointer > CertPointer; #elif USE_GNUTLS typedef std::shared_ptr CertPointer; #else typedef std::shared_ptr CertPointer; #endif #if USE_OPENSSL CtoCpp1(X509_CRL_free, X509_CRL *); typedef Security::LockingPointer > CrlPointer; #elif USE_GNUTLS CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t); typedef Security::LockingPointer CrlPointer; #else typedef void *CrlPointer; #endif typedef std::list CertList; typedef std::list CertRevokeList; #if USE_OPENSSL CtoCpp1(EVP_PKEY_free, EVP_PKEY *) using PrivateKeyPointer = Security::LockingPointer>; #elif USE_GNUTLS using PrivateKeyPointer = std::shared_ptr; #else using PrivateKeyPointer = std::shared_ptr; #endif #if USE_OPENSSL #if OPENSSL_VERSION_MAJOR < 3 CtoCpp1(DH_free, DH *); typedef Security::LockingPointer > DhePointer; #else using DhePointer = PrivateKeyPointer; #endif #elif USE_GNUTLS using DhePointer = void *; #else using DhePointer = void *; #endif class EncryptorAnswer; /// Squid-defined error code (<0), an error code returned by X.509 API, or zero typedef int ErrorCode; /// TLS library-reported non-validation error #if USE_OPENSSL /// the result of the first ERR_get_error(3SSL) call after a library call; /// `openssl errstr` expands these numbers into human-friendlier strings like /// `error:1408F09C:SSL routines:ssl3_get_record:http request` typedef unsigned long LibErrorCode; #elif USE_GNUTLS /// the result of an API function like gnutls_handshake() (e.g., /// GNUTLS_E_WARNING_ALERT_RECEIVED) typedef int LibErrorCode; #else /// should always be zero and virtually unused typedef int LibErrorCode; #endif /// converts numeric LibErrorCode into a human-friendlier string inline const char *ErrorString(const LibErrorCode code) { #if USE_OPENSSL 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 typedef std::unordered_set Errors; namespace Io { enum Type { #if USE_OPENSSL BIO_TO_CLIENT = 6000, BIO_TO_SERVER #elif USE_GNUTLS // NP: this is odd looking but correct. // 'to-client' means we are a server, and vice versa. BIO_TO_CLIENT = GNUTLS_SERVER, BIO_TO_SERVER = GNUTLS_CLIENT #else BIO_TO_CLIENT = 6000, BIO_TO_SERVER #endif }; } // namespace Io // TODO: Either move to Security::Io or remove/restrict the Io namespace. class IoResult; class KeyData; #if USE_OPENSSL using ParsedOptions = uint64_t; #elif USE_GNUTLS typedef std::shared_ptr ParsedOptions; #else class ParsedOptions {}; // we never parse/use TLS options in this case #endif /// bitmask representing configured http(s)_port `sslflags` /// as well tls_outgoing_options `flags`, cache_peer `sslflags`, and /// icap_service `tls-flags` typedef long ParsedPortFlags; class PeerConnector; class BlindPeerConnector; class PeerOptions; class ServerOptions; class ErrorDetail; typedef RefCount ErrorDetailPointer; } // namespace Security /// Squid-specific TLS handling errors (a subset of ErrorCode) /// These errors either distinguish high-level library calls/contexts or /// supplement official certificate validation errors to cover special cases. /// We use negative values, assuming that those official errors are positive. enum { SQUID_TLS_ERR_OFFSET = std::numeric_limits::min(), /* TLS library calls/contexts other than validation (e.g., I/O) */ SQUID_TLS_ERR_ACCEPT, ///< failure to accept a connection from a TLS client SQUID_TLS_ERR_CONNECT, ///< failure to establish a connection with a TLS server /* certificate validation problems not covered by official errors */ SQUID_X509_V_ERR_CERT_CHANGE, SQUID_X509_V_ERR_DOMAIN_MISMATCH, SQUID_X509_V_ERR_INFINITE_VALIDATION, SQUID_TLS_ERR_END }; #endif /* SQUID_SRC_SECURITY_FORWARD_H */