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   // 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