blob: c15d9202af4409e9871f5452c707559d1277e47c [file] [log] [blame]
// 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 <vector>
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_string_piece.h"
namespace quic {
// TlsConnection wraps BoringSSL's SSL object which represents a single TLS
// connection. Callbacks set in BoringSSL which are called with an SSL* argument
// will get dispatched to the TlsConnection object owning that SSL. In turn, the
// TlsConnection will delegate the implementation of that callback to its
// Delegate.
// The owner of the TlsConnection is responsible for driving the TLS handshake
// (and other interactions with the SSL*). This class only handles mapping
// callbacks to the correct instance.
class QUIC_EXPORT_PRIVATE TlsConnection {
// A TlsConnection::Delegate implements the methods that are set as callbacks
// of TlsConnection.
class Delegate {
virtual ~Delegate() {}
// SetEncryptionSecret provides the encryption secrets to use at a
// particular encryption level |level|. The secrets provided here are the
// ones from the TLS 1.3 key schedule (RFC 8446 section 7.1), in particular
// the handshake traffic secrets and application traffic secrets. For a
// given level |level|, |read_secret| is the secret used for reading data,
// and |write_secret| is the secret used for writing data.
virtual void SetEncryptionSecret(
EncryptionLevel level,
const std::vector<uint8_t>& read_secret,
const std::vector<uint8_t>& write_secret) = 0;
// WriteMessage is called when there is |data| from the TLS stack ready for
// the QUIC stack to write in a crypto frame. The data must be transmitted
// at encryption level |level|.
virtual void WriteMessage(EncryptionLevel level, QuicStringPiece data) = 0;
// FlushFlight is called to signal that the current flight of messages have
// all been written (via calls to WriteMessage) and can be flushed to the
// underlying transport.
virtual void FlushFlight() = 0;
// SendAlert causes this TlsConnection to close the QUIC connection with an
// error code corersponding to the TLS alert description |desc| sent at
// level |level|.
virtual void SendAlert(EncryptionLevel level, uint8_t desc) = 0;
friend class TlsConnection;
TlsConnection(const TlsConnection&) = delete;
TlsConnection& operator=(const TlsConnection&) = delete;
// Functions to convert between BoringSSL's enum ssl_encryption_level_t and
// QUIC's EncryptionLevel.
static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
static enum ssl_encryption_level_t BoringEncryptionLevel(
EncryptionLevel level);
SSL* ssl() { return ssl_.get(); }
// TlsConnection does not take ownership of any of its arguments; they must
// outlive the TlsConnection object.
TlsConnection(SSL_CTX* ssl_ctx, Delegate* delegate);
// Creates an SSL_CTX and configures it with the options that are appropriate
// for both client and server. The caller is responsible for ownership of the
// newly created struct.
static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
// From a given SSL* |ssl|, returns a pointer to the TlsConnection that it
// belongs to. This helper method allows the callbacks set in BoringSSL to be
// dispatched to the correct TlsConnection from the SSL* passed into the
// callback.
static TlsConnection* ConnectionFromSsl(const SSL* ssl);
// TlsConnection implements SSL_QUIC_METHOD, which provides the interface
// between BoringSSL's TLS stack and a QUIC implementation.
static const SSL_QUIC_METHOD kSslQuicMethod;
// The following static functions make up the members of kSslQuicMethod:
static int SetEncryptionSecretCallback(SSL* ssl,
enum ssl_encryption_level_t level,
const uint8_t* read_key,
const uint8_t* write_key,
size_t key_length);
static int WriteMessageCallback(SSL* ssl,
enum ssl_encryption_level_t level,
const uint8_t* data,
size_t len);
static int FlushFlightCallback(SSL* ssl);
static int SendAlertCallback(SSL* ssl,
enum ssl_encryption_level_t level,
uint8_t desc);
Delegate* delegate_;
bssl::UniquePtr<SSL> ssl_;
} // namespace quic