blob: ceba9a95ed2f868ae03868a0336bbbfdc7f6156f [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// Copyright (c) 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
6#define QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_
7
8#include "third_party/boringssl/src/include/openssl/base.h"
9#include "third_party/boringssl/src/include/openssl/ssl.h"
10#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
11#include "net/third_party/quiche/src/quic/core/crypto/crypto_message_parser.h"
12#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
13#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
14#include "net/third_party/quiche/src/quic/core/quic_session.h"
15#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
16
17namespace quic {
18
19class QuicCryptoStream;
20
21// Base class for TlsClientHandshaker and TlsServerHandshaker. TlsHandshaker
22// provides functionality common to both the client and server, such as moving
23// messages between the TLS stack and the QUIC crypto stream, and handling
24// derivation of secrets.
25class QUIC_EXPORT_PRIVATE TlsHandshaker : public CryptoMessageParser {
26 public:
27 // TlsHandshaker does not take ownership of any of its arguments; they must
28 // outlive the TlsHandshaker.
29 TlsHandshaker(QuicCryptoStream* stream,
30 QuicSession* session,
31 SSL_CTX* ssl_ctx);
32 TlsHandshaker(const TlsHandshaker&) = delete;
33 TlsHandshaker& operator=(const TlsHandshaker&) = delete;
34
35 ~TlsHandshaker() override;
36
37 // From CryptoMessageParser
38 bool ProcessInput(QuicStringPiece input, EncryptionLevel level) override;
39 size_t InputBytesRemaining() const override { return 0; }
40 QuicErrorCode error() const override { return parser_error_; }
41 const QuicString& error_detail() const override {
42 return parser_error_detail_;
43 }
44
45 // From QuicCryptoStream
46 virtual bool encryption_established() const = 0;
47 virtual bool handshake_confirmed() const = 0;
48 virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
49 const = 0;
50 virtual CryptoMessageParser* crypto_message_parser() { return this; }
51
52 protected:
53 virtual void AdvanceHandshake() = 0;
54
55 virtual void CloseConnection(QuicErrorCode error,
56 const QuicString& reason_phrase) = 0;
57
58 // Creates an SSL_CTX and configures it with the options that are appropriate
59 // for both client and server. The caller is responsible for ownership of the
60 // newly created struct.
61 static bssl::UniquePtr<SSL_CTX> CreateSslCtx();
62
63 // From a given SSL* |ssl|, returns a pointer to the TlsHandshaker that it
64 // belongs to. This is a helper method for implementing callbacks set on an
65 // SSL, as it allows the callback function to find the TlsHandshaker instance
66 // and call an instance method.
67 static TlsHandshaker* HandshakerFromSsl(const SSL* ssl);
68
69 static EncryptionLevel QuicEncryptionLevel(enum ssl_encryption_level_t level);
70 static enum ssl_encryption_level_t BoringEncryptionLevel(
71 EncryptionLevel level);
72
73 // Returns the PRF used by the cipher suite negotiated in the TLS handshake.
74 const EVP_MD* Prf();
75
76 std::unique_ptr<QuicEncrypter> CreateEncrypter(
77 const std::vector<uint8_t>& pp_secret);
78 std::unique_ptr<QuicDecrypter> CreateDecrypter(
79 const std::vector<uint8_t>& pp_secret);
80
81 SSL* ssl() { return ssl_.get(); }
82 QuicCryptoStream* stream() { return stream_; }
83 QuicSession* session() { return session_; }
84
85 private:
86 // TlsHandshaker implements SSL_QUIC_METHOD, which provides the interface
87 // between BoringSSL's TLS stack and a QUIC implementation.
88 static const SSL_QUIC_METHOD kSslQuicMethod;
89
90 // Pointers to the following 4 functions form |kSslQuicMethod|. Each one
91 // is a wrapper around the corresponding instance method below. The |ssl|
92 // argument is used to look up correct TlsHandshaker instance on which to call
93 // the method. According to the BoringSSL documentation, these functions
94 // return 0 on error and 1 otherwise; here they never error and thus always
95 // return 1.
96 static int SetEncryptionSecretCallback(SSL* ssl,
97 enum ssl_encryption_level_t level,
98 const uint8_t* read_key,
99 const uint8_t* write_key,
100 size_t secret_len);
101 static int WriteMessageCallback(SSL* ssl,
102 enum ssl_encryption_level_t level,
103 const uint8_t* data,
104 size_t len);
105 static int FlushFlightCallback(SSL* ssl);
106 static int SendAlertCallback(SSL* ssl,
107 enum ssl_encryption_level_t level,
108 uint8_t alert);
109
110 // SetEncryptionSecret provides the encryption secret to use at a particular
111 // encryption level. The secrets provided here are the ones from the TLS 1.3
112 // key schedule (RFC 8446 section 7.1), in particular the handshake traffic
113 // secrets and application traffic secrets. For a given secret |secret|,
114 // |level| indicates which EncryptionLevel it is to be used at, and |is_write|
115 // indicates whether it is used for encryption or decryption.
116 void SetEncryptionSecret(EncryptionLevel level,
117 const std::vector<uint8_t>& read_secret,
118 const std::vector<uint8_t>& write_secret);
119
120 // WriteMessage is called when there is |data| from the TLS stack ready for
121 // the QUIC stack to write in a crypto frame. The data must be transmitted at
122 // encryption level |level|.
123 void WriteMessage(EncryptionLevel level, QuicStringPiece data);
124
125 // FlushFlight is called to signal that the current flight of
126 // messages have all been written (via calls to WriteMessage) and can be
127 // flushed to the underlying transport.
128 void FlushFlight();
129
130 // SendAlert causes this TlsHandshaker to close the QUIC connection with an
131 // error code corresponding to the TLS alert description |desc|.
132 void SendAlert(EncryptionLevel level, uint8_t desc);
133
134 QuicCryptoStream* stream_;
135 QuicSession* session_;
136
137 QuicErrorCode parser_error_ = QUIC_NO_ERROR;
138 QuicString parser_error_detail_;
139
140 bssl::UniquePtr<SSL> ssl_;
141};
142
143} // namespace quic
144
145#endif // QUICHE_QUIC_CORE_TLS_HANDSHAKER_H_