2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 #ifndef SQUID_SRC_SECURITY_FORWARD_H
10 #define SQUID_SRC_SECURITY_FORWARD_H
12 #include "base/CbDataList.h"
13 #include "base/forward.h"
14 #include "base/ToCpp.h"
15 #include "security/LockingPointer.h"
18 #if HAVE_GNUTLS_ABSTRACT_H
19 #include <gnutls/abstract.h>
21 #endif /* HAVE_LIBGNUTLS */
26 #include "compat/openssl.h"
28 #include <openssl/bn.h>
30 #if HAVE_OPENSSL_ERR_H
31 #include <openssl/err.h>
33 #if HAVE_OPENSSL_RSA_H
34 #include <openssl/rsa.h>
36 #if HAVE_OPENSSL_X509_H
37 #include <openssl/x509.h>
39 #endif /* USE_OPENSSL */
40 #include <unordered_set>
43 // Macro to be used to define the C++ wrapper functor of the sk_*_pop_free
44 // OpenSSL family of functions. The C++ functor is suffixed with the _free_wrapper
46 #define sk_dtor_wrapper(sk_object, argument_type, freefunction) \
47 struct sk_object ## _free_wrapper { \
48 void operator()(argument_type a) { sk_object ## _pop_free(a, freefunction); } \
50 #endif /* USE_OPENSSL */
52 /* flags a SSL connection can be configured with */
53 #define SSL_FLAG_NO_DEFAULT_CA (1<<0)
54 #define SSL_FLAG_DELAYED_AUTH (1<<1)
55 #define SSL_FLAG_DONT_VERIFY_PEER (1<<2)
56 #define SSL_FLAG_DONT_VERIFY_DOMAIN (1<<3)
57 #define SSL_FLAG_NO_SESSION_REUSE (1<<4)
58 #define SSL_FLAG_VERIFY_CRL (1<<5)
59 #define SSL_FLAG_VERIFY_CRL_ALL (1<<6)
60 #define SSL_FLAG_CONDITIONAL_AUTH (1<<7)
62 #if !USE_OPENSSL && !HAVE_LIBGNUTLS
63 /// A helper type to keep all three possible underlying types of the
64 /// Security::Certificate typedef below inside global namespace, so that
65 /// argument-dependent lookup for operator "<<" (Certificate) works inside
66 /// functions declared in Security and global namespaces.
70 /// Network/connection security abstraction layer
75 /// Holds a list of X.509 certificate errors
76 typedef CbDataList
<Security::CertError
> CertErrors
;
79 typedef X509 Certificate
;
81 typedef struct gnutls_x509_crt_int Certificate
;
83 typedef struct notls_x509 Certificate
;
87 CtoCpp1(X509_free
, X509
*);
88 typedef Security::LockingPointer
<X509
, X509_free_cpp
, HardFun
<int, X509
*, X509_up_ref
> > CertPointer
;
90 typedef std::shared_ptr
<struct gnutls_x509_crt_int
> CertPointer
;
92 typedef std::shared_ptr
<Certificate
> CertPointer
;
96 CtoCpp1(X509_CRL_free
, X509_CRL
*);
97 typedef Security::LockingPointer
<X509_CRL
, X509_CRL_free_cpp
, HardFun
<int, X509_CRL
*, X509_CRL_up_ref
> > CrlPointer
;
99 CtoCpp1(gnutls_x509_crl_deinit
, gnutls_x509_crl_t
);
100 typedef Security::LockingPointer
<struct gnutls_x509_crl_int
, gnutls_x509_crl_deinit
> CrlPointer
;
102 typedef void *CrlPointer
;
105 typedef std::list
<Security::CertPointer
> CertList
;
107 typedef std::list
<Security::CrlPointer
> CertRevokeList
;
110 CtoCpp1(EVP_PKEY_free
, EVP_PKEY
*)
111 using PrivateKeyPointer
= Security::LockingPointer
<EVP_PKEY
, EVP_PKEY_free_cpp
, HardFun
<int, EVP_PKEY
*, EVP_PKEY_up_ref
>>;
113 using PrivateKeyPointer
= std::shared_ptr
<struct gnutls_x509_privkey_int
>;
115 using PrivateKeyPointer
= std::shared_ptr
<void>;
119 #if OPENSSL_VERSION_MAJOR < 3
120 CtoCpp1(DH_free
, DH
*);
121 typedef Security::LockingPointer
<DH
, DH_free_cpp
, HardFun
<int, DH
*, DH_up_ref
> > DhePointer
;
123 using DhePointer
= PrivateKeyPointer
;
126 using DhePointer
= void *;
128 using DhePointer
= void *;
131 class EncryptorAnswer
;
133 /// Squid-defined error code (<0), an error code returned by X.509 API, or zero
134 typedef int ErrorCode
;
136 /// TLS library-reported non-validation error
138 /// the result of the first ERR_get_error(3SSL) call after a library call;
139 /// `openssl errstr` expands these numbers into human-friendlier strings like
140 /// `error:1408F09C:SSL routines:ssl3_get_record:http request`
141 typedef unsigned long LibErrorCode
;
143 /// the result of an API function like gnutls_handshake() (e.g.,
144 /// GNUTLS_E_WARNING_ALERT_RECEIVED)
145 typedef int LibErrorCode
;
147 /// should always be zero and virtually unused
148 typedef int LibErrorCode
;
151 /// converts numeric LibErrorCode into a human-friendlier string
152 inline const char *ErrorString(const LibErrorCode code
) {
154 return ERR_error_string(code
, nullptr);
156 return gnutls_strerror(code
);
159 return "[no TLS library]";
163 /// set of Squid defined TLS error codes
164 /// \note using std::unordered_set ensures values are unique, with fast lookup
165 typedef std::unordered_set
<Security::ErrorCode
> Errors
;
171 BIO_TO_CLIENT
= 6000,
174 // NP: this is odd looking but correct.
175 // 'to-client' means we are a server, and vice versa.
176 BIO_TO_CLIENT
= GNUTLS_SERVER
,
177 BIO_TO_SERVER
= GNUTLS_CLIENT
179 BIO_TO_CLIENT
= 6000,
186 // TODO: Either move to Security::Io or remove/restrict the Io namespace.
189 class CommunicationSecrets
;
194 using ParsedOptions
= uint64_t;
196 typedef std::shared_ptr
<struct gnutls_priority_st
> ParsedOptions
;
198 class ParsedOptions
{}; // we never parse/use TLS options in this case
201 /// bitmask representing configured http(s)_port `sslflags`
202 /// as well tls_outgoing_options `flags`, cache_peer `sslflags`, and
203 /// icap_service `tls-flags`
204 typedef long ParsedPortFlags
;
207 class BlindPeerConnector
;
213 typedef RefCount
<ErrorDetail
> ErrorDetailPointer
;
215 std::ostream
&operator <<(std::ostream
&, const KeyLog
&);
217 void OpenLogs(); ///< opens logs enabled in the current configuration
218 void RotateLogs(); ///< rotates logs opened by OpenLogs()
219 void CloseLogs(); ///< closes logs opened by OpenLogs()
221 } // namespace Security
223 /// Squid-specific TLS handling errors (a subset of ErrorCode)
224 /// These errors either distinguish high-level library calls/contexts or
225 /// supplement official certificate validation errors to cover special cases.
226 /// We use negative values, assuming that those official errors are positive.
228 SQUID_TLS_ERR_OFFSET
= std::numeric_limits
<int>::min(),
230 /* TLS library calls/contexts other than validation (e.g., I/O) */
231 SQUID_TLS_ERR_ACCEPT
, ///< failure to accept a connection from a TLS client
232 SQUID_TLS_ERR_CONNECT
, ///< failure to establish a connection with a TLS server
234 /* certificate validation problems not covered by official errors */
235 SQUID_X509_V_ERR_CERT_CHANGE
,
236 SQUID_X509_V_ERR_DOMAIN_MISMATCH
,
237 SQUID_X509_V_ERR_INFINITE_VALIDATION
,
242 #endif /* SQUID_SRC_SECURITY_FORWARD_H */