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
);
84 /// \ingroup ServerProtocolSSLAPI
85 const char *sslGetUserEmail(SSL
*ssl
);
87 /// \ingroup ServerProtocolSSLAPI
88 const char *sslGetUserAttribute(SSL
*ssl
, const char *attribute_name
);
90 /// \ingroup ServerProtocolSSLAPI
91 const char *sslGetCAAttribute(SSL
*ssl
, const char *attribute_name
);
93 /// \ingroup ServerProtocolSSLAPI
94 const char *sslGetUserCertificatePEM(SSL
*ssl
);
96 /// \ingroup ServerProtocolSSLAPI
97 const char *sslGetUserCertificateChainPEM(SSL
*ssl
);
101 /// \ingroup ServerProtocolSSLAPI
102 typedef char const *GETX509ATTRIBUTE(X509
*, const char *);
104 /// \ingroup ServerProtocolSSLAPI
105 GETX509ATTRIBUTE GetX509UserAttribute
;
107 /// \ingroup ServerProtocolSSLAPI
108 GETX509ATTRIBUTE GetX509CAAttribute
;
110 /// \ingroup ServerProtocolSSLAPI
111 GETX509ATTRIBUTE GetX509Fingerprint
;
113 extern const EVP_MD
*DefaultSignHash
;
116 \ingroup ServerProtocolSSLAPI
117 * Supported ssl-bump modes
119 enum BumpMode
{bumpNone
= 0, bumpClientFirst
, bumpServerFirst
, bumpPeek
, bumpStare
, bumpBump
, bumpSplice
, bumpTerminate
, /*bumpErr,*/ bumpEnd
};
121 enum BumpStep
{bumpStep1
, bumpStep2
, bumpStep3
};
124 \ingroup ServerProtocolSSLAPI
125 * Short names for ssl-bump modes
127 extern std::vector
<const char *>BumpModeStr
;
130 \ingroup ServerProtocolSSLAPI
131 * Return the short name of the ssl-bump mode "bm"
133 inline const char *bumpMode(int bm
)
135 return (0 <= bm
&& bm
< Ssl::bumpEnd
) ? Ssl::BumpModeStr
.at(bm
) : NULL
;
138 /// certificates indexed by issuer name
139 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
142 * Load PEM-encoded certificates from the given file.
144 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
147 * Load PEM-encoded certificates to the squid untrusteds certificates
148 * internal DB from the given file.
150 bool loadSquidUntrusted(const char *path
);
153 * Removes all certificates from squid untrusteds certificates
154 * internal DB and frees all memory
156 void unloadSquidUntrusted();
159 * Add the certificate cert to ssl object untrusted certificates.
160 * Squid uses an attached to SSL object list of untrusted certificates,
161 * with certificates which can be used to complete incomplete chains sent
164 void SSL_add_untrusted_cert(SSL
*ssl
, X509
*cert
);
167 * Searches in serverCertificates list for the cert issuer and if not found
168 * and Authority Info Access of cert provides a URI return it.
170 const char *uriOfIssuerIfMissing(X509
*cert
, Security::CertList
const &serverCertificates
);
173 * Fill URIs queue with the uris of missing certificates from serverCertificate chain
174 * if this information provided by Authority Info Access.
176 void missingChainCertificatesUrls(std::queue
<SBuf
> &URIs
, Security::CertList
const &serverCertificates
);
179 \ingroup ServerProtocolSSLAPI
180 * Generate a certificate to be used as untrusted signing certificate, based on a trusted CA
182 bool generateUntrustedCert(Security::CertPointer
& untrustedCert
, EVP_PKEY_Pointer
& untrustedPkey
, Security::CertPointer
const & cert
, EVP_PKEY_Pointer
const & pkey
);
184 /// certificates indexed by issuer name
185 typedef std::multimap
<SBuf
, X509
*> CertsIndexedList
;
188 \ingroup ServerProtocolSSLAPI
189 * Load PEM-encoded certificates from the given file.
191 bool loadCerts(const char *certsFile
, Ssl::CertsIndexedList
&list
);
194 \ingroup ServerProtocolSSLAPI
195 * Load PEM-encoded certificates to the squid untrusteds certificates
196 * internal DB from the given file.
198 bool loadSquidUntrusted(const char *path
);
201 \ingroup ServerProtocolSSLAPI
202 * Removes all certificates from squid untrusteds certificates
203 * internal DB and frees all memory
205 void unloadSquidUntrusted();
208 \ingroup ServerProtocolSSLAPI
209 * Decide on the kind of certificate and generate a CA- or self-signed one
211 Security::ContextPointer
generateSslContext(CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
214 \ingroup ServerProtocolSSLAPI
215 * Check if the certificate of the given context is still valid
216 \param sslContext The context to check
217 \param properties Check if the context certificate matches the given properties
218 \return true if the contexts certificate is valid, false otherwise
220 bool verifySslCertificate(Security::ContextPointer
&, CertificateProperties
const &);
223 \ingroup ServerProtocolSSLAPI
224 * Read private key and certificate from memory and generate SSL context
227 Security::ContextPointer
generateSslContextUsingPkeyAndCertFromMemory(const char * data
, AnyP::PortCfg
&port
);
230 \ingroup ServerProtocolSSLAPI
231 * Create an SSL context using the provided certificate and key
233 Security::ContextPointer
createSSLContext(Security::CertPointer
& x509
, Ssl::EVP_PKEY_Pointer
& pkey
, AnyP::PortCfg
&port
);
236 \ingroup ServerProtocolSSLAPI
237 * Chain signing certificate and chained certificates to an SSL Context
239 void chainCertificatesToSSLContext(Security::ContextPointer
&, AnyP::PortCfg
&);
242 \ingroup ServerProtocolSSLAPI
243 * Configure a previously unconfigured SSL context object.
245 void configureUnconfiguredSslContext(Security::ContextPointer
&, Ssl::CertSignAlgorithm signAlgorithm
, AnyP::PortCfg
&);
248 \ingroup ServerProtocolSSLAPI
249 * Generates a certificate and a private key using provided properies and set it
252 bool configureSSL(SSL
*ssl
, CertificateProperties
const &properties
, AnyP::PortCfg
&port
);
255 \ingroup ServerProtocolSSLAPI
256 * Read private key and certificate from memory and set it to SSL object
259 bool configureSSLUsingPkeyAndCertFromMemory(SSL
*ssl
, const char *data
, AnyP::PortCfg
&port
);
262 \ingroup ServerProtocolSSLAPI
263 * Adds the certificates in certList to the certificate chain of the SSL context
265 void addChainToSslContext(Security::ContextPointer
&, STACK_OF(X509
) *certList
);
268 \ingroup ServerProtocolSSLAPI
269 * Configures sslContext to use squid untrusted certificates internal list
270 * to complete certificate chains when verifies SSL servers certificates.
272 void useSquidUntrusted(SSL_CTX
*sslContext
);
275 \ingroup ServerProtocolSSLAPI
276 * Read certificate, private key and any certificates which must be chained from files.
277 * See also: Ssl::readCertAndPrivateKeyFromFiles function, defined in gadgets.h
278 * \param certFilename name of file with certificate and certificates which must be chainned.
279 * \param keyFilename name of file with private key.
281 void readCertChainAndPrivateKeyFromFiles(Security::CertPointer
& cert
, EVP_PKEY_Pointer
& pkey
, X509_STACK_Pointer
& chain
, char const * certFilename
, char const * keyFilename
);
284 \ingroup ServerProtocolSSLAPI
285 * Iterates over the X509 common and alternate names and to see if matches with given data
286 * using the check_func.
287 \param peer_cert The X509 cert to check
288 \param check_data The data with which the X509 CNs compared
289 \param check_func The function used to match X509 CNs. The CN data passed as ASN1_STRING data
290 \return 1 if any of the certificate CN matches, 0 if none matches.
292 int matchX509CommonNames(X509
*peer_cert
, void *check_data
, int (*check_func
)(void *check_data
, ASN1_STRING
*cn_data
));
295 \ingroup ServerProtocolSSLAPI
296 * Check if the certificate is valid for a server
297 \param cert The X509 cert to check.
298 \param server The server name.
299 \return true if the certificate is valid for the server or false otherwise.
301 bool checkX509ServerValidity(X509
*cert
, const char *server
);
304 \ingroup ServerProtocolSSLAPI
305 * Convert a given ASN1_TIME to a string form.
306 \param tm the time in ASN1_TIME form
307 \param buf the buffer to write the output
308 \param len write at most len bytes
309 \return The number of bytes written
311 int asn1timeToString(ASN1_TIME
*tm
, char *buf
, int len
);
314 \ingroup ServerProtocolSSLAPI
315 * Sets the hostname for the Server Name Indication (SNI) TLS extension
316 * if supported by the used openssl toolkit.
317 \return true if SNI set false otherwise
319 bool setClientSNI(SSL
*ssl
, const char *fqdn
);
325 #if defined(__cplusplus)
327 /** \cond AUTODOCS-IGNORE */
332 /// \ingroup ServerProtocolSSLAPI
334 int SSL_set_fd(SSL
*ssl
, int fd
)
336 return ::SSL_set_fd(ssl
, _get_osfhandle(fd
));
339 /// \ingroup ServerProtocolSSLAPI
340 #define SSL_set_fd(ssl,fd) Squid::SSL_set_fd(ssl,fd)
342 } /* namespace Squid */
346 /// \ingroup ServerProtocolSSLAPI
347 #define SSL_set_fd(s,f) (SSL_set_fd(s, _get_osfhandle(f)))
349 #endif /* __cplusplus */
351 #endif /* _SQUID_WINDOWS_ */
353 #endif /* USE_OPENSSL */
354 #endif /* SQUID_SSL_SUPPORT_H */