ssl_error_classification.h revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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#ifndef CHROME_BROWSER_SSL_SSL_ERROR_CLASSIFICATION_H_ 6#define CHROME_BROWSER_SSL_SSL_ERROR_CLASSIFICATION_H_ 7 8#include <string> 9#include <vector> 10 11#include "base/time/time.h" 12#include "content/public/browser/notification_observer.h" 13#include "content/public/browser/notification_registrar.h" 14#include "net/cert/x509_certificate.h" 15#include "url/gurl.h" 16 17namespace content { 18class WebContents; 19} 20 21// This class classifies characteristics of SSL errors, including information 22// about captive portal detection. 23// 24// This class should only be used on the UI thread because its 25// implementation uses captive_portal::CaptivePortalService which can only be 26// accessed on the UI thread. 27class SSLErrorClassification : public content::NotificationObserver { 28 public: 29 SSLErrorClassification(content::WebContents* web_contents, 30 const base::Time& current_time, 31 const GURL& url, 32 int cert_error, 33 const net::X509Certificate& cert); 34 virtual ~SSLErrorClassification(); 35 36 // Returns true if the system time is in the past. 37 static bool IsUserClockInThePast(const base::Time& time_now); 38 39 // Returns true if the system time is too far in the future or the user is 40 // using a version of Chrome which is more than 1 year old. 41 static bool IsUserClockInTheFuture(const base::Time& time_now); 42 43 // Returns true if the Windows platform is likely to not have SHA-256 support. 44 // On other platforms, returns false always. 45 static bool MaybeWindowsLacksSHA256Support(); 46 47 // A function which calculates the severity score when the ssl error is 48 // |CERT_DATE_INVALID|. The calculated score is between 0.0 and 1.0, higher 49 // being more severe, indicating how severe the certificate's 50 // date invalid error is. 51 void InvalidDateSeverityScore(); 52 53 // A function which calculates the severity score when the ssl error is 54 // |CERT_COMMON_NAME_INVALID|. The calculated score is between 0.0 and 1.0, 55 // higher being more severe, indicating how severe the certificate's common 56 // name invalid error is. 57 void InvalidCommonNameSeverityScore(); 58 59 void RecordUMAStatistics(bool overridable) const; 60 void RecordCaptivePortalUMAStatistics(bool overridable) const; 61 base::TimeDelta TimePassedSinceExpiry() const; 62 63 private: 64 FRIEND_TEST_ALL_PREFIXES(SSLErrorClassificationTest, TestDateInvalidScore); 65 FRIEND_TEST_ALL_PREFIXES(SSLErrorClassificationTest, TestNameMismatch); 66 FRIEND_TEST_ALL_PREFIXES(SSLErrorClassificationTest, 67 TestHostNameHasKnownTLD); 68 69 typedef std::vector<std::string> Tokens; 70 71 // Returns true if the hostname has a known Top Level Domain. 72 static bool IsHostNameKnownTLD(const std::string& host_name); 73 74 // Returns true if the site's hostname differs from one of the DNS 75 // names in the certificate (CN or SANs) only by the presence or 76 // absence of the single-label prefix "www". E.g.: 77 // 78 // www.example.com ~ example.com -> true 79 // example.com ~ www.example.com -> true 80 // www.food.example.com ~ example.com -> false 81 // mail.example.com ~ example.com -> false 82 bool IsWWWSubDomainMatch() const; 83 84 // Returns true if |child| is a subdomain of any of the |potential_parents|. 85 bool NameUnderAnyNames(const Tokens& child, 86 const std::vector<Tokens>& potential_parents) const; 87 88 // Returns true if any of the |potential_children| is a subdomain of the 89 // |parent|. The inverse case should be treated carefully as this is most 90 // likely a MITM attack. We don't want foo.appspot.com to be able to MITM for 91 // appspot.com. 92 bool AnyNamesUnderName(const std::vector<Tokens>& potential_children, 93 const Tokens& parent) const; 94 95 // Returns true if |hostname| is too broad for the scope of a wildcard 96 // certificate. E.g.: 97 // 98 // a.b.example.com ~ *.example.com --> true 99 // b.example.com ~ *.example.com --> false 100 bool IsSubDomainOutsideWildcard(const Tokens& hostname) const; 101 102 // Returns true if the certificate is a shared certificate. Note - This 103 // function should be used with caution (only for UMA histogram) as an 104 // attacker could easily get a certificate with more than 5 names in the SAN 105 // fields. 106 bool IsCertLikelyFromMultiTenantHosting() const; 107 108 static std::vector<Tokens> GetTokenizedDNSNames( 109 const std::vector<std::string>& dns_names); 110 111 // If |potential_subdomain| is a subdomain of |parent|, returns the 112 // number of DNS labels by which |potential_subdomain| is under 113 // |parent|. Otherwise, returns 0. 114 // 115 // For example, 116 // 117 // FindSubDomainDifference(Tokenize("a.b.example.com"), 118 // Tokenize("example.com")) 119 // --> 2. 120 size_t FindSubDomainDifference(const Tokens& potential_subdomain, 121 const Tokens& parent) const; 122 123 static Tokens Tokenize(const std::string& name); 124 125 float CalculateScoreTimePassedSinceExpiry() const; 126 float CalculateScoreEnvironments() const; 127 128 // content::NotificationObserver: 129 virtual void Observe( 130 int type, 131 const content::NotificationSource& source, 132 const content::NotificationDetails& details) OVERRIDE; 133 134 content::WebContents* web_contents_; 135 // This stores the current time. 136 base::Time current_time_; 137 const GURL& request_url_; 138 int cert_error_; 139 // This stores the certificate. 140 const net::X509Certificate& cert_; 141 // Is captive portal detection enabled? 142 bool captive_portal_detection_enabled_; 143 // Did the probe complete before the interstitial was closed? 144 bool captive_portal_probe_completed_; 145 // Did the captive portal probe receive an error or get a non-HTTP response? 146 bool captive_portal_no_response_; 147 // Was a captive portal detected? 148 bool captive_portal_detected_; 149 150 content::NotificationRegistrar registrar_; 151}; 152 153#endif // CHROME_BROWSER_SSL_SSL_ERROR_CLASSIFICATION_H_ 154