]>
Commit | Line | Data |
---|---|---|
f484cdf5 | 1 | /* |
77b1029d | 2 | * Copyright (C) 1996-2020 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 | |
32f1ca3f AJ |
14 | #if USE_OPENSSL |
15 | ||
b0c2361b | 16 | #include "base/CbDataList.h" |
157c5ace | 17 | #include "comm/forward.h" |
24b30fdc | 18 | #include "compat/openssl.h" |
65e41a45 | 19 | #include "sbuf/SBuf.h" |
f97700a0 | 20 | #include "security/forward.h" |
95d2589c CT |
21 | #include "ssl/gadgets.h" |
22 | ||
8cd03ece AJ |
23 | #if HAVE_OPENSSL_X509V3_H |
24 | #include <openssl/x509v3.h> | |
25 | #endif | |
f484cdf5 | 26 | #if HAVE_OPENSSL_ERR_H |
27 | #include <openssl/err.h> | |
28 | #endif | |
a7ad6e4e | 29 | #if HAVE_OPENSSL_ENGINE_H |
30 | #include <openssl/engine.h> | |
31 | #endif | |
55369ae6 AR |
32 | #include <queue> |
33 | #include <map> | |
34 | ||
63be0a78 | 35 | /** |
36 | \defgroup ServerProtocolSSLAPI Server-Side SSL API | |
37 | \ingroup ServerProtocol | |
38 | */ | |
39 | ||
02259ff8 | 40 | // Custom SSL errors; assumes all official errors are positive |
0ad3ff51 | 41 | #define SQUID_X509_V_ERR_INFINITE_VALIDATION -4 |
e7bcc25f | 42 | #define SQUID_X509_V_ERR_CERT_CHANGE -3 |
8e9bae99 | 43 | #define SQUID_ERR_SSL_HANDSHAKE -2 |
02259ff8 CT |
44 | #define SQUID_X509_V_ERR_DOMAIN_MISMATCH -1 |
45 | // All SSL errors range: from smallest (negative) custom to largest SSL error | |
e7bcc25f | 46 | #define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_CERT_CHANGE |
02259ff8 CT |
47 | #define SQUID_SSL_ERROR_MAX INT_MAX |
48 | ||
0ad3ff51 CT |
49 | // Maximum certificate validation callbacks. OpenSSL versions exceeding this |
50 | // limit are deemed stuck in an infinite validation loop (OpenSSL bug #3090) | |
51 | // and will trigger the SQUID_X509_V_ERR_INFINITE_VALIDATION error. | |
52 | // Can be set to a number up to UINT32_MAX | |
53 | #ifndef SQUID_CERT_VALIDATION_ITERATION_MAX | |
54 | #define SQUID_CERT_VALIDATION_ITERATION_MAX 16384 | |
55 | #endif | |
56 | ||
86660d64 CT |
57 | namespace AnyP |
58 | { | |
59 | class PortCfg; | |
60 | }; | |
61 | ||
824d4656 AJ |
62 | namespace Ipc |
63 | { | |
64 | class MemMap; | |
65 | } | |
66 | ||
02259ff8 CT |
67 | namespace Ssl |
68 | { | |
51e09c08 AJ |
69 | |
70 | /// callback for receiving password to access password secured PEM files | |
71 | /// XXX: Requires SSL_CTX_set_default_passwd_cb_userdata()! | |
72 | int AskPasswordCb(char *buf, int size, int rwflag, void *userdata); | |
73 | ||
0a28c16a AJ |
74 | /// initialize the SSL library global state. |
75 | /// call before generating any SSL context | |
76 | void Initialize(); | |
77 | ||
32f1ca3f AJ |
78 | class ErrorDetail; |
79 | class CertValidationResponse; | |
80 | typedef RefCount<CertValidationResponse> CertValidationResponsePointer; | |
81 | ||
c75aba02 | 82 | /// initialize a TLS server context with OpenSSL specific settings |
b23f5f9c | 83 | bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &); |
02259ff8 | 84 | |
c75aba02 | 85 | /// initialize a TLS client context with OpenSSL specific settings |
cc488ec9 | 86 | bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, long flags); |
63be0a78 | 87 | |
621f4299 AJ |
88 | /// set the certificate verify callback for a context |
89 | void SetupVerifyCallback(Security::ContextPointer &); | |
90 | ||
cf487124 AJ |
91 | /// if required, setup callback for generating ephemeral RSA keys |
92 | void MaybeSetupRsaCallback(Security::ContextPointer &); | |
93 | ||
c75aba02 | 94 | } //namespace Ssl |
63be0a78 | 95 | |
63be0a78 | 96 | /// \ingroup ServerProtocolSSLAPI |
a7ad6e4e | 97 | const char *sslGetUserEmail(SSL *ssl); |
63be0a78 | 98 | |
99 | /// \ingroup ServerProtocolSSLAPI | |
00352183 | 100 | const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name); |
63be0a78 | 101 | |
102 | /// \ingroup ServerProtocolSSLAPI | |
00352183 | 103 | const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name); |
63be0a78 | 104 | |
105 | /// \ingroup ServerProtocolSSLAPI | |
12b5040f | 106 | SBuf sslGetUserCertificatePEM(SSL *ssl); |
63be0a78 | 107 | |
108 | /// \ingroup ServerProtocolSSLAPI | |
12b5040f | 109 | SBuf sslGetUserCertificateChainPEM(SSL *ssl); |
a7ad6e4e | 110 | |
95d2589c CT |
111 | namespace Ssl |
112 | { | |
00352183 AR |
113 | /// \ingroup ServerProtocolSSLAPI |
114 | typedef char const *GETX509ATTRIBUTE(X509 *, const char *); | |
12b5040f | 115 | typedef SBuf GETX509PEM(X509 *); |
00352183 AR |
116 | |
117 | /// \ingroup ServerProtocolSSLAPI | |
118 | GETX509ATTRIBUTE GetX509UserAttribute; | |
119 | ||
120 | /// \ingroup ServerProtocolSSLAPI | |
121 | GETX509ATTRIBUTE GetX509CAAttribute; | |
122 | ||
12b5040f DN |
123 | /// \ingroup ServerProtocolSSLAPI |
124 | GETX509PEM GetX509PEM; | |
125 | ||
00352183 AR |
126 | /// \ingroup ServerProtocolSSLAPI |
127 | GETX509ATTRIBUTE GetX509Fingerprint; | |
128 | ||
3c26b00a CT |
129 | extern const EVP_MD *DefaultSignHash; |
130 | ||
caf3666d AR |
131 | /** |
132 | \ingroup ServerProtocolSSLAPI | |
133 | * Supported ssl-bump modes | |
134 | */ | |
1110989a | 135 | enum BumpMode {bumpNone = 0, bumpClientFirst, bumpServerFirst, bumpPeek, bumpStare, bumpBump, bumpSplice, bumpTerminate, /*bumpErr,*/ bumpEnd}; |
5d65362c | 136 | |
caf3666d AR |
137 | /** |
138 | \ingroup ServerProtocolSSLAPI | |
139 | * Short names for ssl-bump modes | |
140 | */ | |
ba6fffba | 141 | extern std::vector<const char *>BumpModeStr; |
caf3666d AR |
142 | |
143 | /** | |
144 | \ingroup ServerProtocolSSLAPI | |
145 | * Return the short name of the ssl-bump mode "bm" | |
146 | */ | |
147 | inline const char *bumpMode(int bm) | |
148 | { | |
ba6fffba | 149 | return (0 <= bm && bm < Ssl::bumpEnd) ? Ssl::BumpModeStr.at(bm) : NULL; |
caf3666d AR |
150 | } |
151 | ||
55369ae6 AR |
152 | /// certificates indexed by issuer name |
153 | typedef std::multimap<SBuf, X509 *> CertsIndexedList; | |
154 | ||
155 | /** | |
55369ae6 AR |
156 | * Load PEM-encoded certificates from the given file. |
157 | */ | |
158 | bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list); | |
159 | ||
160 | /** | |
55369ae6 AR |
161 | * Load PEM-encoded certificates to the squid untrusteds certificates |
162 | * internal DB from the given file. | |
163 | */ | |
164 | bool loadSquidUntrusted(const char *path); | |
165 | ||
166 | /** | |
55369ae6 AR |
167 | * Removes all certificates from squid untrusteds certificates |
168 | * internal DB and frees all memory | |
169 | */ | |
170 | void unloadSquidUntrusted(); | |
171 | ||
172 | /** | |
55369ae6 AR |
173 | * Add the certificate cert to ssl object untrusted certificates. |
174 | * Squid uses an attached to SSL object list of untrusted certificates, | |
175 | * with certificates which can be used to complete incomplete chains sent | |
176 | * by the SSL server. | |
177 | */ | |
178 | void SSL_add_untrusted_cert(SSL *ssl, X509 *cert); | |
179 | ||
180 | /** | |
55369ae6 AR |
181 | * Searches in serverCertificates list for the cert issuer and if not found |
182 | * and Authority Info Access of cert provides a URI return it. | |
183 | */ | |
9fdbe165 | 184 | const char *uriOfIssuerIfMissing(X509 *cert, Security::CertList const &serverCertificates, const Security::ContextPointer &context); |
55369ae6 AR |
185 | |
186 | /** | |
55369ae6 AR |
187 | * Fill URIs queue with the uris of missing certificates from serverCertificate chain |
188 | * if this information provided by Authority Info Access. | |
189 | */ | |
9fdbe165 | 190 | void missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context); |
55369ae6 | 191 | |
aebe6888 CT |
192 | /** |
193 | \ingroup ServerProtocolSSLAPI | |
95588170 | 194 | * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA |
aebe6888 | 195 | */ |
cf487124 | 196 | bool generateUntrustedCert(Security::CertPointer & untrustedCert, Security::PrivateKeyPointer & untrustedPkey, Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey); |
aebe6888 | 197 | |
866be11c CT |
198 | /// certificates indexed by issuer name |
199 | typedef std::multimap<SBuf, X509 *> CertsIndexedList; | |
200 | ||
201 | /** | |
202 | \ingroup ServerProtocolSSLAPI | |
203 | * Load PEM-encoded certificates from the given file. | |
204 | */ | |
205 | bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list); | |
206 | ||
207 | /** | |
208 | \ingroup ServerProtocolSSLAPI | |
209 | * Load PEM-encoded certificates to the squid untrusteds certificates | |
210 | * internal DB from the given file. | |
211 | */ | |
212 | bool loadSquidUntrusted(const char *path); | |
213 | ||
214 | /** | |
215 | \ingroup ServerProtocolSSLAPI | |
216 | * Removes all certificates from squid untrusteds certificates | |
217 | * internal DB and frees all memory | |
218 | */ | |
219 | void unloadSquidUntrusted(); | |
220 | ||
95d2589c CT |
221 | /** |
222 | \ingroup ServerProtocolSSLAPI | |
223 | * Decide on the kind of certificate and generate a CA- or self-signed one | |
224 | */ | |
cf487124 | 225 | Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool trusted); |
95d2589c CT |
226 | |
227 | /** | |
228 | \ingroup ServerProtocolSSLAPI | |
e7bcc25f CT |
229 | * Check if the certificate of the given context is still valid |
230 | \param sslContext The context to check | |
4ece76b2 | 231 | \param properties Check if the context certificate matches the given properties |
e7bcc25f | 232 | \return true if the contexts certificate is valid, false otherwise |
95d2589c | 233 | */ |
b23f5f9c | 234 | bool verifySslCertificate(Security::ContextPointer &, CertificateProperties const &); |
95d2589c CT |
235 | |
236 | /** | |
237 | \ingroup ServerProtocolSSLAPI | |
238 | * Read private key and certificate from memory and generate SSL context | |
239 | * using their. | |
240 | */ | |
cf487124 | 241 | Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &, bool trusted); |
95d2589c | 242 | |
d620ae0e CT |
243 | /** |
244 | \ingroup ServerProtocolSSLAPI | |
245 | * Create an SSL context using the provided certificate and key | |
246 | */ | |
cf487124 | 247 | Security::ContextPointer createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &); |
d620ae0e | 248 | |
d8f0ceab CT |
249 | /** |
250 | \ingroup ServerProtocolSSLAPI | |
251 | * Chain signing certificate and chained certificates to an SSL Context | |
252 | */ | |
cf487124 | 253 | void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &); |
d8f0ceab CT |
254 | |
255 | /** | |
256 | \ingroup ServerProtocolSSLAPI | |
257 | * Configure a previously unconfigured SSL context object. | |
258 | */ | |
b23f5f9c | 259 | void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAlgorithm signAlgorithm, AnyP::PortCfg &); |
d8f0ceab | 260 | |
d620ae0e CT |
261 | /** |
262 | \ingroup ServerProtocolSSLAPI | |
263 | * Generates a certificate and a private key using provided properies and set it | |
264 | * to SSL object. | |
265 | */ | |
266 | bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port); | |
267 | ||
268 | /** | |
269 | \ingroup ServerProtocolSSLAPI | |
270 | * Read private key and certificate from memory and set it to SSL object | |
271 | * using their. | |
272 | */ | |
273 | bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port); | |
274 | ||
866be11c CT |
275 | /** |
276 | \ingroup ServerProtocolSSLAPI | |
277 | * Configures sslContext to use squid untrusted certificates internal list | |
278 | * to complete certificate chains when verifies SSL servers certificates. | |
279 | */ | |
280 | void useSquidUntrusted(SSL_CTX *sslContext); | |
a594dbfa | 281 | |
4d16918e CT |
282 | /** |
283 | \ingroup ServerProtocolSSLAPI | |
284 | * Iterates over the X509 common and alternate names and to see if matches with given data | |
e34763f4 | 285 | * using the check_func. |
4d16918e CT |
286 | \param peer_cert The X509 cert to check |
287 | \param check_data The data with which the X509 CNs compared | |
288 | \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data | |
289 | \return 1 if any of the certificate CN matches, 0 if none matches. | |
290 | */ | |
291 | int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data)); | |
95d2589c | 292 | |
8eb0a7ee CT |
293 | /** |
294 | \ingroup ServerProtocolSSLAPI | |
295 | * Check if the certificate is valid for a server | |
296 | \param cert The X509 cert to check. | |
297 | \param server The server name. | |
298 | \return true if the certificate is valid for the server or false otherwise. | |
299 | */ | |
300 | bool checkX509ServerValidity(X509 *cert, const char *server); | |
301 | ||
4d16918e CT |
302 | /** |
303 | \ingroup ServerProtocolSSLAPI | |
304 | * Convert a given ASN1_TIME to a string form. | |
305 | \param tm the time in ASN1_TIME form | |
306 | \param buf the buffer to write the output | |
307 | \param len write at most len bytes | |
308 | \return The number of bytes written | |
309 | */ | |
310 | int asn1timeToString(ASN1_TIME *tm, char *buf, int len); | |
311 | ||
253749a8 CT |
312 | /** |
313 | \ingroup ServerProtocolSSLAPI | |
314 | * Sets the hostname for the Server Name Indication (SNI) TLS extension | |
315 | * if supported by the used openssl toolkit. | |
253749a8 | 316 | */ |
428819f3 | 317 | void setClientSNI(SSL *ssl, const char *fqdn); |
d620ae0e | 318 | |
5107d2c4 CT |
319 | /** |
320 | \ingroup ServerProtocolSSLAPI | |
321 | * Generates a unique key based on CertificateProperties object and store it to key | |
322 | */ | |
323 | void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key); | |
324 | ||
325 | /** | |
326 | \ingroup ServerProtocolSSLAPI | |
64e64225 AR |
327 | Creates and returns an OpenSSL BIO object for writing to `buf` (or throws). |
328 | TODO: Add support for reading from `buf`. | |
5107d2c4 CT |
329 | */ |
330 | BIO *BIO_new_SBuf(SBuf *buf); | |
4d16918e | 331 | } //namespace Ssl |
815eaa44 | 332 | |
7aa9bb3e | 333 | #if _SQUID_WINDOWS_ |
3d73543d | 334 | |
1191b93b | 335 | #if defined(__cplusplus) |
3d73543d | 336 | |
63be0a78 | 337 | /** \cond AUTODOCS-IGNORE */ |
26ac0430 AJ |
338 | namespace Squid |
339 | { | |
63be0a78 | 340 | /** \endcond */ |
3d73543d | 341 | |
63be0a78 | 342 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 343 | inline |
344 | int SSL_set_fd(SSL *ssl, int fd) | |
345 | { | |
346 | return ::SSL_set_fd(ssl, _get_osfhandle(fd)); | |
347 | } | |
348 | ||
63be0a78 | 349 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 350 | #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd) |
351 | ||
352 | } /* namespace Squid */ | |
353 | ||
354 | #else | |
355 | ||
63be0a78 | 356 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 357 | #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f))) |
358 | ||
359 | #endif /* __cplusplus */ | |
360 | ||
7aa9bb3e | 361 | #endif /* _SQUID_WINDOWS_ */ |
3d73543d | 362 | |
32f1ca3f | 363 | #endif /* USE_OPENSSL */ |
b5638623 | 364 | #endif /* SQUID_SSL_SUPPORT_H */ |
f53969cc | 365 |