// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "net/quic/quic_server_info.h" #include #include "base/pickle.h" #include "base/stl_util.h" using std::string; namespace { const int kQuicCryptoConfigVersion = 2; } // namespace namespace net { QuicServerInfo::State::State() {} QuicServerInfo::State::~State() {} void QuicServerInfo::State::Clear() { base::STLClearObject(&server_config); base::STLClearObject(&source_address_token); base::STLClearObject(&cert_sct); base::STLClearObject(&chlo_hash); base::STLClearObject(&server_config_sig); base::STLClearObject(&certs); } QuicServerInfo::QuicServerInfo(const quic::QuicServerId& server_id) : server_id_(server_id) {} QuicServerInfo::~QuicServerInfo() {} const QuicServerInfo::State& QuicServerInfo::state() const { return state_; } QuicServerInfo::State* QuicServerInfo::mutable_state() { return &state_; } bool QuicServerInfo::Parse(const string& data) { State* state = mutable_state(); state->Clear(); bool r = ParseInner(data); if (!r) state->Clear(); return r; } bool QuicServerInfo::ParseInner(const string& data) { State* state = mutable_state(); // No data was read from the disk cache. if (data.empty()) { return false; } base::Pickle p(data.data(), data.size()); base::PickleIterator iter(p); int version = -1; if (!iter.ReadInt(&version)) { DVLOG(1) << "Missing version"; return false; } if (version != kQuicCryptoConfigVersion) { DVLOG(1) << "Unsupported version"; return false; } if (!iter.ReadString(&state->server_config)) { DVLOG(1) << "Malformed server_config"; return false; } if (!iter.ReadString(&state->source_address_token)) { DVLOG(1) << "Malformed source_address_token"; return false; } if (!iter.ReadString(&state->cert_sct)) { DVLOG(1) << "Malformed cert_sct"; return false; } if (!iter.ReadString(&state->chlo_hash)) { DVLOG(1) << "Malformed chlo_hash"; return false; } if (!iter.ReadString(&state->server_config_sig)) { DVLOG(1) << "Malformed server_config_sig"; return false; } // Read certs. uint32_t num_certs; if (!iter.ReadUInt32(&num_certs)) { DVLOG(1) << "Malformed num_certs"; return false; } for (uint32_t i = 0; i < num_certs; i++) { string cert; if (!iter.ReadString(&cert)) { DVLOG(1) << "Malformed cert"; return false; } state->certs.push_back(cert); } return true; } string QuicServerInfo::Serialize() { string pickled_data = SerializeInner(); state_.Clear(); return pickled_data; } string QuicServerInfo::SerializeInner() const { if (state_.certs.size() > std::numeric_limits::max()) return std::string(); base::Pickle p; p.WriteInt(kQuicCryptoConfigVersion); p.WriteString(state_.server_config); p.WriteString(state_.source_address_token); p.WriteString(state_.cert_sct); p.WriteString(state_.chlo_hash); p.WriteString(state_.server_config_sig); p.WriteUInt32(state_.certs.size()); for (size_t i = 0; i < state_.certs.size(); i++) p.WriteString(state_.certs[i]); return string(reinterpret_cast(p.data()), p.size()); } } // namespace net