2 * Copyright (C) 1996-2017 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 "sbuf/SBuf.h"
19 #include "security/forward.h"
20 #include "ssl/gadgets.h"
22 #if HAVE_OPENSSL_X509V3_H
23 #include <openssl/x509v3.h>
25 #if HAVE_OPENSSL_ERR_H
26 #include <openssl/err.h>
28 #if HAVE_OPENSSL_ENGINE_H
29 #include <openssl/engine.h>
35 \defgroup ServerProtocolSSLAPI Server-Side SSL API
36 \ingroup ServerProtocol
39 // Custom SSL errors; assumes all official errors are positive
40 #define SQUID_X509_V_ERR_INFINITE_VALIDATION -4
41 #define SQUID_X509_V_ERR_CERT_CHANGE -3
42 #define SQUID_ERR_SSL_HANDSHAKE -2
43 #define SQUID_X509_V_ERR_DOMAIN_MISMATCH -1
44 // All SSL errors range: from smallest (negative) custom to largest SSL error
45 #define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_CERT_CHANGE
46 #define SQUID_SSL_ERROR_MAX INT_MAX
48 // Maximum certificate validation callbacks. OpenSSL versions exceeding this
49 // limit are deemed stuck in an infinite validation loop (OpenSSL bug #3090)
50 // and will trigger the SQUID_X509_V_ERR_INFINITE_VALIDATION error.
51 // Can be set to a number up to UINT32_MAX
52 #ifndef SQUID_CERT_VALIDATION_ITERATION_MAX
53 #define SQUID_CERT_VALIDATION_ITERATION_MAX 16384
68 /// initialize the SSL library global state.
69 /// call before generating any SSL context
73 class CertValidationResponse
;
74 typedef RefCount
<CertValidationResponse
> CertValidationResponsePointer
;
76 /// initialize a TLS server context with OpenSSL specific settings
77 bool InitServerContext(Security::ContextPointer
&, AnyP::PortCfg
&);
79 /// initialize a TLS client context with OpenSSL specific settings
80 bool InitClientContext(Security::ContextPointer
&, Security::PeerOptions
&, long flags
);
82 /// set the certificate verify callback for a context
83 void SetupVerifyCallback(Security::ContextPointer
&);
85 /// if required, setup callback for generating ephemeral RSA keys
86 void MaybeSetupRsaCallback(Security::ContextPointer
&);
90 /// \ingroup ServerProtocolSSLAPI
91 const char *sslGetUserEmail(SSL
*ssl
);
93 /// \ingroup ServerProtocolSSLAPI
94 const char *sslGetUserAttribute(SSL
*ssl
, const char *attribute_name
);
96 /// \ingroup ServerProtocolSSLAPI
97 const char *sslGetCAAttribute(SSL
*ssl
, const char *attribute_name
);
99 /// \ingroup ServerProtocolSSLAPI
100 const char *sslGetUserCertificatePEM(SSL
*ssl
);
102 /// \ingroup ServerProtocolSSLAPI
103 const char *sslGetUserCertificateChainPEM(SSL
*ssl
);
107 /// \ingroup ServerProtocolSSLAPI
108 typedef char const *GETX509ATTRIBUTE(X509
*, const char *);
110 /// \ingroup ServerProtocolSSLAPI
111 GETX509ATTRIBUTE GetX509UserAttribute
;
113 /// \ingroup ServerProtocolSSLAPI
114 GETX509ATTRIBUTE GetX509CAAttribute
;
116 /// \ingroup ServerProtocolSSLAPI
117 GETX509ATTRIBUTE GetX509Fingerprint
;
119 extern const EVP_MD
*DefaultSignHash
;
122 \ingroup ServerProtocolSSLAPI
123 * Supported ssl-bump modes
125 enum BumpMode
{bumpNone
= 0, bumpClientFirst
, bumpServerFirst
, bumpPeek
, bumpStare
, bumpBump
, bumpSplice
, bumpTerminate
, /*bumpErr,*/ bumpEnd
};
127 enum BumpStep
{bumpStep1
, bumpStep2
, bumpStep3
};
130 \ingroup ServerProtocolSSLAPI
131 * Short names for ssl-bump modes
133 extern std::vector
<const char *>BumpModeStr
;
136 \ingroup ServerProtocolSSLAPI
137 * Return the short name of the ssl-bump mode "bm"
139 inline const char *bumpMode(int bm
)
141 return (0 <= bm
&& bm
< Ssl::bumpEnd
) ? Ssl::BumpModeStr
.at(bm
) : NULL
;
144 /// certificates indexed by issuer name
145 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
148 * Load PEM-encoded certificates from the given file.
150 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
153 * Load PEM-encoded certificates to the squid untrusteds certificates
154 * internal DB from the given file.
156 bool loadSquidUntrusted(const char *path
);
159 * Removes all certificates from squid untrusteds certificates
160 * internal DB and frees all memory
162 void unloadSquidUntrusted();
165 * Add the certificate cert to ssl object untrusted certificates.
166 * Squid uses an attached to SSL object list of untrusted certificates,
167 * with certificates which can be used to complete incomplete chains sent
170 void SSL_add_untrusted_cert(SSL
*ssl
, X509
*cert
);
173 * Searches in serverCertificates list for the cert issuer and if not found
174 * and Authority Info Access of cert provides a URI return it.
176 const char *uriOfIssuerIfMissing(X509
*cert
, Security::CertList
const &serverCertificates
);
179 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
180 * if this information provided by Authority Info Access.
182 void missingChainCertificatesUrls(std::queue
<SBuf
> &URIs
, Security::CertList
const &serverCertificates
);
185 \ingroup ServerProtocolSSLAPI
186 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
188 bool generateUntrustedCert(Security::CertPointer
& untrustedCert
, Security::PrivateKeyPointer
& untrustedPkey
, Security::CertPointer
const & cert
, Security::PrivateKeyPointer
const & pkey
);
190 /// certificates indexed by issuer name
191 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
194 \ingroup ServerProtocolSSLAPI
195 * Load PEM-encoded certificates from the given file.
197 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
200 \ingroup ServerProtocolSSLAPI
201 * Load PEM-encoded certificates to the squid untrusteds certificates
202 * internal DB from the given file.
204 bool loadSquidUntrusted(const char *path
);
207 \ingroup ServerProtocolSSLAPI
208 * Removes all certificates from squid untrusteds certificates
209 * internal DB and frees all memory
211 void unloadSquidUntrusted();
214 \ingroup ServerProtocolSSLAPI
215 * Decide on the kind of certificate and generate a CA- or self-signed one
217 Security::ContextPointer
GenerateSslContext(CertificateProperties
const &, Security::ServerOptions
&, bool trusted
);
220 \ingroup ServerProtocolSSLAPI
221 * Check if the certificate of the given context is still valid
222 \param sslContext The context to check
223 \param properties Check if the context certificate matches the given properties
224 \return true if the contexts certificate is valid, false otherwise
226 bool verifySslCertificate(Security::ContextPointer
&, CertificateProperties
const &);
229 \ingroup ServerProtocolSSLAPI
230 * Read private key and certificate from memory and generate SSL context
233 Security::ContextPointer
GenerateSslContextUsingPkeyAndCertFromMemory(const char * data
, Security::ServerOptions
&, bool trusted
);
236 \ingroup ServerProtocolSSLAPI
237 * Create an SSL context using the provided certificate and key
239 Security::ContextPointer
createSSLContext(Security::CertPointer
& x509
, Security::PrivateKeyPointer
& pkey
, Security::ServerOptions
&);
242 \ingroup ServerProtocolSSLAPI
243 * Chain signing certificate and chained certificates to an SSL Context
245 void chainCertificatesToSSLContext(Security::ContextPointer
&, Security::ServerOptions
&);
248 \ingroup ServerProtocolSSLAPI
249 * Configure a previously unconfigured SSL context object.
251 void configureUnconfiguredSslContext(Security::ContextPointer
&, Ssl::CertSignAlgorithm signAlgorithm
, AnyP::PortCfg
&);
254 \ingroup ServerProtocolSSLAPI
255 * Generates a certificate and a private key using provided properies and set it
258 bool configureSSL(SSL
*ssl
, CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
261 \ingroup ServerProtocolSSLAPI
262 * Read private key and certificate from memory and set it to SSL object
265 bool configureSSLUsingPkeyAndCertFromMemory(SSL
*ssl
, const char *data
, AnyP::PortCfg
&port
);
268 \ingroup ServerProtocolSSLAPI
269 * Adds the certificates in certList to the certificate chain of the SSL context
271 void addChainToSslContext(Security::ContextPointer
&, Security::CertList
&);
274 \ingroup ServerProtocolSSLAPI
275 * Configures sslContext to use squid untrusted certificates internal list
276 * to complete certificate chains when verifies SSL servers certificates.
278 void useSquidUntrusted(SSL_CTX
*sslContext
);
281 \ingroup ServerProtocolSSLAPI
282 * Read certificate, private key and any certificates which must be chained from files.
283 * See also: Ssl::readCertAndPrivateKeyFromFiles function, defined in gadgets.h
284 * \param certFilename name of file with certificate and certificates which must be chainned.
285 * \param keyFilename name of file with private key.
287 void readCertChainAndPrivateKeyFromFiles(Security::CertPointer
& cert
, Security::PrivateKeyPointer
& pkey
, Security::CertList
&chain
, char const * certFilename
, char const * keyFilename
);
290 \ingroup ServerProtocolSSLAPI
291 * Iterates over the X509 common and alternate names and to see if matches with given data
292 * using the check_func.
293 \param peer_cert The X509 cert to check
294 \param check_data The data with which the X509 CNs compared
295 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
296 \return 1 if any of the certificate CN matches, 0 if none matches.
298 int matchX509CommonNames(X509
*peer_cert
, void *check_data
, int (*check_func
)(void *check_data
, ASN1_STRING
*cn_data
));
301 \ingroup ServerProtocolSSLAPI
302 * Check if the certificate is valid for a server
303 \param cert The X509 cert to check.
304 \param server The server name.
305 \return true if the certificate is valid for the server or false otherwise.
307 bool checkX509ServerValidity(X509
*cert
, const char *server
);
310 \ingroup ServerProtocolSSLAPI
311 * Convert a given ASN1_TIME to a string form.
312 \param tm the time in ASN1_TIME form
313 \param buf the buffer to write the output
314 \param len write at most len bytes
315 \return The number of bytes written
317 int asn1timeToString(ASN1_TIME
*tm
, char *buf
, int len
);
320 \ingroup ServerProtocolSSLAPI
321 * Sets the hostname for the Server Name Indication (SNI) TLS extension
322 * if supported by the used openssl toolkit.
323 \return true if SNI set false otherwise
325 bool setClientSNI(SSL
*ssl
, const char *fqdn
);
328 \ingroup ServerProtocolSSLAPI
329 * Generates a unique key based on CertificateProperties object and store it to key
331 void InRamCertificateDbKey(const Ssl::CertificateProperties
&certProperties
, SBuf
&key
);
334 \ingroup ServerProtocolSSLAPI
335 Creates and returns an OpenSSL BIO object for writing to `buf` (or throws).
336 TODO: Add support for reading from `buf`.
338 BIO
*BIO_new_SBuf(SBuf
*buf
);
343 #if defined(__cplusplus)
345 /** \cond AUTODOCS-IGNORE */
350 /// \ingroup ServerProtocolSSLAPI
352 int SSL_set_fd(SSL
*ssl
, int fd
)
354 return ::SSL_set_fd(ssl
, _get_osfhandle(fd
));
357 /// \ingroup ServerProtocolSSLAPI
358 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
360 } /* namespace Squid */
364 /// \ingroup ServerProtocolSSLAPI
365 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
367 #endif /* __cplusplus */
369 #endif /* _SQUID_WINDOWS_ */
371 #endif /* USE_OPENSSL */
372 #endif /* SQUID_SSL_SUPPORT_H */