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