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