1 // Copyright 2014 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/quic_server_info.h" 6 7 #include <limits> 8 9 #include "base/logging.h" 10 #include "base/pickle.h" 11 #include "base/stl_util.h" 12 13 using std::string; 14 15 namespace { 16 17 const int kQuicCryptoConfigVersion = 2; 18 19 } // namespace 20 21 namespace net { 22 23 QuicServerInfo::State::State() = default; 24 25 QuicServerInfo::State::~State() = default; 26 Clear()27void QuicServerInfo::State::Clear() { 28 base::STLClearObject(&server_config); 29 base::STLClearObject(&source_address_token); 30 base::STLClearObject(&cert_sct); 31 base::STLClearObject(&chlo_hash); 32 base::STLClearObject(&server_config_sig); 33 base::STLClearObject(&certs); 34 } 35 QuicServerInfo(const quic::QuicServerId & server_id)36QuicServerInfo::QuicServerInfo(const quic::QuicServerId& server_id) 37 : server_id_(server_id) {} 38 39 QuicServerInfo::~QuicServerInfo() = default; 40 state() const41const QuicServerInfo::State& QuicServerInfo::state() const { 42 return state_; 43 } 44 mutable_state()45QuicServerInfo::State* QuicServerInfo::mutable_state() { 46 return &state_; 47 } 48 Parse(const string & data)49bool QuicServerInfo::Parse(const string& data) { 50 State* state = mutable_state(); 51 52 state->Clear(); 53 54 bool r = ParseInner(data); 55 if (!r) 56 state->Clear(); 57 return r; 58 } 59 ParseInner(const string & data)60bool QuicServerInfo::ParseInner(const string& data) { 61 State* state = mutable_state(); 62 63 // No data was read from the disk cache. 64 if (data.empty()) { 65 return false; 66 } 67 68 base::Pickle p(data.data(), data.size()); 69 base::PickleIterator iter(p); 70 71 int version = -1; 72 if (!iter.ReadInt(&version)) { 73 DVLOG(1) << "Missing version"; 74 return false; 75 } 76 77 if (version != kQuicCryptoConfigVersion) { 78 DVLOG(1) << "Unsupported version"; 79 return false; 80 } 81 82 if (!iter.ReadString(&state->server_config)) { 83 DVLOG(1) << "Malformed server_config"; 84 return false; 85 } 86 if (!iter.ReadString(&state->source_address_token)) { 87 DVLOG(1) << "Malformed source_address_token"; 88 return false; 89 } 90 if (!iter.ReadString(&state->cert_sct)) { 91 DVLOG(1) << "Malformed cert_sct"; 92 return false; 93 } 94 if (!iter.ReadString(&state->chlo_hash)) { 95 DVLOG(1) << "Malformed chlo_hash"; 96 return false; 97 } 98 if (!iter.ReadString(&state->server_config_sig)) { 99 DVLOG(1) << "Malformed server_config_sig"; 100 return false; 101 } 102 103 // Read certs. 104 uint32_t num_certs; 105 if (!iter.ReadUInt32(&num_certs)) { 106 DVLOG(1) << "Malformed num_certs"; 107 return false; 108 } 109 110 for (uint32_t i = 0; i < num_certs; i++) { 111 string cert; 112 if (!iter.ReadString(&cert)) { 113 DVLOG(1) << "Malformed cert"; 114 return false; 115 } 116 state->certs.push_back(cert); 117 } 118 119 return true; 120 } 121 Serialize()122string QuicServerInfo::Serialize() { 123 string pickled_data = SerializeInner(); 124 state_.Clear(); 125 return pickled_data; 126 } 127 SerializeInner() const128string QuicServerInfo::SerializeInner() const { 129 if (state_.certs.size() > std::numeric_limits<uint32_t>::max()) 130 return std::string(); 131 132 base::Pickle p; 133 p.WriteInt(kQuicCryptoConfigVersion); 134 p.WriteString(state_.server_config); 135 p.WriteString(state_.source_address_token); 136 p.WriteString(state_.cert_sct); 137 p.WriteString(state_.chlo_hash); 138 p.WriteString(state_.server_config_sig); 139 p.WriteUInt32(state_.certs.size()); 140 141 for (const auto& cert : state_.certs) 142 p.WriteString(cert); 143 144 return string(reinterpret_cast<const char*>(p.data()), p.size()); 145 } 146 147 } // namespace net 148