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/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/strings/string_tokenizer.h" | 9 #include "base/strings/string_tokenizer.h" |
10 #include "net/http/http_security_headers.h" | 10 #include "net/http/http_security_headers.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // 3. Directive names are case-insensitive. | 157 // 3. Directive names are case-insensitive. |
158 // | 158 // |
159 // 4. UAs MUST ignore any STS header fields containing directives, or | 159 // 4. UAs MUST ignore any STS header fields containing directives, or |
160 // other header field value data, that does not conform to the | 160 // other header field value data, that does not conform to the |
161 // syntax defined in this specification. | 161 // syntax defined in this specification. |
162 // | 162 // |
163 // 5. If an STS header field contains directive(s) not recognized by | 163 // 5. If an STS header field contains directive(s) not recognized by |
164 // the UA, the UA MUST ignore the unrecognized directives and if the | 164 // the UA, the UA MUST ignore the unrecognized directives and if the |
165 // STS header field otherwise satisfies the above requirements (1 | 165 // STS header field otherwise satisfies the above requirements (1 |
166 // through 4), the UA MUST process the recognized directives. | 166 // through 4), the UA MUST process the recognized directives. |
167 bool ParseHSTSHeader(const base::Time& now, const std::string& value, | 167 bool ParseHSTSHeader(const std::string& value, |
168 base::Time* expiry, // OUT | 168 base::TimeDelta* max_age, // OUT |
169 bool* include_subdomains) { // OUT | 169 bool* include_subdomains) { // OUT |
170 uint32 max_age_candidate = 0; | 170 uint32 max_age_candidate = 0; |
171 bool include_subdomains_candidate = false; | 171 bool include_subdomains_candidate = false; |
172 | 172 |
173 // We must see max-age exactly once. | 173 // We must see max-age exactly once. |
174 int max_age_observed = 0; | 174 int max_age_observed = 0; |
175 // We must see includeSubdomains exactly 0 or 1 times. | 175 // We must see includeSubdomains exactly 0 or 1 times. |
176 int include_subdomains_observed = 0; | 176 int include_subdomains_observed = 0; |
177 | 177 |
178 enum ParserState { | 178 enum ParserState { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 // We've consumed all the input. Let's see what state we ended up in. | 249 // We've consumed all the input. Let's see what state we ended up in. |
250 if (max_age_observed != 1 || | 250 if (max_age_observed != 1 || |
251 (include_subdomains_observed != 0 && include_subdomains_observed != 1)) { | 251 (include_subdomains_observed != 0 && include_subdomains_observed != 1)) { |
252 return false; | 252 return false; |
253 } | 253 } |
254 | 254 |
255 switch (state) { | 255 switch (state) { |
256 case AFTER_MAX_AGE: | 256 case AFTER_MAX_AGE: |
257 case AFTER_INCLUDE_SUBDOMAINS: | 257 case AFTER_INCLUDE_SUBDOMAINS: |
258 case AFTER_UNKNOWN_LABEL: | 258 case AFTER_UNKNOWN_LABEL: |
259 *expiry = now + base::TimeDelta::FromSeconds(max_age_candidate); | 259 *max_age = base::TimeDelta::FromSeconds(max_age_candidate); |
260 *include_subdomains = include_subdomains_candidate; | 260 *include_subdomains = include_subdomains_candidate; |
261 return true; | 261 return true; |
262 case START: | 262 case START: |
263 case DIRECTIVE_END: | 263 case DIRECTIVE_END: |
264 case AFTER_MAX_AGE_LABEL: | 264 case AFTER_MAX_AGE_LABEL: |
265 case AFTER_MAX_AGE_EQUALS: | 265 case AFTER_MAX_AGE_EQUALS: |
266 return false; | 266 return false; |
267 default: | 267 default: |
268 NOTREACHED(); | 268 NOTREACHED(); |
269 return false; | 269 return false; |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
273 // "Public-Key-Pins" ":" | 273 // "Public-Key-Pins" ":" |
274 // "max-age" "=" delta-seconds ";" | 274 // "max-age" "=" delta-seconds ";" |
275 // "pin-" algo "=" base64 [ ";" ... ] | 275 // "pin-" algo "=" base64 [ ";" ... ] |
276 bool ParseHPKPHeader(const base::Time& now, | 276 bool ParseHPKPHeader(const std::string& value, |
277 const std::string& value, | |
278 const HashValueVector& chain_hashes, | 277 const HashValueVector& chain_hashes, |
279 base::Time* expiry, | 278 base::TimeDelta* max_age, |
280 HashValueVector* hashes) { | 279 HashValueVector* hashes) { |
281 bool parsed_max_age = false; | 280 bool parsed_max_age = false; |
282 uint32 max_age_candidate = 0; | 281 uint32 max_age_candidate = 0; |
283 HashValueVector pins; | 282 HashValueVector pins; |
284 | 283 |
285 std::string source = value; | 284 std::string source = value; |
286 | 285 |
287 while (!source.empty()) { | 286 while (!source.empty()) { |
288 StringPair semicolon = Split(source, ';'); | 287 StringPair semicolon = Split(source, ';'); |
289 semicolon.first = Strip(semicolon.first); | 288 semicolon.first = Strip(semicolon.first); |
(...skipping 21 matching lines...) Expand all Loading... |
311 | 310 |
312 source = semicolon.second; | 311 source = semicolon.second; |
313 } | 312 } |
314 | 313 |
315 if (!parsed_max_age) | 314 if (!parsed_max_age) |
316 return false; | 315 return false; |
317 | 316 |
318 if (!IsPinListValid(pins, chain_hashes)) | 317 if (!IsPinListValid(pins, chain_hashes)) |
319 return false; | 318 return false; |
320 | 319 |
321 *expiry = now + base::TimeDelta::FromSeconds(max_age_candidate); | 320 *max_age = base::TimeDelta::FromSeconds(max_age_candidate); |
322 for (HashValueVector::const_iterator i = pins.begin(); | 321 for (HashValueVector::const_iterator i = pins.begin(); |
323 i != pins.end(); ++i) { | 322 i != pins.end(); ++i) { |
324 hashes->push_back(*i); | 323 hashes->push_back(*i); |
325 } | 324 } |
326 | 325 |
327 return true; | 326 return true; |
328 } | 327 } |
329 | 328 |
330 } // namespace net | 329 } // namespace net |
OLD | NEW |