// 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 <limits>
#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<uint32>::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<const char *>(p.data()), p.size());
}
QuicServerInfoFactory::~QuicServerInfoFactory() {}
} // namespace net