// 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/crypto/quic_server_info.h" #include #include "base/pickle.h" using std::string; namespace { const int kQuicCryptoConfigVersion = 1; } // namespace namespace net { QuicServerInfo::State::State() {} QuicServerInfo::State::~State() {} void QuicServerInfo::State::Clear() { server_config.clear(); source_address_token.clear(); server_config_sig.clear(); certs.clear(); } QuicServerInfo::QuicServerInfo(const 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; } Pickle p(data.data(), data.size()); PickleIterator iter(p); int version = -1; if (!p.ReadInt(&iter, &version)) { DVLOG(1) << "Missing version"; return false; } if (version != kQuicCryptoConfigVersion) { DVLOG(1) << "Unsupported version"; return false; } if (!p.ReadString(&iter, &state->server_config)) { DVLOG(1) << "Malformed server_config"; return false; } if (!p.ReadString(&iter, &state->source_address_token)) { DVLOG(1) << "Malformed source_address_token"; return false; } if (!p.ReadString(&iter, &state->server_config_sig)) { DVLOG(1) << "Malformed server_config_sig"; return false; } // Read certs. uint32 num_certs; if (!p.ReadUInt32(&iter, &num_certs)) { DVLOG(1) << "Malformed num_certs"; return false; } for (uint32 i = 0; i < num_certs; i++) { string cert; if (!p.ReadString(&iter, &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 { Pickle p(sizeof(Pickle::Header)); if (!p.WriteInt(kQuicCryptoConfigVersion) || !p.WriteString(state_.server_config) || !p.WriteString(state_.source_address_token) || !p.WriteString(state_.server_config_sig) || state_.certs.size() > std::numeric_limits::max() || !p.WriteUInt32(state_.certs.size())) { return string(); } for (size_t i = 0; i < state_.certs.size(); i++) { if (!p.WriteString(state_.certs[i])) { return string(); } } return string(reinterpret_cast(p.data()), p.size()); } QuicServerInfoFactory::~QuicServerInfoFactory() {} } // namespace net