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