]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/support.h
Detail client closures of CONNECT tunnels during TLS handshake (#691)
[thirdparty/squid.git] / src / ssl / support.h
1 /*
2 * Copyright (C) 1996-2020 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 /* DEBUG: section 83 SSL accelerator support */
10
11 #ifndef SQUID_SSL_SUPPORT_H
12 #define SQUID_SSL_SUPPORT_H
13
14 #if USE_OPENSSL
15
16 #include "base/CbDataList.h"
17 #include "comm/forward.h"
18 #include "compat/openssl.h"
19 #include "sbuf/SBuf.h"
20 #include "security/forward.h"
21 #include "ssl/gadgets.h"
22
23 #if HAVE_OPENSSL_X509V3_H
24 #include <openssl/x509v3.h>
25 #endif
26 #if HAVE_OPENSSL_ERR_H
27 #include <openssl/err.h>
28 #endif
29 #if HAVE_OPENSSL_ENGINE_H
30 #include <openssl/engine.h>
31 #endif
32 #include <queue>
33 #include <map>
34
35 /**
36 \defgroup ServerProtocolSSLAPI Server-Side SSL API
37 \ingroup ServerProtocol
38 */
39
40 // Maximum certificate validation callbacks. OpenSSL versions exceeding this
41 // limit are deemed stuck in an infinite validation loop (OpenSSL bug #3090)
42 // and will trigger the SQUID_X509_V_ERR_INFINITE_VALIDATION error.
43 // Can be set to a number up to UINT32_MAX
44 #ifndef SQUID_CERT_VALIDATION_ITERATION_MAX
45 #define SQUID_CERT_VALIDATION_ITERATION_MAX 16384
46 #endif
47
48 namespace AnyP
49 {
50 class PortCfg;
51 };
52
53 namespace Ipc
54 {
55 class MemMap;
56 }
57
58 namespace Ssl
59 {
60
61 /// callback for receiving password to access password secured PEM files
62 /// XXX: Requires SSL_CTX_set_default_passwd_cb_userdata()!
63 int AskPasswordCb(char *buf, int size, int rwflag, void *userdata);
64
65 /// initialize the SSL library global state.
66 /// call before generating any SSL context
67 void Initialize();
68
69 class CertValidationResponse;
70 typedef RefCount<CertValidationResponse> CertValidationResponsePointer;
71
72 /// initialize a TLS server context with OpenSSL specific settings
73 bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &);
74
75 /// initialize a TLS client context with OpenSSL specific settings
76 bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, Security::ParsedPortFlags);
77
78 /// set the certificate verify callback for a context
79 void ConfigurePeerVerification(Security::ContextPointer &, const Security::ParsedPortFlags);
80 void DisablePeerVerification(Security::ContextPointer &);
81
82 /// if required, setup callback for generating ephemeral RSA keys
83 void MaybeSetupRsaCallback(Security::ContextPointer &);
84
85 } //namespace Ssl
86
87 /// \ingroup ServerProtocolSSLAPI
88 const char *sslGetUserEmail(SSL *ssl);
89
90 /// \ingroup ServerProtocolSSLAPI
91 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name);
92
93 /// \ingroup ServerProtocolSSLAPI
94 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name);
95
96 /// \ingroup ServerProtocolSSLAPI
97 SBuf sslGetUserCertificatePEM(SSL *ssl);
98
99 /// \ingroup ServerProtocolSSLAPI
100 SBuf sslGetUserCertificateChainPEM(SSL *ssl);
101
102 namespace Ssl
103 {
104 /// \ingroup ServerProtocolSSLAPI
105 typedef char const *GETX509ATTRIBUTE(X509 *, const char *);
106 typedef SBuf GETX509PEM(X509 *);
107
108 /// \ingroup ServerProtocolSSLAPI
109 GETX509ATTRIBUTE GetX509UserAttribute;
110
111 /// \ingroup ServerProtocolSSLAPI
112 GETX509ATTRIBUTE GetX509CAAttribute;
113
114 /// \ingroup ServerProtocolSSLAPI
115 GETX509PEM GetX509PEM;
116
117 /// \ingroup ServerProtocolSSLAPI
118 GETX509ATTRIBUTE GetX509Fingerprint;
119
120 extern const EVP_MD *DefaultSignHash;
121
122 /**
123 \ingroup ServerProtocolSSLAPI
124 * Supported ssl-bump modes
125 */
126 enum BumpMode {bumpNone = 0, bumpClientFirst, bumpServerFirst, bumpPeek, bumpStare, bumpBump, bumpSplice, bumpTerminate, /*bumpErr,*/ bumpEnd};
127
128 /**
129 \ingroup ServerProtocolSSLAPI
130 * Short names for ssl-bump modes
131 */
132 extern std::vector<const char *>BumpModeStr;
133
134 /**
135 \ingroup ServerProtocolSSLAPI
136 * Return the short name of the ssl-bump mode "bm"
137 */
138 inline const char *bumpMode(int bm)
139 {
140 return (0 <= bm && bm < Ssl::bumpEnd) ? Ssl::BumpModeStr.at(bm) : NULL;
141 }
142
143 /// certificates indexed by issuer name
144 typedef std::multimap<SBuf, X509 *> CertsIndexedList;
145
146 /**
147 * Load PEM-encoded certificates from the given file.
148 */
149 bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list);
150
151 /**
152 * Load PEM-encoded certificates to the squid untrusteds certificates
153 * internal DB from the given file.
154 */
155 bool loadSquidUntrusted(const char *path);
156
157 /**
158 * Removes all certificates from squid untrusteds certificates
159 * internal DB and frees all memory
160 */
161 void unloadSquidUntrusted();
162
163 /**
164 * Add the certificate cert to ssl object untrusted certificates.
165 * Squid uses an attached to SSL object list of untrusted certificates,
166 * with certificates which can be used to complete incomplete chains sent
167 * by the SSL server.
168 */
169 void SSL_add_untrusted_cert(SSL *ssl, X509 *cert);
170
171 /**
172 * Searches in serverCertificates list for the cert issuer and if not found
173 * and Authority Info Access of cert provides a URI return it.
174 */
175 const char *uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates, const Security::ContextPointer &context);
176
177 /**
178 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
179 * if this information provided by Authority Info Access.
180 */
181 void missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context);
182
183 /**
184 \ingroup ServerProtocolSSLAPI
185 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
186 */
187 bool generateUntrustedCert(Security::CertPointer & untrustedCert, Security::PrivateKeyPointer & untrustedPkey, Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey);
188
189 /// certificates indexed by issuer name
190 typedef std::multimap<SBuf, X509 *> CertsIndexedList;
191
192 /**
193 \ingroup ServerProtocolSSLAPI
194 * Load PEM-encoded certificates from the given file.
195 */
196 bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list);
197
198 /**
199 \ingroup ServerProtocolSSLAPI
200 * Load PEM-encoded certificates to the squid untrusteds certificates
201 * internal DB from the given file.
202 */
203 bool loadSquidUntrusted(const char *path);
204
205 /**
206 \ingroup ServerProtocolSSLAPI
207 * Removes all certificates from squid untrusteds certificates
208 * internal DB and frees all memory
209 */
210 void unloadSquidUntrusted();
211
212 /**
213 \ingroup ServerProtocolSSLAPI
214 * Decide on the kind of certificate and generate a CA- or self-signed one
215 */
216 Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool trusted);
217
218 /**
219 \ingroup ServerProtocolSSLAPI
220 * Check if the certificate of the given context is still valid
221 \param sslContext The context to check
222 \param properties Check if the context certificate matches the given properties
223 \return true if the contexts certificate is valid, false otherwise
224 */
225 bool verifySslCertificate(const Security::ContextPointer &, CertificateProperties const &);
226
227 /**
228 \ingroup ServerProtocolSSLAPI
229 * Read private key and certificate from memory and generate SSL context
230 * using their.
231 */
232 Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &, bool trusted);
233
234 /**
235 \ingroup ServerProtocolSSLAPI
236 * Create an SSL context using the provided certificate and key
237 */
238 Security::ContextPointer createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &);
239
240 /**
241 \ingroup ServerProtocolSSLAPI
242 * Chain signing certificate and chained certificates to an SSL Context
243 */
244 void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &);
245
246 /**
247 \ingroup ServerProtocolSSLAPI
248 * Configure a previously unconfigured SSL context object.
249 */
250 void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAlgorithm signAlgorithm, AnyP::PortCfg &);
251
252 /**
253 \ingroup ServerProtocolSSLAPI
254 * Generates a certificate and a private key using provided properties and set it
255 * to SSL object.
256 */
257 bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port);
258
259 /**
260 \ingroup ServerProtocolSSLAPI
261 * Read private key and certificate from memory and set it to SSL object
262 * using their.
263 */
264 bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port);
265
266 /**
267 \ingroup ServerProtocolSSLAPI
268 * Configures sslContext to use squid untrusted certificates internal list
269 * to complete certificate chains when verifies SSL servers certificates.
270 */
271 void useSquidUntrusted(SSL_CTX *sslContext);
272
273 /**
274 \ingroup ServerProtocolSSLAPI
275 * Iterates over the X509 common and alternate names and to see if matches with given data
276 * using the check_func.
277 \param peer_cert The X509 cert to check
278 \param check_data The data with which the X509 CNs compared
279 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
280 \return 1 if any of the certificate CN matches, 0 if none matches.
281 */
282 int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data));
283
284 /**
285 \ingroup ServerProtocolSSLAPI
286 * Check if the certificate is valid for a server
287 \param cert The X509 cert to check.
288 \param server The server name.
289 \return true if the certificate is valid for the server or false otherwise.
290 */
291 bool checkX509ServerValidity(X509 *cert, const char *server);
292
293 /**
294 \ingroup ServerProtocolSSLAPI
295 * Convert a given ASN1_TIME to a string form.
296 \param tm the time in ASN1_TIME form
297 \param buf the buffer to write the output
298 \param len write at most len bytes
299 \return The number of bytes written
300 */
301 int asn1timeToString(ASN1_TIME *tm, char *buf, int len);
302
303 /**
304 \ingroup ServerProtocolSSLAPI
305 * Sets the hostname for the Server Name Indication (SNI) TLS extension
306 * if supported by the used openssl toolkit.
307 */
308 void setClientSNI(SSL *ssl, const char *fqdn);
309
310 /**
311 \ingroup ServerProtocolSSLAPI
312 * Generates a unique key based on CertificateProperties object and store it to key
313 */
314 void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key);
315
316 /**
317 \ingroup ServerProtocolSSLAPI
318 Creates and returns an OpenSSL BIO object for writing to `buf` (or throws).
319 TODO: Add support for reading from `buf`.
320 */
321 BIO *BIO_new_SBuf(SBuf *buf);
322 } //namespace Ssl
323
324 #if _SQUID_WINDOWS_
325
326 #if defined(__cplusplus)
327
328 /** \cond AUTODOCS-IGNORE */
329 namespace Squid
330 {
331 /** \endcond */
332
333 /// \ingroup ServerProtocolSSLAPI
334 inline
335 int SSL_set_fd(SSL *ssl, int fd)
336 {
337 return ::SSL_set_fd(ssl, _get_osfhandle(fd));
338 }
339
340 /// \ingroup ServerProtocolSSLAPI
341 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
342
343 } /* namespace Squid */
344
345 #else
346
347 /// \ingroup ServerProtocolSSLAPI
348 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
349
350 #endif /* __cplusplus */
351
352 #endif /* _SQUID_WINDOWS_ */
353
354 #endif /* USE_OPENSSL */
355 #endif /* SQUID_SSL_SUPPORT_H */
356