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