]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ssl/support.h
TLS: Move the remaining SSL_SESSION cache callbacks to security/Session.*.
[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 /// initialize a TLS server context with OpenSSL specific settings
77 bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &);
78
79 /// initialize a TLS client context with OpenSSL specific settings
80 bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, long flags);
81
82 } //namespace Ssl
83
84 /// \ingroup ServerProtocolSSLAPI
85 const char *sslGetUserEmail(SSL *ssl);
86
87 /// \ingroup ServerProtocolSSLAPI
88 const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name);
89
90 /// \ingroup ServerProtocolSSLAPI
91 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name);
92
93 /// \ingroup ServerProtocolSSLAPI
94 const char *sslGetUserCertificatePEM(SSL *ssl);
95
96 /// \ingroup ServerProtocolSSLAPI
97 const char *sslGetUserCertificateChainPEM(SSL *ssl);
98
99 namespace Ssl
100 {
101 /// \ingroup ServerProtocolSSLAPI
102 typedef char const *GETX509ATTRIBUTE(X509 *, const char *);
103
104 /// \ingroup ServerProtocolSSLAPI
105 GETX509ATTRIBUTE GetX509UserAttribute;
106
107 /// \ingroup ServerProtocolSSLAPI
108 GETX509ATTRIBUTE GetX509CAAttribute;
109
110 /// \ingroup ServerProtocolSSLAPI
111 GETX509ATTRIBUTE GetX509Fingerprint;
112
113 extern const EVP_MD *DefaultSignHash;
114
115 /**
116 \ingroup ServerProtocolSSLAPI
117 * Supported ssl-bump modes
118 */
119 enum BumpMode {bumpNone = 0, bumpClientFirst, bumpServerFirst, bumpPeek, bumpStare, bumpBump, bumpSplice, bumpTerminate, /*bumpErr,*/ bumpEnd};
120
121 enum BumpStep {bumpStep1, bumpStep2, bumpStep3};
122
123 /**
124 \ingroup ServerProtocolSSLAPI
125 * Short names for ssl-bump modes
126 */
127 extern std::vector<const char *>BumpModeStr;
128
129 /**
130 \ingroup ServerProtocolSSLAPI
131 * Return the short name of the ssl-bump mode "bm"
132 */
133 inline const char *bumpMode(int bm)
134 {
135 return (0 <= bm && bm < Ssl::bumpEnd) ? Ssl::BumpModeStr.at(bm) : NULL;
136 }
137
138 /// certificates indexed by issuer name
139 typedef std::multimap<SBuf, X509 *> CertsIndexedList;
140
141 /**
142 * Load PEM-encoded certificates from the given file.
143 */
144 bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list);
145
146 /**
147 * Load PEM-encoded certificates to the squid untrusteds certificates
148 * internal DB from the given file.
149 */
150 bool loadSquidUntrusted(const char *path);
151
152 /**
153 * Removes all certificates from squid untrusteds certificates
154 * internal DB and frees all memory
155 */
156 void unloadSquidUntrusted();
157
158 /**
159 * Add the certificate cert to ssl object untrusted certificates.
160 * Squid uses an attached to SSL object list of untrusted certificates,
161 * with certificates which can be used to complete incomplete chains sent
162 * by the SSL server.
163 */
164 void SSL_add_untrusted_cert(SSL *ssl, X509 *cert);
165
166 /**
167 * Searches in serverCertificates list for the cert issuer and if not found
168 * and Authority Info Access of cert provides a URI return it.
169 */
170 const char *uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates);
171
172 /**
173 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
174 * if this information provided by Authority Info Access.
175 */
176 void missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates);
177
178 /**
179 \ingroup ServerProtocolSSLAPI
180 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
181 */
182 bool generateUntrustedCert(Security::CertPointer & untrustedCert, EVP_PKEY_Pointer & untrustedPkey, Security::CertPointer const & cert, EVP_PKEY_Pointer const & pkey);
183
184 /// certificates indexed by issuer name
185 typedef std::multimap<SBuf, X509 *> CertsIndexedList;
186
187 /**
188 \ingroup ServerProtocolSSLAPI
189 * Load PEM-encoded certificates from the given file.
190 */
191 bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list);
192
193 /**
194 \ingroup ServerProtocolSSLAPI
195 * Load PEM-encoded certificates to the squid untrusteds certificates
196 * internal DB from the given file.
197 */
198 bool loadSquidUntrusted(const char *path);
199
200 /**
201 \ingroup ServerProtocolSSLAPI
202 * Removes all certificates from squid untrusteds certificates
203 * internal DB and frees all memory
204 */
205 void unloadSquidUntrusted();
206
207 /**
208 \ingroup ServerProtocolSSLAPI
209 * Decide on the kind of certificate and generate a CA- or self-signed one
210 */
211 Security::ContextPointer generateSslContext(CertificateProperties const &properties, AnyP::PortCfg &port);
212
213 /**
214 \ingroup ServerProtocolSSLAPI
215 * Check if the certificate of the given context is still valid
216 \param sslContext The context to check
217 \param properties Check if the context certificate matches the given properties
218 \return true if the contexts certificate is valid, false otherwise
219 */
220 bool verifySslCertificate(Security::ContextPointer &, CertificateProperties const &);
221
222 /**
223 \ingroup ServerProtocolSSLAPI
224 * Read private key and certificate from memory and generate SSL context
225 * using their.
226 */
227 Security::ContextPointer generateSslContextUsingPkeyAndCertFromMemory(const char * data, AnyP::PortCfg &port);
228
229 /**
230 \ingroup ServerProtocolSSLAPI
231 * Create an SSL context using the provided certificate and key
232 */
233 Security::ContextPointer createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port);
234
235 /**
236 \ingroup ServerProtocolSSLAPI
237 * Chain signing certificate and chained certificates to an SSL Context
238 */
239 void chainCertificatesToSSLContext(Security::ContextPointer &, AnyP::PortCfg &);
240
241 /**
242 \ingroup ServerProtocolSSLAPI
243 * Configure a previously unconfigured SSL context object.
244 */
245 void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAlgorithm signAlgorithm, AnyP::PortCfg &);
246
247 /**
248 \ingroup ServerProtocolSSLAPI
249 * Generates a certificate and a private key using provided properies and set it
250 * to SSL object.
251 */
252 bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port);
253
254 /**
255 \ingroup ServerProtocolSSLAPI
256 * Read private key and certificate from memory and set it to SSL object
257 * using their.
258 */
259 bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port);
260
261 /**
262 \ingroup ServerProtocolSSLAPI
263 * Adds the certificates in certList to the certificate chain of the SSL context
264 */
265 void addChainToSslContext(Security::ContextPointer &, STACK_OF(X509) *certList);
266
267 /**
268 \ingroup ServerProtocolSSLAPI
269 * Configures sslContext to use squid untrusted certificates internal list
270 * to complete certificate chains when verifies SSL servers certificates.
271 */
272 void useSquidUntrusted(SSL_CTX *sslContext);
273
274 /**
275 \ingroup ServerProtocolSSLAPI
276 * Read certificate, private key and any certificates which must be chained from files.
277 * See also: Ssl::readCertAndPrivateKeyFromFiles function, defined in gadgets.h
278 * \param certFilename name of file with certificate and certificates which must be chainned.
279 * \param keyFilename name of file with private key.
280 */
281 void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, EVP_PKEY_Pointer & pkey, X509_STACK_Pointer & chain, char const * certFilename, char const * keyFilename);
282
283 /**
284 \ingroup ServerProtocolSSLAPI
285 * Iterates over the X509 common and alternate names and to see if matches with given data
286 * using the check_func.
287 \param peer_cert The X509 cert to check
288 \param check_data The data with which the X509 CNs compared
289 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
290 \return 1 if any of the certificate CN matches, 0 if none matches.
291 */
292 int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data));
293
294 /**
295 \ingroup ServerProtocolSSLAPI
296 * Check if the certificate is valid for a server
297 \param cert The X509 cert to check.
298 \param server The server name.
299 \return true if the certificate is valid for the server or false otherwise.
300 */
301 bool checkX509ServerValidity(X509 *cert, const char *server);
302
303 /**
304 \ingroup ServerProtocolSSLAPI
305 * Convert a given ASN1_TIME to a string form.
306 \param tm the time in ASN1_TIME form
307 \param buf the buffer to write the output
308 \param len write at most len bytes
309 \return The number of bytes written
310 */
311 int asn1timeToString(ASN1_TIME *tm, char *buf, int len);
312
313 /**
314 \ingroup ServerProtocolSSLAPI
315 * Sets the hostname for the Server Name Indication (SNI) TLS extension
316 * if supported by the used openssl toolkit.
317 \return true if SNI set false otherwise
318 */
319 bool setClientSNI(SSL *ssl, const char *fqdn);
320
321 } //namespace Ssl
322
323 #if _SQUID_WINDOWS_
324
325 #if defined(__cplusplus)
326
327 /** \cond AUTODOCS-IGNORE */
328 namespace Squid
329 {
330 /** \endcond */
331
332 /// \ingroup ServerProtocolSSLAPI
333 inline
334 int SSL_set_fd(SSL *ssl, int fd)
335 {
336 return ::SSL_set_fd(ssl, _get_osfhandle(fd));
337 }
338
339 /// \ingroup ServerProtocolSSLAPI
340 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
341
342 } /* namespace Squid */
343
344 #else
345
346 /// \ingroup ServerProtocolSSLAPI
347 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
348
349 #endif /* __cplusplus */
350
351 #endif /* _SQUID_WINDOWS_ */
352
353 #endif /* USE_OPENSSL */
354 #endif /* SQUID_SSL_SUPPORT_H */
355