OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/base64.h" | 5 #include "base/base64.h" |
6 #include "base/basictypes.h" | 6 #include "base/basictypes.h" |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/string_tokenizer.h" | 8 #include "base/strings/string_tokenizer.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "net/http/http_security_headers.h" | 10 #include "net/http/http_security_headers.h" |
(...skipping 30 matching lines...) Expand all Loading... |
41 if (i > kMaxHSTSAgeSecs) | 41 if (i > kMaxHSTSAgeSecs) |
42 i = kMaxHSTSAgeSecs; | 42 i = kMaxHSTSAgeSecs; |
43 *result = (uint32)i; | 43 *result = (uint32)i; |
44 return true; | 44 return true; |
45 } | 45 } |
46 | 46 |
47 // Returns true iff there is an item in |pins| which is not present in | 47 // Returns true iff there is an item in |pins| which is not present in |
48 // |from_cert_chain|. Such an SPKI hash is called a "backup pin". | 48 // |from_cert_chain|. Such an SPKI hash is called a "backup pin". |
49 bool IsBackupPinPresent(const HashValueVector& pins, | 49 bool IsBackupPinPresent(const HashValueVector& pins, |
50 const HashValueVector& from_cert_chain) { | 50 const HashValueVector& from_cert_chain) { |
51 for (HashValueVector::const_iterator i = pins.begin(); i != pins.end(); | 51 for (HashValueVector::const_iterator i = pins.begin(); i != pins.end(); ++i) { |
52 ++i) { | 52 HashValueVector::const_iterator j = std::find_if( |
53 HashValueVector::const_iterator j = | 53 from_cert_chain.begin(), from_cert_chain.end(), HashValuesEqual(*i)); |
54 std::find_if(from_cert_chain.begin(), from_cert_chain.end(), | |
55 HashValuesEqual(*i)); | |
56 if (j == from_cert_chain.end()) | 54 if (j == from_cert_chain.end()) |
57 return true; | 55 return true; |
58 } | 56 } |
59 | 57 |
60 return false; | 58 return false; |
61 } | 59 } |
62 | 60 |
63 // Returns true if the intersection of |a| and |b| is not empty. If either | 61 // Returns true if the intersection of |a| and |b| is not empty. If either |
64 // |a| or |b| is empty, returns false. | 62 // |a| or |b| is empty, returns false. |
65 bool HashesIntersect(const HashValueVector& a, | 63 bool HashesIntersect(const HashValueVector& a, const HashValueVector& b) { |
66 const HashValueVector& b) { | |
67 for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) { | 64 for (HashValueVector::const_iterator i = a.begin(); i != a.end(); ++i) { |
68 HashValueVector::const_iterator j = | 65 HashValueVector::const_iterator j = |
69 std::find_if(b.begin(), b.end(), HashValuesEqual(*i)); | 66 std::find_if(b.begin(), b.end(), HashValuesEqual(*i)); |
70 if (j != b.end()) | 67 if (j != b.end()) |
71 return true; | 68 return true; |
72 } | 69 } |
73 return false; | 70 return false; |
74 } | 71 } |
75 | 72 |
76 // Returns true iff |pins| contains both a live and a backup pin. A live pin | 73 // Returns true iff |pins| contains both a live and a backup pin. A live pin |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 return pair; | 112 return pair; |
116 } | 113 } |
117 | 114 |
118 bool ParseAndAppendPin(const std::string& value, | 115 bool ParseAndAppendPin(const std::string& value, |
119 HashValueTag tag, | 116 HashValueTag tag, |
120 HashValueVector* hashes) { | 117 HashValueVector* hashes) { |
121 std::string unquoted = HttpUtil::Unquote(value); | 118 std::string unquoted = HttpUtil::Unquote(value); |
122 std::string decoded; | 119 std::string decoded; |
123 | 120 |
124 if (unquoted.empty()) | 121 if (unquoted.empty()) |
125 return false; | 122 return false; |
126 | 123 |
127 if (!base::Base64Decode(unquoted, &decoded)) | 124 if (!base::Base64Decode(unquoted, &decoded)) |
128 return false; | 125 return false; |
129 | 126 |
130 HashValue hash(tag); | 127 HashValue hash(tag); |
131 if (decoded.size() != hash.size()) | 128 if (decoded.size() != hash.size()) |
132 return false; | 129 return false; |
133 | 130 |
134 memcpy(hash.data(), decoded.data(), hash.size()); | 131 memcpy(hash.data(), decoded.data(), hash.size()); |
135 hashes->push_back(hash); | 132 hashes->push_back(hash); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 while (!source.empty()) { | 285 while (!source.empty()) { |
289 StringPair semicolon = Split(source, ';'); | 286 StringPair semicolon = Split(source, ';'); |
290 semicolon.first = Strip(semicolon.first); | 287 semicolon.first = Strip(semicolon.first); |
291 semicolon.second = Strip(semicolon.second); | 288 semicolon.second = Strip(semicolon.second); |
292 StringPair equals = Split(semicolon.first, '='); | 289 StringPair equals = Split(semicolon.first, '='); |
293 equals.first = Strip(equals.first); | 290 equals.first = Strip(equals.first); |
294 equals.second = Strip(equals.second); | 291 equals.second = Strip(equals.second); |
295 | 292 |
296 if (LowerCaseEqualsASCII(equals.first, "max-age")) { | 293 if (LowerCaseEqualsASCII(equals.first, "max-age")) { |
297 if (equals.second.empty() || | 294 if (equals.second.empty() || |
298 !MaxAgeToInt(equals.second.begin(), equals.second.end(), | 295 !MaxAgeToInt( |
299 &max_age_candidate)) { | 296 equals.second.begin(), equals.second.end(), &max_age_candidate)) { |
300 return false; | 297 return false; |
301 } | 298 } |
302 parsed_max_age = true; | 299 parsed_max_age = true; |
303 } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1")) { | 300 } else if (LowerCaseEqualsASCII(equals.first, "pin-sha1")) { |
304 if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA1, &pins)) | 301 if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA1, &pins)) |
305 return false; | 302 return false; |
306 } else if (LowerCaseEqualsASCII(equals.first, "pin-sha256")) { | 303 } else if (LowerCaseEqualsASCII(equals.first, "pin-sha256")) { |
307 if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA256, &pins)) | 304 if (!ParseAndAppendPin(equals.second, HASH_VALUE_SHA256, &pins)) |
308 return false; | 305 return false; |
309 } else if (LowerCaseEqualsASCII(equals.first, "includesubdomains")) { | 306 } else if (LowerCaseEqualsASCII(equals.first, "includesubdomains")) { |
310 include_subdomains_candidate = true; | 307 include_subdomains_candidate = true; |
311 } else { | 308 } else { |
312 // Silently ignore unknown directives for forward compatibility. | 309 // Silently ignore unknown directives for forward compatibility. |
313 } | 310 } |
314 | 311 |
315 source = semicolon.second; | 312 source = semicolon.second; |
316 } | 313 } |
317 | 314 |
318 if (!parsed_max_age) | 315 if (!parsed_max_age) |
319 return false; | 316 return false; |
320 | 317 |
321 if (!IsPinListValid(pins, chain_hashes)) | 318 if (!IsPinListValid(pins, chain_hashes)) |
322 return false; | 319 return false; |
323 | 320 |
324 *max_age = base::TimeDelta::FromSeconds(max_age_candidate); | 321 *max_age = base::TimeDelta::FromSeconds(max_age_candidate); |
325 *include_subdomains = include_subdomains_candidate; | 322 *include_subdomains = include_subdomains_candidate; |
326 for (HashValueVector::const_iterator i = pins.begin(); | 323 for (HashValueVector::const_iterator i = pins.begin(); i != pins.end(); ++i) { |
327 i != pins.end(); ++i) { | |
328 bool found = false; | 324 bool found = false; |
329 | 325 |
330 for (HashValueVector::const_iterator j = hashes->begin(); | 326 for (HashValueVector::const_iterator j = hashes->begin(); |
331 j != hashes->end(); ++j) { | 327 j != hashes->end(); |
| 328 ++j) { |
332 if (j->Equals(*i)) { | 329 if (j->Equals(*i)) { |
333 found = true; | 330 found = true; |
334 break; | 331 break; |
335 } | 332 } |
336 } | 333 } |
337 | 334 |
338 if (!found) | 335 if (!found) |
339 hashes->push_back(*i); | 336 hashes->push_back(*i); |
340 } | 337 } |
341 | 338 |
342 return true; | 339 return true; |
343 } | 340 } |
344 | 341 |
345 } // namespace net | 342 } // namespace net |
OLD | NEW |