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

Side by Side Diff: chrome/browser/net/packed_ct_ev_whitelist.cc

Issue 547603002: Certificate Transparency: Code for unpacking EV cert hashes whitelist (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Avoiding globals in favour of passing the SSLConfigService around Created 6 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2014 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 "chrome/browser/net/packed_ct_ev_whitelist.h"
6
7 #include <set>
8
9 #include "base/big_endian.h"
10 #include "base/bind.h"
11 #include "base/file_util.h"
12 #include "base/lazy_instance.h"
13 #include "base/logging.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "net/ssl/ssl_config_service.h"
16
17 namespace {
18 const uint8_t kCertHashLengthBits = 64; // 8 bytes
19 const uint64_t kGolombMParameterBits = 47; // 2^47
20 } // namespace
21
22 namespace internal {
23
24 BitStreamReader::BitStreamReader(const base::StringPiece& source)
25 : source_(source), current_byte_(0), current_bit_(7) {
26 }
27
28 bool BitStreamReader::ReadUnaryEncoding(uint64_t* out) {
29 uint64_t res = 0;
30 if (BitsLeft() == 0)
31 return false;
32
33 while ((BitsLeft() > 0) && ReadBit())
34 res++;
35
36 *out = res;
37 return true;
38 }
39
40 bool BitStreamReader::ReadBits(uint8_t num_bits, uint64_t* out) {
41 if (num_bits > 64)
42 return false;
43
44 if (BitsLeft() < num_bits)
45 return false;
46
47 uint64_t res = 0;
48 for (uint8_t i = 0; i < num_bits; ++i)
49 res |= (static_cast<uint64_t>(ReadBit()) << (num_bits - (i + 1)));
50
51 *out = res;
52 return true;
53 }
54
55 uint64_t BitStreamReader::BitsLeft() const {
56 if (current_byte_ == source_.length())
57 return 0;
58 return (source_.length() - (current_byte_ + 1)) * 8 + current_bit_ + 1;
59 }
60
61 uint8_t BitStreamReader::ReadBit() {
62 DCHECK_GT(BitsLeft(), 0u);
63 DCHECK(current_bit_ < 8 && current_bit_ >= 0);
64 uint8_t res =
65 (source_.data()[current_byte_] & (1 << current_bit_)) >> current_bit_;
66 current_bit_--;
67 if (current_bit_ < 0) {
68 current_byte_++;
69 current_bit_ = 7;
70 }
71
72 return res;
73 }
74
75 void SetNewEVWhitelistInSSLConfigService(
76 scoped_refptr<net::ct::EVCertsWhitelist> new_whitelist,
77 scoped_refptr<net::SSLConfigService> ssl_config_service) {
78 if (ssl_config_service.get() != NULL) {
79 ssl_config_service->SetEVCertsWhitelist(new_whitelist);
80 }
81 }
82
83 } // namespace internal
84
85 void SetEVWhitelistFromFile(
86 const base::FilePath& compressed_whitelist_file,
87 scoped_refptr<net::SSLConfigService> ssl_config_service) {
88 VLOG(1) << "Setting EV whitelist from file: "
89 << compressed_whitelist_file.value();
90 std::string compressed_list;
91 if (!base::ReadFileToString(compressed_whitelist_file, &compressed_list)) {
92 VLOG(1) << "Failed reading from " << compressed_whitelist_file.value();
93 return;
94 }
95
96 scoped_refptr<net::ct::EVCertsWhitelist> new_whitelist(
97 new PackedEVCertsWhitelist(compressed_list));
98 if (!new_whitelist->IsValid()) {
99 VLOG(1) << "Failed uncompressing EV certs whitelist.";
100 return;
101 }
102
103 base::Callback<void(void)> assign_cb =
104 base::Bind(&internal::SetNewEVWhitelistInSSLConfigService,
105 new_whitelist,
106 ssl_config_service);
107 content::BrowserThread::PostTask(
108 content::BrowserThread::IO, FROM_HERE, assign_cb);
109 }
110
111 bool PackedEVCertsWhitelist::UncompressEVWhitelist(
112 const std::string& compressed_whitelist,
113 std::set<std::string>* uncompressed_list) {
114 internal::BitStreamReader reader(base::StringPiece(
115 compressed_whitelist.data(), compressed_whitelist.size()));
116 std::set<std::string> result;
117
118 VLOG(1) << "Uncompressing EV whitelist of size "
119 << compressed_whitelist.size();
120 uint64_t curr_hash(0);
121 if (!reader.ReadBits(kCertHashLengthBits, &curr_hash)) {
122 VLOG(1) << "Failed reading first hash.";
123 return false;
124 }
125 char hash_bytes[8];
126 base::WriteBigEndian(hash_bytes, curr_hash);
127 result.insert(std::string(hash_bytes, 8));
128 static const uint64_t M = static_cast<uint64_t>(1) << kGolombMParameterBits;
129
130 while (reader.BitsLeft() > kGolombMParameterBits) {
131 uint64_t read_prefix = 0;
132 if (!reader.ReadUnaryEncoding(&read_prefix)) {
133 VLOG(1) << "Failed reading unary-encoded prefix.";
134 return false;
135 }
136
137 uint64_t r = 0;
138 if (!reader.ReadBits(kGolombMParameterBits, &r)) {
139 VLOG(1) << "Failed reading " << kGolombMParameterBits << " bits.";
140 return false;
141 }
142
143 uint64_t curr_diff = read_prefix * M + r;
144 curr_hash += curr_diff;
145
146 base::WriteBigEndian(hash_bytes, curr_hash);
147 result.insert(std::string(hash_bytes, 8));
148 }
149
150 uncompressed_list->swap(result);
151 return true;
152 }
153
154 PackedEVCertsWhitelist::PackedEVCertsWhitelist(
155 const std::string& compressed_whitelist)
156 : is_whitelist_valid_(false) {
157 std::set<std::string> new_whitelist;
158 if (!UncompressEVWhitelist(compressed_whitelist, &new_whitelist))
159 return;
160
161 whitelist_.swap(new_whitelist);
162 is_whitelist_valid_ = true;
163 }
164
165 PackedEVCertsWhitelist::~PackedEVCertsWhitelist() {
166 }
167
168 bool PackedEVCertsWhitelist::ContainsCertificateHash(
169 const std::string& certificate_hash) const {
170 return whitelist_.find(certificate_hash) != whitelist_.end();
171 }
172
173 bool PackedEVCertsWhitelist::IsValid() const {
174 return is_whitelist_valid_;
175 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698