Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/api/api.h" 4 : #include "envoy/config/typed_config.h" 5 : #include "envoy/network/connection.h" 6 : #include "envoy/network/post_io_action.h" 7 : #include "envoy/protobuf/message_validator.h" 8 : #include "envoy/server/options.h" 9 : #include "envoy/singleton/manager.h" 10 : 11 : #include "openssl/ssl.h" 12 : 13 : namespace Envoy { 14 : namespace Ssl { 15 : 16 : class HandshakeCallbacks { 17 : public: 18 0 : virtual ~HandshakeCallbacks() = default; 19 : 20 : /** 21 : * @return the connection. 22 : */ 23 : virtual Network::Connection& connection() const PURE; 24 : 25 : /** 26 : * A callback which will be executed at most once upon successful completion 27 : * of a handshake. 28 : */ 29 : virtual void onSuccess(SSL* ssl) PURE; 30 : 31 : /** 32 : * A callback which will be executed at most once upon handshake failure. 33 : */ 34 : virtual void onFailure() PURE; 35 : 36 : /** 37 : * Returns a pointer to the transportSocketCallbacks struct, or nullptr if 38 : * unset. 39 : */ 40 : virtual Network::TransportSocketCallbacks* transportSocketCallbacks() PURE; 41 : 42 : /** 43 : * A callback to be called upon certificate validation completion if the validation is 44 : * asynchronous. 45 : */ 46 : virtual void onAsynchronousCertValidationComplete() PURE; 47 : }; 48 : 49 : /** 50 : * Base interface for performing TLS handshakes. 51 : */ 52 : class Handshaker { 53 : public: 54 0 : virtual ~Handshaker() = default; 55 : 56 : /** 57 : * Performs a TLS handshake and returns an action indicating 58 : * whether the callsite should close the connection or keep it open. 59 : */ 60 : virtual Network::PostIoAction doHandshake() PURE; 61 : }; 62 : 63 : using HandshakerSharedPtr = std::shared_ptr<Handshaker>; 64 : using HandshakerFactoryCb = 65 : std::function<HandshakerSharedPtr(bssl::UniquePtr<SSL>, int, HandshakeCallbacks*)>; 66 : 67 : // Callback for modifying an SSL_CTX. 68 : using SslCtxCb = std::function<void(SSL_CTX*)>; 69 : 70 : class HandshakerFactoryContext { 71 : public: 72 0 : virtual ~HandshakerFactoryContext() = default; 73 : 74 : /** 75 : * Returns the singleton manager. 76 : */ 77 : virtual Singleton::Manager& singletonManager() PURE; 78 : 79 : /** 80 : * @return reference to the server options 81 : */ 82 : virtual const Server::Options& options() const PURE; 83 : 84 : /** 85 : * @return reference to the Api object 86 : */ 87 : virtual Api::Api& api() PURE; 88 : 89 : /** 90 : * The list of supported protocols exposed via ALPN, from ContextConfig. 91 : */ 92 : virtual absl::string_view alpnProtocols() const PURE; 93 : }; 94 : 95 : struct HandshakerCapabilities { 96 : // Whether or not a handshaker implementation provides certificates itself. 97 : bool provides_certificates = false; 98 : 99 : // Whether or not a handshaker implementation verifies certificates itself. 100 : bool verifies_peer_certificates = false; 101 : 102 : // Whether or not a handshaker implementation handles session resumption 103 : // itself. 104 : bool handles_session_resumption = false; 105 : 106 : // Whether or not a handshaker implementation provides its own list of ciphers 107 : // and curves. 108 : bool provides_ciphers_and_curves = false; 109 : 110 : // Whether or not a handshaker implementation handles ALPN selection. 111 : bool handles_alpn_selection = false; 112 : 113 : // Should return true if this handshaker is FIPS-compliant. 114 : // Envoy will fail to compile if this returns true and `--define=boringssl=fips`. 115 : bool is_fips_compliant = true; 116 : 117 : // Whether or not a handshaker implementation provides its own list of 118 : // supported signature algorithms. 119 : bool provides_sigalgs = false; 120 : }; 121 : 122 : class HandshakerFactory : public Config::TypedFactory { 123 : public: 124 : /** 125 : * @returns a callback to create a Handshaker. Accepts the |config| and 126 : * |validation_visitor| for early validation. This virtual base doesn't 127 : * perform MessageUtil::downcastAndValidate, but an implementation should. 128 : */ 129 : virtual HandshakerFactoryCb 130 : createHandshakerCb(const Protobuf::Message& message, 131 : HandshakerFactoryContext& handshaker_factory_context, 132 : ProtobufMessage::ValidationVisitor& validation_visitor) PURE; 133 : 134 0 : std::string category() const override { return "envoy.tls_handshakers"; } 135 : 136 : /** 137 : * Implementations should return a struct with their capabilities. See 138 : * HandshakerCapabilities above. For any capability a Handshaker 139 : * implementation explicitly declares, Envoy will not also configure that SSL 140 : * capability. 141 : */ 142 : virtual HandshakerCapabilities capabilities() const PURE; 143 : 144 : /** 145 : * Implementations should return a callback for configuring an SSL_CTX context 146 : * before it is used to create any SSL objects. Providing 147 : * |handshaker_factory_context| as an argument allows callsites to access the 148 : * API and other factory context methods. 149 : */ 150 : virtual SslCtxCb sslctxCb(HandshakerFactoryContext& handshaker_factory_context) const PURE; 151 : }; 152 : 153 : } // namespace Ssl 154 : } // namespace Envoy