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
&);
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 const char *sslGetUserCertificatePEM(SSL
*ssl
);
99 /// \ingroup ServerProtocolSSLAPI
100 const char *sslGetUserCertificateChainPEM(SSL
*ssl
);
104 /// \ingroup ServerProtocolSSLAPI
105 typedef char const *GETX509ATTRIBUTE(X509
*, const char *);
107 /// \ingroup ServerProtocolSSLAPI
108 GETX509ATTRIBUTE GetX509UserAttribute
;
110 /// \ingroup ServerProtocolSSLAPI
111 GETX509ATTRIBUTE GetX509CAAttribute
;
113 /// \ingroup ServerProtocolSSLAPI
114 GETX509ATTRIBUTE GetX509Fingerprint
;
116 extern const EVP_MD
*DefaultSignHash
;
119 \ingroup ServerProtocolSSLAPI
120 * Supported ssl-bump modes
122 enum BumpMode
{bumpNone
= 0, bumpClientFirst
, bumpServerFirst
, bumpPeek
, bumpStare
, bumpBump
, bumpSplice
, bumpTerminate
, /*bumpErr,*/ bumpEnd
};
124 enum BumpStep
{bumpStep1
, bumpStep2
, bumpStep3
};
127 \ingroup ServerProtocolSSLAPI
128 * Short names for ssl-bump modes
130 extern std::vector
<const char *>BumpModeStr
;
133 \ingroup ServerProtocolSSLAPI
134 * Return the short name of the ssl-bump mode "bm"
136 inline const char *bumpMode(int bm
)
138 return (0 <= bm
&& bm
< Ssl::bumpEnd
) ? Ssl::BumpModeStr
.at(bm
) : NULL
;
141 /// certificates indexed by issuer name
142 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
145 * Load PEM-encoded certificates from the given file.
147 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
150 * Load PEM-encoded certificates to the squid untrusteds certificates
151 * internal DB from the given file.
153 bool loadSquidUntrusted(const char *path
);
156 * Removes all certificates from squid untrusteds certificates
157 * internal DB and frees all memory
159 void unloadSquidUntrusted();
162 * Add the certificate cert to ssl object untrusted certificates.
163 * Squid uses an attached to SSL object list of untrusted certificates,
164 * with certificates which can be used to complete incomplete chains sent
167 void SSL_add_untrusted_cert(SSL
*ssl
, X509
*cert
);
170 * Searches in serverCertificates list for the cert issuer and if not found
171 * and Authority Info Access of cert provides a URI return it.
173 const char *uriOfIssuerIfMissing(X509
*cert
, Security::CertList
const &serverCertificates
);
176 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
177 * if this information provided by Authority Info Access.
179 void missingChainCertificatesUrls(std::queue
<SBuf
> &URIs
, Security::CertList
const &serverCertificates
);
182 \ingroup ServerProtocolSSLAPI
183 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
185 bool generateUntrustedCert(Security::CertPointer
& untrustedCert
, EVP_PKEY_Pointer
& untrustedPkey
, Security::CertPointer
const & cert
, EVP_PKEY_Pointer
const & pkey
);
187 /// certificates indexed by issuer name
188 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
191 \ingroup ServerProtocolSSLAPI
192 * Load PEM-encoded certificates from the given file.
194 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
197 \ingroup ServerProtocolSSLAPI
198 * Load PEM-encoded certificates to the squid untrusteds certificates
199 * internal DB from the given file.
201 bool loadSquidUntrusted(const char *path
);
204 \ingroup ServerProtocolSSLAPI
205 * Removes all certificates from squid untrusteds certificates
206 * internal DB and frees all memory
208 void unloadSquidUntrusted();
211 \ingroup ServerProtocolSSLAPI
212 * Decide on the kind of certificate and generate a CA- or self-signed one
214 Security::ContextPointer
generateSslContext(CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
217 \ingroup ServerProtocolSSLAPI
218 * Check if the certificate of the given context is still valid
219 \param sslContext The context to check
220 \param properties Check if the context certificate matches the given properties
221 \return true if the contexts certificate is valid, false otherwise
223 bool verifySslCertificate(Security::ContextPointer
&, CertificateProperties
const &);
226 \ingroup ServerProtocolSSLAPI
227 * Read private key and certificate from memory and generate SSL context
230 Security::ContextPointer
generateSslContextUsingPkeyAndCertFromMemory(const char * data
, AnyP::PortCfg
&port
);
233 \ingroup ServerProtocolSSLAPI
234 * Create an SSL context using the provided certificate and key
236 Security::ContextPointer
createSSLContext(Security::CertPointer
& x509
, Ssl::EVP_PKEY_Pointer
& pkey
, AnyP::PortCfg
&port
);
239 \ingroup ServerProtocolSSLAPI
240 * Chain signing certificate and chained certificates to an SSL Context
242 void chainCertificatesToSSLContext(Security::ContextPointer
&, AnyP::PortCfg
&);
245 \ingroup ServerProtocolSSLAPI
246 * Configure a previously unconfigured SSL context object.
248 void configureUnconfiguredSslContext(Security::ContextPointer
&, Ssl::CertSignAlgorithm signAlgorithm
, AnyP::PortCfg
&);
251 \ingroup ServerProtocolSSLAPI
252 * Generates a certificate and a private key using provided properies and set it
255 bool configureSSL(SSL
*ssl
, CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
258 \ingroup ServerProtocolSSLAPI
259 * Read private key and certificate from memory and set it to SSL object
262 bool configureSSLUsingPkeyAndCertFromMemory(SSL
*ssl
, const char *data
, AnyP::PortCfg
&port
);
265 \ingroup ServerProtocolSSLAPI
266 * Adds the certificates in certList to the certificate chain of the SSL context
268 void addChainToSslContext(Security::ContextPointer
&, STACK_OF(X509
) *certList
);
271 \ingroup ServerProtocolSSLAPI
272 * Configures sslContext to use squid untrusted certificates internal list
273 * to complete certificate chains when verifies SSL servers certificates.
275 void useSquidUntrusted(SSL_CTX
*sslContext
);
278 \ingroup ServerProtocolSSLAPI
279 * Read certificate, private key and any certificates which must be chained from files.
280 * See also: Ssl::readCertAndPrivateKeyFromFiles function, defined in gadgets.h
281 * \param certFilename name of file with certificate and certificates which must be chainned.
282 * \param keyFilename name of file with private key.
284 void readCertChainAndPrivateKeyFromFiles(Security::CertPointer
& cert
, EVP_PKEY_Pointer
& pkey
, X509_STACK_Pointer
& chain
, char const * certFilename
, char const * keyFilename
);
287 \ingroup ServerProtocolSSLAPI
288 * Iterates over the X509 common and alternate names and to see if matches with given data
289 * using the check_func.
290 \param peer_cert The X509 cert to check
291 \param check_data The data with which the X509 CNs compared
292 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
293 \return 1 if any of the certificate CN matches, 0 if none matches.
295 int matchX509CommonNames(X509
*peer_cert
, void *check_data
, int (*check_func
)(void *check_data
, ASN1_STRING
*cn_data
));
298 \ingroup ServerProtocolSSLAPI
299 * Check if the certificate is valid for a server
300 \param cert The X509 cert to check.
301 \param server The server name.
302 \return true if the certificate is valid for the server or false otherwise.
304 bool checkX509ServerValidity(X509
*cert
, const char *server
);
307 \ingroup ServerProtocolSSLAPI
308 * Convert a given ASN1_TIME to a string form.
309 \param tm the time in ASN1_TIME form
310 \param buf the buffer to write the output
311 \param len write at most len bytes
312 \return The number of bytes written
314 int asn1timeToString(ASN1_TIME
*tm
, char *buf
, int len
);
317 \ingroup ServerProtocolSSLAPI
318 * Sets the hostname for the Server Name Indication (SNI) TLS extension
319 * if supported by the used openssl toolkit.
320 \return true if SNI set false otherwise
322 bool setClientSNI(SSL
*ssl
, const char *fqdn
);
328 #if defined(__cplusplus)
330 /** \cond AUTODOCS-IGNORE */
335 /// \ingroup ServerProtocolSSLAPI
337 int SSL_set_fd(SSL
*ssl
, int fd
)
339 return ::SSL_set_fd(ssl
, _get_osfhandle(fd
));
342 /// \ingroup ServerProtocolSSLAPI
343 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
345 } /* namespace Squid */
349 /// \ingroup ServerProtocolSSLAPI
350 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
352 #endif /* __cplusplus */
354 #endif /* _SQUID_WINDOWS_ */
356 #endif /* USE_OPENSSL */
357 #endif /* SQUID_SSL_SUPPORT_H */