Home | History | Annotate | Download | only in crypto
      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|.
     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|.
     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.
     70   QuicTag tag() const { return tag_; }
     71   // Sets the message tag.
     72   void set_tag(QuicTag tag) { tag_ = tag; }
     73 
     74   const QuicTagValueMap& tag_value_map() const { return tag_value_map_; }
     75 
     76   void Insert(QuicTagValueMap::const_iterator begin,
     77               QuicTagValueMap::const_iterator end);
     78 
     79   // SetTaglist sets an element with the given tag to contain a list of tags,
     80   // passed as varargs. The argument list must be terminated with a 0 element.
     81   void SetTaglist(QuicTag tag, ...);
     82 
     83   void SetStringPiece(QuicTag tag, base::StringPiece value);
     84 
     85   // Erase removes a tag/value, if present, from the message.
     86   void Erase(QuicTag tag);
     87 
     88   // GetTaglist finds an element with the given tag containing zero or more
     89   // tags. If such a tag doesn't exist, it returns false. Otherwise it sets
     90   // |out_tags| and |out_len| to point to the array of tags and returns true.
     91   // The array points into the CryptoHandshakeMessage and is valid only for as
     92   // long as the CryptoHandshakeMessage exists and is not modified.
     93   QuicErrorCode GetTaglist(QuicTag tag, const QuicTag** out_tags,
     94                            size_t* out_len) const;
     95 
     96   bool GetStringPiece(QuicTag tag, base::StringPiece* out) const;
     97 
     98   // GetNthValue24 interprets the value with the given tag to be a series of
     99   // 24-bit, length prefixed values and it returns the subvalue with the given
    100   // index.
    101   QuicErrorCode GetNthValue24(QuicTag tag,
    102                               unsigned index,
    103                               base::StringPiece* out) const;
    104   QuicErrorCode GetUint16(QuicTag tag, uint16* out) const;
    105   QuicErrorCode GetUint32(QuicTag tag, uint32* out) const;
    106   QuicErrorCode GetUint64(QuicTag tag, uint64* out) const;
    107 
    108   // size returns 4 (message tag) + 2 (uint16, number of entries) +
    109   // (4 (tag) + 4 (end offset))*tag_value_map_.size() +  value sizes.
    110   size_t size() const;
    111 
    112   // set_minimum_size sets the minimum number of bytes that the message should
    113   // consume. The CryptoFramer will add a PAD tag as needed when serializing in
    114   // order to ensure this. Setting a value of 0 disables padding.
    115   //
    116   // Padding is useful in order to ensure that messages are a minimum size. A
    117   // QUIC server can require a minimum size in order to reduce the
    118   // amplification factor of any mirror DoS attack.
    119   void set_minimum_size(size_t min_bytes);
    120 
    121   size_t minimum_size() const;
    122 
    123   // DebugString returns a multi-line, string representation of the message
    124   // suitable for including in debug output.
    125   std::string DebugString() const;
    126 
    127  private:
    128   // GetPOD is a utility function for extracting a plain-old-data value. If
    129   // |tag| exists in the message, and has a value of exactly |len| bytes then
    130   // it copies |len| bytes of data into |out|. Otherwise |len| bytes at |out|
    131   // are zeroed out.
    132   //
    133   // If used to copy integers then this assumes that the machine is
    134   // little-endian.
    135   QuicErrorCode GetPOD(QuicTag tag, void* out, size_t len) const;
    136 
    137   std::string DebugStringInternal(size_t indent) const;
    138 
    139   QuicTag tag_;
    140   QuicTagValueMap tag_value_map_;
    141 
    142   size_t minimum_size_;
    143 
    144   // The serialized form of the handshake message. This member is constructed
    145   // lasily.
    146   mutable scoped_ptr<QuicData> serialized_;
    147 };
    148 
    149 // A CrypterPair contains the encrypter and decrypter for an encryption level.
    150 struct NET_EXPORT_PRIVATE CrypterPair {
    151   CrypterPair();
    152   ~CrypterPair();
    153   scoped_ptr<QuicEncrypter> encrypter;
    154   scoped_ptr<QuicDecrypter> decrypter;
    155 };
    156 
    157 // Parameters negotiated by the crypto handshake.
    158 struct NET_EXPORT_PRIVATE QuicCryptoNegotiatedParameters {
    159   // Initializes the members to 0 or empty values.
    160   QuicCryptoNegotiatedParameters();
    161   ~QuicCryptoNegotiatedParameters();
    162 
    163   uint16 version;
    164   QuicTag key_exchange;
    165   QuicTag aead;
    166   std::string initial_premaster_secret;
    167   std::string forward_secure_premaster_secret;
    168   CrypterPair initial_crypters;
    169   CrypterPair forward_secure_crypters;
    170   // Normalized SNI: converted to lower case and trailing '.' removed.
    171   std::string sni;
    172   std::string client_nonce;
    173   std::string server_nonce;
    174   // hkdf_input_suffix contains the HKDF input following the label: the GUID,
    175   // client hello and server config. This is only populated in the client
    176   // because only the client needs to derive the forward secure keys at a later
    177   // time from the initial keys.
    178   std::string hkdf_input_suffix;
    179   // cached_certs contains the cached certificates that a client used when
    180   // sending a client hello.
    181   std::vector<std::string> cached_certs;
    182   // client_key_exchange is used by clients to store the ephemeral KeyExchange
    183   // for the connection.
    184   scoped_ptr<KeyExchange> client_key_exchange;
    185   // channel_id is set by servers to a ChannelID key when the client correctly
    186   // proves possession of the corresponding private key. It consists of 32
    187   // bytes of x coordinate, followed by 32 bytes of y coordinate. Both values
    188   // are big-endian and the pair is a P-256 public key.
    189   std::string channel_id;
    190 };
    191 
    192 // QuicCryptoConfig contains common configuration between clients and servers.
    193 class NET_EXPORT_PRIVATE QuicCryptoConfig {
    194  public:
    195   enum {
    196     // CONFIG_VERSION is the one (and, for the moment, only) version number that
    197     // we implement.
    198     CONFIG_VERSION = 0,
    199   };
    200 
    201   // kInitialLabel is a constant that is used when deriving the initial
    202   // (non-forward secure) keys for the connection in order to tie the resulting
    203   // key to this protocol.
    204   static const char kInitialLabel[];
    205 
    206   // kCETVLabel is a constant that is used when deriving the keys for the
    207   // encrypted tag/value block in the client hello.
    208   static const char kCETVLabel[];
    209 
    210   // kForwardSecureLabel is a constant that is used when deriving the forward
    211   // secure keys for the connection in order to tie the resulting key to this
    212   // protocol.
    213   static const char kForwardSecureLabel[];
    214 
    215   QuicCryptoConfig();
    216   ~QuicCryptoConfig();
    217 
    218   // Protocol version
    219   uint16 version;
    220   // Key exchange methods. The following two members' values correspond by
    221   // index.
    222   QuicTagVector kexs;
    223   // Authenticated encryption with associated data (AEAD) algorithms.
    224   QuicTagVector aead;
    225 
    226   const CommonCertSets* common_cert_sets;
    227 
    228  private:
    229   DISALLOW_COPY_AND_ASSIGN(QuicCryptoConfig);
    230 };
    231 
    232 // QuicCryptoClientConfig contains crypto-related configuration settings for a
    233 // client. Note that this object isn't thread-safe. It's designed to be used on
    234 // a single thread at a time.
    235 class NET_EXPORT_PRIVATE QuicCryptoClientConfig : public QuicCryptoConfig {
    236  public:
    237   // A CachedState contains the information that the client needs in order to
    238   // perform a 0-RTT handshake with a server. This information can be reused
    239   // over several connections to the same server.
    240   class CachedState {
    241    public:
    242     CachedState();
    243     ~CachedState();
    244 
    245     // IsComplete returns true if this object contains enough information to
    246     // perform a handshake with the server. |now| is used to judge whether any
    247     // cached server config has expired.
    248     bool IsComplete(QuicWallTime now) const;
    249 
    250     // GetServerConfig returns the parsed contents of |server_config|, or NULL
    251     // if |server_config| is empty. The return value is owned by this object
    252     // and is destroyed when this object is.
    253     const CryptoHandshakeMessage* GetServerConfig() const;
    254 
    255     // SetServerConfig checks that |server_config| parses correctly and stores
    256     // it in |server_config_|. |now| is used to judge whether |server_config|
    257     // has expired.
    258     QuicErrorCode SetServerConfig(base::StringPiece server_config,
    259                                   QuicWallTime now,
    260                                   std::string* error_details);
    261 
    262     // InvalidateServerConfig clears the cached server config (if any).
    263     void InvalidateServerConfig();
    264 
    265     // SetProof stores a certificate chain and signature.
    266     void SetProof(const std::vector<std::string>& certs,
    267                   base::StringPiece signature);
    268 
    269     // SetProofValid records that the certificate chain and signature have been
    270     // validated and that it's safe to assume that the server is legitimate.
    271     // (Note: this does not check the chain or signature.)
    272     void SetProofValid();
    273 
    274     // If the server config or the proof has changed then it needs to be
    275     // revalidated. Helper function to keep server_config_valid_ and
    276     // generation_counter_ in sync.
    277     void SetProofInvalid();
    278 
    279     const std::string& server_config() const;
    280     const std::string& source_address_token() const;
    281     const std::vector<std::string>& certs() const;
    282     const std::string& signature() const;
    283     bool proof_valid() const;
    284     uint64 generation_counter() const;
    285     const ProofVerifyDetails* proof_verify_details() const;
    286 
    287     void set_source_address_token(base::StringPiece token);
    288 
    289     // SetProofVerifyDetails takes ownership of |details|.
    290     void SetProofVerifyDetails(ProofVerifyDetails* details);
    291 
    292    private:
    293     std::string server_config_id_;      // An opaque id from the server.
    294     std::string server_config_;         // A serialized handshake message.
    295     std::string source_address_token_;  // An opaque proof of IP ownership.
    296     std::vector<std::string> certs_;    // A list of certificates in leaf-first
    297                                         // order.
    298     std::string server_config_sig_;     // A signature of |server_config_|.
    299     bool server_config_valid_;          // True if |server_config_| is correctly
    300                                         // signed and |certs_| has been
    301                                         // validated.
    302     // Generation counter associated with the |server_config_|, |certs_| and
    303     // |server_config_sig_| combination. It is incremented whenever we set
    304     // server_config_valid_ to false.
    305     uint64 generation_counter_;
    306 
    307     scoped_ptr<ProofVerifyDetails> proof_verify_details_;
    308 
    309     // scfg contains the cached, parsed value of |server_config|.
    310     mutable scoped_ptr<CryptoHandshakeMessage> scfg_;
    311   };
    312 
    313   QuicCryptoClientConfig();
    314   ~QuicCryptoClientConfig();
    315 
    316   // Sets the members to reasonable, default values.
    317   void SetDefaults();
    318 
    319   // LookupOrCreate returns a CachedState for the given hostname. If no such
    320   // CachedState currently exists, it will be created and cached.
    321   CachedState* LookupOrCreate(const std::string& server_hostname);
    322 
    323   // FillInchoateClientHello sets |out| to be a CHLO message that elicits a
    324   // source-address token or SCFG from a server. If |cached| is non-NULL, the
    325   // source-address token will be taken from it. |out_params| is used in order
    326   // to store the cached certs that were sent as hints to the server in
    327   // |out_params->cached_certs|.
    328   void FillInchoateClientHello(const std::string& server_hostname,
    329                                const CachedState* cached,
    330                                QuicCryptoNegotiatedParameters* out_params,
    331                                CryptoHandshakeMessage* out) const;
    332 
    333   // FillClientHello sets |out| to be a CHLO message based on the configuration
    334   // of this object. This object must have cached enough information about
    335   // |server_hostname| in order to perform a handshake. This can be checked
    336   // with the |IsComplete| member of |CachedState|.
    337   //
    338   // |clock| and |rand| are used to generate the nonce and |out_params| is
    339   // filled with the results of the handshake that the server is expected to
    340   // accept.
    341   QuicErrorCode FillClientHello(const std::string& server_hostname,
    342                                 QuicGuid guid,
    343                                 const CachedState* cached,
    344                                 QuicWallTime now,
    345                                 QuicRandom* rand,
    346                                 QuicCryptoNegotiatedParameters* out_params,
    347                                 CryptoHandshakeMessage* out,
    348                                 std::string* error_details) const;
    349 
    350   // ProcessRejection processes a REJ message from a server and updates the
    351   // cached information about that server. After this, |IsComplete| may return
    352   // true for that server's CachedState. If the rejection message contains
    353   // state about a future handshake (i.e. an nonce value from the server), then
    354   // it will be saved in |out_params|. |now| is used to judge whether the
    355   // server config in the rejection message has expired.
    356   QuicErrorCode ProcessRejection(CachedState* cached,
    357                                  const CryptoHandshakeMessage& rej,
    358                                  QuicWallTime now,
    359                                  QuicCryptoNegotiatedParameters* out_params,
    360                                  std::string* error_details);
    361 
    362   // ProcessServerHello processes the message in |server_hello|, writes the
    363   // negotiated parameters to |out_params| and returns QUIC_NO_ERROR. If
    364   // |server_hello| is unacceptable then it puts an error message in
    365   // |error_details| and returns an error code.
    366   QuicErrorCode ProcessServerHello(const CryptoHandshakeMessage& server_hello,
    367                                    QuicGuid guid,
    368                                    QuicCryptoNegotiatedParameters* out_params,
    369                                    std::string* error_details);
    370 
    371   ProofVerifier* proof_verifier() const;
    372 
    373   // SetProofVerifier takes ownership of a |ProofVerifier| that clients are
    374   // free to use in order to verify certificate chains from servers. If a
    375   // ProofVerifier is set then the client will request a certificate chain from
    376   // the server.
    377   void SetProofVerifier(ProofVerifier* verifier);
    378 
    379   ChannelIDSigner* channel_id_signer() const;
    380 
    381   // SetChannelIDSigner sets a ChannelIDSigner that will be called when the
    382   // server supports channel IDs to sign a message proving possession of the
    383   // given ChannelID. This object takes ownership of |signer|.
    384   void SetChannelIDSigner(ChannelIDSigner* signer);
    385 
    386  private:
    387   // cached_states_ maps from the server hostname to the cached information
    388   // about that server.
    389   std::map<std::string, CachedState*> cached_states_;
    390 
    391   scoped_ptr<ProofVerifier> proof_verifier_;
    392   scoped_ptr<ChannelIDSigner> channel_id_signer_;
    393 
    394   DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientConfig);
    395 };
    396 
    397 }  // namespace net
    398 
    399 #endif  // NET_QUIC_CRYPTO_CRYPTO_HANDSHAKE_H_
    400