summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/crypto/tls_connection.h
blob: 28b5684ad4a6dd85c0e3f4d203a3bb7a35f9c30a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
// 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.

#ifndef QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_
#define QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_

#include <vector>

#include "absl/strings/string_view.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "quic/core/quic_types.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 {
 public:
  // A TlsConnection::Delegate implements the methods that are set as callbacks
  // of TlsConnection.
  class QUIC_EXPORT_PRIVATE Delegate {
   public:
    virtual ~Delegate() {}

   protected:
    // Certificate management functions:

    // Verifies the peer's certificate chain. It may use
    // SSL_get0_peer_certificates to get the cert chain. This method returns
    // ssl_verify_ok if the cert is valid, ssl_verify_invalid if it is invalid,
    // or ssl_verify_retry if verification is happening asynchronously.
    virtual enum ssl_verify_result_t VerifyCert(uint8_t* out_alert) = 0;

    // QUIC-TLS interface functions:

    // SetWriteSecret provides the encryption secret used to encrypt messages at
    // encryption level |level|. The secret provided here is the one from the
    // TLS 1.3 key schedule (RFC 8446 section 7.1), in particular the handshake
    // traffic secrets and application traffic secrets. The provided write
    // secret must be used with the provided cipher suite |cipher|.
    virtual void SetWriteSecret(EncryptionLevel level,
                                const SSL_CIPHER* cipher,
                                const std::vector<uint8_t>& write_secret) = 0;

    // SetReadSecret is similar to SetWriteSecret, except that it is used for
    // decrypting messages. SetReadSecret at a particular level is always called
    // after SetWriteSecret for that level, except for ENCRYPTION_ZERO_RTT,
    // where the EncryptionLevel for SetWriteSecret is
    // ENCRYPTION_FORWARD_SECURE.
    virtual bool SetReadSecret(EncryptionLevel level,
                               const SSL_CIPHER* cipher,
                               const std::vector<uint8_t>& read_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,
                              absl::string_view 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() const { return ssl_.get(); }

 protected:
  // 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.
  //
  // The provided |cert_verify_mode| is passed in as the |mode| argument for
  // |SSL_CTX_set_verify|. See
  // https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#SSL_VERIFY_NONE
  // for a description of possible values.
  static bssl::UniquePtr<SSL_CTX> CreateSslCtx(int cert_verify_mode);

  // 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);

 private:
  // Registered as the callback for SSL_CTX_set_custom_verify. The
  // implementation is delegated to Delegate::VerifyCert.
  static enum ssl_verify_result_t VerifyCallback(SSL* ssl, uint8_t* out_alert);

  // 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 SetReadSecretCallback(SSL* ssl,
                                   enum ssl_encryption_level_t level,
                                   const SSL_CIPHER* cipher,
                                   const uint8_t* secret,
                                   size_t secret_len);
  static int SetWriteSecretCallback(SSL* ssl,
                                    enum ssl_encryption_level_t level,
                                    const SSL_CIPHER* cipher,
                                    const uint8_t* secret,
                                    size_t secret_len);
  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

#endif  // QUICHE_QUIC_CORE_CRYPTO_TLS_CONNECTION_H_