]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ssl/support.h
Source Format Enforcement (#763)
[thirdparty/squid.git] / src / ssl / support.h
index deaca3d85a9ca1e00ea359f38a3a9bc4d089be41..b35584579df1f8ea2aa6389a0823a76e19409a60 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -15,6 +15,7 @@
 
 #include "base/CbDataList.h"
 #include "comm/forward.h"
+#include "compat/openssl.h"
 #include "sbuf/SBuf.h"
 #include "security/forward.h"
 #include "ssl/gadgets.h"
  \ingroup ServerProtocol
  */
 
-// Custom SSL errors; assumes all official errors are positive
-#define SQUID_X509_V_ERR_INFINITE_VALIDATION -4
-#define SQUID_X509_V_ERR_CERT_CHANGE -3
-#define SQUID_ERR_SSL_HANDSHAKE -2
-#define SQUID_X509_V_ERR_DOMAIN_MISMATCH -1
-// All SSL errors range: from smallest (negative) custom to largest SSL error
-#define SQUID_SSL_ERROR_MIN SQUID_X509_V_ERR_CERT_CHANGE
-#define SQUID_SSL_ERROR_MAX INT_MAX
-
 // Maximum certificate validation callbacks. OpenSSL versions exceeding this
 // limit are deemed stuck in an infinite validation loop (OpenSSL bug #3090)
 // and will trigger the SQUID_X509_V_ERR_INFINITE_VALIDATION error.
@@ -65,11 +57,15 @@ class MemMap;
 
 namespace Ssl
 {
+
+/// callback for receiving password to access password secured PEM files
+/// XXX: Requires SSL_CTX_set_default_passwd_cb_userdata()!
+int AskPasswordCb(char *buf, int size, int rwflag, void *userdata);
+
 /// initialize the SSL library global state.
 /// call before generating any SSL context
 void Initialize();
 
-class ErrorDetail;
 class CertValidationResponse;
 typedef RefCount<CertValidationResponse> CertValidationResponsePointer;
 
@@ -77,10 +73,11 @@ typedef RefCount<CertValidationResponse> CertValidationResponsePointer;
 bool InitServerContext(Security::ContextPointer &, AnyP::PortCfg &);
 
 /// initialize a TLS client context with OpenSSL specific settings
-bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, long flags);
+bool InitClientContext(Security::ContextPointer &, Security::PeerOptions &, Security::ParsedPortFlags);
 
 /// set the certificate verify callback for a context
-void SetupVerifyCallback(Security::ContextPointer &);
+void ConfigurePeerVerification(Security::ContextPointer &, const Security::ParsedPortFlags);
+void DisablePeerVerification(Security::ContextPointer &);
 
 /// if required, setup callback for generating ephemeral RSA keys
 void MaybeSetupRsaCallback(Security::ContextPointer &);
@@ -97,15 +94,16 @@ const char *sslGetUserAttribute(SSL *ssl, const char *attribute_name);
 const char *sslGetCAAttribute(SSL *ssl, const char *attribute_name);
 
 /// \ingroup ServerProtocolSSLAPI
-const char *sslGetUserCertificatePEM(SSL *ssl);
+SBuf sslGetUserCertificatePEM(SSL *ssl);
 
 /// \ingroup ServerProtocolSSLAPI
-const char *sslGetUserCertificateChainPEM(SSL *ssl);
+SBuf sslGetUserCertificateChainPEM(SSL *ssl);
 
 namespace Ssl
 {
 /// \ingroup ServerProtocolSSLAPI
 typedef char const *GETX509ATTRIBUTE(X509 *, const char *);
+typedef SBuf GETX509PEM(X509 *);
 
 /// \ingroup ServerProtocolSSLAPI
 GETX509ATTRIBUTE GetX509UserAttribute;
@@ -113,6 +111,9 @@ GETX509ATTRIBUTE GetX509UserAttribute;
 /// \ingroup ServerProtocolSSLAPI
 GETX509ATTRIBUTE GetX509CAAttribute;
 
+/// \ingroup ServerProtocolSSLAPI
+GETX509PEM GetX509PEM;
+
 /// \ingroup ServerProtocolSSLAPI
 GETX509ATTRIBUTE GetX509Fingerprint;
 
@@ -124,8 +125,6 @@ extern const EVP_MD *DefaultSignHash;
  */
 enum BumpMode {bumpNone = 0, bumpClientFirst, bumpServerFirst, bumpPeek, bumpStare, bumpBump, bumpSplice, bumpTerminate, /*bumpErr,*/ bumpEnd};
 
-enum BumpStep {bumpStep1, bumpStep2, bumpStep3};
-
 /**
  \ingroup  ServerProtocolSSLAPI
  * Short names for ssl-bump modes
@@ -169,17 +168,20 @@ void unloadSquidUntrusted();
  */
 void SSL_add_untrusted_cert(SSL *ssl, X509 *cert);
 
-/**
- * Searches in serverCertificates list for the cert issuer and if not found
- * and Authority Info Access of cert provides a URI return it.
- */
-const char *uriOfIssuerIfMissing(X509 *cert,  Security::CertList const &serverCertificates, const Security::ContextPointer &context);
+/// finds certificate issuer URI in the Authority Info Access extension
+const char *findIssuerUri(X509 *cert);
+
+/// Searches serverCertificates and local databases for the cert issuer.
+/// \param context where to retrieve the configured CA's db; may be nil
+/// \returns the found issuer certificate or nil
+Security::CertPointer findIssuerCertificate(X509 *cert, const STACK_OF(X509) *serverCertificates, const Security::ContextPointer &context);
 
 /**
  * Fill URIs queue with the uris of missing certificates from serverCertificate chain
  * if this information provided by Authority Info Access.
+ \return whether at least one URI is known, including previously known ones
  */
-void missingChainCertificatesUrls(std::queue<SBuf> &URIs, Security::CertList const &serverCertificates, const Security::ContextPointer &context);
+bool missingChainCertificatesUrls(std::queue<SBuf> &URIs, const STACK_OF(X509) &serverCertificates, const Security::ContextPointer &context);
 
 /**
   \ingroup ServerProtocolSSLAPI
@@ -223,7 +225,7 @@ Security::ContextPointer GenerateSslContext(CertificateProperties const &, Secur
   \param properties Check if the context certificate matches the given properties
   \return true if the contexts certificate is valid, false otherwise
  */
-bool verifySslCertificate(Security::ContextPointer &, CertificateProperties const &);
+bool verifySslCertificate(const Security::ContextPointer &, CertificateProperties const &);
 
 /**
   \ingroup ServerProtocolSSLAPI
@@ -252,7 +254,7 @@ void configureUnconfiguredSslContext(Security::ContextPointer &, Ssl::CertSignAl
 
 /**
   \ingroup ServerProtocolSSLAPI
-  * Generates a certificate and a private key using provided properies and set it
+  * Generates a certificate and a private key using provided properties and set it
   * to SSL object.
  */
 bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port);
@@ -264,12 +266,6 @@ bool configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortC
  */
 bool configureSSLUsingPkeyAndCertFromMemory(SSL *ssl, const char *data, AnyP::PortCfg &port);
 
-/**
-  \ingroup ServerProtocolSSLAPI
-  * Adds the certificates in certList to the certificate chain of the SSL context
- */
-void addChainToSslContext(Security::ContextPointer &, Security::CertList &);
-
 /**
   \ingroup ServerProtocolSSLAPI
   * Configures sslContext to use squid untrusted certificates internal list
@@ -277,15 +273,6 @@ void addChainToSslContext(Security::ContextPointer &, Security::CertList &);
  */
 void useSquidUntrusted(SSL_CTX *sslContext);
 
-/**
- \ingroup ServerProtocolSSLAPI
- *  Read certificate, private key and any certificates which must be chained from files.
- * See also: Ssl::readCertAndPrivateKeyFromFiles function,  defined in gadgets.h
- * \param certFilename name of file with certificate and certificates which must be chainned.
- * \param keyFilename name of file with private key.
- */
-void readCertChainAndPrivateKeyFromFiles(Security::CertPointer & cert, Security::PrivateKeyPointer & pkey, Security::CertList &chain, char const * certFilename, char const * keyFilename);
-
 /**
    \ingroup ServerProtocolSSLAPI
    * Iterates over the X509 common and alternate names and to see if  matches with given data
@@ -320,9 +307,8 @@ int asn1timeToString(ASN1_TIME *tm, char *buf, int len);
    \ingroup ServerProtocolSSLAPI
    * Sets the hostname for the Server Name Indication (SNI) TLS extension
    * if supported by the used openssl toolkit.
-   \return true if SNI set false otherwise
 */
-bool setClientSNI(SSL *ssl, const char *fqdn);
+void setClientSNI(SSL *ssl, const char *fqdn);
 
 /**
   \ingroup ServerProtocolSSLAPI
@@ -336,6 +322,48 @@ void InRamCertificateDbKey(const Ssl::CertificateProperties &certProperties, SBu
   TODO: Add support for reading from `buf`.
  */
 BIO *BIO_new_SBuf(SBuf *buf);
+
+/// Validates the given TLS connection server certificate chain in conjunction
+/// with a (possibly empty) set of "extra" intermediate certs. Also consults
+/// sslproxy_foreign_intermediate_certs. This is a C++/Squid-friendly wrapper of
+/// OpenSSL "verification callback function" (\ref OpenSSL_vcb_disambiguation).
+/// OpenSSL has a similar wrapper, ssl_verify_cert_chain(), but that wrapper is
+/// not a part of the public OpenSSL API.
+bool VerifyConnCertificates(Security::Connection &, const Ssl::X509_STACK_Pointer &extraCerts);
+
+// TODO: Move other ssl_ex_index_* validation-related information here.
+/// OpenSSL "verify_callback function" input/output parameters. This information
+/// cannot be passed through the verification API directly, so it is aggregated
+/// in this class and exchanged via ssl_ex_index_verify_callback_parameters. For
+/// OpenSSL validation callback details, see \ref OpenSSL_vcb_disambiguation.
+class VerifyCallbackParameters {
+public:
+    /// creates a VerifyCallbackParameters object and adds it to the given TLS connection
+    /// \returns the successfully created and added object
+    static VerifyCallbackParameters *New(Security::Connection &);
+
+    /// \returns the VerifyCallbackParameters object previously attached via New()
+    static VerifyCallbackParameters &At(Security::Connection &);
+
+    /// \returns the VerifyCallbackParameters object previously attached via New() or nil
+    static VerifyCallbackParameters *Find(Security::Connection &);
+
+    /* input parameters */
+
+    /// whether X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY should be cleared
+    /// (after setting hidMissingIssuer) because the validation initiator wants
+    /// to get the missing certificates and redo the validation with them
+    bool callerHandlesMissingCertificates = false;
+
+    /* output parameters */
+
+    /// whether certificate validation has failed due to missing certificate(s)
+    /// (i.e. X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY), but the failure was
+    /// cleared/hidden due to true callerHandlesMissingCertificates setting; the
+    /// certificate chain has to be deemed untrusted until revalidation (if any)
+    bool hidMissingIssuer = false;
+};
+
 } //namespace Ssl
 
 #if _SQUID_WINDOWS_