summaryrefslogtreecommitdiff
path: root/chromium/net/third_party/quiche/src/quic/core/crypto/proof_source.h
blob: cee94f2e4af0bd0a9f18d0d78a21e06eba179001 (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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
// Copyright (c) 2013 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_PROOF_SOURCE_H_
#define QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_

#include <memory>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "third_party/boringssl/src/include/openssl/ssl.h"
#include "quic/core/crypto/quic_crypto_proof.h"
#include "quic/core/quic_versions.h"
#include "quic/platform/api/quic_export.h"
#include "quic/platform/api/quic_reference_counted.h"
#include "quic/platform/api/quic_socket_address.h"

namespace quic {

namespace test {
class FakeProofSourceHandle;
}  // namespace test

// CryptoBuffers is a RAII class to own a std::vector<CRYPTO_BUFFER*> and the
// buffers the elements point to.
struct QUIC_EXPORT_PRIVATE CryptoBuffers {
  CryptoBuffers() = default;
  CryptoBuffers(const CryptoBuffers&) = delete;
  CryptoBuffers(CryptoBuffers&&) = default;
  ~CryptoBuffers();

  std::vector<CRYPTO_BUFFER*> value;
};

// ProofSource is an interface by which a QUIC server can obtain certificate
// chains and signatures that prove its identity.
class QUIC_EXPORT_PRIVATE ProofSource {
 public:
  // Chain is a reference-counted wrapper for a vector of stringified
  // certificates.
  struct QUIC_EXPORT_PRIVATE Chain : public QuicReferenceCounted {
    explicit Chain(const std::vector<std::string>& certs);
    Chain(const Chain&) = delete;
    Chain& operator=(const Chain&) = delete;

    CryptoBuffers ToCryptoBuffers() const;

    const std::vector<std::string> certs;

   protected:
    ~Chain() override;
  };

  // Details is an abstract class which acts as a container for any
  // implementation-specific details that a ProofSource wants to return.
  class QUIC_EXPORT_PRIVATE Details {
   public:
    virtual ~Details() {}
  };

  // Callback base class for receiving the results of an async call to GetProof.
  class QUIC_EXPORT_PRIVATE Callback {
   public:
    Callback() {}
    virtual ~Callback() {}

    // Invoked upon completion of GetProof.
    //
    // |ok| indicates whether the operation completed successfully.  If false,
    // the values of the remaining three arguments are undefined.
    //
    // |chain| is a reference-counted pointer to an object representing the
    // certificate chain.
    //
    // |signature| contains the signature of the server config.
    //
    // |leaf_cert_sct| holds the signed timestamp (RFC6962) of the leaf cert.
    //
    // |details| holds a pointer to an object representing the statistics, if
    // any, gathered during the operation of GetProof.  If no stats are
    // available, this will be nullptr.
    virtual void Run(bool ok,
                     const QuicReferenceCountedPointer<Chain>& chain,
                     const QuicCryptoProof& proof,
                     std::unique_ptr<Details> details) = 0;

   private:
    Callback(const Callback&) = delete;
    Callback& operator=(const Callback&) = delete;
  };

  // Base class for signalling the completion of a call to ComputeTlsSignature.
  class QUIC_EXPORT_PRIVATE SignatureCallback {
   public:
    SignatureCallback() {}
    virtual ~SignatureCallback() = default;

    // Invoked upon completion of ComputeTlsSignature.
    //
    // |ok| indicates whether the operation completed successfully.
    //
    // |signature| contains the signature of the data provided to
    // ComputeTlsSignature. Its value is undefined if |ok| is false.
    //
    // |details| holds a pointer to an object representing the statistics, if
    // any, gathered during the operation of ComputeTlsSignature.  If no stats
    // are available, this will be nullptr.
    virtual void Run(bool ok,
                     std::string signature,
                     std::unique_ptr<Details> details) = 0;

   private:
    SignatureCallback(const SignatureCallback&) = delete;
    SignatureCallback& operator=(const SignatureCallback&) = delete;
  };

  virtual ~ProofSource() {}

  // GetProof finds a certificate chain for |hostname| (in leaf-first order),
  // and calculates a signature of |server_config| using that chain.
  //
  // The signature uses SHA-256 as the hash function and PSS padding when the
  // key is RSA.
  //
  // The signature uses SHA-256 as the hash function when the key is ECDSA.
  // The signature may use an ECDSA key.
  //
  // The signature depends on |chlo_hash| which means that the signature can not
  // be cached.
  //
  // |hostname| may be empty to signify that a default certificate should be
  // used.
  //
  // This function may be called concurrently.
  //
  // Callers should expect that |callback| might be invoked synchronously.
  virtual void GetProof(const QuicSocketAddress& server_address,
                        const QuicSocketAddress& client_address,
                        const std::string& hostname,
                        const std::string& server_config,
                        QuicTransportVersion transport_version,
                        absl::string_view chlo_hash,
                        std::unique_ptr<Callback> callback) = 0;

  // Returns the certificate chain for |hostname| in leaf-first order.
  virtual QuicReferenceCountedPointer<Chain> GetCertChain(
      const QuicSocketAddress& server_address,
      const QuicSocketAddress& client_address,
      const std::string& hostname) = 0;

  // Computes a signature using the private key of the certificate for
  // |hostname|. The value in |in| is signed using the algorithm specified by
  // |signature_algorithm|, which is an |SSL_SIGN_*| value (as defined in TLS
  // 1.3). Implementations can only assume that |in| is valid during the call to
  // ComputeTlsSignature - an implementation computing signatures asynchronously
  // must copy it if the value to be signed is used outside of this function.
  //
  // Callers should expect that |callback| might be invoked synchronously.
  virtual void ComputeTlsSignature(
      const QuicSocketAddress& server_address,
      const QuicSocketAddress& client_address,
      const std::string& hostname,
      uint16_t signature_algorithm,
      absl::string_view in,
      std::unique_ptr<SignatureCallback> callback) = 0;

  class QUIC_EXPORT_PRIVATE DecryptCallback {
   public:
    DecryptCallback() = default;
    virtual ~DecryptCallback() = default;

    virtual void Run(std::vector<uint8_t> plaintext) = 0;

   private:
    DecryptCallback(const Callback&) = delete;
    DecryptCallback& operator=(const Callback&) = delete;
  };

  // TicketCrypter is an interface for managing encryption and decryption of TLS
  // session tickets. A TicketCrypter gets used as an
  // SSL_CTX_set_ticket_aead_method in BoringSSL, which has a synchronous
  // Encrypt/Seal operation and a potentially asynchronous Decrypt/Open
  // operation. This interface allows for ticket decryptions to be performed on
  // a remote service.
  class QUIC_EXPORT_PRIVATE TicketCrypter {
   public:
    TicketCrypter() = default;
    virtual ~TicketCrypter() = default;

    // MaxOverhead returns the maximum number of bytes of overhead that may get
    // added when encrypting the ticket.
    virtual size_t MaxOverhead() = 0;

    // Encrypt takes a serialized TLS session ticket in |in|, encrypts it, and
    // returns the encrypted ticket. The resulting value must not be larger than
    // MaxOverhead bytes larger than |in|. If encryption fails, this method
    // returns an empty vector.
    virtual std::vector<uint8_t> Encrypt(absl::string_view in) = 0;

    // Decrypt takes an encrypted ticket |in|, decrypts it, and calls
    // |callback->Run| with the decrypted ticket, which must not be larger than
    // |in|. If decryption fails, the callback is invoked with an empty
    // vector.
    virtual void Decrypt(absl::string_view in,
                         std::unique_ptr<DecryptCallback> callback) = 0;
  };

  // Returns the TicketCrypter used for encrypting and decrypting TLS
  // session tickets, or nullptr if that functionality is not supported. The
  // TicketCrypter returned (if not nullptr) must be valid for the lifetime of
  // the ProofSource, and the caller does not take ownership of said
  // TicketCrypter.
  virtual TicketCrypter* GetTicketCrypter() = 0;
};

// ProofSourceHandleCallback is an interface that contains the callbacks when
// the operations in ProofSourceHandle completes.
// TODO(wub): Consider deprecating ProofSource by moving all functionalities of
// ProofSource into ProofSourceHandle.
class QUIC_EXPORT_PRIVATE ProofSourceHandleCallback {
 public:
  virtual ~ProofSourceHandleCallback() = default;

  // Called when a ProofSourceHandle::SelectCertificate operation completes.
  // |ok| indicates whether the operation was successful.
  // |is_sync| indicates whether the operation completed synchronously, i.e.
  //      whether it is completed before ProofSourceHandle::SelectCertificate
  //      returned.
  // |chain| the certificate chain in leaf-first order.
  //
  // When called asynchronously(is_sync=false), this method will be responsible
  // to continue the handshake from where it left off.
  virtual void OnSelectCertificateDone(bool ok,
                                       bool is_sync,
                                       const ProofSource::Chain* chain) = 0;

  // Called when a ProofSourceHandle::ComputeSignature operation completes.
  virtual void OnComputeSignatureDone(
      bool ok,
      bool is_sync,
      std::string signature,
      std::unique_ptr<ProofSource::Details> details) = 0;
};

// ProofSourceHandle is an interface by which a TlsServerHandshaker can obtain
// certificate chains and signatures that prove its identity.
// The operations this interface supports are similar to those in ProofSource,
// the main difference is that ProofSourceHandle is per-handshaker, so
// an implementation can have states that are shared by multiple calls on the
// same handle.
//
// A handle object is owned by a TlsServerHandshaker. Since there might be an
// async operation pending when the handle destructs, an implementation must
// ensure when such operations finish, their corresponding callback method won't
// be invoked.
//
// A handle will have at most one async operation pending at a time.
class QUIC_EXPORT_PRIVATE ProofSourceHandle {
 public:
  virtual ~ProofSourceHandle() = default;

  // Cancel the pending operation, if any.
  // Once called, any completion method on |callback()| won't be invoked.
  virtual void CancelPendingOperation() = 0;

  // Starts a select certificate operation. If the operation is not cancelled
  // when it completes, callback()->OnSelectCertificateDone will be invoked.
  //
  // If the operation is handled synchronously:
  // - QUIC_SUCCESS or QUIC_FAILURE will be returned.
  // - callback()->OnSelectCertificateDone should be invoked before the function
  //   returns.
  //
  // If the operation is handled asynchronously:
  // - QUIC_PENDING will be returned.
  // - When the operation is done, callback()->OnSelectCertificateDone should be
  //   invoked.
  virtual QuicAsyncStatus SelectCertificate(
      const QuicSocketAddress& server_address,
      const QuicSocketAddress& client_address,
      const std::string& hostname,
      absl::string_view client_hello,
      const std::string& alpn,
      const std::vector<uint8_t>& quic_transport_params,
      const absl::optional<std::vector<uint8_t>>& early_data_context) = 0;

  // Starts a compute signature operation. If the operation is not cancelled
  // when it completes, callback()->OnComputeSignatureDone will be invoked.
  //
  // See the comments of SelectCertificate for sync vs. async operations.
  virtual QuicAsyncStatus ComputeSignature(
      const QuicSocketAddress& server_address,
      const QuicSocketAddress& client_address,
      const std::string& hostname,
      uint16_t signature_algorithm,
      absl::string_view in,
      size_t max_signature_size) = 0;

 protected:
  // Returns the object that will be notified when an operation completes.
  virtual ProofSourceHandleCallback* callback() = 0;

 private:
  friend class test::FakeProofSourceHandle;
};

}  // namespace quic

#endif  // QUICHE_QUIC_CORE_CRYPTO_PROOF_SOURCE_H_