]>
Commit | Line | Data |
---|---|---|
f484cdf5 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 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 | ||
0ad3ff51 CT |
40 | // Maximum certificate validation callbacks. OpenSSL versions exceeding this |
41 | // limit are deemed stuck in an infinite validation loop (OpenSSL bug #3090) | |
42 | // and will trigger the SQUID_X509_V_ERR_INFINITE_VALIDATION error. | |
43 | // Can be set to a number up to UINT32_MAX | |
44 | #ifndef SQUID_CERT_VALIDATION_ITERATION_MAX | |
45 | #define SQUID_CERT_VALIDATION_ITERATION_MAX 16384 | |
46 | #endif | |
47 | ||
86660d64 CT |
48 | namespace AnyP |
49 | { | |
50 | class PortCfg; | |
51 | }; | |
52 | ||
824d4656 AJ |
53 | namespace Ipc |
54 | { | |
55 | class MemMap; | |
56 | } | |
57 | ||
02259ff8 CT |
58 | namespace Ssl |
59 | { | |
51e09c08 AJ |
60 | |
61 | /// callback for receiving password to access password secured PEM files | |
62 | /// XXX: Requires SSL_CTX_set_default_passwd_cb_userdata()! | |
63 | int AskPasswordCb(char *buf, int size, int rwflag, void *userdata); | |
64 | ||
0a28c16a AJ |
65 | /// initialize the SSL library global state. |
66 | /// call before generating any SSL context | |
67 | void Initialize(); | |
68 | ||
32f1ca3f AJ |
69 | class CertValidationResponse; |
70 | typedef RefCount<CertValidationResponse> CertValidationResponsePointer; | |
71 | ||
c75aba02 | 72 | /// initialize a TLS server context with OpenSSL specific settings |
b23f5f9c | 73 | bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &); |
02259ff8 | 74 | |
c75aba02 | 75 | /// initialize a TLS client context with OpenSSL specific settings |
983fab6e | 76 | bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, Security::ParsedPortFlags); |
63be0a78 | 77 | |
621f4299 | 78 | /// set the certificate verify callback for a context |
983fab6e | 79 | void ConfigurePeerVerification(Security::ContextPointer &, const Security::ParsedPortFlags); |
80 | void DisablePeerVerification(Security::ContextPointer &); | |
621f4299 | 81 | |
cf487124 AJ |
82 | /// if required, setup callback for generating ephemeral RSA keys |
83 | void MaybeSetupRsaCallback(Security::ContextPointer &); | |
84 | ||
c75aba02 | 85 | } //namespace Ssl |
63be0a78 | 86 | |
63be0a78 | 87 | /// \ingroup ServerProtocolSSLAPI |
a7ad6e4e | 88 | const char *sslGetUserEmail(SSL *ssl); |
63be0a78 | 89 | |
90 | /// \ingroup ServerProtocolSSLAPI | |
00352183 | 91 | const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name); |
63be0a78 | 92 | |
93 | /// \ingroup ServerProtocolSSLAPI | |
00352183 | 94 | const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name); |
63be0a78 | 95 | |
96 | /// \ingroup ServerProtocolSSLAPI | |
12b5040f | 97 | SBuf sslGetUserCertificatePEM(SSL *ssl); |
63be0a78 | 98 | |
99 | /// \ingroup ServerProtocolSSLAPI | |
12b5040f | 100 | SBuf sslGetUserCertificateChainPEM(SSL *ssl); |
a7ad6e4e | 101 | |
95d2589c CT |
102 | namespace Ssl |
103 | { | |
00352183 AR |
104 | /// \ingroup ServerProtocolSSLAPI |
105 | typedef char const *GETX509ATTRIBUTE(X509 *, const char *); | |
12b5040f | 106 | typedef SBuf GETX509PEM(X509 *); |
00352183 AR |
107 | |
108 | /// \ingroup ServerProtocolSSLAPI | |
109 | GETX509ATTRIBUTE GetX509UserAttribute; | |
110 | ||
111 | /// \ingroup ServerProtocolSSLAPI | |
112 | GETX509ATTRIBUTE GetX509CAAttribute; | |
113 | ||
12b5040f DN |
114 | /// \ingroup ServerProtocolSSLAPI |
115 | GETX509PEM GetX509PEM; | |
116 | ||
00352183 AR |
117 | /// \ingroup ServerProtocolSSLAPI |
118 | GETX509ATTRIBUTE GetX509Fingerprint; | |
119 | ||
3c26b00a CT |
120 | extern const EVP_MD *DefaultSignHash; |
121 | ||
caf3666d AR |
122 | /** |
123 | \ingroup ServerProtocolSSLAPI | |
124 | * Supported ssl-bump modes | |
125 | */ | |
1110989a | 126 | enum BumpMode {bumpNone = 0, bumpClientFirst, bumpServerFirst, bumpPeek, bumpStare, bumpBump, bumpSplice, bumpTerminate, /*bumpErr,*/ bumpEnd}; |
5d65362c | 127 | |
caf3666d AR |
128 | /** |
129 | \ingroup ServerProtocolSSLAPI | |
130 | * Short names for ssl-bump modes | |
131 | */ | |
ba6fffba | 132 | extern std::vector<const char *>BumpModeStr; |
caf3666d AR |
133 | |
134 | /** | |
135 | \ingroup ServerProtocolSSLAPI | |
136 | * Return the short name of the ssl-bump mode "bm" | |
137 | */ | |
138 | inline const char *bumpMode(int bm) | |
139 | { | |
aee3523a | 140 | return (0 <= bm && bm < Ssl::bumpEnd) ? Ssl::BumpModeStr.at(bm) : nullptr; |
caf3666d AR |
141 | } |
142 | ||
55369ae6 AR |
143 | /// certificates indexed by issuer name |
144 | typedef std::multimap<SBuf, X509 *> CertsIndexedList; | |
145 | ||
146 | /** | |
55369ae6 AR |
147 | * Load PEM-encoded certificates from the given file. |
148 | */ | |
149 | bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list); | |
150 | ||
151 | /** | |
55369ae6 AR |
152 | * Load PEM-encoded certificates to the squid untrusteds certificates |
153 | * internal DB from the given file. | |
154 | */ | |
155 | bool loadSquidUntrusted(const char *path); | |
156 | ||
157 | /** | |
55369ae6 AR |
158 | * Removes all certificates from squid untrusteds certificates |
159 | * internal DB and frees all memory | |
160 | */ | |
161 | void unloadSquidUntrusted(); | |
162 | ||
163 | /** | |
55369ae6 AR |
164 | * Add the certificate cert to ssl object untrusted certificates. |
165 | * Squid uses an attached to SSL object list of untrusted certificates, | |
166 | * with certificates which can be used to complete incomplete chains sent | |
167 | * by the SSL server. | |
168 | */ | |
169 | void SSL_add_untrusted_cert(SSL *ssl, X509 *cert); | |
170 | ||
800967af CT |
171 | /// finds certificate issuer URI in the Authority Info Access extension |
172 | const char *findIssuerUri(X509 *cert); | |
173 | ||
174 | /// Searches serverCertificates and local databases for the cert issuer. | |
175 | /// \param context where to retrieve the configured CA's db; may be nil | |
176 | /// \returns the found issuer certificate or nil | |
177 | Security::CertPointer findIssuerCertificate(X509 *cert, const STACK_OF(X509) *serverCertificates, const Security::ContextPointer &context); | |
55369ae6 AR |
178 | |
179 | /** | |
55369ae6 AR |
180 | * Fill URIs queue with the uris of missing certificates from serverCertificate chain |
181 | * if this information provided by Authority Info Access. | |
800967af | 182 | \return whether at least one URI is known, including previously known ones |
55369ae6 | 183 | */ |
800967af | 184 | bool missingChainCertificatesUrls(std::queue<SBuf> &URIs, const STACK_OF(X509) &serverCertificates, const Security::ContextPointer &context); |
55369ae6 | 185 | |
aebe6888 CT |
186 | /** |
187 | \ingroup ServerProtocolSSLAPI | |
95588170 | 188 | * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA |
aebe6888 | 189 | */ |
cf487124 | 190 | bool generateUntrustedCert(Security::CertPointer & untrustedCert, Security::PrivateKeyPointer & untrustedPkey, Security::CertPointer const & cert, Security::PrivateKeyPointer const & pkey); |
aebe6888 | 191 | |
866be11c CT |
192 | /// certificates indexed by issuer name |
193 | typedef std::multimap<SBuf, X509 *> CertsIndexedList; | |
194 | ||
195 | /** | |
196 | \ingroup ServerProtocolSSLAPI | |
197 | * Load PEM-encoded certificates from the given file. | |
198 | */ | |
199 | bool loadCerts(const char *certsFile, Ssl::CertsIndexedList &list); | |
200 | ||
201 | /** | |
202 | \ingroup ServerProtocolSSLAPI | |
203 | * Load PEM-encoded certificates to the squid untrusteds certificates | |
204 | * internal DB from the given file. | |
205 | */ | |
206 | bool loadSquidUntrusted(const char *path); | |
207 | ||
208 | /** | |
209 | \ingroup ServerProtocolSSLAPI | |
210 | * Removes all certificates from squid untrusteds certificates | |
211 | * internal DB and frees all memory | |
212 | */ | |
213 | void unloadSquidUntrusted(); | |
214 | ||
95d2589c CT |
215 | /** |
216 | \ingroup ServerProtocolSSLAPI | |
217 | * Decide on the kind of certificate and generate a CA- or self-signed one | |
218 | */ | |
cf487124 | 219 | Security::ContextPointer GenerateSslContext(CertificateProperties const &, Security::ServerOptions &, bool trusted); |
95d2589c CT |
220 | |
221 | /** | |
222 | \ingroup ServerProtocolSSLAPI | |
e7bcc25f CT |
223 | * Check if the certificate of the given context is still valid |
224 | \param sslContext The context to check | |
4ece76b2 | 225 | \param properties Check if the context certificate matches the given properties |
e7bcc25f | 226 | \return true if the contexts certificate is valid, false otherwise |
95d2589c | 227 | */ |
72247610 | 228 | bool verifySslCertificate(const Security::ContextPointer &, CertificateProperties const &); |
95d2589c CT |
229 | |
230 | /** | |
231 | \ingroup ServerProtocolSSLAPI | |
232 | * Read private key and certificate from memory and generate SSL context | |
233 | * using their. | |
234 | */ | |
cf487124 | 235 | Security::ContextPointer GenerateSslContextUsingPkeyAndCertFromMemory(const char * data, Security::ServerOptions &, bool trusted); |
95d2589c | 236 | |
d620ae0e CT |
237 | /** |
238 | \ingroup ServerProtocolSSLAPI | |
239 | * Create an SSL context using the provided certificate and key | |
240 | */ | |
cf487124 | 241 | Security::ContextPointer createSSLContext(Security::CertPointer & x509, Security::PrivateKeyPointer & pkey, Security::ServerOptions &); |
d620ae0e | 242 | |
d8f0ceab CT |
243 | /** |
244 | \ingroup ServerProtocolSSLAPI | |
245 | * Chain signing certificate and chained certificates to an SSL Context | |
246 | */ | |
cf487124 | 247 | void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &); |
d8f0ceab CT |
248 | |
249 | /** | |
250 | \ingroup ServerProtocolSSLAPI | |
251 | * Configure a previously unconfigured SSL context object. | |
252 | */ | |
b23f5f9c | 253 | void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAlgorithm signAlgorithm, AnyP::PortCfg &); |
d8f0ceab | 254 | |
d620ae0e CT |
255 | /** |
256 | \ingroup ServerProtocolSSLAPI | |
2f8abb64 | 257 | * Generates a certificate and a private key using provided properties and set it |
d620ae0e CT |
258 | * to SSL object. |
259 | */ | |
260 | bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port); | |
261 | ||
262 | /** | |
263 | \ingroup ServerProtocolSSLAPI | |
264 | * Read private key and certificate from memory and set it to SSL object | |
265 | * using their. | |
266 | */ | |
267 | bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port); | |
268 | ||
866be11c CT |
269 | /** |
270 | \ingroup ServerProtocolSSLAPI | |
271 | * Configures sslContext to use squid untrusted certificates internal list | |
272 | * to complete certificate chains when verifies SSL servers certificates. | |
273 | */ | |
274 | void useSquidUntrusted(SSL_CTX *sslContext); | |
a594dbfa | 275 | |
4d16918e CT |
276 | /** |
277 | \ingroup ServerProtocolSSLAPI | |
278 | * Iterates over the X509 common and alternate names and to see if matches with given data | |
e34763f4 | 279 | * using the check_func. |
4d16918e CT |
280 | \param peer_cert The X509 cert to check |
281 | \param check_data The data with which the X509 CNs compared | |
282 | \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data | |
283 | \return 1 if any of the certificate CN matches, 0 if none matches. | |
284 | */ | |
285 | int matchX509CommonNames(X509 *peer_cert, void *check_data, int (*check_func)(void *check_data, ASN1_STRING *cn_data)); | |
95d2589c | 286 | |
8eb0a7ee CT |
287 | /** |
288 | \ingroup ServerProtocolSSLAPI | |
289 | * Check if the certificate is valid for a server | |
290 | \param cert The X509 cert to check. | |
291 | \param server The server name. | |
292 | \return true if the certificate is valid for the server or false otherwise. | |
293 | */ | |
294 | bool checkX509ServerValidity(X509 *cert, const char *server); | |
295 | ||
4d16918e CT |
296 | /** |
297 | \ingroup ServerProtocolSSLAPI | |
298 | * Convert a given ASN1_TIME to a string form. | |
299 | \param tm the time in ASN1_TIME form | |
300 | \param buf the buffer to write the output | |
301 | \param len write at most len bytes | |
302 | \return The number of bytes written | |
303 | */ | |
304 | int asn1timeToString(ASN1_TIME *tm, char *buf, int len); | |
305 | ||
253749a8 CT |
306 | /** |
307 | \ingroup ServerProtocolSSLAPI | |
308 | * Sets the hostname for the Server Name Indication (SNI) TLS extension | |
309 | * if supported by the used openssl toolkit. | |
253749a8 | 310 | */ |
428819f3 | 311 | void setClientSNI(SSL *ssl, const char *fqdn); |
d620ae0e | 312 | |
5107d2c4 CT |
313 | /** |
314 | \ingroup ServerProtocolSSLAPI | |
315 | * Generates a unique key based on CertificateProperties object and store it to key | |
316 | */ | |
317 | void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBuf &key); | |
318 | ||
319 | /** | |
320 | \ingroup ServerProtocolSSLAPI | |
64e64225 AR |
321 | Creates and returns an OpenSSL BIO object for writing to `buf` (or throws). |
322 | TODO: Add support for reading from `buf`. | |
5107d2c4 CT |
323 | */ |
324 | BIO *BIO_new_SBuf(SBuf *buf); | |
800967af CT |
325 | |
326 | /// Validates the given TLS connection server certificate chain in conjunction | |
327 | /// with a (possibly empty) set of "extra" intermediate certs. Also consults | |
328 | /// sslproxy_foreign_intermediate_certs. This is a C++/Squid-friendly wrapper of | |
329 | /// OpenSSL "verification callback function" (\ref OpenSSL_vcb_disambiguation). | |
330 | /// OpenSSL has a similar wrapper, ssl_verify_cert_chain(), but that wrapper is | |
331 | /// not a part of the public OpenSSL API. | |
332 | bool VerifyConnCertificates(Security::Connection &, const Ssl::X509_STACK_Pointer &extraCerts); | |
333 | ||
334 | // TODO: Move other ssl_ex_index_* validation-related information here. | |
335 | /// OpenSSL "verify_callback function" input/output parameters. This information | |
336 | /// cannot be passed through the verification API directly, so it is aggregated | |
337 | /// in this class and exchanged via ssl_ex_index_verify_callback_parameters. For | |
338 | /// OpenSSL validation callback details, see \ref OpenSSL_vcb_disambiguation. | |
339 | class VerifyCallbackParameters { | |
340 | public: | |
341 | /// creates a VerifyCallbackParameters object and adds it to the given TLS connection | |
342 | /// \returns the successfully created and added object | |
343 | static VerifyCallbackParameters *New(Security::Connection &); | |
344 | ||
345 | /// \returns the VerifyCallbackParameters object previously attached via New() | |
346 | static VerifyCallbackParameters &At(Security::Connection &); | |
347 | ||
348 | /// \returns the VerifyCallbackParameters object previously attached via New() or nil | |
349 | static VerifyCallbackParameters *Find(Security::Connection &); | |
350 | ||
351 | /* input parameters */ | |
352 | ||
353 | /// whether X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY should be cleared | |
354 | /// (after setting hidMissingIssuer) because the validation initiator wants | |
355 | /// to get the missing certificates and redo the validation with them | |
356 | bool callerHandlesMissingCertificates = false; | |
357 | ||
358 | /* output parameters */ | |
359 | ||
360 | /// whether certificate validation has failed due to missing certificate(s) | |
361 | /// (i.e. X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY), but the failure was | |
362 | /// cleared/hidden due to true callerHandlesMissingCertificates setting; the | |
363 | /// certificate chain has to be deemed untrusted until revalidation (if any) | |
364 | bool hidMissingIssuer = false; | |
365 | }; | |
366 | ||
4d16918e | 367 | } //namespace Ssl |
815eaa44 | 368 | |
7aa9bb3e | 369 | #if _SQUID_WINDOWS_ |
3d73543d | 370 | |
1191b93b | 371 | #if defined(__cplusplus) |
3d73543d | 372 | |
63be0a78 | 373 | /** \cond AUTODOCS-IGNORE */ |
26ac0430 AJ |
374 | namespace Squid |
375 | { | |
63be0a78 | 376 | /** \endcond */ |
3d73543d | 377 | |
63be0a78 | 378 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 379 | inline |
380 | int SSL_set_fd(SSL *ssl, int fd) | |
381 | { | |
382 | return ::SSL_set_fd(ssl, _get_osfhandle(fd)); | |
383 | } | |
384 | ||
63be0a78 | 385 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 386 | #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd) |
387 | ||
388 | } /* namespace Squid */ | |
389 | ||
390 | #else | |
391 | ||
63be0a78 | 392 | /// \ingroup ServerProtocolSSLAPI |
3d73543d | 393 | #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f))) |
394 | ||
395 | #endif /* __cplusplus */ | |
396 | ||
7aa9bb3e | 397 | #endif /* _SQUID_WINDOWS_ */ |
3d73543d | 398 | |
32f1ca3f | 399 | #endif /* USE_OPENSSL */ |
b5638623 | 400 | #endif /* SQUID_SSL_SUPPORT_H */ |
f53969cc | 401 |