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