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