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