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 NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ 6 #define NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/scoped_ptr.h" 13 #include "base/strings/string_piece.h" 14 #include "net/base/net_export.h" 15 #include "net/cert/cert_verify_result.h" 16 #include "net/cert/x509_certificate.h" 17 #include "net/quic/crypto/crypto_protocol.h" 18 #include "net/quic/crypto/proof_verifier.h" 19 #include "net/quic/quic_protocol.h" 20 21 namespace net { 22 23 class ChannelIDSigner; 24 class CommonCertSets; 25 class KeyExchange; 26 class ProofVerifier; 27 class QuicDecrypter; 28 class QuicEncrypter; 29 class QuicRandom; 30 31 // An intermediate format of a handshake message that's convenient for a 32 // CryptoFramer to serialize from or parse into. 33 class NET_EXPORT_PRIVATE CryptoHandshakeMessage { 34 public: 35 CryptoHandshakeMessage(); 36 CryptoHandshakeMessage(const CryptoHandshakeMessage& other); 37 ~CryptoHandshakeMessage(); 38 39 CryptoHandshakeMessage& operator=(const CryptoHandshakeMessage& other); 40 41 // Clears state. 42 void Clear(); 43 44 // GetSerialized returns the serialized form of this message and caches the 45 // result. Subsequently altering the message does not invalidate the cache. 46 const QuicData& GetSerialized() const; 47 48 // MarkDirty invalidates the cache created by |GetSerialized|. 49 void MarkDirty(); 50 51 // SetValue sets an element with the given tag to the raw, memory contents of 52 // |v|. SetValue(QuicTag tag,const T & v)53 template<class T> void SetValue(QuicTag tag, const T& v) { 54 tag_value_map_[tag] = 55 std::string(reinterpret_cast<const char*>(&v), sizeof(v)); 56 } 57 58 // SetVector sets an element with the given tag to the raw contents of an 59 // array of elements in |v|. SetVector(QuicTag tag,const std::vector<T> & v)60 template<class T> void SetVector(QuicTag tag, const std::vector<T>& v) { 61 if (v.empty()) { 62 tag_value_map_[tag] = std::string(); 63 } else { 64 tag_value_map_[tag] = std::string(reinterpret_cast<const char*>(&v[0]), 65 v.size() * sizeof(T)); 66 } 67 } 68 69 // Returns the message tag. tag()70 QuicTag tag() const { return tag_; } 71 // Sets the message tag. set_tag(QuicTag tag)72 void set_tag(QuicTag tag) { tag_ = tag; } 73 tag_value_map()74 const QuicTagValueMap& tag_value_map() const { return tag_value_map_; } 75 76 // SetTaglist sets an element with the given tag to contain a list of tags, 77 // passed as varargs. The argument list must be terminated with a 0 element. 78 void SetTaglist(QuicTag tag, ...); 79 80 void SetStringPiece(QuicTag tag, base::StringPiece value); 81 82 // Erase removes a tag/value, if present, from the message. 83 void Erase(QuicTag tag); 84 85 // GetTaglist finds an element with the given tag containing zero or more 86 // tags. If such a tag doesn't exist, it returns false. Otherwise it sets 87 // |out_tags| and |out_len| to point to the array of tags and returns true. 88 // The array points into the CryptoHandshakeMessage and is valid only for as 89 // long as the CryptoHandshakeMessage exists and is not modified. 90 QuicErrorCode GetTaglist(QuicTag tag, const QuicTag** out_tags, 91 size_t* out_len) const; 92 93 bool GetStringPiece(QuicTag tag, base::StringPiece* out) const; 94 95 // GetNthValue24 interprets the value with the given tag to be a series of 96 // 24-bit, length prefixed values and it returns the subvalue with the given 97 // index. 98 QuicErrorCode GetNthValue24(QuicTag tag, 99 unsigned index, 100 base::StringPiece* out) const; 101 QuicErrorCode GetUint16(QuicTag tag, uint16* out) const; 102 QuicErrorCode GetUint32(QuicTag tag, uint32* out) const; 103 QuicErrorCode GetUint64(QuicTag tag, uint64* out) const; 104 105 // size returns 4 (message tag) + 2 (uint16, number of entries) + 106 // (4 (tag) + 4 (end offset))*tag_value_map_.size() + ∑ value sizes. 107 size_t size() const; 108 109 // set_minimum_size sets the minimum number of bytes that the message should 110 // consume. The CryptoFramer will add a PAD tag as needed when serializing in 111 // order to ensure this. Setting a value of 0 disables padding. 112 // 113 // Padding is useful in order to ensure that messages are a minimum size. A 114 // QUIC server can require a minimum size in order to reduce the 115 // amplification factor of any mirror DoS attack. 116 void set_minimum_size(size_t min_bytes); 117 118 size_t minimum_size() const; 119 120 // DebugString returns a multi-line, string representation of the message 121 // suitable for including in debug output. 122 std::string DebugString() const; 123 124 private: 125 // GetPOD is a utility function for extracting a plain-old-data value. If 126 // |tag| exists in the message, and has a value of exactly |len| bytes then 127 // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out| 128 // are zeroed out. 129 // 130 // If used to copy integers then this assumes that the machine is 131 // little-endian. 132 QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const; 133 134 std::string DebugStringInternal(size_t indent) const; 135 136 QuicTag tag_; 137 QuicTagValueMap tag_value_map_; 138 139 size_t minimum_size_; 140 141 // The serialized form of the handshake message. This member is constructed 142 // lasily. 143 mutable scoped_ptr<QuicData> serialized_; 144 }; 145 146 // A CrypterPair contains the encrypter and decrypter for an encryption level. 147 struct NET_EXPORT_PRIVATE CrypterPair { 148 CrypterPair(); 149 ~CrypterPair(); 150 scoped_ptr<QuicEncrypter> encrypter; 151 scoped_ptr<QuicDecrypter> decrypter; 152 }; 153 154 // Parameters negotiated by the crypto handshake. 155 struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters { 156 // Initializes the members to 0 or empty values. 157 QuicCryptoNegotiatedParameters(); 158 ~QuicCryptoNegotiatedParameters(); 159 160 QuicTag key_exchange; 161 QuicTag aead; 162 std::string initial_premaster_secret; 163 std::string forward_secure_premaster_secret; 164 CrypterPair initial_crypters; 165 CrypterPair forward_secure_crypters; 166 // Normalized SNI: converted to lower case and trailing '.' removed. 167 std::string sni; 168 std::string client_nonce; 169 std::string server_nonce; 170 // hkdf_input_suffix contains the HKDF input following the label: the GUID, 171 // client hello and server config. This is only populated in the client 172 // because only the client needs to derive the forward secure keys at a later 173 // time from the initial keys. 174 std::string hkdf_input_suffix; 175 // cached_certs contains the cached certificates that a client used when 176 // sending a client hello. 177 std::vector<std::string> cached_certs; 178 // client_key_exchange is used by clients to store the ephemeral KeyExchange 179 // for the connection. 180 scoped_ptr<KeyExchange> client_key_exchange; 181 // channel_id is set by servers to a ChannelID key when the client correctly 182 // proves possession of the corresponding private key. It consists of 32 183 // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values 184 // are big-endian and the pair is a P-256 public key. 185 std::string channel_id; 186 }; 187 188 // QuicCryptoConfig contains common configuration between clients and servers. 189 class NET_EXPORT_PRIVATE QuicCryptoConfig { 190 public: 191 // kInitialLabel is a constant that is used when deriving the initial 192 // (non-forward secure) keys for the connection in order to tie the resulting 193 // key to this protocol. 194 static const char kInitialLabel[]; 195 196 // kCETVLabel is a constant that is used when deriving the keys for the 197 // encrypted tag/value block in the client hello. 198 static const char kCETVLabel[]; 199 200 // kForwardSecureLabel is a constant that is used when deriving the forward 201 // secure keys for the connection in order to tie the resulting key to this 202 // protocol. 203 static const char kForwardSecureLabel[]; 204 205 QuicCryptoConfig(); 206 ~QuicCryptoConfig(); 207 208 // Key exchange methods. The following two members' values correspond by 209 // index. 210 QuicTagVector kexs; 211 // Authenticated encryption with associated data (AEAD) algorithms. 212 QuicTagVector aead; 213 214 const CommonCertSets* common_cert_sets; 215 216 private: 217 DISALLOW_COPY_AND_ASSIGN(QuicCryptoConfig); 218 }; 219 220 } // namespace net 221 222 #endif // NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_ 223