Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: net/tools/ct_mapper/entry_reader.cc

Issue 1238413004: Framework for iterating over certificates in CT database from Chromium code. (not for review) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make samples page work Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/tools/ct_mapper/entry_reader.h ('k') | net/tools/ct_mapper/index.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
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/tools/ct_mapper/entry_reader.h"
6
7 #include <iostream>
8 #include <memory>
9
10 #include "base/files/file_util.h"
11 #include "base/files/memory_mapped_file.h"
12 #include "net/tools/ct_mapper/entry.h"
13
14 namespace net {
15
16 namespace {
17
18 class BytesReader {
19 public:
20 BytesReader() {}
21
22 BytesReader(const uint8_t* data, size_t size) { Assign(data, size); }
23
24 void Assign(const uint8_t* data, size_t size) {
25 data_ = data;
26 size_ = size;
27 }
28
29 bool ReadBytes(size_t count, const uint8_t** out) WARN_UNUSED_RESULT {
30 if (position_ + count > size_)
31 return false; // Not enough data left.
32 *out = (data_ + position_);
33 position_ += count;
34 return true;
35 }
36
37 bool ReadBigEndianUint32(uint32_t* out) WARN_UNUSED_RESULT {
38 const uint8_t* x;
39 if (!ReadBytes(4, &x))
40 return false;
41 *out = x[0] << 24 | x[1] << 16 | x[2] << 8 | x[3];
42 return true;
43 }
44
45 bool ReadBigEndianUint16(uint16_t* out) WARN_UNUSED_RESULT {
46 const uint8_t* x;
47 if (!ReadBytes(2, &x))
48 return false;
49 *out = x[0] << 8 | x[1];
50 return true;
51 }
52
53 bool eof() const { return position_ == size_; }
54
55 size_t position() const { return position_; }
56
57 private:
58 const uint8_t* data_ = nullptr;
59 size_t size_ = 0;
60 size_t position_ = 0;
61 };
62
63 bool ReadCertificateBytes(BytesReader* reader, der::Input* cert) {
64 uint32_t cert_len;
65 if (!reader->ReadBigEndianUint32(&cert_len)) {
66 if (!reader->eof()) {
67 std::cerr << "Failed reading certificate length (4 byte big-endian "
68 "number) at position="
69 << reader->position() << "\n";
70 }
71 return false;
72 }
73
74 const uint8_t* cert_bytes;
75 if (!reader->ReadBytes(cert_len, &cert_bytes)) {
76 std::cerr << "Failed reading reading certificate of length=" << cert_len
77 << " from position=" << reader->position() << "\n";
78 return false;
79 }
80
81 *cert = net::der::Input(cert_bytes, cert_len);
82 return true;
83 }
84
85 std::unique_ptr<base::MemoryMappedFile> LoadFile(const base::FilePath& path) {
86 std::unique_ptr<base::MemoryMappedFile> file(new base::MemoryMappedFile());
87
88 if (!file->Initialize(path) || !file->IsValid()) {
89 std::cerr << "ERROR: Couldn't initialize memory mapped file: "
90 << path.value() << "\n";
91 return nullptr;
92 }
93
94 return file;
95 }
96
97 class CtDumpEntryReader : public EntryReader {
98 public:
99 bool Init(const base::FilePath& entries_path,
100 const base::FilePath& extra_certs_path) {
101 // Read in all of the extra certs.
102 if (!base::ReadFileToString(extra_certs_path, &extra_certs_data_)) {
103 std::cerr << "ERROR: Couldn't read extra certs file: "
104 << extra_certs_path.value() << "\n";
105 return false;
106 }
107
108 BytesReader extra_certs_reader(
109 reinterpret_cast<const uint8_t*>(extra_certs_data_.data()),
110 extra_certs_data_.size());
111
112 der::Input cert;
113 while (ReadCertificateBytes(&extra_certs_reader, &cert)) {
114 extra_certs_.push_back(cert);
115 }
116
117 entries_file_ = LoadFile(entries_path);
118 if (!entries_file_)
119 return false;
120
121 entries_reader_.Assign(entries_file_->data(), entries_file_->length());
122 return true;
123 }
124
125 bool ReadAndAppend(std::vector<Entry>* out) {
126 der::Input cert;
127 if (!ReadCertificateBytes(&entries_reader_, &cert))
128 return false;
129
130 uint16_t num_extra_certs;
131 if (!entries_reader_.ReadBigEndianUint16(&num_extra_certs)) {
132 std::cerr << "Failed reading number of extra certs at position="
133 << entries_reader_.position() << "\n";
134 return false;
135 }
136
137 std::vector<der::Input> extra_certs;
138 extra_certs.reserve(num_extra_certs);
139
140 for (size_t i = 0; i < num_extra_certs; ++i) {
141 uint16_t extra_cert_index;
142 if (!entries_reader_.ReadBigEndianUint16(&extra_cert_index)) {
143 std::cerr << "Failed reading extra_cert at position="
144 << entries_reader_.position() << "\n";
145 return false;
146 }
147
148 if (extra_cert_index >= extra_certs_.size()) {
149 std::cerr << "Invalid extra_cert_index=" << extra_cert_index
150 << " at position=" << entries_reader_.position() << "\n";
151 return false;
152 }
153
154 extra_certs.push_back(extra_certs_[extra_cert_index]);
155 }
156
157 out->emplace_back(cert);
158 std::swap(out->back().extra_certs, extra_certs);
159 return true;
160 }
161
162 bool Read(std::vector<Entry>* entries, size_t max_entries) override {
163 entries->clear();
164
165 while (num_consumed_extra_certs_ < extra_certs_.size() &&
166 entries->size() < max_entries) {
167 entries->emplace_back(Entry::Type::kExtraCert,
168 extra_certs_[num_consumed_extra_certs_++]);
169 }
170
171 while (entries->size() < max_entries && ReadAndAppend(entries))
172 ;
173
174 return !entries->empty();
175 }
176
177 double GetProgress() const override {
178 return static_cast<double>(entries_reader_.position()) /
179 static_cast<double>(entries_file_->length());
180 }
181
182 private:
183 std::unique_ptr<base::MemoryMappedFile> entries_file_;
184 BytesReader entries_reader_;
185
186 std::string extra_certs_data_;
187 std::vector<der::Input> extra_certs_;
188 size_t num_consumed_extra_certs_ = 0;
189 };
190
191 } // namespace
192
193 std::unique_ptr<EntryReader> CreateEntryReaderForCertificateTransparencyDb(
194 const base::FilePath& path) {
195 if (!base::DirectoryExists(path)) {
196 std::cerr
197 << "ERROR: the input must be a directory (containing CT db dump)\n";
198 return nullptr;
199 }
200
201 std::unique_ptr<CtDumpEntryReader> result(new CtDumpEntryReader());
202 if (!result->Init(path.AppendASCII("entries.bin"),
203 path.AppendASCII("extra_certs.bin"))) {
204 return nullptr;
205 }
206
207 return std::move(result);
208 }
209
210 } // namespace net
OLDNEW
« no previous file with comments | « net/tools/ct_mapper/entry_reader.h ('k') | net/tools/ct_mapper/index.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698