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