| 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 |