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

Side by Side Diff: net/cert/ct_ev_whitelist.cc

Issue 462543002: Certificate Transparency: Code for unpacking EV cert hashes whitelist (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressing comments + adding method for determining presence of valid EV whitelist. Created 6 years, 3 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/cert/ct_ev_whitelist.h ('k') | net/cert/ct_ev_whitelist_unittest.cc » ('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 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 "net/cert/ct_ev_whitelist.h"
6
7 #include <set>
8
9 #include "base/big_endian.h"
10 #include "base/file_util.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13
14 namespace net {
15
16 namespace ct {
17
18 namespace {
19 base::LazyInstance<std::set<std::string> >::Leaky g_current_ev_whitelist =
20 LAZY_INSTANCE_INITIALIZER;
21
22 const uint8 kCertHashLengthBits = 64; // 8 bytes
23 const uint64 kGolombMParameterBits = 47; // 2^47
24 } // namespace
25
26 namespace internal {
27
28 BitStreamReader::BitStreamReader(const char* source, size_t length)
29 : source_(source), length_(length), current_byte_(0), current_bit_(7) {
30 }
31
32 bool BitStreamReader::ReadUnaryEncoding(uint64* out) {
33 uint64 res = 0;
34 if (BitsLeft() == 0)
35 return false;
36
37 while ((BitsLeft() > 0) && ReadBit())
38 res++;
39
40 *out = res;
41 return true;
42 }
43
44 bool BitStreamReader::ReadBits(uint8 num_bits, uint64* out) {
45 if (num_bits > 64)
46 return false;
47
48 if (BitsLeft() < num_bits)
49 return false;
50
51 uint64 res = 0;
52 for (uint8 i = 0; i < num_bits; ++i)
53 res |= (static_cast<uint64>(ReadBit()) << (num_bits - (i + 1)));
54
55 *out = res;
56 return true;
57 }
58
59 uint64 BitStreamReader::BitsLeft() const {
60 if (current_byte_ == length_)
61 return 0;
62 return (length_ - (current_byte_ + 1)) * 8 + current_bit_ + 1;
63 }
64
65 uint8 BitStreamReader::ReadBit() {
66 DCHECK_GT(BitsLeft(), 0u);
67 DCHECK(current_bit_ < 8 && current_bit_ >= 0);
68 uint8 res = (source_[current_byte_] & (1 << current_bit_)) >> current_bit_;
69 current_bit_--;
70 if (current_bit_ < 0) {
71 current_byte_++;
72 current_bit_ = 7;
73 }
74
75 return res;
76 }
77
78 bool UncompressEVWhitelist(const std::string& compressed_whitelist,
79 std::set<std::string>* uncompressed_list) {
80 BitStreamReader reader(compressed_whitelist.data(),
81 compressed_whitelist.size());
82 std::set<std::string> result;
83
84 VLOG(1) << "Uncompressing EV whitelist of size "
85 << compressed_whitelist.size();
86 uint64 curr_hash(0);
87 if (!reader.ReadBits(kCertHashLengthBits, &curr_hash)) {
88 VLOG(1) << "Failed reading first hash.";
89 return false;
90 }
91 char hash_bytes[8];
92 base::WriteBigEndian(hash_bytes, curr_hash);
93 result.insert(std::string(hash_bytes, 8));
94 static const uint64 M = static_cast<uint64>(1) << kGolombMParameterBits;
95
96 while (reader.BitsLeft() > kGolombMParameterBits) {
97 uint64 read_prefix = 0;
98 if (!reader.ReadUnaryEncoding(&read_prefix)) {
99 VLOG(1) << "Failed reading unary-encoded prefix.";
100 return false;
101 }
102
103 uint64 r = 0;
104 if (!reader.ReadBits(kGolombMParameterBits, &r)) {
105 VLOG(1) << "Failed reading " << kGolombMParameterBits << " bits.";
106 return false;
107 }
108
109 uint64 curr_diff = read_prefix * M + r;
110 curr_hash += curr_diff;
111
112 base::WriteBigEndian(hash_bytes, curr_hash);
113 result.insert(std::string(hash_bytes, 8));
114 }
115
116 uncompressed_list->swap(result);
117 return true;
118 }
119
120 void SetEVWhitelistData(std::set<std::string>& ev_whitelist) {
121 g_current_ev_whitelist.Get().swap(ev_whitelist);
122 }
123
124 } // namespace internal
125
126 void SetEVWhitelistFromFile(const base::FilePath& compressed_whitelist_file) {
127 VLOG(1) << "Setting EV whitelist from file: "
128 << compressed_whitelist_file.value();
129 std::string compressed_list;
130 if (!base::ReadFileToString(compressed_whitelist_file, &compressed_list)) {
131 VLOG(1) << "Failed reading from " << compressed_whitelist_file.value();
132 return;
133 }
134
135 std::set<std::string> uncompressed_list;
136 if (!internal::UncompressEVWhitelist(compressed_list, &uncompressed_list)) {
137 VLOG(1) << "Failed uncompressing.";
138 return;
139 }
140 VLOG(1) << "Uncompressing succeeded, hashes: " << uncompressed_list.size();
141
142 internal::SetEVWhitelistData(uncompressed_list);
143 }
144
145 bool IsCertificateHashInWhitelist(const std::string& certificate_hash) {
146 const std::set<std::string>& current_ev_whitelist =
147 g_current_ev_whitelist.Get();
148 return current_ev_whitelist.find(certificate_hash) !=
149 current_ev_whitelist.end();
150 }
151
152 bool HasValidEVWhitelist() {
153 return !g_current_ev_whitelist.Get().empty();
154 }
155
156 } // namespace ct
157
158 } // namespace net
OLDNEW
« no previous file with comments | « net/cert/ct_ev_whitelist.h ('k') | net/cert/ct_ev_whitelist_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698