1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/cert/ct_serialization.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <string_view>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
10*6777b538SAndroid Build Coastguard Worker #include "base/numerics/checked_math.h"
11*6777b538SAndroid Build Coastguard Worker #include "crypto/sha2.h"
12*6777b538SAndroid Build Coastguard Worker #include "net/cert/merkle_tree_leaf.h"
13*6777b538SAndroid Build Coastguard Worker #include "net/cert/signed_certificate_timestamp.h"
14*6777b538SAndroid Build Coastguard Worker #include "net/cert/signed_tree_head.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/bytestring.h"
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker namespace net::ct {
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker namespace {
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker const size_t kLogIdLength = crypto::kSHA256Length;
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker enum SignatureType {
24*6777b538SAndroid Build Coastguard Worker SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP = 0,
25*6777b538SAndroid Build Coastguard Worker TREE_HASH = 1,
26*6777b538SAndroid Build Coastguard Worker };
27*6777b538SAndroid Build Coastguard Worker
28*6777b538SAndroid Build Coastguard Worker // Reads a variable-length SCT list that has been TLS encoded.
29*6777b538SAndroid Build Coastguard Worker // The bytes read from |in| are discarded (i.e. |in|'s prefix removed)
30*6777b538SAndroid Build Coastguard Worker // |max_list_length| contains the overall length of the encoded list.
31*6777b538SAndroid Build Coastguard Worker // |max_item_length| contains the maximum length of a single item.
32*6777b538SAndroid Build Coastguard Worker // On success, returns true and updates |*out| with the encoded list.
ReadSCTList(CBS * in,std::vector<std::string_view> * out)33*6777b538SAndroid Build Coastguard Worker bool ReadSCTList(CBS* in, std::vector<std::string_view>* out) {
34*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> result;
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker CBS sct_list_data;
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker if (!CBS_get_u16_length_prefixed(in, &sct_list_data))
39*6777b538SAndroid Build Coastguard Worker return false;
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker while (CBS_len(&sct_list_data) != 0) {
42*6777b538SAndroid Build Coastguard Worker CBS sct_list_item;
43*6777b538SAndroid Build Coastguard Worker if (!CBS_get_u16_length_prefixed(&sct_list_data, &sct_list_item) ||
44*6777b538SAndroid Build Coastguard Worker CBS_len(&sct_list_item) == 0) {
45*6777b538SAndroid Build Coastguard Worker return false;
46*6777b538SAndroid Build Coastguard Worker }
47*6777b538SAndroid Build Coastguard Worker
48*6777b538SAndroid Build Coastguard Worker result.emplace_back(reinterpret_cast<const char*>(CBS_data(&sct_list_item)),
49*6777b538SAndroid Build Coastguard Worker CBS_len(&sct_list_item));
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker result.swap(*out);
53*6777b538SAndroid Build Coastguard Worker return true;
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker // Checks and converts a hash algorithm.
57*6777b538SAndroid Build Coastguard Worker // |in| is the numeric representation of the algorithm.
58*6777b538SAndroid Build Coastguard Worker // If the hash algorithm value is in a set of known values, fills in |out| and
59*6777b538SAndroid Build Coastguard Worker // returns true. Otherwise, returns false.
ConvertHashAlgorithm(unsigned in,DigitallySigned::HashAlgorithm * out)60*6777b538SAndroid Build Coastguard Worker bool ConvertHashAlgorithm(unsigned in, DigitallySigned::HashAlgorithm* out) {
61*6777b538SAndroid Build Coastguard Worker switch (in) {
62*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_NONE:
63*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_MD5:
64*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_SHA1:
65*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_SHA224:
66*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_SHA256:
67*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_SHA384:
68*6777b538SAndroid Build Coastguard Worker case DigitallySigned::HASH_ALGO_SHA512:
69*6777b538SAndroid Build Coastguard Worker break;
70*6777b538SAndroid Build Coastguard Worker default:
71*6777b538SAndroid Build Coastguard Worker return false;
72*6777b538SAndroid Build Coastguard Worker }
73*6777b538SAndroid Build Coastguard Worker *out = static_cast<DigitallySigned::HashAlgorithm>(in);
74*6777b538SAndroid Build Coastguard Worker return true;
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker
77*6777b538SAndroid Build Coastguard Worker // Checks and converts a signing algorithm.
78*6777b538SAndroid Build Coastguard Worker // |in| is the numeric representation of the algorithm.
79*6777b538SAndroid Build Coastguard Worker // If the signing algorithm value is in a set of known values, fills in |out|
80*6777b538SAndroid Build Coastguard Worker // and returns true. Otherwise, returns false.
ConvertSignatureAlgorithm(unsigned in,DigitallySigned::SignatureAlgorithm * out)81*6777b538SAndroid Build Coastguard Worker bool ConvertSignatureAlgorithm(
82*6777b538SAndroid Build Coastguard Worker unsigned in,
83*6777b538SAndroid Build Coastguard Worker DigitallySigned::SignatureAlgorithm* out) {
84*6777b538SAndroid Build Coastguard Worker switch (in) {
85*6777b538SAndroid Build Coastguard Worker case DigitallySigned::SIG_ALGO_ANONYMOUS:
86*6777b538SAndroid Build Coastguard Worker case DigitallySigned::SIG_ALGO_RSA:
87*6777b538SAndroid Build Coastguard Worker case DigitallySigned::SIG_ALGO_DSA:
88*6777b538SAndroid Build Coastguard Worker case DigitallySigned::SIG_ALGO_ECDSA:
89*6777b538SAndroid Build Coastguard Worker break;
90*6777b538SAndroid Build Coastguard Worker default:
91*6777b538SAndroid Build Coastguard Worker return false;
92*6777b538SAndroid Build Coastguard Worker }
93*6777b538SAndroid Build Coastguard Worker *out = static_cast<DigitallySigned::SignatureAlgorithm>(in);
94*6777b538SAndroid Build Coastguard Worker return true;
95*6777b538SAndroid Build Coastguard Worker }
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker // Writes a SignedEntryData of type X.509 cert to |*output|.
98*6777b538SAndroid Build Coastguard Worker // |input| is the SignedEntryData containing the certificate.
99*6777b538SAndroid Build Coastguard Worker // Returns true if the leaf_certificate in the SignedEntryData does not exceed
100*6777b538SAndroid Build Coastguard Worker // kMaxAsn1CertificateLength and so can be written to |output|.
EncodeAsn1CertSignedEntry(const SignedEntryData & input,CBB * output)101*6777b538SAndroid Build Coastguard Worker bool EncodeAsn1CertSignedEntry(const SignedEntryData& input, CBB* output) {
102*6777b538SAndroid Build Coastguard Worker CBB child;
103*6777b538SAndroid Build Coastguard Worker return CBB_add_u24_length_prefixed(output, &child) &&
104*6777b538SAndroid Build Coastguard Worker CBB_add_bytes(
105*6777b538SAndroid Build Coastguard Worker &child,
106*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input.leaf_certificate.data()),
107*6777b538SAndroid Build Coastguard Worker input.leaf_certificate.size()) &&
108*6777b538SAndroid Build Coastguard Worker CBB_flush(output);
109*6777b538SAndroid Build Coastguard Worker }
110*6777b538SAndroid Build Coastguard Worker
111*6777b538SAndroid Build Coastguard Worker // Writes a SignedEntryData of type PreCertificate to |*output|.
112*6777b538SAndroid Build Coastguard Worker // |input| is the SignedEntryData containing the TBSCertificate and issuer key
113*6777b538SAndroid Build Coastguard Worker // hash. Returns true if the TBSCertificate component in the SignedEntryData
114*6777b538SAndroid Build Coastguard Worker // does not exceed kMaxTbsCertificateLength and so can be written to |output|.
EncodePrecertSignedEntry(const SignedEntryData & input,CBB * output)115*6777b538SAndroid Build Coastguard Worker bool EncodePrecertSignedEntry(const SignedEntryData& input, CBB* output) {
116*6777b538SAndroid Build Coastguard Worker CBB child;
117*6777b538SAndroid Build Coastguard Worker return CBB_add_bytes(
118*6777b538SAndroid Build Coastguard Worker output,
119*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input.issuer_key_hash.data),
120*6777b538SAndroid Build Coastguard Worker kLogIdLength) &&
121*6777b538SAndroid Build Coastguard Worker CBB_add_u24_length_prefixed(output, &child) &&
122*6777b538SAndroid Build Coastguard Worker CBB_add_bytes(
123*6777b538SAndroid Build Coastguard Worker &child,
124*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input.tbs_certificate.data()),
125*6777b538SAndroid Build Coastguard Worker input.tbs_certificate.size()) &&
126*6777b538SAndroid Build Coastguard Worker CBB_flush(output);
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker
129*6777b538SAndroid Build Coastguard Worker } // namespace
130*6777b538SAndroid Build Coastguard Worker
EncodeDigitallySigned(const DigitallySigned & input,CBB * output_cbb)131*6777b538SAndroid Build Coastguard Worker bool EncodeDigitallySigned(const DigitallySigned& input, CBB* output_cbb) {
132*6777b538SAndroid Build Coastguard Worker CBB child;
133*6777b538SAndroid Build Coastguard Worker return CBB_add_u8(output_cbb, input.hash_algorithm) &&
134*6777b538SAndroid Build Coastguard Worker CBB_add_u8(output_cbb, input.signature_algorithm) &&
135*6777b538SAndroid Build Coastguard Worker CBB_add_u16_length_prefixed(output_cbb, &child) &&
136*6777b538SAndroid Build Coastguard Worker CBB_add_bytes(
137*6777b538SAndroid Build Coastguard Worker &child,
138*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input.signature_data.data()),
139*6777b538SAndroid Build Coastguard Worker input.signature_data.size()) &&
140*6777b538SAndroid Build Coastguard Worker CBB_flush(output_cbb);
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker
EncodeDigitallySigned(const DigitallySigned & input,std::string * output)143*6777b538SAndroid Build Coastguard Worker bool EncodeDigitallySigned(const DigitallySigned& input,
144*6777b538SAndroid Build Coastguard Worker std::string* output) {
145*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
146*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
147*6777b538SAndroid Build Coastguard Worker !EncodeDigitallySigned(input, output_cbb.get()) ||
148*6777b538SAndroid Build Coastguard Worker !CBB_flush(output_cbb.get())) {
149*6777b538SAndroid Build Coastguard Worker return false;
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
152*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
153*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
154*6777b538SAndroid Build Coastguard Worker return true;
155*6777b538SAndroid Build Coastguard Worker }
156*6777b538SAndroid Build Coastguard Worker
DecodeDigitallySigned(CBS * input,DigitallySigned * output)157*6777b538SAndroid Build Coastguard Worker bool DecodeDigitallySigned(CBS* input, DigitallySigned* output) {
158*6777b538SAndroid Build Coastguard Worker uint8_t hash_algo;
159*6777b538SAndroid Build Coastguard Worker uint8_t sig_algo;
160*6777b538SAndroid Build Coastguard Worker CBS sig_data;
161*6777b538SAndroid Build Coastguard Worker
162*6777b538SAndroid Build Coastguard Worker if (!CBS_get_u8(input, &hash_algo) || !CBS_get_u8(input, &sig_algo) ||
163*6777b538SAndroid Build Coastguard Worker !CBS_get_u16_length_prefixed(input, &sig_data)) {
164*6777b538SAndroid Build Coastguard Worker return false;
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker
167*6777b538SAndroid Build Coastguard Worker DigitallySigned result;
168*6777b538SAndroid Build Coastguard Worker if (!ConvertHashAlgorithm(hash_algo, &result.hash_algorithm) ||
169*6777b538SAndroid Build Coastguard Worker !ConvertSignatureAlgorithm(sig_algo, &result.signature_algorithm)) {
170*6777b538SAndroid Build Coastguard Worker return false;
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker result.signature_data.assign(
174*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const char*>(CBS_data(&sig_data)), CBS_len(&sig_data));
175*6777b538SAndroid Build Coastguard Worker
176*6777b538SAndroid Build Coastguard Worker *output = result;
177*6777b538SAndroid Build Coastguard Worker return true;
178*6777b538SAndroid Build Coastguard Worker }
179*6777b538SAndroid Build Coastguard Worker
DecodeDigitallySigned(std::string_view * input,DigitallySigned * output)180*6777b538SAndroid Build Coastguard Worker bool DecodeDigitallySigned(std::string_view* input, DigitallySigned* output) {
181*6777b538SAndroid Build Coastguard Worker CBS input_cbs;
182*6777b538SAndroid Build Coastguard Worker CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()),
183*6777b538SAndroid Build Coastguard Worker input->size());
184*6777b538SAndroid Build Coastguard Worker bool result = DecodeDigitallySigned(&input_cbs, output);
185*6777b538SAndroid Build Coastguard Worker input->remove_prefix(input->size() - CBS_len(&input_cbs));
186*6777b538SAndroid Build Coastguard Worker return result;
187*6777b538SAndroid Build Coastguard Worker }
188*6777b538SAndroid Build Coastguard Worker
EncodeSignedEntry(const SignedEntryData & input,CBB * output)189*6777b538SAndroid Build Coastguard Worker static bool EncodeSignedEntry(const SignedEntryData& input, CBB* output) {
190*6777b538SAndroid Build Coastguard Worker if (!CBB_add_u16(output, input.type)) {
191*6777b538SAndroid Build Coastguard Worker return false;
192*6777b538SAndroid Build Coastguard Worker }
193*6777b538SAndroid Build Coastguard Worker switch (input.type) {
194*6777b538SAndroid Build Coastguard Worker case SignedEntryData::LOG_ENTRY_TYPE_X509:
195*6777b538SAndroid Build Coastguard Worker return EncodeAsn1CertSignedEntry(input, output);
196*6777b538SAndroid Build Coastguard Worker case SignedEntryData::LOG_ENTRY_TYPE_PRECERT:
197*6777b538SAndroid Build Coastguard Worker return EncodePrecertSignedEntry(input, output);
198*6777b538SAndroid Build Coastguard Worker }
199*6777b538SAndroid Build Coastguard Worker return false;
200*6777b538SAndroid Build Coastguard Worker }
201*6777b538SAndroid Build Coastguard Worker
EncodeSignedEntry(const SignedEntryData & input,std::string * output)202*6777b538SAndroid Build Coastguard Worker bool EncodeSignedEntry(const SignedEntryData& input, std::string* output) {
203*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
204*6777b538SAndroid Build Coastguard Worker
205*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
206*6777b538SAndroid Build Coastguard Worker !EncodeSignedEntry(input, output_cbb.get()) ||
207*6777b538SAndroid Build Coastguard Worker !CBB_flush(output_cbb.get())) {
208*6777b538SAndroid Build Coastguard Worker return false;
209*6777b538SAndroid Build Coastguard Worker }
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
212*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
213*6777b538SAndroid Build Coastguard Worker return true;
214*6777b538SAndroid Build Coastguard Worker }
215*6777b538SAndroid Build Coastguard Worker
ReadTimeSinceEpoch(CBS * input,base::Time * output)216*6777b538SAndroid Build Coastguard Worker static bool ReadTimeSinceEpoch(CBS* input, base::Time* output) {
217*6777b538SAndroid Build Coastguard Worker uint64_t time_since_epoch = 0;
218*6777b538SAndroid Build Coastguard Worker if (!CBS_get_u64(input, &time_since_epoch))
219*6777b538SAndroid Build Coastguard Worker return false;
220*6777b538SAndroid Build Coastguard Worker
221*6777b538SAndroid Build Coastguard Worker base::CheckedNumeric<int64_t> time_since_epoch_signed = time_since_epoch;
222*6777b538SAndroid Build Coastguard Worker
223*6777b538SAndroid Build Coastguard Worker if (!time_since_epoch_signed.IsValid()) {
224*6777b538SAndroid Build Coastguard Worker return false;
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker
227*6777b538SAndroid Build Coastguard Worker *output = base::Time::UnixEpoch() +
228*6777b538SAndroid Build Coastguard Worker base::Milliseconds(int64_t{time_since_epoch_signed.ValueOrDie()});
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker return true;
231*6777b538SAndroid Build Coastguard Worker }
232*6777b538SAndroid Build Coastguard Worker
WriteTimeSinceEpoch(const base::Time & timestamp,CBB * output)233*6777b538SAndroid Build Coastguard Worker static bool WriteTimeSinceEpoch(const base::Time& timestamp, CBB* output) {
234*6777b538SAndroid Build Coastguard Worker base::TimeDelta time_since_epoch = timestamp - base::Time::UnixEpoch();
235*6777b538SAndroid Build Coastguard Worker return CBB_add_u64(output, time_since_epoch.InMilliseconds());
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker
EncodeTreeLeaf(const MerkleTreeLeaf & leaf,std::string * output)238*6777b538SAndroid Build Coastguard Worker bool EncodeTreeLeaf(const MerkleTreeLeaf& leaf, std::string* output) {
239*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
240*6777b538SAndroid Build Coastguard Worker CBB child;
241*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
242*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), 0) || // version: 1
243*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), 0) || // type: timestamped entry
244*6777b538SAndroid Build Coastguard Worker !WriteTimeSinceEpoch(leaf.timestamp, output_cbb.get()) ||
245*6777b538SAndroid Build Coastguard Worker !EncodeSignedEntry(leaf.signed_entry, output_cbb.get()) ||
246*6777b538SAndroid Build Coastguard Worker !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
247*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(&child,
248*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(leaf.extensions.data()),
249*6777b538SAndroid Build Coastguard Worker leaf.extensions.size()) ||
250*6777b538SAndroid Build Coastguard Worker !CBB_flush(output_cbb.get())) {
251*6777b538SAndroid Build Coastguard Worker return false;
252*6777b538SAndroid Build Coastguard Worker }
253*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
254*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
255*6777b538SAndroid Build Coastguard Worker return true;
256*6777b538SAndroid Build Coastguard Worker }
257*6777b538SAndroid Build Coastguard Worker
EncodeV1SCTSignedData(const base::Time & timestamp,const std::string & serialized_log_entry,const std::string & extensions,std::string * output)258*6777b538SAndroid Build Coastguard Worker bool EncodeV1SCTSignedData(const base::Time& timestamp,
259*6777b538SAndroid Build Coastguard Worker const std::string& serialized_log_entry,
260*6777b538SAndroid Build Coastguard Worker const std::string& extensions,
261*6777b538SAndroid Build Coastguard Worker std::string* output) {
262*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
263*6777b538SAndroid Build Coastguard Worker CBB child;
264*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
265*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), SignedCertificateTimestamp::V1) ||
266*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), SIGNATURE_TYPE_CERTIFICATE_TIMESTAMP) ||
267*6777b538SAndroid Build Coastguard Worker !WriteTimeSinceEpoch(timestamp, output_cbb.get()) ||
268*6777b538SAndroid Build Coastguard Worker // NOTE: serialized_log_entry must already be serialized and contain the
269*6777b538SAndroid Build Coastguard Worker // length as the prefix.
270*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(
271*6777b538SAndroid Build Coastguard Worker output_cbb.get(),
272*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(serialized_log_entry.data()),
273*6777b538SAndroid Build Coastguard Worker serialized_log_entry.size()) ||
274*6777b538SAndroid Build Coastguard Worker !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
275*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(&child,
276*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(extensions.data()),
277*6777b538SAndroid Build Coastguard Worker extensions.size()) ||
278*6777b538SAndroid Build Coastguard Worker !CBB_flush(output_cbb.get())) {
279*6777b538SAndroid Build Coastguard Worker return false;
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
282*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
283*6777b538SAndroid Build Coastguard Worker return true;
284*6777b538SAndroid Build Coastguard Worker }
285*6777b538SAndroid Build Coastguard Worker
EncodeTreeHeadSignature(const SignedTreeHead & signed_tree_head,std::string * output)286*6777b538SAndroid Build Coastguard Worker bool EncodeTreeHeadSignature(const SignedTreeHead& signed_tree_head,
287*6777b538SAndroid Build Coastguard Worker std::string* output) {
288*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
289*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
290*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), signed_tree_head.version) ||
291*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), TREE_HASH) ||
292*6777b538SAndroid Build Coastguard Worker !WriteTimeSinceEpoch(signed_tree_head.timestamp, output_cbb.get()) ||
293*6777b538SAndroid Build Coastguard Worker !CBB_add_u64(output_cbb.get(), signed_tree_head.tree_size) ||
294*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(
295*6777b538SAndroid Build Coastguard Worker output_cbb.get(),
296*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(signed_tree_head.sha256_root_hash),
297*6777b538SAndroid Build Coastguard Worker kSthRootHashLength)) {
298*6777b538SAndroid Build Coastguard Worker return false;
299*6777b538SAndroid Build Coastguard Worker }
300*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
301*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
302*6777b538SAndroid Build Coastguard Worker return true;
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker
DecodeSCTList(std::string_view input,std::vector<std::string_view> * output)305*6777b538SAndroid Build Coastguard Worker bool DecodeSCTList(std::string_view input,
306*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view>* output) {
307*6777b538SAndroid Build Coastguard Worker std::vector<std::string_view> result;
308*6777b538SAndroid Build Coastguard Worker CBS input_cbs;
309*6777b538SAndroid Build Coastguard Worker CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input.data()),
310*6777b538SAndroid Build Coastguard Worker input.size());
311*6777b538SAndroid Build Coastguard Worker if (!ReadSCTList(&input_cbs, &result) || CBS_len(&input_cbs) != 0 ||
312*6777b538SAndroid Build Coastguard Worker result.empty()) {
313*6777b538SAndroid Build Coastguard Worker return false;
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker
316*6777b538SAndroid Build Coastguard Worker output->swap(result);
317*6777b538SAndroid Build Coastguard Worker return true;
318*6777b538SAndroid Build Coastguard Worker }
319*6777b538SAndroid Build Coastguard Worker
DecodeSignedCertificateTimestamp(std::string_view * input,scoped_refptr<SignedCertificateTimestamp> * output)320*6777b538SAndroid Build Coastguard Worker bool DecodeSignedCertificateTimestamp(
321*6777b538SAndroid Build Coastguard Worker std::string_view* input,
322*6777b538SAndroid Build Coastguard Worker scoped_refptr<SignedCertificateTimestamp>* output) {
323*6777b538SAndroid Build Coastguard Worker auto result = base::MakeRefCounted<SignedCertificateTimestamp>();
324*6777b538SAndroid Build Coastguard Worker uint8_t version;
325*6777b538SAndroid Build Coastguard Worker CBS input_cbs;
326*6777b538SAndroid Build Coastguard Worker CBS_init(&input_cbs, reinterpret_cast<const uint8_t*>(input->data()),
327*6777b538SAndroid Build Coastguard Worker input->size());
328*6777b538SAndroid Build Coastguard Worker if (!CBS_get_u8(&input_cbs, &version) ||
329*6777b538SAndroid Build Coastguard Worker version != SignedCertificateTimestamp::V1) {
330*6777b538SAndroid Build Coastguard Worker return false;
331*6777b538SAndroid Build Coastguard Worker }
332*6777b538SAndroid Build Coastguard Worker
333*6777b538SAndroid Build Coastguard Worker result->version = SignedCertificateTimestamp::V1;
334*6777b538SAndroid Build Coastguard Worker CBS log_id;
335*6777b538SAndroid Build Coastguard Worker CBS extensions;
336*6777b538SAndroid Build Coastguard Worker if (!CBS_get_bytes(&input_cbs, &log_id, kLogIdLength) ||
337*6777b538SAndroid Build Coastguard Worker !ReadTimeSinceEpoch(&input_cbs, &result->timestamp) ||
338*6777b538SAndroid Build Coastguard Worker !CBS_get_u16_length_prefixed(&input_cbs, &extensions) ||
339*6777b538SAndroid Build Coastguard Worker !DecodeDigitallySigned(&input_cbs, &result->signature)) {
340*6777b538SAndroid Build Coastguard Worker return false;
341*6777b538SAndroid Build Coastguard Worker }
342*6777b538SAndroid Build Coastguard Worker
343*6777b538SAndroid Build Coastguard Worker result->log_id.assign(reinterpret_cast<const char*>(CBS_data(&log_id)),
344*6777b538SAndroid Build Coastguard Worker CBS_len(&log_id));
345*6777b538SAndroid Build Coastguard Worker result->extensions.assign(
346*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const char*>(CBS_data(&extensions)),
347*6777b538SAndroid Build Coastguard Worker CBS_len(&extensions));
348*6777b538SAndroid Build Coastguard Worker output->swap(result);
349*6777b538SAndroid Build Coastguard Worker input->remove_prefix(input->size() - CBS_len(&input_cbs));
350*6777b538SAndroid Build Coastguard Worker return true;
351*6777b538SAndroid Build Coastguard Worker }
352*6777b538SAndroid Build Coastguard Worker
EncodeSignedCertificateTimestamp(const scoped_refptr<ct::SignedCertificateTimestamp> & input,std::string * output)353*6777b538SAndroid Build Coastguard Worker bool EncodeSignedCertificateTimestamp(
354*6777b538SAndroid Build Coastguard Worker const scoped_refptr<ct::SignedCertificateTimestamp>& input,
355*6777b538SAndroid Build Coastguard Worker std::string* output) {
356*6777b538SAndroid Build Coastguard Worker // This function only supports serialization of V1 SCTs.
357*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(SignedCertificateTimestamp::V1, input->version);
358*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(kLogIdLength, input->log_id.size());
359*6777b538SAndroid Build Coastguard Worker
360*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
361*6777b538SAndroid Build Coastguard Worker CBB child;
362*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
363*6777b538SAndroid Build Coastguard Worker !CBB_add_u8(output_cbb.get(), input->version) ||
364*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(output_cbb.get(),
365*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input->log_id.data()),
366*6777b538SAndroid Build Coastguard Worker kLogIdLength) ||
367*6777b538SAndroid Build Coastguard Worker !WriteTimeSinceEpoch(input->timestamp, output_cbb.get()) ||
368*6777b538SAndroid Build Coastguard Worker !CBB_add_u16_length_prefixed(output_cbb.get(), &child) ||
369*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(&child,
370*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(input->extensions.data()),
371*6777b538SAndroid Build Coastguard Worker input->extensions.size()) ||
372*6777b538SAndroid Build Coastguard Worker !EncodeDigitallySigned(input->signature, output_cbb.get()) ||
373*6777b538SAndroid Build Coastguard Worker !CBB_flush(output_cbb.get())) {
374*6777b538SAndroid Build Coastguard Worker return false;
375*6777b538SAndroid Build Coastguard Worker }
376*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
377*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
378*6777b538SAndroid Build Coastguard Worker return true;
379*6777b538SAndroid Build Coastguard Worker }
380*6777b538SAndroid Build Coastguard Worker
EncodeSCTListForTesting(const std::vector<std::string> & scts,std::string * output)381*6777b538SAndroid Build Coastguard Worker bool EncodeSCTListForTesting(const std::vector<std::string>& scts,
382*6777b538SAndroid Build Coastguard Worker std::string* output) {
383*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB output_cbb;
384*6777b538SAndroid Build Coastguard Worker CBB output_child;
385*6777b538SAndroid Build Coastguard Worker if (!CBB_init(output_cbb.get(), 64) ||
386*6777b538SAndroid Build Coastguard Worker !CBB_add_u16_length_prefixed(output_cbb.get(), &output_child)) {
387*6777b538SAndroid Build Coastguard Worker return false;
388*6777b538SAndroid Build Coastguard Worker }
389*6777b538SAndroid Build Coastguard Worker
390*6777b538SAndroid Build Coastguard Worker for (const std::string& sct : scts) {
391*6777b538SAndroid Build Coastguard Worker bssl::ScopedCBB encoded_sct;
392*6777b538SAndroid Build Coastguard Worker CBB encoded_sct_child;
393*6777b538SAndroid Build Coastguard Worker if (!CBB_init(encoded_sct.get(), 64) ||
394*6777b538SAndroid Build Coastguard Worker !CBB_add_u16_length_prefixed(encoded_sct.get(), &encoded_sct_child) ||
395*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(&encoded_sct_child,
396*6777b538SAndroid Build Coastguard Worker reinterpret_cast<const uint8_t*>(sct.data()),
397*6777b538SAndroid Build Coastguard Worker sct.size()) ||
398*6777b538SAndroid Build Coastguard Worker !CBB_flush(encoded_sct.get()) ||
399*6777b538SAndroid Build Coastguard Worker !CBB_add_bytes(&output_child, CBB_data(encoded_sct.get()),
400*6777b538SAndroid Build Coastguard Worker CBB_len(encoded_sct.get()))) {
401*6777b538SAndroid Build Coastguard Worker return false;
402*6777b538SAndroid Build Coastguard Worker }
403*6777b538SAndroid Build Coastguard Worker }
404*6777b538SAndroid Build Coastguard Worker
405*6777b538SAndroid Build Coastguard Worker if (!CBB_flush(output_cbb.get())) {
406*6777b538SAndroid Build Coastguard Worker return false;
407*6777b538SAndroid Build Coastguard Worker }
408*6777b538SAndroid Build Coastguard Worker output->append(reinterpret_cast<const char*>(CBB_data(output_cbb.get())),
409*6777b538SAndroid Build Coastguard Worker CBB_len(output_cbb.get()));
410*6777b538SAndroid Build Coastguard Worker return true;
411*6777b538SAndroid Build Coastguard Worker }
412*6777b538SAndroid Build Coastguard Worker
413*6777b538SAndroid Build Coastguard Worker } // namespace net::ct
414