xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_framer.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2012 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_CRYPTO_CRYPTO_FRAMER_H_
6 #define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "absl/strings/string_view.h"
16 #include "quiche/quic/core/crypto/crypto_handshake_message.h"
17 #include "quiche/quic/core/crypto/crypto_message_parser.h"
18 #include "quiche/quic/platform/api/quic_export.h"
19 
20 namespace quic {
21 
22 class CryptoFramer;
23 class QuicData;
24 class QuicDataWriter;
25 
26 class QUICHE_EXPORT CryptoFramerVisitorInterface {
27  public:
~CryptoFramerVisitorInterface()28   virtual ~CryptoFramerVisitorInterface() {}
29 
30   // Called if an error is detected.
31   virtual void OnError(CryptoFramer* framer) = 0;
32 
33   // Called when a complete handshake message has been parsed.
34   virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
35 };
36 
37 // A class for framing the crypto messages that are exchanged in a QUIC
38 // session.
39 class QUICHE_EXPORT CryptoFramer : public CryptoMessageParser {
40  public:
41   CryptoFramer();
42 
43   ~CryptoFramer() override;
44 
45   // ParseMessage parses exactly one message from the given
46   // absl::string_view. If there is an error, the message is truncated,
47   // or the message has trailing garbage then nullptr will be returned.
48   static std::unique_ptr<CryptoHandshakeMessage> ParseMessage(
49       absl::string_view in);
50 
51   // Set callbacks to be called from the framer.  A visitor must be set, or
52   // else the framer will crash.  It is acceptable for the visitor to do
53   // nothing.  If this is called multiple times, only the last visitor
54   // will be used.  |visitor| will be owned by the framer.
set_visitor(CryptoFramerVisitorInterface * visitor)55   void set_visitor(CryptoFramerVisitorInterface* visitor) {
56     visitor_ = visitor;
57   }
58 
59   QuicErrorCode error() const override;
60   const std::string& error_detail() const override;
61 
62   // Processes input data, which must be delivered in order. Returns
63   // false if there was an error, and true otherwise. ProcessInput optionally
64   // takes an EncryptionLevel, but it is ignored. The variant with the
65   // EncryptionLevel is provided to match the CryptoMessageParser interface.
66   bool ProcessInput(absl::string_view input, EncryptionLevel level) override;
67   bool ProcessInput(absl::string_view input);
68 
69   // Returns the number of bytes of buffered input data remaining to be
70   // parsed.
71   size_t InputBytesRemaining() const override;
72 
73   // Checks if the specified tag has been seen. Returns |true| if it
74   // has, and |false| if it has not or a CHLO has not been seen.
75   bool HasTag(QuicTag tag) const;
76 
77   // Even if the CHLO has not been fully received, force processing of
78   // the handshake message. This is dangerous and should not be used
79   // except as a mechanism of last resort.
80   void ForceHandshake();
81 
82   // Returns a new QuicData owned by the caller that contains a serialized
83   // |message|, or nullptr if there was an error.
84   static std::unique_ptr<QuicData> ConstructHandshakeMessage(
85       const CryptoHandshakeMessage& message);
86 
87   // Debug only method which permits processing truncated messages.
set_process_truncated_messages(bool process_truncated_messages)88   void set_process_truncated_messages(bool process_truncated_messages) {
89     process_truncated_messages_ = process_truncated_messages;
90   }
91 
92  private:
93   // Clears per-message state.  Does not clear the visitor.
94   void Clear();
95 
96   // Process does does the work of |ProcessInput|, but returns an error code,
97   // doesn't set error_ and doesn't call |visitor_->OnError()|.
98   QuicErrorCode Process(absl::string_view input);
99 
100   static bool WritePadTag(QuicDataWriter* writer, size_t pad_length,
101                           uint32_t* end_offset);
102 
103   // Represents the current state of the parsing state machine.
104   enum CryptoFramerState {
105     STATE_READING_TAG,
106     STATE_READING_NUM_ENTRIES,
107     STATE_READING_TAGS_AND_LENGTHS,
108     STATE_READING_VALUES
109   };
110 
111   // Visitor to invoke when messages are parsed.
112   CryptoFramerVisitorInterface* visitor_;
113   // Last error.
114   QuicErrorCode error_;
115   // Remaining unparsed data.
116   std::string buffer_;
117   // Current state of the parsing.
118   CryptoFramerState state_;
119   // The message currently being parsed.
120   CryptoHandshakeMessage message_;
121   // The issue which caused |error_|
122   std::string error_detail_;
123   // Number of entires in the message currently being parsed.
124   uint16_t num_entries_;
125   // tags_and_lengths_ contains the tags that are currently being parsed and
126   // their lengths.
127   std::vector<std::pair<QuicTag, size_t>> tags_and_lengths_;
128   // Cumulative length of all values in the message currently being parsed.
129   size_t values_len_;
130   // Set to true to allow of processing of truncated messages for debugging.
131   bool process_truncated_messages_;
132 };
133 
134 }  // namespace quic
135 
136 #endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_FRAMER_H_
137