xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake_message.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2013 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_HANDSHAKE_MESSAGE_H_
6 #define QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "absl/strings/string_view.h"
15 #include "quiche/quic/core/quic_packets.h"
16 #include "quiche/quic/core/quic_types.h"
17 #include "quiche/quic/platform/api/quic_export.h"
18 
19 namespace quic {
20 
21 // An intermediate format of a handshake message that's convenient for a
22 // CryptoFramer to serialize from or parse into.
23 class QUICHE_EXPORT CryptoHandshakeMessage {
24  public:
25   CryptoHandshakeMessage();
26   CryptoHandshakeMessage(const CryptoHandshakeMessage& other);
27   CryptoHandshakeMessage(CryptoHandshakeMessage&& other);
28   ~CryptoHandshakeMessage();
29 
30   CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other);
31   CryptoHandshakeMessage& operator=(CryptoHandshakeMessage&& other);
32 
33   bool operator==(const CryptoHandshakeMessage& rhs) const;
34   bool operator!=(const CryptoHandshakeMessage& rhs) const;
35 
36   // Clears state.
37   void Clear();
38 
39   // GetSerialized returns the serialized form of this message and caches the
40   // result. Subsequently altering the message does not invalidate the cache.
41   const QuicData& GetSerialized() const;
42 
43   // MarkDirty invalidates the cache created by |GetSerialized|.
44   void MarkDirty();
45 
46   // SetValue sets an element with the given tag to the raw, memory contents of
47   // |v|.
48   template <class T>
SetValue(QuicTag tag,const T & v)49   void SetValue(QuicTag tag, const T& v) {
50     tag_value_map_[tag] =
51         std::string(reinterpret_cast<const char*>(&v), sizeof(v));
52   }
53 
54   // SetVector sets an element with the given tag to the raw contents of an
55   // array of elements in |v|.
56   template <class T>
SetVector(QuicTag tag,const std::vector<T> & v)57   void SetVector(QuicTag tag, const std::vector<T>& v) {
58     if (v.empty()) {
59       tag_value_map_[tag] = std::string();
60     } else {
61       tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]),
62                                         v.size() * sizeof(T));
63     }
64   }
65 
66   // Sets an element with the given tag to the on-the-wire representation of
67   // |version|.
68   void SetVersion(QuicTag tag, ParsedQuicVersion version);
69 
70   // Sets an element with the given tag to the on-the-wire representation of
71   // the elements in |versions|.
72   void SetVersionVector(QuicTag tag, ParsedQuicVersionVector versions);
73 
74   // Returns the message tag.
tag()75   QuicTag tag() const { return tag_; }
76   // Sets the message tag.
set_tag(QuicTag tag)77   void set_tag(QuicTag tag) { tag_ = tag; }
78 
tag_value_map()79   const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
80 
81   void SetStringPiece(QuicTag tag, absl::string_view value);
82 
83   // Erase removes a tag/value, if present, from the message.
84   void Erase(QuicTag tag);
85 
86   // GetTaglist finds an element with the given tag containing zero or more
87   // tags. If such a tag doesn't exist, it returns an error code. Otherwise it
88   // populates |out_tags| with the tags and returns QUIC_NO_ERROR.
89   QuicErrorCode GetTaglist(QuicTag tag, QuicTagVector* out_tags) const;
90 
91   // GetVersionLabelList finds an element with the given tag containing zero or
92   // more version labels. If such a tag doesn't exist, it returns an error code.
93   // Otherwise it populates |out| with the labels and returns QUIC_NO_ERROR.
94   QuicErrorCode GetVersionLabelList(QuicTag tag,
95                                     QuicVersionLabelVector* out) const;
96 
97   // GetVersionLabel finds an element with the given tag containing a single
98   // version label. If such a tag doesn't exist, it returns an error code.
99   // Otherwise it populates |out| with the label and returns QUIC_NO_ERROR.
100   QuicErrorCode GetVersionLabel(QuicTag tag, QuicVersionLabel* out) const;
101 
102   bool GetStringPiece(QuicTag tag, absl::string_view* out) const;
103   bool HasStringPiece(QuicTag tag) const;
104 
105   // GetNthValue24 interprets the value with the given tag to be a series of
106   // 24-bit, length prefixed values and it returns the subvalue with the given
107   // index.
108   QuicErrorCode GetNthValue24(QuicTag tag, unsigned index,
109                               absl::string_view* out) const;
110   QuicErrorCode GetUint32(QuicTag tag, uint32_t* out) const;
111   QuicErrorCode GetUint64(QuicTag tag, uint64_t* out) const;
112 
113   QuicErrorCode GetStatelessResetToken(QuicTag tag,
114                                        StatelessResetToken* out) const;
115 
116   // size returns 4 (message tag) + 2 (uint16_t, number of entries) +
117   // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes.
118   size_t size() const;
119 
120   // set_minimum_size sets the minimum number of bytes that the message should
121   // consume. The CryptoFramer will add a PAD tag as needed when serializing in
122   // order to ensure this. Setting a value of 0 disables padding.
123   //
124   // Padding is useful in order to ensure that messages are a minimum size. A
125   // QUIC server can require a minimum size in order to reduce the
126   // amplification factor of any mirror DoS attack.
127   void set_minimum_size(size_t min_bytes);
128 
129   size_t minimum_size() const;
130 
131   // DebugString returns a multi-line, string representation of the message
132   // suitable for including in debug output.
133   std::string DebugString() const;
134 
135  private:
136   // GetPOD is a utility function for extracting a plain-old-data value. If
137   // |tag| exists in the message, and has a value of exactly |len| bytes then
138   // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
139   // are zeroed out.
140   //
141   // If used to copy integers then this assumes that the machine is
142   // little-endian.
143   QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
144 
145   std::string DebugStringInternal(size_t indent) const;
146 
147   QuicTag tag_;
148   QuicTagValueMap tag_value_map_;
149 
150   size_t minimum_size_;
151 
152   // The serialized form of the handshake message. This member is constructed
153   // lazily.
154   mutable std::unique_ptr<QuicData> serialized_;
155 };
156 
157 }  // namespace quic
158 
159 #endif  // QUICHE_QUIC_CORE_CRYPTO_CRYPTO_HANDSHAKE_MESSAGE_H_
160