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

Side by Side Diff: net/http/transport_security_state.h

Issue 1211933005: Initial (partial) implementation of HPKP violation reporting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: style fixes, comments Created 5 years, 6 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/http/transport_security_reporter.cc ('k') | net/http/transport_security_state.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 5 #ifndef NET_HTTP_TRANSPORT_SECURITY_STATE_H_
6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 6 #define NET_HTTP_TRANSPORT_SECURITY_STATE_H_
7 7
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
11 #include <vector> 11 #include <vector>
12 12
13 #include "base/basictypes.h" 13 #include "base/basictypes.h"
14 #include "base/gtest_prod_util.h" 14 #include "base/gtest_prod_util.h"
15 #include "base/threading/non_thread_safe.h" 15 #include "base/threading/non_thread_safe.h"
16 #include "base/time/time.h" 16 #include "base/time/time.h"
17 #include "net/base/net_export.h" 17 #include "net/base/net_export.h"
18 #include "net/cert/x509_cert_types.h" 18 #include "net/cert/x509_cert_types.h"
19 #include "net/cert/x509_certificate.h" 19 #include "net/cert/x509_certificate.h"
20 20
21 class GURL;
22
21 namespace net { 23 namespace net {
22 24
23 class SSLInfo; 25 class SSLInfo;
24 26
25 // Tracks which hosts have enabled strict transport security and/or public 27 // Tracks which hosts have enabled strict transport security and/or public
26 // key pins. 28 // key pins.
27 // 29 //
28 // This object manages the in-memory store. Register a Delegate with 30 // This object manages the in-memory store. Register a Delegate with
29 // |SetDelegate| to persist the state to disk. 31 // |SetDelegate| to persist the state to disk.
30 // 32 //
31 // HTTP strict transport security (HSTS) is defined in 33 // HTTP strict transport security (HSTS) is defined in
32 // http://tools.ietf.org/html/ietf-websec-strict-transport-sec, and 34 // http://tools.ietf.org/html/ietf-websec-strict-transport-sec, and
33 // HTTP-based dynamic public key pinning (HPKP) is defined in 35 // HTTP-based dynamic public key pinning (HPKP) is defined in
34 // http://tools.ietf.org/html/ietf-websec-key-pinning. 36 // http://tools.ietf.org/html/ietf-websec-key-pinning.
35 class NET_EXPORT TransportSecurityState 37 class NET_EXPORT TransportSecurityState
36 : NON_EXPORTED_BASE(public base::NonThreadSafe) { 38 : NON_EXPORTED_BASE(public base::NonThreadSafe) {
37 public: 39 public:
38 class NET_EXPORT Delegate { 40 class NET_EXPORT Delegate {
39 public: 41 public:
40 // This function may not block and may be called with internal locks held. 42 // This function may not block and may be called with internal locks held.
41 // Thus it must not reenter the TransportSecurityState object. 43 // Thus it must not reenter the TransportSecurityState object.
42 virtual void StateIsDirty(TransportSecurityState* state) = 0; 44 virtual void StateIsDirty(TransportSecurityState* state) = 0;
43 45
44 protected: 46 protected:
45 virtual ~Delegate() {} 47 virtual ~Delegate() {}
46 }; 48 };
47 49
48 TransportSecurityState();
49 ~TransportSecurityState();
50
51 // A DomainState describes the transport security state (required upgrade 50 // A DomainState describes the transport security state (required upgrade
52 // to HTTPS, and/or any public key pins). 51 // to HTTPS, and/or any public key pins).
53 // 52 //
54 // TODO(davidben): STSState and PKPState are queried and processed 53 // TODO(davidben): STSState and PKPState are queried and processed
55 // independently (with the exception of ShouldSSLErrorsBeFatal triggering on 54 // independently (with the exception of ShouldSSLErrorsBeFatal triggering on
56 // both and on-disk storage). DomainState should be split into the 55 // both and on-disk storage). DomainState should be split into the
57 // two. https://crbug.com/470295. 56 // two. https://crbug.com/470295.
58 class NET_EXPORT DomainState { 57 class NET_EXPORT DomainState {
59 public: 58 public:
60 enum UpgradeMode { 59 enum UpgradeMode {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 // NOT intersect with the set of SPKIs in the TLS server's certificate 105 // NOT intersect with the set of SPKIs in the TLS server's certificate
107 // chain. 106 // chain.
108 HashValueVector bad_spki_hashes; 107 HashValueVector bad_spki_hashes;
109 108
110 // Are subdomains subject to this policy state? 109 // Are subdomains subject to this policy state?
111 bool include_subdomains; 110 bool include_subdomains;
112 111
113 // The domain which matched during a search for this DomainState entry. 112 // The domain which matched during a search for this DomainState entry.
114 // Updated by |GetDynamicDomainState| and |GetStaticDomainState|. 113 // Updated by |GetDynamicDomainState| and |GetStaticDomainState|.
115 std::string domain; 114 std::string domain;
115
116 // Optional; a uri-reference indicating where reports should be
117 // sent when this pin is violated.
118 std::string report_uri;
116 }; 119 };
117 120
118 // Takes a set of SubjectPublicKeyInfo |hashes| and returns true if: 121 // Takes a set of SubjectPublicKeyInfo |hashes| and returns true if:
119 // 1) |bad_static_spki_hashes| does not intersect |hashes|; AND 122 // 1) |bad_static_spki_hashes| does not intersect |hashes|; AND
120 // 2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty 123 // 2) Both |static_spki_hashes| and |dynamic_spki_hashes| are empty
121 // or at least one of them intersects |hashes|. 124 // or at least one of them intersects |hashes|.
122 // 125 //
123 // |{dynamic,static}_spki_hashes| contain trustworthy public key hashes, 126 // |{dynamic,static}_spki_hashes| contain trustworthy public key hashes,
124 // any one of which is sufficient to validate the certificate chain in 127 // any one of which is sufficient to validate the certificate chain in
125 // question. The public keys could be of a root CA, intermediate CA, or 128 // question. The public keys could be of a root CA, intermediate CA, or
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 bool HasNext() const { return iterator_ != end_; } 162 bool HasNext() const { return iterator_ != end_; }
160 void Advance() { ++iterator_; } 163 void Advance() { ++iterator_; }
161 const std::string& hostname() const { return iterator_->first; } 164 const std::string& hostname() const { return iterator_->first; }
162 const DomainState& domain_state() const { return iterator_->second; } 165 const DomainState& domain_state() const { return iterator_->second; }
163 166
164 private: 167 private:
165 std::map<std::string, DomainState>::const_iterator iterator_; 168 std::map<std::string, DomainState>::const_iterator iterator_;
166 std::map<std::string, DomainState>::const_iterator end_; 169 std::map<std::string, DomainState>::const_iterator end_;
167 }; 170 };
168 171
172 class NET_EXPORT Reporter {
173 public:
174 virtual ~Reporter() {}
175
176 // Returns true if a violation report should be sent for the host in
177 // the given |pkp_state|, and returns the report destination URI in
178 // |report_uri|. Returns false if a report should not be sent.
179 virtual bool GetHPKPReportUri(const DomainState::PKPState& pkp_state,
180 GURL* report_uri) = 0;
181
182 // Builds a serialized HPKP violation report in
183 // |serialized_report|. Returns true on success and false on
184 // failure.
185 virtual bool BuildHPKPReport(
186 const std::string& hostname,
187 uint16_t port,
188 const base::Time& expiry,
189 bool include_subdomains,
190 const std::string& effective_hostname,
191 const scoped_refptr<X509Certificate>& served_certificate_chain,
192 const scoped_refptr<X509Certificate>& validated_certificate_chain,
193 const HashValueVector& spki_hashes,
194 std::string* serialized_report) = 0;
195
196 // Sends the given serialized |report| to |report_uri|.
197 virtual void SendHPKPReport(const GURL& report_uri,
198 const std::string& report) = 0;
199 };
200
201 // Indicates whether or not a public key pin check should send a
202 // report if a violation is detected.
203 enum PublicKeyPinReportStatus {
204 DO_NOT_SEND_PUBLIC_KEY_PIN_REPORT,
205 SEND_PUBLIC_KEY_PIN_REPORT
206 };
207
208 TransportSecurityState();
209 ~TransportSecurityState();
210
169 // These functions search for static and dynamic DomainStates, and invoke the 211 // These functions search for static and dynamic DomainStates, and invoke the
170 // functions of the same name on them. These functions are the primary public 212 // functions of the same name on them. These functions are the primary public
171 // interface; direct access to DomainStates is best left to tests. 213 // interface; direct access to DomainStates is best left to tests.
172 bool ShouldSSLErrorsBeFatal(const std::string& host); 214 bool ShouldSSLErrorsBeFatal(const std::string& host);
173 bool ShouldUpgradeToSSL(const std::string& host); 215 bool ShouldUpgradeToSSL(const std::string& host);
174 bool CheckPublicKeyPins(const std::string& host, 216 bool CheckPublicKeyPins(
175 bool is_issued_by_known_root, 217 const std::string& host,
176 const HashValueVector& hashes, 218 bool is_issued_by_known_root,
177 std::string* failure_log); 219 const HashValueVector& hashes,
220 uint16_t port,
221 const scoped_refptr<X509Certificate>& served_certificate_chain,
222 const scoped_refptr<X509Certificate>& validated_certificate_chain,
223 const PublicKeyPinReportStatus report_status,
224 std::string* failure_log);
178 bool HasPublicKeyPins(const std::string& host); 225 bool HasPublicKeyPins(const std::string& host);
179 226
180 // Assign a |Delegate| for persisting the transport security state. If 227 // Assign a |Delegate| for persisting the transport security state. If
181 // |NULL|, state will not be persisted. The caller retains 228 // |NULL|, state will not be persisted. The caller retains
182 // ownership of |delegate|. 229 // ownership of |delegate|.
183 // Note: This is only used for serializing/deserializing the 230 // Note: This is only used for serializing/deserializing the
184 // TransportSecurityState. 231 // TransportSecurityState.
185 void SetDelegate(Delegate* delegate); 232 void SetDelegate(Delegate* delegate);
186 233
234 void SetReporter(Reporter* reporter);
235
187 // Clears all dynamic data (e.g. HSTS and HPKP data). 236 // Clears all dynamic data (e.g. HSTS and HPKP data).
188 // 237 //
189 // Does NOT persist changes using the Delegate, as this function is only 238 // Does NOT persist changes using the Delegate, as this function is only
190 // used to clear any dynamic data prior to re-loading it from a file. 239 // used to clear any dynamic data prior to re-loading it from a file.
191 // Note: This is only used for serializing/deserializing the 240 // Note: This is only used for serializing/deserializing the
192 // TransportSecurityState. 241 // TransportSecurityState.
193 void ClearDynamicData(); 242 void ClearDynamicData();
194 243
195 // Inserts |state| into |enabled_hosts_| under the key |hashed_host|. 244 // Inserts |state| into |enabled_hosts_| under the key |hashed_host|.
196 // |hashed_host| is already in the internal representation. 245 // |hashed_host| is already in the internal representation.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 // HSTS header (used for net-internals and unit tests). 296 // HSTS header (used for net-internals and unit tests).
248 void AddHSTS(const std::string& host, 297 void AddHSTS(const std::string& host,
249 const base::Time& expiry, 298 const base::Time& expiry,
250 bool include_subdomains); 299 bool include_subdomains);
251 300
252 // Adds explicitly-specified data as if it was processed from an 301 // Adds explicitly-specified data as if it was processed from an
253 // HPKP header (used for net-internals and unit tests). 302 // HPKP header (used for net-internals and unit tests).
254 void AddHPKP(const std::string& host, 303 void AddHPKP(const std::string& host,
255 const base::Time& expiry, 304 const base::Time& expiry,
256 bool include_subdomains, 305 bool include_subdomains,
257 const HashValueVector& hashes); 306 const HashValueVector& hashes,
307 const std::string& report_uri);
258 308
259 // Returns true iff we have any static public key pins for the |host| and 309 // Returns true iff we have any static public key pins for the |host| and
260 // iff its set of required pins is the set we expect for Google 310 // iff its set of required pins is the set we expect for Google
261 // properties. 311 // properties.
262 // 312 //
263 // If |host| matches both an exact entry and is a subdomain of another 313 // If |host| matches both an exact entry and is a subdomain of another
264 // entry, the exact match determines the return value. 314 // entry, the exact match determines the return value.
265 static bool IsGooglePinnedProperty(const std::string& host); 315 static bool IsGooglePinnedProperty(const std::string& host);
266 316
267 // The maximum number of seconds for which we'll cache an HSTS request. 317 // The maximum number of seconds for which we'll cache an HSTS request.
(...skipping 16 matching lines...) Expand all
284 // representation of first-class DomainStates, and exposing the preloads 334 // representation of first-class DomainStates, and exposing the preloads
285 // to the caller with |GetStaticDomainState|. 335 // to the caller with |GetStaticDomainState|.
286 static void ReportUMAOnPinFailure(const std::string& host); 336 static void ReportUMAOnPinFailure(const std::string& host);
287 337
288 // IsBuildTimely returns true if the current build is new enough ensure that 338 // IsBuildTimely returns true if the current build is new enough ensure that
289 // built in security information (i.e. HSTS preloading and pinning 339 // built in security information (i.e. HSTS preloading and pinning
290 // information) is timely. 340 // information) is timely.
291 static bool IsBuildTimely(); 341 static bool IsBuildTimely();
292 342
293 // Helper method for actually checking pins. 343 // Helper method for actually checking pins.
294 bool CheckPublicKeyPinsImpl(const std::string& host, 344 bool CheckPublicKeyPinsImpl(
295 const HashValueVector& hashes, 345 const std::string& host,
296 std::string* failure_log); 346 const HashValueVector& hashes,
347 uint16_t port,
348 const scoped_refptr<X509Certificate>& served_certificate_chain,
349 const scoped_refptr<X509Certificate>& validated_certificate_chain,
350 const PublicKeyPinReportStatus report_status,
351 std::string* failure_log);
297 352
298 // If a Delegate is present, notify it that the internal state has 353 // If a Delegate is present, notify it that the internal state has
299 // changed. 354 // changed.
300 void DirtyNotify(); 355 void DirtyNotify();
301 356
302 // Adds HSTS state to |host|. 357 // Adds HSTS state to |host|.
303 void AddHSTSInternal(const std::string& host, 358 void AddHSTSInternal(const std::string& host,
304 DomainState::UpgradeMode upgrade_mode, 359 DomainState::UpgradeMode upgrade_mode,
305 const base::Time& expiry, 360 const base::Time& expiry,
306 bool include_subdomains); 361 bool include_subdomains);
307 362
308 // Adds HPKP state to |host|. 363 // Adds HPKP state to |host|.
309 void AddHPKPInternal(const std::string& host, 364 void AddHPKPInternal(const std::string& host,
310 const base::Time& last_observed, 365 const base::Time& last_observed,
311 const base::Time& expiry, 366 const base::Time& expiry,
312 bool include_subdomains, 367 bool include_subdomains,
313 const HashValueVector& hashes); 368 const HashValueVector& hashes,
369 const std::string& report_uri);
314 370
315 // Enable TransportSecurity for |host|. |state| supercedes any previous 371 // Enable TransportSecurity for |host|. |state| supercedes any previous
316 // state for the |host|, including static entries. 372 // state for the |host|, including static entries.
317 // 373 //
318 // The new state for |host| is persisted using the Delegate (if any). 374 // The new state for |host| is persisted using the Delegate (if any).
319 void EnableHost(const std::string& host, const DomainState& state); 375 void EnableHost(const std::string& host, const DomainState& state);
320 376
321 // The set of hosts that have enabled TransportSecurity. |sts.domain| and 377 // The set of hosts that have enabled TransportSecurity. |sts.domain| and
322 // |pkp.domain| will always be empty for a DomainState in this map; the domain 378 // |pkp.domain| will always be empty for a DomainState in this map; the domain
323 // comes from the map key instead. 379 // comes from the map key instead.
324 DomainStateMap enabled_hosts_; 380 DomainStateMap enabled_hosts_;
325 381
326 Delegate* delegate_; 382 Delegate* delegate_;
327 383
384 Reporter* reporter_;
385
328 // True if static pins should be used. 386 // True if static pins should be used.
329 bool enable_static_pins_; 387 bool enable_static_pins_;
330 388
331 DISALLOW_COPY_AND_ASSIGN(TransportSecurityState); 389 DISALLOW_COPY_AND_ASSIGN(TransportSecurityState);
332 }; 390 };
333 391
334 } // namespace net 392 } // namespace net
335 393
336 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_ 394 #endif // NET_HTTP_TRANSPORT_SECURITY_STATE_H_
OLDNEW
« no previous file with comments | « net/http/transport_security_reporter.cc ('k') | net/http/transport_security_state.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698