Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
647e23c
[tls] Add a custom listener handshaker for TLS.
ambuc Jul 14, 2020
a497d44
[misc] run fix_format
ambuc Jul 14, 2020
df9dfb2
Merge branch 'master' of github.com:envoyproxy/envoy into custom-hand…
ambuc Jul 15, 2020
22f2003
[misc] run fix_format
ambuc Jul 15, 2020
a403972
[ssl] Rename some HandshakerCallbacks methods.
ambuc Jul 20, 2020
59d5905
[tls] Rename HandOff/HandBack.
ambuc Jul 20, 2020
2168d8b
[misc] run fix_format
ambuc Jul 20, 2020
44b31b8
[misc] remove comment formatting on PemPasswordCallback, breaking che…
ambuc Jul 20, 2020
78656cc
[misc] fix typo in handshaker_test
ambuc Jul 20, 2020
2240f09
[tls] omit rwflag argument entirely
ambuc Jul 20, 2020
e6de2a1
[ssl] Remove unnecessary ctor and max_proto_version
ambuc Jul 20, 2020
bff00b6
[ssl] initialize() takes a reference
ambuc Jul 20, 2020
1c2a650
Handshakers now raise Connected as part of OnSuccessCb.
ambuc Jul 20, 2020
aaae5bf
[tls] HandshakerFactory is of category 'envoy.tls_handshakers'.
ambuc Jul 20, 2020
1266425
[tls] More specific documentation on DoHandshake.
ambuc Jul 20, 2020
d9db724
[tls] Factory should hold the config message, not context config
ambuc Jul 21, 2020
48a840e
[tls] Introduce a default HandshakerFactoryImpl
ambuc Jul 21, 2020
32c5095
[tls] requireCertificates as a method on the factory, not the handsha…
ambuc Jul 21, 2020
3b94f43
[tls] Add test for HandshakerWithOutOfProcessComponent
ambuc Jul 21, 2020
08e4183
[tls] Clarify guidance on doHandshake() handling nullptrs
ambuc Jul 21, 2020
0dc6bde
Merge branch 'master' of github.com:envoyproxy/envoy into custom-hand…
ambuc Jul 21, 2020
480e433
[misc] Run fix_format.
ambuc Jul 21, 2020
61b7d5c
[tls] Move SSL into Handshaker and remove extra HandshakerCallbacks m…
ambuc Jul 22, 2020
508ea7a
Merge branch 'master' of github.com:envoyproxy/envoy into custom-hand…
ambuc Jul 22, 2020
2e21ee8
[tls] Remove ::initialize() method
ambuc Jul 22, 2020
51ace82
[tls] Add test with example HandshakerImpl demonstrating special case…
ambuc Jul 23, 2020
5dbb557
Merge branch 'master' of github.com:envoyproxy/envoy into custom-hand…
ambuc Jul 23, 2020
4e3af18
[tls] handshaker_factory_ must be a reseatable reference
ambuc Jul 24, 2020
78e3f2f
[tls] handshaker_test.cc calls SSL_set_cert_cb in ctor
ambuc Jul 24, 2020
e4b22fd
[api] Remove typed_config stutter
ambuc Jul 24, 2020
6725f9c
Resolved merge conflicts
ambuc Jul 27, 2020
fad305b
[tls] Refactor HandshakerFactory with callback to allow for early val…
ambuc Jul 28, 2020
36c4d83
[tls] More clarity around Handshaker interface documentation.
ambuc Jul 28, 2020
7c3020d
[misc] Add bssl, rbio, wbio to dictionary.
ambuc Jul 28, 2020
cb39b1a
[misc] Run fix_format.
ambuc Jul 28, 2020
ed5f209
[tls] Clean up initialization order inside context_config_impl
ambuc Jul 29, 2020
2c7d3c8
[tls] Rename methods to onSuccessCb/onFailureCb
ambuc Jul 29, 2020
2d5ec2f
[tls] dedup HandshakerMaker with HandshakerFactoryCb
ambuc Jul 29, 2020
f32acbc
[misc] Remove wbio, rbio, bssl from dictionary
ambuc Jul 29, 2020
18dc2c6
[tls] HandshakerPtr is now a shared_ptr; SslSocketInfo retains access…
ambuc Jul 29, 2020
c7c40b5
Move HandshakerCallbacks into setCallbacks()
ambuc Jul 29, 2020
f711e26
[misc] Rename HandshakerPtr to HandshakerSharedPtr
ambuc Jul 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion api/envoy/extensions/transport_sockets/tls/v3/tls.proto
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,13 @@ message DownstreamTlsContext {
}];
}

// Custom config for customizing listener handshaker behavior.
message CustomListenerHandshaker {
Comment thread
ambuc marked this conversation as resolved.
Outdated
config.core.v3.TypedExtensionConfig typed_config = 1;
}

// TLS context shared by both client and server TLS contexts.
// [#next-free-field: 11]
// [#next-free-field: 12]
message CommonTlsContext {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.auth.CommonTlsContext";

Expand Down Expand Up @@ -201,4 +206,7 @@ message CommonTlsContext {
//
// There is no default for this parameter. If empty, Envoy will not expose ALPN.
repeated string alpn_protocols = 4;

// Custom TLS handshaker. If empty, defaults to native TLS handshaker.
CustomListenerHandshaker custom_listener_handshaker = 11;
}
13 changes: 12 additions & 1 deletion api/envoy/extensions/transport_sockets/tls/v4alpha/tls.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions include/envoy/ssl/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ envoy_cc_library(
hdrs = ["context_config.h"],
deps = [
":certificate_validation_context_config_interface",
":handshaker_interface",
":tls_certificate_config_interface",
],
)
Expand Down Expand Up @@ -68,3 +69,20 @@ envoy_cc_library(
deps = [
],
)

envoy_cc_library(
name = "handshaker_interface",
hdrs = ["handshaker.h"],
external_deps = ["ssl"],
deps = [
":socket_state",
"//include/envoy/config:typed_config_interface",
"//include/envoy/network:transport_socket_interface",
],
)

envoy_cc_library(
name = "socket_state",
hdrs = ["socket_state.h"],
deps = [],
)
6 changes: 6 additions & 0 deletions include/envoy/ssl/context_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "envoy/common/pure.h"
#include "envoy/ssl/certificate_validation_context_config.h"
#include "envoy/ssl/handshaker.h"
#include "envoy/ssl/tls_certificate_config.h"

#include "absl/types/optional.h"
Expand Down Expand Up @@ -73,6 +74,11 @@ class ContextConfig {
* @param callback callback that is executed by context config.
*/
virtual void setSecretUpdateCallback(std::function<void()> callback) PURE;

/**
* @return the handshaker to use for TLS handshakes.
*/
virtual Ssl::HandshakerPtr createHandshaker() const PURE;
};

class ClientContextConfig : public virtual ContextConfig {
Expand Down
96 changes: 96 additions & 0 deletions include/envoy/ssl/handshaker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#pragma once

#include "envoy/api/api.h"
#include "envoy/common/pure.h"
#include "envoy/config/typed_config.h"
#include "envoy/network/transport_socket.h"
#include "envoy/ssl/socket_state.h"

#include "openssl/ssl.h"

namespace Envoy {
namespace Ssl {

class HandshakerCallbacks {
public:
virtual ~HandshakerCallbacks() = default;

/**
* Hands off the internally-held SSL object for external manipulation.
*/
virtual bssl::UniquePtr<SSL> Handoff() PURE;
Comment thread
ambuc marked this conversation as resolved.
Outdated
/**
* Accepts an SSL object for internal storage.
*/
virtual void Handback(bssl::UniquePtr<SSL> ssl) PURE;
Comment thread
ambuc marked this conversation as resolved.
Outdated
/**
* Called when a handshake is successfully performed.
*/
virtual void LogHandshake(SSL* ssl) PURE;
/**
* Called when a handshake fails.
*/
virtual void ErrorCb() PURE;
Comment thread
ambuc marked this conversation as resolved.
Outdated
};

class Handshaker {
public:
virtual ~Handshaker() = default;

// The initialize method must be called with a non-null SSL* before
// doHandshake() is called.
virtual void initialize(SSL* ssl) PURE;
Comment thread
ambuc marked this conversation as resolved.
Outdated

/**
* Do the handshake.
*
* NB: This method may be called with |ssl| == nullptr, for example during a
* reentrant call to doHandshake() during a period when the handshaker has
* handed off the SSL*.
Comment thread
ambuc marked this conversation as resolved.
Outdated
*
* NB: |state| is mutable.
*/
virtual Network::PostIoAction doHandshake(SocketState& state, SSL* ssl,
HandshakerCallbacks& callbacks) PURE;

/**
* Set an internal pointer to the Network::TransportSocketCallbacks struct.
* Depending on impl, these callbacks can be invoked to access connection
* state, raise connection events, etc.
*/
virtual void setTransportSocketCallbacks(Network::TransportSocketCallbacks& callbacks) PURE;
Comment thread
ambuc marked this conversation as resolved.
Outdated

/**
* Subclasses should return true if the tls context accompanying this
Comment thread
ambuc marked this conversation as resolved.
Outdated
* handshaker expects certificates.
*/
virtual bool requireCertificates() PURE;
};

using HandshakerPtr = std::unique_ptr<Handshaker>;

class HandshakerFactoryContext {
public:
virtual ~HandshakerFactoryContext() = default;

/**
* @return reference to the Api object
*/
virtual Api::Api& api() PURE;

/**
* The list of supported protocols exposed via ALPN, from ContextConfig.
*/
virtual absl::string_view alpnProtocols() const PURE;
};

class HandshakerFactory : public Config::TypedFactory {
public:
virtual HandshakerPtr createHandshaker(const Protobuf::Message& config,
HandshakerFactoryContext& context) PURE;

std::string category() const override { return "envoy.handshakers"; }
Comment thread
ambuc marked this conversation as resolved.
Outdated
};

} // namespace Ssl
} // namespace Envoy
9 changes: 9 additions & 0 deletions include/envoy/ssl/socket_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

namespace Envoy {
namespace Ssl {

enum class SocketState { PreHandshake, HandshakeInProgress, HandshakeComplete, ShutdownSent };

} // namespace Ssl
} // namespace Envoy
33 changes: 33 additions & 0 deletions source/extensions/transport_sockets/tls/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,12 @@ envoy_cc_library(
deps = [
":context_config_lib",
":context_lib",
":handshaker_lib",
":utility_lib",
"//include/envoy/network:connection_interface",
"//include/envoy/network:transport_socket_interface",
"//include/envoy/ssl:handshaker_interface",
"//include/envoy/ssl:socket_state",
"//include/envoy/ssl:ssl_socket_extended_info_interface",
"//include/envoy/ssl/private_key:private_key_callbacks_interface",
"//include/envoy/ssl/private_key:private_key_interface",
Expand All @@ -63,6 +66,7 @@ envoy_cc_library(
"ssl",
],
deps = [
":handshaker_lib",
"//include/envoy/secret:secret_callbacks_interface",
"//include/envoy/secret:secret_provider_interface",
"//include/envoy/server:transport_socket_config_interface",
Expand Down Expand Up @@ -118,6 +122,35 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "handshaker_lib",
srcs = ["handshaker_impl.cc"],
hdrs = ["handshaker_impl.h"],
external_deps = [
"ssl",
],
deps = [
"//include/envoy/ssl:context_config_interface",
"//include/envoy/ssl:context_interface",
"//include/envoy/ssl:context_manager_interface",
"//include/envoy/ssl:handshaker_interface",
"//include/envoy/ssl:socket_state",
"//include/envoy/ssl:ssl_socket_extended_info_interface",
"//include/envoy/ssl/private_key:private_key_interface",
"//include/envoy/stats:stats_interface",
"//include/envoy/stats:stats_macros",
"//source/common/common:assert_lib",
"//source/common/common:base64_lib",
"//source/common/common:hex_lib",
"//source/common/common:utility_lib",
"//source/common/network:address_lib",
"//source/common/protobuf:utility_lib",
"//source/common/stats:symbol_table_lib",
"//source/common/stats:utility_lib",
"//source/extensions/transport_sockets/tls/private_key:private_key_manager_lib",
],
)

envoy_cc_library(
name = "utility_lib",
srcs = ["utility.cc"],
Expand Down
22 changes: 21 additions & 1 deletion source/extensions/transport_sockets/tls/context_config_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,15 @@ ContextConfigImpl::ContextConfigImpl(
}
}
}

if (config.has_custom_listener_handshaker()) {
auto& handshaker_config = config.custom_listener_handshaker().typed_config();
handshaker_factory_ =
&Config::Utility::getAndCheckFactory<Ssl::HandshakerFactory>(handshaker_config);
handshaker_config_message_ = Config::Utility::translateAnyToFactoryConfig(
handshaker_config.typed_config(), factory_context.messageValidationVisitor(),
*handshaker_factory_);
}
}

Ssl::CertificateValidationContextConfigPtr ContextConfigImpl::getCombinedValidationContextConfig(
Expand All @@ -224,6 +233,15 @@ Ssl::CertificateValidationContextConfigPtr ContextConfigImpl::getCombinedValidat
return std::make_unique<Envoy::Ssl::CertificateValidationContextConfigImpl>(combined_cvc, api_);
}

Ssl::HandshakerPtr ContextConfigImpl::createHandshaker() const {
if (handshaker_factory_ == nullptr) {
return std::make_unique<HandshakerImpl>();
} else {
HandshakerFactoryContextImpl context(api_, alpnProtocols());
return handshaker_factory_->createHandshaker(*handshaker_config_message_, context);
}
}

void ContextConfigImpl::setSecretUpdateCallback(std::function<void()> callback) {
if (!tls_certificate_providers_.empty()) {
if (tc_update_callback_handle_) {
Expand Down Expand Up @@ -409,7 +427,9 @@ ServerContextConfigImpl::ServerContextConfigImpl(

if ((config.common_tls_context().tls_certificates().size() +
config.common_tls_context().tls_certificate_sds_secret_configs().size()) == 0) {
throw EnvoyException("No TLS certificates found for server context");
if (createHandshaker()->requireCertificates()) {
Comment thread
ambuc marked this conversation as resolved.
Outdated
throw EnvoyException("No TLS certificates found for server context");
}
} else if (!config.common_tls_context().tls_certificates().empty() &&
!config.common_tls_context().tls_certificate_sds_secret_configs().empty()) {
throw EnvoyException("SDS and non-SDS TLS certificates may not be mixed in server contexts");
Expand Down
8 changes: 8 additions & 0 deletions source/extensions/transport_sockets/tls/context_config_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "common/json/json_loader.h"
#include "common/ssl/tls_certificate_config_impl.h"

#include "extensions/transport_sockets/tls/handshaker_impl.h"

namespace Envoy {
namespace Extensions {
namespace TransportSockets {
Expand Down Expand Up @@ -60,6 +62,8 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig {
const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext&
dynamic_cvc);

Ssl::HandshakerPtr createHandshaker() const override;

protected:
ContextConfigImpl(const envoy::extensions::transport_sockets::tls::v3::CommonTlsContext& config,
const unsigned default_min_protocol_version,
Expand Down Expand Up @@ -94,6 +98,10 @@ class ContextConfigImpl : public virtual Ssl::ContextConfig {
Envoy::Common::CallbackHandle* cvc_validation_callback_handle_{};
const unsigned min_protocol_version_;
const unsigned max_protocol_version_;

// Ptr to HandshakerFactory. If nullptr, uses default Handshaker impl.
Ssl::HandshakerFactory* handshaker_factory_{};
Comment thread
ambuc marked this conversation as resolved.
Outdated
ProtobufTypes::MessagePtr handshaker_config_message_;
Comment thread
ambuc marked this conversation as resolved.
Outdated
};

class ClientContextConfigImpl : public ContextConfigImpl, public Envoy::Ssl::ClientContextConfig {
Expand Down
Loading