15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "net/quic/crypto/quic_server_info.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include <limits>
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/pickle.h"
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using std::string;
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace {
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const int kQuicCryptoConfigVersion = 1;
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}  // namespace
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace net {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicServerInfo::State::State() {}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicServerInfo::State::~State() {}
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void QuicServerInfo::State::Clear() {
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  server_config.clear();
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  source_address_token.clear();
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  server_config_sig.clear();
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  certs.clear();
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochQuicServerInfo::QuicServerInfo(const QuicServerId& server_id)
33e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    : server_id_(server_id) {
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicServerInfo::~QuicServerInfo() {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const QuicServerInfo::State& QuicServerInfo::state() const {
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return state_;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicServerInfo::State* QuicServerInfo::mutable_state() {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return &state_;
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicServerInfo::Parse(const string& data) {
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  State* state = mutable_state();
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  state->Clear();
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool r = ParseInner(data);
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!r)
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    state->Clear();
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return r;
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool QuicServerInfo::ParseInner(const string& data) {
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  State* state = mutable_state();
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // No data was read from the disk cache.
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (data.empty()) {
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Pickle p(data.data(), data.size());
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  PickleIterator iter(p);
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int version = -1;
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.ReadInt(&iter, &version)) {
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Missing version";
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (version != kQuicCryptoConfigVersion) {
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Unsupported version";
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.ReadString(&iter, &state->server_config)) {
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Malformed server_config";
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.ReadString(&iter, &state->source_address_token)) {
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Malformed source_address_token";
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.ReadString(&iter, &state->server_config_sig)) {
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Malformed server_config_sig";
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Read certs.
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  uint32 num_certs;
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.ReadUInt32(&iter, &num_certs)) {
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    DVLOG(1) << "Malformed num_certs";
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (uint32 i = 0; i < num_certs; i++) {
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    string cert;
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!p.ReadString(&iter, &cert)) {
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      DVLOG(1) << "Malformed cert";
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return false;
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    state->certs.push_back(cert);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return true;
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)string QuicServerInfo::Serialize() {
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  string pickled_data = SerializeInner();
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  state_.Clear();
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return pickled_data;
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)string QuicServerInfo::SerializeInner() const {
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Pickle p(sizeof(Pickle::Header));
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!p.WriteInt(kQuicCryptoConfigVersion) ||
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !p.WriteString(state_.server_config) ||
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !p.WriteString(state_.source_address_token) ||
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !p.WriteString(state_.server_config_sig) ||
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      state_.certs.size() > std::numeric_limits<uint32>::max() ||
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      !p.WriteUInt32(state_.certs.size())) {
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return string();
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < state_.certs.size(); i++) {
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (!p.WriteString(state_.certs[i])) {
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return string();
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return string(reinterpret_cast<const char *>(p.data()), p.size());
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)QuicServerInfoFactory::~QuicServerInfoFactory() {}
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace net
142