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