1// Copyright (c) 2012 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_QUIC_CRYPTO_CLIENT_STREAM_H_
6#define NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
7
8#include <string>
9
10#include "net/quic/crypto/channel_id.h"
11#include "net/quic/crypto/proof_verifier.h"
12#include "net/quic/crypto/quic_crypto_client_config.h"
13#include "net/quic/quic_config.h"
14#include "net/quic/quic_crypto_stream.h"
15#include "net/quic/quic_server_id.h"
16
17namespace net {
18
19class QuicClientSessionBase;
20
21namespace test {
22class CryptoTestUtils;
23class QuicClientSessionPeer;
24}  // namespace test
25
26class NET_EXPORT_PRIVATE QuicCryptoClientStream : public QuicCryptoStream {
27 public:
28  QuicCryptoClientStream(const QuicServerId& server_id,
29                         QuicClientSessionBase* session,
30                         ProofVerifyContext* verify_context,
31                         QuicCryptoClientConfig* crypto_config);
32  virtual ~QuicCryptoClientStream();
33
34  // CryptoFramerVisitorInterface implementation
35  virtual void OnHandshakeMessage(
36      const CryptoHandshakeMessage& message) OVERRIDE;
37
38  // Performs a crypto handshake with the server. Returns true if the crypto
39  // handshake is started successfully.
40  // TODO(agl): this should probably return void.
41  virtual bool CryptoConnect();
42
43  // num_sent_client_hellos returns the number of client hello messages that
44  // have been sent. If the handshake has completed then this is one greater
45  // than the number of round-trips needed for the handshake.
46  int num_sent_client_hellos() const;
47
48  // Returns true if a channel ID was sent on this connection.
49  bool WasChannelIDSent() const;
50
51  // Returns true if our ChannelIDSourceCallback was run, which implies the
52  // ChannelIDSource operated asynchronously. Intended for testing.
53  bool WasChannelIDSourceCallbackRun() const;
54
55 private:
56  // ChannelIDSourceCallbackImpl is passed as the callback method to
57  // GetChannelIDKey. The ChannelIDSource calls this class with the result of
58  // channel ID lookup when lookup is performed asynchronously.
59  class ChannelIDSourceCallbackImpl : public ChannelIDSourceCallback {
60   public:
61    explicit ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream);
62    virtual ~ChannelIDSourceCallbackImpl();
63
64    // ChannelIDSourceCallback interface.
65    virtual void Run(scoped_ptr<ChannelIDKey>* channel_id_key) OVERRIDE;
66
67    // Cancel causes any future callbacks to be ignored. It must be called on
68    // the same thread as the callback will be made on.
69    void Cancel();
70
71   private:
72    QuicCryptoClientStream* stream_;
73  };
74
75  // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
76  // The ProofVerifier calls this class with the result of proof verification
77  // when verification is performed asynchronously.
78  class ProofVerifierCallbackImpl : public ProofVerifierCallback {
79   public:
80    explicit ProofVerifierCallbackImpl(QuicCryptoClientStream* stream);
81    virtual ~ProofVerifierCallbackImpl();
82
83    // ProofVerifierCallback interface.
84    virtual void Run(bool ok,
85                     const string& error_details,
86                     scoped_ptr<ProofVerifyDetails>* details) OVERRIDE;
87
88    // Cancel causes any future callbacks to be ignored. It must be called on
89    // the same thread as the callback will be made on.
90    void Cancel();
91
92   private:
93    QuicCryptoClientStream* stream_;
94  };
95
96  friend class test::CryptoTestUtils;
97  friend class test::QuicClientSessionPeer;
98
99  enum State {
100    STATE_IDLE,
101    STATE_INITIALIZE,
102    STATE_SEND_CHLO,
103    STATE_RECV_REJ,
104    STATE_VERIFY_PROOF,
105    STATE_VERIFY_PROOF_COMPLETE,
106    STATE_GET_CHANNEL_ID,
107    STATE_GET_CHANNEL_ID_COMPLETE,
108    STATE_RECV_SHLO,
109    STATE_INITIALIZE_SCUP,
110    STATE_VERIFY_PROOF_DONE,
111  };
112
113  // Handles new server config and optional source-address token provided by the
114  // server during a connection.
115  void HandleServerConfigUpdateMessage(
116      const CryptoHandshakeMessage& server_config_update);
117
118  // DoHandshakeLoop performs a step of the handshake state machine. Note that
119  // |in| may be NULL if the call did not result from a received message.
120  void DoHandshakeLoop(const CryptoHandshakeMessage* in);
121
122  // Start the proof verification if |server_id_| is https and |cached| has
123  // signature.
124  void DoInitializeServerConfigUpdate(
125      QuicCryptoClientConfig::CachedState* cached);
126
127  // Starts the proof verification. Returns the QuicAsyncStatus returned by the
128  // ProofVerifier's VerifyProof.
129  QuicAsyncStatus DoVerifyProof(QuicCryptoClientConfig::CachedState* cached);
130
131  // If proof is valid then it sets the proof as valid (which persists the
132  // server config) and returns QUIC_NO_ERROR. If not, it closes the connection
133  // and returns QUIC_PROOF_INVALID.
134  QuicErrorCode DoVerifyProofComplete(
135      QuicCryptoClientConfig::CachedState* cached);
136
137  // Called to set the proof of |cached| valid.  Also invokes the session's
138  // OnProofValid() method.
139  void SetCachedProofValid(QuicCryptoClientConfig::CachedState* cached);
140
141  // Returns true if the server crypto config in |cached| requires a ChannelID
142  // and the client config settings also allow sending a ChannelID.
143  bool RequiresChannelID(QuicCryptoClientConfig::CachedState* cached);
144
145  QuicClientSessionBase* client_session();
146
147  State next_state_;
148  // num_client_hellos_ contains the number of client hello messages that this
149  // connection has sent.
150  int num_client_hellos_;
151
152  QuicCryptoClientConfig* const crypto_config_;
153
154  // Client's connection nonce (4-byte timestamp + 28 random bytes)
155  std::string nonce_;
156  // Server's (hostname, port, is_https, privacy_mode) tuple.
157  const QuicServerId server_id_;
158
159  // Generation counter from QuicCryptoClientConfig's CachedState.
160  uint64 generation_counter_;
161
162  // True if a channel ID was sent.
163  bool channel_id_sent_;
164
165  // True if channel_id_source_callback_ was run.
166  bool channel_id_source_callback_run_;
167
168  // channel_id_source_callback_ contains the callback object that we passed
169  // to an asynchronous channel ID lookup. The ChannelIDSource owns this
170  // object.
171  ChannelIDSourceCallbackImpl* channel_id_source_callback_;
172
173  // These members are used to store the result of an asynchronous channel ID
174  // lookup. These members must not be used after
175  // STATE_GET_CHANNEL_ID_COMPLETE.
176  scoped_ptr<ChannelIDKey> channel_id_key_;
177
178  // verify_context_ contains the context object that we pass to asynchronous
179  // proof verifications.
180  scoped_ptr<ProofVerifyContext> verify_context_;
181
182  // proof_verify_callback_ contains the callback object that we passed to an
183  // asynchronous proof verification. The ProofVerifier owns this object.
184  ProofVerifierCallbackImpl* proof_verify_callback_;
185
186  // These members are used to store the result of an asynchronous proof
187  // verification. These members must not be used after
188  // STATE_VERIFY_PROOF_COMPLETE.
189  bool verify_ok_;
190  string verify_error_details_;
191  scoped_ptr<ProofVerifyDetails> verify_details_;
192
193  DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream);
194};
195
196}  // namespace net
197
198#endif  // NET_QUIC_QUIC_CRYPTO_CLIENT_STREAM_H_
199