Refactor TlsHandshaker classes
QuicCryptoClientConfig and QuicCryptoServerConfig each own an SSL_CTX,
which is currently created by TlsHandshaker. Those crypto config classes
can't take a dependency on TlsHandshaker (because TlsHandshaker depends on
classes have a dependency in the other direction), resulting in the SSL_CTX
being passed into the crypto config constructors. The SSL_CTX shouldn't be
exposed like this, as it's essentially an implementation detail of the
crypto handshake.
This CL splits TlsHandshaker in two. TlsConnection (and its subclasses) are
in quic/core/crypto, and handle the callbacks from BoringSSL. In turn, it
passes the implementation of those callbacks to a delegate. TlsHandshaker
implements this delegate and owns the TlsConnection.
gfe-relnote: refactor TLS handshake classes in QUIC; not flag protected
PiperOrigin-RevId: 253140899
Change-Id: Ie907a7f61798c29a385be15ea0f53403b86508ab
diff --git a/quic/core/crypto/tls_server_connection.cc b/quic/core/crypto/tls_server_connection.cc
new file mode 100644
index 0000000..a3a1815
--- /dev/null
+++ b/quic/core/crypto/tls_server_connection.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quiche/src/quic/core/crypto/tls_server_connection.h"
+
+namespace quic {
+
+TlsServerConnection::TlsServerConnection(SSL_CTX* ssl_ctx, Delegate* delegate)
+ : TlsConnection(ssl_ctx, delegate->ConnectionDelegate()),
+ delegate_(delegate) {}
+
+// static
+bssl::UniquePtr<SSL_CTX> TlsServerConnection::CreateSslCtx() {
+ bssl::UniquePtr<SSL_CTX> ssl_ctx = TlsConnection::CreateSslCtx();
+ SSL_CTX_set_tlsext_servername_callback(ssl_ctx.get(),
+ &SelectCertificateCallback);
+ SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), &SelectAlpnCallback, nullptr);
+ return ssl_ctx;
+}
+
+void TlsServerConnection::SetCertChain(
+ const std::vector<CRYPTO_BUFFER*>& cert_chain) {
+ SSL_set_chain_and_key(ssl(), cert_chain.data(), cert_chain.size(), nullptr,
+ &TlsServerConnection::kPrivateKeyMethod);
+}
+
+const SSL_PRIVATE_KEY_METHOD TlsServerConnection::kPrivateKeyMethod{
+ &TlsServerConnection::PrivateKeySign,
+ nullptr, // decrypt
+ &TlsServerConnection::PrivateKeyComplete,
+};
+
+// static
+TlsServerConnection* TlsServerConnection::ConnectionFromSsl(SSL* ssl) {
+ return static_cast<TlsServerConnection*>(
+ TlsConnection::ConnectionFromSsl(ssl));
+}
+
+// static
+int TlsServerConnection::SelectCertificateCallback(SSL* ssl,
+ int* out_alert,
+ void* arg) {
+ return ConnectionFromSsl(ssl)->delegate_->SelectCertificate(out_alert);
+}
+
+// static
+int TlsServerConnection::SelectAlpnCallback(SSL* ssl,
+ const uint8_t** out,
+ uint8_t* out_len,
+ const uint8_t* in,
+ unsigned in_len,
+ void* arg) {
+ return ConnectionFromSsl(ssl)->delegate_->SelectAlpn(out, out_len, in,
+ in_len);
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeySign(SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out,
+ uint16_t sig_alg,
+ const uint8_t* in,
+ size_t in_len) {
+ return ConnectionFromSsl(ssl)->delegate_->PrivateKeySign(
+ out, out_len, max_out, sig_alg,
+ QuicStringPiece(reinterpret_cast<const char*>(in), in_len));
+}
+
+// static
+ssl_private_key_result_t TlsServerConnection::PrivateKeyComplete(
+ SSL* ssl,
+ uint8_t* out,
+ size_t* out_len,
+ size_t max_out) {
+ return ConnectionFromSsl(ssl)->delegate_->PrivateKeyComplete(out, out_len,
+ max_out);
+}
+
+} // namespace quic