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