2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 83 SSL accelerator support */
11 #ifndef SQUID_SSL_SUPPORT_H
12 #define SQUID_SSL_SUPPORT_H
16 #include "base/CbDataList.h"
17 #include "comm/forward.h"
18 #include "compat/openssl.h"
19 #include "sbuf/SBuf.h"
20 #include "security/forward.h"
21 #include "ssl/gadgets.h"
23 #if HAVE_OPENSSL_X509V3_H
24 #include <openssl/x509v3.h>
26 #if HAVE_OPENSSL_ERR_H
27 #include <openssl/err.h>
29 #if HAVE_OPENSSL_ENGINE_H
30 #include <openssl/engine.h>
36 \defgroup ServerProtocolSSLAPI Server-Side SSL API
37 \ingroup ServerProtocol
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
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
);
65 /// initialize the SSL library global state.
66 /// call before generating any SSL context
69 class CertValidationResponse
;
70 typedef RefCount
<CertValidationResponse
> CertValidationResponsePointer
;
72 /// initialize a TLS server context with OpenSSL specific settings
73 bool InitServerContext(Security::ContextPointer
&, AnyP::PortCfg
&);
75 /// initialize a TLS client context with OpenSSL specific settings
76 bool InitClientContext(Security::ContextPointer
&, Security::PeerOptions
&, Security::ParsedPortFlags
);
78 /// set the certificate verify callback for a context
79 void ConfigurePeerVerification(Security::ContextPointer
&, const Security::ParsedPortFlags
);
80 void DisablePeerVerification(Security::ContextPointer
&);
82 /// if required, setup callback for generating ephemeral RSA keys
83 void MaybeSetupRsaCallback(Security::ContextPointer
&);
87 /// \ingroup ServerProtocolSSLAPI
88 const char *sslGetUserEmail(SSL
*ssl
);
90 /// \ingroup ServerProtocolSSLAPI
91 const char *sslGetUserAttribute(SSL
*ssl
, const char *attribute_name
);
93 /// \ingroup ServerProtocolSSLAPI
94 const char *sslGetCAAttribute(SSL
*ssl
, const char *attribute_name
);
96 /// \ingroup ServerProtocolSSLAPI
97 SBuf
sslGetUserCertificatePEM(SSL
*ssl
);
99 /// \ingroup ServerProtocolSSLAPI
100 SBuf
sslGetUserCertificateChainPEM(SSL
*ssl
);
104 /// \ingroup ServerProtocolSSLAPI
105 typedef char const *GETX509ATTRIBUTE(X509
*, const char *);
106 typedef SBuf
GETX509PEM(X509
*);
108 /// \ingroup ServerProtocolSSLAPI
109 GETX509ATTRIBUTE GetX509UserAttribute
;
111 /// \ingroup ServerProtocolSSLAPI
112 GETX509ATTRIBUTE GetX509CAAttribute
;
114 /// \ingroup ServerProtocolSSLAPI
115 GETX509PEM GetX509PEM
;
117 /// \ingroup ServerProtocolSSLAPI
118 GETX509ATTRIBUTE GetX509Fingerprint
;
120 extern const EVP_MD
*DefaultSignHash
;
123 \ingroup ServerProtocolSSLAPI
124 * Supported ssl-bump modes
126 enum BumpMode
{bumpNone
= 0, bumpClientFirst
, bumpServerFirst
, bumpPeek
, bumpStare
, bumpBump
, bumpSplice
, bumpTerminate
, /*bumpErr,*/ bumpEnd
};
129 \ingroup ServerProtocolSSLAPI
130 * Short names for ssl-bump modes
132 extern std::vector
<const char *>BumpModeStr
;
135 \ingroup ServerProtocolSSLAPI
136 * Return the short name of the ssl-bump mode "bm"
138 inline const char *bumpMode(int bm
)
140 return (0 <= bm
&& bm
< Ssl::bumpEnd
) ? Ssl::BumpModeStr
.at(bm
) : NULL
;
143 /// certificates indexed by issuer name
144 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
147 * Load PEM-encoded certificates from the given file.
149 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
152 * Load PEM-encoded certificates to the squid untrusteds certificates
153 * internal DB from the given file.
155 bool loadSquidUntrusted(const char *path
);
158 * Removes all certificates from squid untrusteds certificates
159 * internal DB and frees all memory
161 void unloadSquidUntrusted();
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
169 void SSL_add_untrusted_cert(SSL
*ssl
, X509
*cert
);
172 * Searches in serverCertificates list for the cert issuer and if not found
173 * and Authority Info Access of cert provides a URI return it.
175 const char *uriOfIssuerIfMissing(X509
*cert
, Security::CertList
const &serverCertificates
, const Security::ContextPointer
&context
);
178 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
179 * if this information provided by Authority Info Access.
181 void missingChainCertificatesUrls(std::queue
<SBuf
> &URIs
, Security::CertList
const &serverCertificates
, const Security::ContextPointer
&context
);
184 \ingroup ServerProtocolSSLAPI
185 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
187 bool generateUntrustedCert(Security::CertPointer
& untrustedCert
, Security::PrivateKeyPointer
& untrustedPkey
, Security::CertPointer
const & cert
, Security::PrivateKeyPointer
const & pkey
);
189 /// certificates indexed by issuer name
190 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
193 \ingroup ServerProtocolSSLAPI
194 * Load PEM-encoded certificates from the given file.
196 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
199 \ingroup ServerProtocolSSLAPI
200 * Load PEM-encoded certificates to the squid untrusteds certificates
201 * internal DB from the given file.
203 bool loadSquidUntrusted(const char *path
);
206 \ingroup ServerProtocolSSLAPI
207 * Removes all certificates from squid untrusteds certificates
208 * internal DB and frees all memory
210 void unloadSquidUntrusted();
213 \ingroup ServerProtocolSSLAPI
214 * Decide on the kind of certificate and generate a CA- or self-signed one
216 Security::ContextPointer
GenerateSslContext(CertificateProperties
const &, Security::ServerOptions
&, bool trusted
);
219 \ingroup ServerProtocolSSLAPI
220 * Check if the certificate of the given context is still valid
221 \param sslContext The context to check
222 \param properties Check if the context certificate matches the given properties
223 \return true if the contexts certificate is valid, false otherwise
225 bool verifySslCertificate(const Security::ContextPointer
&, CertificateProperties
const &);
228 \ingroup ServerProtocolSSLAPI
229 * Read private key and certificate from memory and generate SSL context
232 Security::ContextPointer
GenerateSslContextUsingPkeyAndCertFromMemory(const char * data
, Security::ServerOptions
&, bool trusted
);
235 \ingroup ServerProtocolSSLAPI
236 * Create an SSL context using the provided certificate and key
238 Security::ContextPointer
createSSLContext(Security::CertPointer
& x509
, Security::PrivateKeyPointer
& pkey
, Security::ServerOptions
&);
241 \ingroup ServerProtocolSSLAPI
242 * Chain signing certificate and chained certificates to an SSL Context
244 void chainCertificatesToSSLContext(Security::ContextPointer
&, Security::ServerOptions
&);
247 \ingroup ServerProtocolSSLAPI
248 * Configure a previously unconfigured SSL context object.
250 void configureUnconfiguredSslContext(Security::ContextPointer
&, Ssl::CertSignAlgorithm signAlgorithm
, AnyP::PortCfg
&);
253 \ingroup ServerProtocolSSLAPI
254 * Generates a certificate and a private key using provided properties and set it
257 bool configureSSL(SSL
*ssl
, CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
260 \ingroup ServerProtocolSSLAPI
261 * Read private key and certificate from memory and set it to SSL object
264 bool configureSSLUsingPkeyAndCertFromMemory(SSL
*ssl
, const char *data
, AnyP::PortCfg
&port
);
267 \ingroup ServerProtocolSSLAPI
268 * Configures sslContext to use squid untrusted certificates internal list
269 * to complete certificate chains when verifies SSL servers certificates.
271 void useSquidUntrusted(SSL_CTX
*sslContext
);
274 \ingroup ServerProtocolSSLAPI
275 * Iterates over the X509 common and alternate names and to see if matches with given data
276 * using the check_func.
277 \param peer_cert The X509 cert to check
278 \param check_data The data with which the X509 CNs compared
279 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
280 \return 1 if any of the certificate CN matches, 0 if none matches.
282 int matchX509CommonNames(X509
*peer_cert
, void *check_data
, int (*check_func
)(void *check_data
, ASN1_STRING
*cn_data
));
285 \ingroup ServerProtocolSSLAPI
286 * Check if the certificate is valid for a server
287 \param cert The X509 cert to check.
288 \param server The server name.
289 \return true if the certificate is valid for the server or false otherwise.
291 bool checkX509ServerValidity(X509
*cert
, const char *server
);
294 \ingroup ServerProtocolSSLAPI
295 * Convert a given ASN1_TIME to a string form.
296 \param tm the time in ASN1_TIME form
297 \param buf the buffer to write the output
298 \param len write at most len bytes
299 \return The number of bytes written
301 int asn1timeToString(ASN1_TIME
*tm
, char *buf
, int len
);
304 \ingroup ServerProtocolSSLAPI
305 * Sets the hostname for the Server Name Indication (SNI) TLS extension
306 * if supported by the used openssl toolkit.
308 void setClientSNI(SSL
*ssl
, const char *fqdn
);
311 \ingroup ServerProtocolSSLAPI
312 * Generates a unique key based on CertificateProperties object and store it to key
314 void InRamCertificateDbKey(const Ssl::CertificateProperties
&certProperties
, SBuf
&key
);
317 \ingroup ServerProtocolSSLAPI
318 Creates and returns an OpenSSL BIO object for writing to `buf` (or throws).
319 TODO: Add support for reading from `buf`.
321 BIO
*BIO_new_SBuf(SBuf
*buf
);
326 #if defined(__cplusplus)
328 /** \cond AUTODOCS-IGNORE */
333 /// \ingroup ServerProtocolSSLAPI
335 int SSL_set_fd(SSL
*ssl
, int fd
)
337 return ::SSL_set_fd(ssl
, _get_osfhandle(fd
));
340 /// \ingroup ServerProtocolSSLAPI
341 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
343 } /* namespace Squid */
347 /// \ingroup ServerProtocolSSLAPI
348 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
350 #endif /* __cplusplus */
352 #endif /* _SQUID_WINDOWS_ */
354 #endif /* USE_OPENSSL */
355 #endif /* SQUID_SSL_SUPPORT_H */