• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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