]> git.ipfire.org Git - thirdparty/squid.git/blob - src/security/forward.h
Maintenance: update --with-gnutls detection (#1685)
[thirdparty/squid.git] / src / security / forward.h
1 /*
2 * Copyright (C) 1996-2023 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 ErrorDetail;
213 typedef RefCount<ErrorDetail> ErrorDetailPointer;
214
215 std::ostream &operator <<(std::ostream &, const KeyLog &);
216
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()
220
221 } // namespace Security
222
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.
227 enum {
228 SQUID_TLS_ERR_OFFSET = std::numeric_limits<int>::min(),
229
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
233
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,
238
239 SQUID_TLS_ERR_END
240 };
241
242 #endif /* SQUID_SRC_SECURITY_FORWARD_H */
243