-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[tls] Add a custom listener handshaker for TLS. #12075
Conversation
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
What's the use case for a custom handshaker? |
@rojkov We want to be able to modify TLS termination to perform crypto operations outside of the Envoy binary. |
Probably a custom |
I got the impression |
…shaking Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
@ggreenway @PiotrSikora @lizan could you folks take a look at this? Thanks. |
For some use cases, yes. But custom handshaker allows you to offload more than just private key operations. |
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
…ck_format Signed-off-by: James Buckland <jbuckland@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the overall design is fine.
I'd like to see a reference implementation of calling another handshaker out of process, or at least in another thread in a test. This can't be adequately tested without it I don't think. Also, I think should be clear how to implement this interface, ie an implementation needs to get some data from the SSL
, send it to the thing that does the privatekey operations, do those operations, send the result back, and apply the result to the SSL
. The private-key operation server-like thing doesn't need to be production-grade, but the envoy implementation of a handshaker probably should be.
One option for a Handshaker implementation would be to write an integration with https://github.com/cloudflare/gokeyless. Although I don't know if the license actually allows that (it's not a standard open-source license). |
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The overall pattern looks good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you put names like this (bssl, rbio, etc) in backticks in the comment the spellchecker won't check them, and then they don't need to be in the dictionary.
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
… to a non-dangling SSL*. Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
Signed-off-by: James Buckland <jbuckland@google.com>
handshaker_callbacks_ = &handshaker_callbacks; | ||
} | ||
|
||
SSL* ssl() override { return ssl_.get(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're missing an important restriction on the use of this method: access to the SSL* object before handshake is complete should be forbidden.
I think this restriction clashes with use of this method in SslSocketInfo's constructor and possibly in a few other places.
} | ||
|
||
Network::PostIoAction doHandshake(Ssl::SocketState& state) override { | ||
ASSERT(state != Ssl::SocketState::HandshakeComplete && state != Ssl::SocketState::ShutdownSent); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This for test doHandshake implementation looks too real. it seems like a copy of HandshakeImpl::doHandshake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It basically is. I specifically wanted to demonstrate special-case error handling under switch(SSL_get_error(...))
. Should I add more comments to call out that only the SSL_ERROR_WANT_X509_LOOKUP
block is different?
virtual SSL* ssl() PURE; | ||
}; | ||
|
||
using HandshakerSharedPtr = std::shared_ptr<Handshaker>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like we should statically know the lifetime of this, and should be able to use a unique_ptr + references.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the alternative here? @lizan pointed out (#12075 (comment)) that the SslSocketInfo struct expects to have access to the SSL object after the connection has been destroyed, for logging purposes. What do you think of explicitly std::move()ing the SSL object from the handshaker to the SslSocketInfo just before ~SslSocket(), perhaps during SslSocket::shutdown()? @antoniovicente
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might make sense for Handshaker
to implement Ssl::ConnectionInfo
, as the socket info class is basically represent the result of handshake.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handshaker providing Ssl::ConnectionInfo makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PTAL @ #12571, I am attempting to move the handshaker behavior into SslSocketInfo before adding an extension point.
/wait |
Additional Description: This PR necessitated decoupling SslHandshakerImpl from ContextConfig a bit. We now pass an int representing the index of the extended_info struct rather than the ContextConfig. This PR moves SslHandshakerImpl to its own build target, moves SslHandshaker construction into the ContextConfig, and adds a HandshakerFactoryContext and HandshakerFactory for modifying the ContextConfig's behavior when constructing a Handshaker. This PR also adds a control (requireCertificates) to turn off the release asserts that a context must have certificates. This PR builds off work in #12571 and refines work done (and abandoned) in #12075. For more discussion please see the comments section of #12075. Risk Level: Low. This PR does not modify existing handshaking behavior, it just adds an extension point for modifying it. Testing: A representative alternative implementation was added under :handshaker_test. Docs Changes: N/a Release Notes: N/a Signed-off-by: James Buckland <jbuckland@google.com>
Additional Description: This PR necessitated decoupling SslHandshakerImpl from ContextConfig a bit. We now pass an int representing the index of the extended_info struct rather than the ContextConfig. This PR moves SslHandshakerImpl to its own build target, moves SslHandshaker construction into the ContextConfig, and adds a HandshakerFactoryContext and HandshakerFactory for modifying the ContextConfig's behavior when constructing a Handshaker. This PR also adds a control (requireCertificates) to turn off the release asserts that a context must have certificates. This PR builds off work in envoyproxy/envoy#12571 and refines work done (and abandoned) in envoyproxy/envoy#12075. For more discussion please see the comments section of envoyproxy/envoy#12075. Risk Level: Low. This PR does not modify existing handshaking behavior, it just adds an extension point for modifying it. Testing: A representative alternative implementation was added under :handshaker_test. Docs Changes: N/a Release Notes: N/a Signed-off-by: James Buckland <jbuckland@google.com> Mirrored from https://github.com/envoyproxy/envoy @ 7d6e7a4e559bdf0346687f7f404412e2412ea6fb
Signed-off-by: James Buckland jbuckland@google.com
Commit Message: [tls] Add a custom listener handshaker for TLS.
Additional Description: This CL introduces a mechanism for modifying the behavior a TLS socket uses to handshake. It moves the existing implementation into a default HandshakerImpl and introduces an extension for injecting custom handshaker behavior.
Risk Level: Low, the default handshaking behavior in unmodified Envoy is unchanged.
Testing: All existing unit/integration tests use the default handshaking behavior (as before). The existing handshaker implementation also gains unit tests.
Docs Changes: None -- I think the API comments will generate documentation.
Release Notes: n/a