1 // Copyright 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.
5 #ifndef NET_QUIC_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
6 #define NET_QUIC_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_
12 #include "base/memory/scoped_ptr.h"
13 #include "base/strings/string_piece.h"
14 #include "net/base/net_export.h"
15 #include "net/quic/crypto/crypto_handshake.h"
16 #include "net/quic/quic_protocol.h"
20 class ChannelIDSigner;
21 class CryptoHandshakeMessage;
23 class ProofVerifyDetails;
26 class QuicServerInfoFactory;
28 // QuicCryptoClientConfig contains crypto-related configuration settings for a
29 // client. Note that this object isn't thread-safe. It's designed to be used on
30 // a single thread at a time.
31 class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
33 // A CachedState contains the information that the client needs in order to
34 // perform a 0-RTT handshake with a server. This information can be reused
35 // over several connections to the same server.
36 class NET_EXPORT_PRIVATE CachedState {
39 explicit CachedState(scoped_ptr<QuicServerInfo> quic_server_info);
42 // IsComplete returns true if this object contains enough information to
43 // perform a handshake with the server. |now| is used to judge whether any
44 // cached server config has expired.
45 bool IsComplete(QuicWallTime now) const;
47 // GetServerConfig returns the parsed contents of |server_config|, or NULL
48 // if |server_config| is empty. The return value is owned by this object
49 // and is destroyed when this object is.
50 const CryptoHandshakeMessage* GetServerConfig() const;
52 // SetServerConfig checks that |server_config| parses correctly and stores
53 // it in |server_config_|. |now| is used to judge whether |server_config|
55 QuicErrorCode SetServerConfig(base::StringPiece server_config,
57 std::string* error_details);
59 // InvalidateServerConfig clears the cached server config (if any).
60 void InvalidateServerConfig();
62 // SetProof stores a certificate chain and signature.
63 void SetProof(const std::vector<std::string>& certs,
64 base::StringPiece signature);
66 // Clears the certificate chain and signature and invalidates the proof.
69 // SetProofValid records that the certificate chain and signature have been
70 // validated and that it's safe to assume that the server is legitimate.
71 // (Note: this does not check the chain or signature.)
74 // If the server config or the proof has changed then it needs to be
75 // revalidated. Helper function to keep server_config_valid_ and
76 // generation_counter_ in sync.
77 void SetProofInvalid();
79 const std::string& server_config() const;
80 const std::string& source_address_token() const;
81 const std::vector<std::string>& certs() const;
82 const std::string& signature() const;
83 bool proof_valid() const;
84 uint64 generation_counter() const;
85 const ProofVerifyDetails* proof_verify_details() const;
87 void set_source_address_token(base::StringPiece token);
89 // SetProofVerifyDetails takes ownership of |details|.
90 void SetProofVerifyDetails(ProofVerifyDetails* details);
92 // Copy the |server_config_|, |source_address_token_|, |certs_| and
93 // |server_config_sig_| from the |other|. The remaining fields,
94 // |generation_counter_|, |proof_verify_details_|, and |scfg_| remain
96 void InitializeFrom(const CachedState& other);
99 std::string server_config_; // A serialized handshake message.
100 std::string source_address_token_; // An opaque proof of IP ownership.
101 std::vector<std::string> certs_; // A list of certificates in leaf-first
103 std::string server_config_sig_; // A signature of |server_config_|.
104 bool server_config_valid_; // True if |server_config_| is correctly
105 // signed and |certs_| has been
107 // Generation counter associated with the |server_config_|, |certs_| and
108 // |server_config_sig_| combination. It is incremented whenever we set
109 // server_config_valid_ to false.
110 uint64 generation_counter_;
112 scoped_ptr<ProofVerifyDetails> proof_verify_details_;
114 // scfg contains the cached, parsed value of |server_config|.
115 mutable scoped_ptr<CryptoHandshakeMessage> scfg_;
117 // |quic_server_info_| is used to fetch crypto config information from disk.
118 scoped_ptr<QuicServerInfo> quic_server_info_;
120 DISALLOW_COPY_AND_ASSIGN(CachedState);
123 QuicCryptoClientConfig();
124 ~QuicCryptoClientConfig();
126 // Sets the members to reasonable, default values.
129 // Create returns a CachedState for the given hostname. It creates a
130 // CachedState and caches it. If |quic_server_info_factory| is not NULL, then
131 // it is used to create QuicServerInfo which is used to fetch crypto config
132 // information from disk for the given hostname.
133 CachedState* Create(const std::string& server_hostname,
134 QuicServerInfoFactory* quic_server_info_factory);
136 // LookupOrCreate returns a CachedState for the given hostname. If no such
137 // CachedState currently exists, it will be created and cached.
138 // TODO(rtenneti): fix the server code and pass QuicServerInfoFactory as
140 CachedState* LookupOrCreate(const std::string& server_hostname);
142 // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
143 // source-address token or SCFG from a server. If |cached| is non-NULL, the
144 // source-address token will be taken from it. |out_params| is used in order
145 // to store the cached certs that were sent as hints to the server in
146 // |out_params->cached_certs|. |preferred_version| is the version of the QUIC
147 // protocol that this client chose to use initially. This allows the server to
148 // detect downgrade attacks.
149 void FillInchoateClientHello(const std::string& server_hostname,
150 const QuicVersion preferred_version,
151 const CachedState* cached,
152 QuicCryptoNegotiatedParameters* out_params,
153 CryptoHandshakeMessage* out) const;
155 // FillClientHello sets |out| to be a CHLO message based on the configuration
156 // of this object. This object must have cached enough information about
157 // |server_hostname| in order to perform a handshake. This can be checked
158 // with the |IsComplete| member of |CachedState|.
160 // |clock| and |rand| are used to generate the nonce and |out_params| is
161 // filled with the results of the handshake that the server is expected to
162 // accept. |preferred_version| is the version of the QUIC protocol that this
163 // client chose to use initially. This allows the server to detect downgrade
165 QuicErrorCode FillClientHello(const std::string& server_hostname,
167 const QuicVersion preferred_version,
168 const CachedState* cached,
171 QuicCryptoNegotiatedParameters* out_params,
172 CryptoHandshakeMessage* out,
173 std::string* error_details) const;
175 // ProcessRejection processes a REJ message from a server and updates the
176 // cached information about that server. After this, |IsComplete| may return
177 // true for that server's CachedState. If the rejection message contains
178 // state about a future handshake (i.e. an nonce value from the server), then
179 // it will be saved in |out_params|. |now| is used to judge whether the
180 // server config in the rejection message has expired.
181 QuicErrorCode ProcessRejection(const CryptoHandshakeMessage& rej,
184 QuicCryptoNegotiatedParameters* out_params,
185 std::string* error_details);
187 // ProcessServerHello processes the message in |server_hello|, updates the
188 // cached information about that server, writes the negotiated parameters to
189 // |out_params| and returns QUIC_NO_ERROR. If |server_hello| is unacceptable
190 // then it puts an error message in |error_details| and returns an error
191 // code. |negotiated_versions| contains the list of version, if any, that were
192 // present in a version negotiation packet previously recevied from the
193 // server. The contents of this list will be compared against the list of
194 // versions provided in the VER tag of the server hello.
195 QuicErrorCode ProcessServerHello(const CryptoHandshakeMessage& server_hello,
197 const QuicVersionVector& negotiated_versions,
199 QuicCryptoNegotiatedParameters* out_params,
200 std::string* error_details);
202 ProofVerifier* proof_verifier() const;
204 // SetProofVerifier takes ownership of a |ProofVerifier| that clients are
205 // free to use in order to verify certificate chains from servers. If a
206 // ProofVerifier is set then the client will request a certificate chain from
208 void SetProofVerifier(ProofVerifier* verifier);
210 ChannelIDSigner* channel_id_signer() const;
212 // SetChannelIDSigner sets a ChannelIDSigner that will be called when the
213 // server supports channel IDs to sign a message proving possession of the
214 // given ChannelID. This object takes ownership of |signer|.
215 void SetChannelIDSigner(ChannelIDSigner* signer);
217 // Initialize the CachedState from |canonical_crypto_config| for the
218 // |canonical_server_hostname| as the initial CachedState for
219 // |server_hostname|. We will copy config data only if
220 // |canonical_crypto_config| has valid proof.
221 void InitializeFrom(const std::string& server_hostname,
222 const std::string& canonical_server_hostname,
223 QuicCryptoClientConfig* canonical_crypto_config);
226 // cached_states_ maps from the server hostname to the cached information
227 // about that server.
228 std::map<std::string, CachedState*> cached_states_;
230 scoped_ptr<ProofVerifier> proof_verifier_;
231 scoped_ptr<ChannelIDSigner> channel_id_signer_;
233 DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientConfig);
238 #endif // NET_QUIC_CRYPTO_QUIC_CRYPTO_CLIENT_CONFIG_H_