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