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