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