]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/security/forward.h
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / security / forward.h
index a452c94e433a0ffdd14385f03ecfa50bb6298246..57191ddfd0dc6e3f69201f3ed3ce312af8732bd1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
 #define SQUID_SRC_SECURITY_FORWARD_H
 
 #include "base/CbDataList.h"
+#include "base/forward.h"
 #include "security/Context.h"
 #include "security/Session.h"
 
-#if USE_GNUTLS && HAVE_GNUTLS_X509_H
-#include <gnutls/x509.h>
+#if USE_GNUTLS && HAVE_GNUTLS_ABSTRACT_H
+#include <gnutls/abstract.h>
 #endif
 #include <list>
-#if USE_OPENSSL && HAVE_OPENSSL_ERR_H
+#include <limits>
+#if USE_OPENSSL
+#include "compat/openssl.h"
+#if HAVE_OPENSSL_BN_H
+#include <openssl/bn.h>
+#endif
+#if HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
 #endif
+#if HAVE_OPENSSL_RSA_H
+#include <openssl/rsa.h>
+#endif
+#endif /* USE_OPENSSL */
 #include <unordered_set>
 
 #if USE_OPENSSL
         struct sk_object ## _free_wrapper { \
             void operator()(argument_type a) { sk_object ## _pop_free(a, freefunction); } \
         }
-
-#if !HAVE_LIBCRYPTO_X509_UP_REF // OpenSSL 1.1 API
-#if defined(CRYPTO_LOCK_X509) // OpenSSL 1.0 API
-inline int X509_up_ref(X509 *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509); return 0;}
-#else
-#error missing both OpenSSL API features X509_up_ref (v1.1) and CRYPTO_LOCK_X509 (v1.0)
-#endif /* CRYPTO_LOCK_X509 */
-#endif /* X509_up_ref */
-
-#if !HAVE_LIBCRYPTO_X509_CRL_UP_REF // OpenSSL 1.1 API
-#if defined(CRYPTO_LOCK_X509_CRL) // OpenSSL 1.0 API
-inline int X509_CRL_up_ref(X509_CRL *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_X509_CRL); return 0;}
-#else
-#error missing both OpenSSL API features X509_up_ref (v1.1) and CRYPTO_LOCK_X509 (v1.0)
-#endif /* CRYPTO_LOCK_X509_CRL */
-#endif /* X509_CRL_up_ref */
-#if !HAVE_LIBCRYPTO_DH_UP_REF // OpenSSL 1.1 API
-#if defined(CRYPTO_LOCK_DH) // OpenSSL 1.0 API
-inline int DH_up_ref(DH *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_DH); return 0;}
-#else
-
-#error missing both OpenSSL API features DH_up_ref (v1.1) and CRYPTO_LOCK_DH (v1.0)
-#endif /* OpenSSL 1.0 CRYPTO_LOCK_X509_CRL */
-#endif /* OpenSSL 1.1 DH_up_ref */
-
-#if !HAVE_LIBCRYPTO_EVP_PKEY_UP_REF
-#if defined(CRYPTO_LOCK_EVP_PKEY) // OpenSSL 1.0
-inline int EVP_PKEY_up_ref(EVP_PKEY *t) {if (t) CRYPTO_add(&t->references, 1, CRYPTO_LOCK_EVP_PKEY); return 0;}
-#endif
-#else
-#error missing both OpenSSL API features EVP_PKEY_up_ref (v1.1) and CRYPTO_LOCK_EVP_PKEY (v1.0)
-#endif
-
 #endif /* USE_OPENSSL */
 
 /* flags a SSL connection can be configured with */
@@ -73,6 +51,15 @@ inline int EVP_PKEY_up_ref(EVP_PKEY *t) {if (t) CRYPTO_add(&t->references, 1, CR
 #define SSL_FLAG_NO_SESSION_REUSE   (1<<4)
 #define SSL_FLAG_VERIFY_CRL         (1<<5)
 #define SSL_FLAG_VERIFY_CRL_ALL     (1<<6)
+#define SSL_FLAG_CONDITIONAL_AUTH   (1<<7)
+
+#if !USE_OPENSSL && !USE_GNUTLS
+/// A helper type to keep all three possible underlying types of the
+/// Security::Certificate typedef below inside global namespace, so that
+/// argument-dependent lookup for operator "<<" (Certificate) works inside
+/// functions declared in Security and global namespaces.
+struct notls_x509 {};
+#endif
 
 /// Network/connection security abstraction layer
 namespace Security
@@ -83,20 +70,27 @@ class CertError;
 typedef CbDataList<Security::CertError> CertErrors;
 
 #if USE_OPENSSL
-CtoCpp1(X509_free, X509 *)
+typedef X509 Certificate;
+#elif USE_GNUTLS
+typedef struct gnutls_x509_crt_int Certificate;
+#else
+typedef struct notls_x509 Certificate;
+#endif
+
+#if USE_OPENSSL
+CtoCpp1(X509_free, X509 *);
 typedef Security::LockingPointer<X509, X509_free_cpp, HardFun<int, X509 *, X509_up_ref> > CertPointer;
 #elif USE_GNUTLS
-CtoCpp1(gnutls_x509_crt_deinit, gnutls_x509_crt_t)
-typedef Security::LockingPointer<struct gnutls_x509_crt_int, gnutls_x509_crt_deinit> CertPointer;
+typedef std::shared_ptr<struct gnutls_x509_crt_int> CertPointer;
 #else
-typedef void * CertPointer;
+typedef std::shared_ptr<Certificate> CertPointer;
 #endif
 
 #if USE_OPENSSL
-CtoCpp1(X509_CRL_free, X509_CRL *)
+CtoCpp1(X509_CRL_free, X509_CRL *);
 typedef Security::LockingPointer<X509_CRL, X509_CRL_free_cpp, HardFun<int, X509_CRL *, X509_CRL_up_ref> > CrlPointer;
 #elif USE_GNUTLS
-CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t)
+CtoCpp1(gnutls_x509_crl_deinit, gnutls_x509_crl_t);
 typedef Security::LockingPointer<struct gnutls_x509_crl_int, gnutls_x509_crl_deinit> CrlPointer;
 #else
 typedef void *CrlPointer;
@@ -107,23 +101,55 @@ typedef std::list<Security::CertPointer> CertList;
 typedef std::list<Security::CrlPointer> CertRevokeList;
 
 #if USE_OPENSSL
+CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
+using PrivateKeyPointer = Security::LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, HardFun<int, EVP_PKEY *, EVP_PKEY_up_ref>>;
+#elif USE_GNUTLS
+using PrivateKeyPointer = std::shared_ptr<struct gnutls_x509_privkey_int>;
+#else
+using PrivateKeyPointer = std::shared_ptr<void>;
+#endif
+
+#if USE_OPENSSL
+#if OPENSSL_VERSION_MAJOR < 3
 CtoCpp1(DH_free, DH *);
 typedef Security::LockingPointer<DH, DH_free_cpp, HardFun<int, DH *, DH_up_ref> > DhePointer;
 #else
-typedef void *DhePointer;
+using DhePointer = PrivateKeyPointer;
+#endif
+#elif USE_GNUTLS
+using DhePointer = void *;
+#else
+using DhePointer = void *;
 #endif
 
 class EncryptorAnswer;
 
-/// Squid defined error code (<0), an error code returned by X.509 API, or SSL_ERROR_NONE
+/// Squid-defined error code (<0), an error code returned by X.509 API, or zero
 typedef int ErrorCode;
 
-inline const char *ErrorString(const ErrorCode code) {
+/// TLS library-reported non-validation error
+#if USE_OPENSSL
+/// the result of the first ERR_get_error(3SSL) call after a library call;
+/// `openssl errstr` expands these numbers into human-friendlier strings like
+/// `error:1408F09C:SSL routines:ssl3_get_record:http request`
+typedef unsigned long LibErrorCode;
+#elif USE_GNUTLS
+/// the result of an API function like gnutls_handshake() (e.g.,
+/// GNUTLS_E_WARNING_ALERT_RECEIVED)
+typedef int LibErrorCode;
+#else
+/// should always be zero and virtually unused
+typedef int LibErrorCode;
+#endif
+
+/// converts numeric LibErrorCode into a human-friendlier string
+inline const char *ErrorString(const LibErrorCode code) {
 #if USE_OPENSSL
     return ERR_error_string(code, nullptr);
 #elif USE_GNUTLS
     return gnutls_strerror(code);
 #else
+    (void)code;
     return "[no TLS library]";
 #endif
 }
@@ -151,30 +177,61 @@ enum Type {
 
 } // namespace Io
 
+// TODO: Either move to Security::Io or remove/restrict the Io namespace.
+class IoResult;
+
+class CommunicationSecrets;
 class KeyData;
+class KeyLog;
 
 #if USE_OPENSSL
-typedef long ParsedOptions;
+using ParsedOptions = uint64_t;
 #elif USE_GNUTLS
 typedef std::shared_ptr<struct gnutls_priority_st> ParsedOptions;
 #else
 class ParsedOptions {}; // we never parse/use TLS options in this case
 #endif
 
+/// bitmask representing configured http(s)_port `sslflags`
+/// as well tls_outgoing_options `flags`, cache_peer `sslflags`, and
+/// icap_service `tls-flags`
+typedef long ParsedPortFlags;
+
 class PeerConnector;
+class BlindPeerConnector;
 class PeerOptions;
 
-#if USE_OPENSSL
-CtoCpp1(EVP_PKEY_free, EVP_PKEY *)
-typedef Security::LockingPointer<EVP_PKEY, EVP_PKEY_free_cpp, HardFun<int, EVP_PKEY *, EVP_PKEY_up_ref> > PrivateKeyPointer;
-#else
-// XXX: incompatible with the other PrivateKeyPointer declaration (lacks self-initialization)
-typedef void *PrivateKeyPointer;
-#endif
-
 class ServerOptions;
 
+class ErrorDetail;
+typedef RefCount<ErrorDetail> ErrorDetailPointer;
+
+std::ostream &operator <<(std::ostream &, const KeyLog &);
+
+void OpenLogs(); ///< opens logs enabled in the current configuration
+void RotateLogs(); ///< rotates logs opened by OpenLogs()
+void CloseLogs(); ///< closes logs opened by OpenLogs()
+
 } // namespace Security
 
+/// Squid-specific TLS handling errors (a subset of ErrorCode)
+/// These errors either distinguish high-level library calls/contexts or
+/// supplement official certificate validation errors to cover special cases.
+/// We use negative values, assuming that those official errors are positive.
+enum {
+    SQUID_TLS_ERR_OFFSET = std::numeric_limits<int>::min(),
+
+    /* TLS library calls/contexts other than validation (e.g., I/O) */
+    SQUID_TLS_ERR_ACCEPT, ///< failure to accept a connection from a TLS client
+    SQUID_TLS_ERR_CONNECT, ///< failure to establish a connection with a TLS server
+
+    /* certificate validation problems not covered by official errors */
+    SQUID_X509_V_ERR_CERT_CHANGE,
+    SQUID_X509_V_ERR_DOMAIN_MISMATCH,
+    SQUID_X509_V_ERR_INFINITE_VALIDATION,
+
+    SQUID_TLS_ERR_END
+};
+
 #endif /* SQUID_SRC_SECURITY_FORWARD_H */