]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (C) 1996-2025 The Squid Software Foundation and contributors | |
3 | * | |
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. | |
7 | */ | |
8 | ||
9 | #ifndef SQUID_SRC_SECURITY_FORWARD_H | |
10 | #define SQUID_SRC_SECURITY_FORWARD_H | |
11 | ||
12 | #include "base/CbDataList.h" | |
13 | #include "base/forward.h" | |
14 | #include "base/ToCpp.h" | |
15 | #include "security/LockingPointer.h" | |
16 | ||
17 | #if HAVE_LIBGNUTLS | |
18 | #if HAVE_GNUTLS_ABSTRACT_H | |
19 | #include <gnutls/abstract.h> | |
20 | #endif | |
21 | #endif /* HAVE_LIBGNUTLS */ | |
22 | #include <list> | |
23 | #include <limits> | |
24 | #include <memory> | |
25 | #if USE_OPENSSL | |
26 | #include "compat/openssl.h" | |
27 | #if HAVE_OPENSSL_BN_H | |
28 | #include <openssl/bn.h> | |
29 | #endif | |
30 | #if HAVE_OPENSSL_ERR_H | |
31 | #include <openssl/err.h> | |
32 | #endif | |
33 | #if HAVE_OPENSSL_RSA_H | |
34 | #include <openssl/rsa.h> | |
35 | #endif | |
36 | #if HAVE_OPENSSL_X509_H | |
37 | #include <openssl/x509.h> | |
38 | #endif | |
39 | #endif /* USE_OPENSSL */ | |
40 | #include <unordered_set> | |
41 | ||
42 | #if USE_OPENSSL | |
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 | |
45 | // extension | |
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); } \ | |
49 | } | |
50 | #endif /* USE_OPENSSL */ | |
51 | ||
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) | |
61 | ||
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. | |
67 | struct notls_x509 {}; | |
68 | #endif | |
69 | ||
70 | /// Network/connection security abstraction layer | |
71 | namespace Security | |
72 | { | |
73 | ||
74 | class CertError; | |
75 | /// Holds a list of X.509 certificate errors | |
76 | typedef CbDataList<Security::CertError> CertErrors; | |
77 | ||
78 | #if USE_OPENSSL | |
79 | typedef X509 Certificate; | |
80 | #elif HAVE_LIBGNUTLS | |
81 | typedef struct gnutls_x509_crt_int Certificate; | |
82 | #else | |
83 | typedef struct notls_x509 Certificate; | |
84 | #endif | |
85 | ||
86 | #if USE_OPENSSL | |
87 | CtoCpp1(X509_free, X509 *); | |
88 | typedef Security::LockingPointer<X509, X509_free_cpp, HardFun<int, X509 *, X509_up_ref> > CertPointer; | |
89 | #elif HAVE_LIBGNUTLS | |
90 | typedef std::shared_ptr<struct gnutls_x509_crt_int> CertPointer; | |
91 | #else | |
92 | typedef std::shared_ptr<Certificate> CertPointer; | |
93 | #endif | |
94 | ||
95 | #if USE_OPENSSL | |
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; | |
98 | #elif HAVE_LIBGNUTLS | |
99 | CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t); | |
100 | typedef Security::LockingPointer<struct gnutls_x509_crl_int, gnutls_x509_crl_deinit> CrlPointer; | |
101 | #else | |
102 | typedef void *CrlPointer; | |
103 | #endif | |
104 | ||
105 | typedef std::list<Security::CertPointer> CertList; | |
106 | ||
107 | typedef std::list<Security::CrlPointer> CertRevokeList; | |
108 | ||
109 | #if USE_OPENSSL | |
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>>; | |
112 | #elif HAVE_LIBGNUTLS | |
113 | using PrivateKeyPointer = std::shared_ptr<struct gnutls_x509_privkey_int>; | |
114 | #else | |
115 | using PrivateKeyPointer = std::shared_ptr<void>; | |
116 | #endif | |
117 | ||
118 | #if USE_OPENSSL | |
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; | |
122 | #else | |
123 | using DhePointer = PrivateKeyPointer; | |
124 | #endif | |
125 | #elif HAVE_LIBGNUTLS | |
126 | using DhePointer = void *; | |
127 | #else | |
128 | using DhePointer = void *; | |
129 | #endif | |
130 | ||
131 | class EncryptorAnswer; | |
132 | ||
133 | /// Squid-defined error code (<0), an error code returned by X.509 API, or zero | |
134 | typedef int ErrorCode; | |
135 | ||
136 | /// TLS library-reported non-validation error | |
137 | #if USE_OPENSSL | |
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; | |
142 | #elif HAVE_LIBGNUTLS | |
143 | /// the result of an API function like gnutls_handshake() (e.g., | |
144 | /// GNUTLS_E_WARNING_ALERT_RECEIVED) | |
145 | typedef int LibErrorCode; | |
146 | #else | |
147 | /// should always be zero and virtually unused | |
148 | typedef int LibErrorCode; | |
149 | #endif | |
150 | ||
151 | /// converts numeric LibErrorCode into a human-friendlier string | |
152 | inline const char *ErrorString(const LibErrorCode code) { | |
153 | #if USE_OPENSSL | |
154 | return ERR_error_string(code, nullptr); | |
155 | #elif HAVE_LIBGNUTLS | |
156 | return gnutls_strerror(code); | |
157 | #else | |
158 | (void)code; | |
159 | return "[no TLS library]"; | |
160 | #endif | |
161 | } | |
162 | ||
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; | |
166 | ||
167 | namespace Io | |
168 | { | |
169 | enum Type { | |
170 | #if USE_OPENSSL | |
171 | BIO_TO_CLIENT = 6000, | |
172 | BIO_TO_SERVER | |
173 | #elif HAVE_LIBGNUTLS | |
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 | |
178 | #else | |
179 | BIO_TO_CLIENT = 6000, | |
180 | BIO_TO_SERVER | |
181 | #endif | |
182 | }; | |
183 | ||
184 | } // namespace Io | |
185 | ||
186 | // TODO: Either move to Security::Io or remove/restrict the Io namespace. | |
187 | class IoResult; | |
188 | ||
189 | class CommunicationSecrets; | |
190 | class KeyData; | |
191 | class KeyLog; | |
192 | ||
193 | #if USE_OPENSSL | |
194 | using ParsedOptions = uint64_t; | |
195 | #elif HAVE_LIBGNUTLS | |
196 | typedef std::shared_ptr<struct gnutls_priority_st> ParsedOptions; | |
197 | #else | |
198 | class ParsedOptions {}; // we never parse/use TLS options in this case | |
199 | #endif | |
200 | ||
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; | |
205 | ||
206 | class PeerConnector; | |
207 | class BlindPeerConnector; | |
208 | class PeerOptions; | |
209 | ||
210 | class ServerOptions; | |
211 | ||
212 | class FuturePeerContext; | |
213 | ||
214 | class ErrorDetail; | |
215 | typedef RefCount<ErrorDetail> ErrorDetailPointer; | |
216 | ||
217 | std::ostream &operator <<(std::ostream &, const KeyLog &); | |
218 | ||
219 | void OpenLogs(); ///< opens logs enabled in the current configuration | |
220 | void RotateLogs(); ///< rotates logs opened by OpenLogs() | |
221 | void CloseLogs(); ///< closes logs opened by OpenLogs() | |
222 | ||
223 | } // namespace Security | |
224 | ||
225 | /// Squid-specific TLS handling errors (a subset of ErrorCode) | |
226 | /// These errors either distinguish high-level library calls/contexts or | |
227 | /// supplement official certificate validation errors to cover special cases. | |
228 | /// We use negative values, assuming that those official errors are positive. | |
229 | enum { | |
230 | SQUID_TLS_ERR_OFFSET = std::numeric_limits<int>::min(), | |
231 | ||
232 | /* TLS library calls/contexts other than validation (e.g., I/O) */ | |
233 | SQUID_TLS_ERR_ACCEPT, ///< failure to accept a connection from a TLS client | |
234 | SQUID_TLS_ERR_CONNECT, ///< failure to establish a connection with a TLS server | |
235 | ||
236 | /* certificate validation problems not covered by official errors */ | |
237 | SQUID_X509_V_ERR_CERT_CHANGE, | |
238 | SQUID_X509_V_ERR_DOMAIN_MISMATCH, | |
239 | SQUID_X509_V_ERR_INFINITE_VALIDATION, | |
240 | ||
241 | SQUID_TLS_ERR_END | |
242 | }; | |
243 | ||
244 | #endif /* SQUID_SRC_SECURITY_FORWARD_H */ | |
245 |