]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ssl/support.h
Maintenance: Removed most NULLs using modernize-use-nullptr (#1075)
[thirdparty/squid.git] / src / ssl / support.h
CommitLineData
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
48namespace AnyP
49{
50class PortCfg;
51};
52
824d4656
AJ
53namespace Ipc
54{
55class MemMap;
56}
57
02259ff8
CT
58namespace 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()!
63int 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
67void Initialize();
68
32f1ca3f
AJ
69class CertValidationResponse;
70typedef RefCount<CertValidationResponse> CertValidationResponsePointer;
71
c75aba02 72/// initialize a TLS server context with OpenSSL specific settings
b23f5f9c 73bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &);
02259ff8 74
c75aba02 75/// initialize a TLS client context with OpenSSL specific settings
983fab6e 76bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, Security::ParsedPortFlags);
63be0a78 77
621f4299 78/// set the certificate verify callback for a context
983fab6e 79void ConfigurePeerVerification(Security::ContextPointer &, const Security::ParsedPortFlags);
80void DisablePeerVerification(Security::ContextPointer &);
621f4299 81
cf487124
AJ
82/// if required, setup callback for generating ephemeral RSA keys
83void MaybeSetupRsaCallback(Security::ContextPointer &);
84
c75aba02 85} //namespace Ssl
63be0a78 86
63be0a78 87/// \ingroup ServerProtocolSSLAPI
a7ad6e4e 88const char *sslGetUserEmail(SSL *ssl);
63be0a78 89
90/// \ingroup ServerProtocolSSLAPI
00352183 91const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name);
63be0a78 92
93/// \ingroup ServerProtocolSSLAPI
00352183 94const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name);
63be0a78 95
96/// \ingroup ServerProtocolSSLAPI
12b5040f 97SBuf sslGetUserCertificatePEM(SSL *ssl);
63be0a78 98
99/// \ingroup ServerProtocolSSLAPI
12b5040f 100SBuf sslGetUserCertificateChainPEM(SSL *ssl);
a7ad6e4e 101
95d2589c
CT
102namespace Ssl
103{
00352183
AR
104/// \ingroup ServerProtocolSSLAPI
105typedef char const *GETX509ATTRIBUTE(X509 *, const char *);
12b5040f 106typedef SBuf GETX509PEM(X509 *);
00352183
AR
107
108/// \ingroup ServerProtocolSSLAPI
109GETX509ATTRIBUTE GetX509UserAttribute;
110
111/// \ingroup ServerProtocolSSLAPI
112GETX509ATTRIBUTE GetX509CAAttribute;
113
12b5040f
DN
114/// \ingroup ServerProtocolSSLAPI
115GETX509PEM GetX509PEM;
116
00352183
AR
117/// \ingroup ServerProtocolSSLAPI
118GETX509ATTRIBUTE GetX509Fingerprint;
119
3c26b00a
CT
120extern const EVP_MD *DefaultSignHash;
121
caf3666d
AR
122/**
123 \ingroup ServerProtocolSSLAPI
124 * Supported ssl-bump modes
125 */
1110989a 126enum 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 132extern std::vector<const char *>BumpModeStr;
caf3666d
AR
133
134/**
135 \ingroup ServerProtocolSSLAPI
136 * Return the short name of the ssl-bump mode "bm"
137 */
138inline 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
144typedef std::multimap<SBuf, X509 *> CertsIndexedList;
145
146/**
55369ae6
AR
147 * Load PEM-encoded certificates from the given file.
148 */
149bool 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 */
155bool loadSquidUntrusted(const char *path);
156
157/**
55369ae6
AR
158 * Removes all certificates from squid untrusteds certificates
159 * internal DB and frees all memory
160 */
161void 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 */
169void SSL_add_untrusted_cert(SSL *ssl, X509 *cert);
170
800967af
CT
171/// finds certificate issuer URI in the Authority Info Access extension
172const 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
177Security::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 184bool 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 190bool 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
193typedef std::multimap<SBuf, X509 *> CertsIndexedList;
194
195/**
196 \ingroup ServerProtocolSSLAPI
197 * Load PEM-encoded certificates from the given file.
198 */
199bool 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 */
206bool 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 */
213void 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 219Security::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 228bool 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 235Security::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 241Security::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 247void chainCertificatesToSSLContext(Security::ContextPointer &, Security::ServerOptions &);
d8f0ceab
CT
248
249/**
250 \ingroup ServerProtocolSSLAPI
251 * Configure a previously unconfigured SSL context object.
252 */
b23f5f9c 253void 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 */
260bool 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 */
267bool 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 */
274void 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 */
285int 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 */
294bool 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 */
304int 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 311void 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 */
317void 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 */
324BIO *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.
332bool 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.
339class VerifyCallbackParameters {
340public:
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
374namespace Squid
375{
63be0a78 376/** \endcond */
3d73543d 377
63be0a78 378/// \ingroup ServerProtocolSSLAPI
3d73543d 379inline
380int 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