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