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 "net/third_party/quiche/src/quic/core/quic_packets.h" 15 #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" 16 #include "net/third_party/quiche/src/quic/platform/api/quic_uint128.h" 17 #include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.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 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> SetValue(QuicTag tag,const T & v)46 void SetValue(QuicTag tag, const T& v) { 47 tag_value_map_[tag] = 48 std::string(reinterpret_cast<const char*>(&v), sizeof(v)); 49 } 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> SetVector(QuicTag tag,const std::vector<T> & v)54 void SetVector(QuicTag tag, const std::vector<T>& v) { 55 if (v.empty()) { 56 tag_value_map_[tag] = std::string(); 57 } else { 58 tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]), 59 v.size() * sizeof(T)); 60 } 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. tag()72 QuicTag tag() const { return tag_; } 73 // Sets the message tag. set_tag(QuicTag tag)74 void set_tag(QuicTag tag) { tag_ = tag; } 75 tag_value_map()76 const QuicTagValueMap& tag_value_map() const { return tag_value_map_; } 77 78 void SetStringPiece(QuicTag tag, quiche::QuicheStringPiece 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, quiche::QuicheStringPiece* 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 quiche::QuicheStringPiece* 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. 129 std::string DebugString() const; 130 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 141 std::string DebugStringInternal(size_t indent) const; 142 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_ 156