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

Side by Side Diff: net/base/transport_security_state.cc

Issue 8364023: Report second-level domains for UMA on pin failure. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "net/base/transport_security_state.h" 5 #include "net/base/transport_security_state.h"
6 6
7 #if defined(USE_OPENSSL) 7 #if defined(USE_OPENSSL)
8 #include <openssl/ecdsa.h> 8 #include <openssl/ecdsa.h>
9 #include <openssl/ssl.h> 9 #include <openssl/ssl.h>
10 #else // !defined(USE_OPENSSL) 10 #else // !defined(USE_OPENSSL)
11 #include <nspr.h> 11 #include <nspr.h>
12 12
13 #include <cryptohi.h> 13 #include <cryptohi.h>
14 #include <hasht.h> 14 #include <hasht.h>
15 #include <keyhi.h> 15 #include <keyhi.h>
16 #include <pk11pub.h> 16 #include <pk11pub.h>
17 #endif 17 #endif
18 18
19 #include "base/base64.h" 19 #include "base/base64.h"
20 #include "base/json/json_reader.h" 20 #include "base/json/json_reader.h"
21 #include "base/json/json_writer.h" 21 #include "base/json/json_writer.h"
22 #include "base/logging.h" 22 #include "base/logging.h"
23 #include "base/memory/scoped_ptr.h" 23 #include "base/memory/scoped_ptr.h"
24 #include "base/metrics/histogram.h"
24 #include "base/sha1.h" 25 #include "base/sha1.h"
25 #include "base/string_number_conversions.h" 26 #include "base/string_number_conversions.h"
26 #include "base/string_tokenizer.h" 27 #include "base/string_tokenizer.h"
27 #include "base/string_util.h" 28 #include "base/string_util.h"
28 #include "base/utf_string_conversions.h" 29 #include "base/utf_string_conversions.h"
29 #include "base/values.h" 30 #include "base/values.h"
30 #include "crypto/sha2.h" 31 #include "crypto/sha2.h"
31 #include "googleurl/src/gurl.h" 32 #include "googleurl/src/gurl.h"
32 #include "net/base/dns_util.h" 33 #include "net/base/dns_util.h"
33 34
34 #if defined(USE_OPENSSL) 35 #if defined(USE_OPENSSL)
35 #include "crypto/openssl_util.h" 36 #include "crypto/openssl_util.h"
36 #endif 37 #endif
37 38
38 namespace net { 39 namespace net {
39 40
41 static const char kPinFailure[] = "SSL.PinFailure";
wtc 2011/10/25 00:49:57 Same here: please clarify what kind of pin failure
42
40 const long int TransportSecurityState::kMaxHSTSAgeSecs = 86400 * 365; // 1 year 43 const long int TransportSecurityState::kMaxHSTSAgeSecs = 86400 * 365; // 1 year
41 44
42 TransportSecurityState::TransportSecurityState(const std::string& hsts_hosts) 45 TransportSecurityState::TransportSecurityState(const std::string& hsts_hosts)
43 : delegate_(NULL) { 46 : delegate_(NULL) {
44 if (!hsts_hosts.empty()) { 47 if (!hsts_hosts.empty()) {
45 bool dirty; 48 bool dirty;
46 Deserialise(hsts_hosts, &dirty, &forced_hosts_); 49 Deserialise(hsts_hosts, &dirty, &forced_hosts_);
47 } 50 }
48 } 51 }
49 52
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 if (!LowerCaseEqualsASCII(tokenizer.token(), "max-age")) 244 if (!LowerCaseEqualsASCII(tokenizer.token(), "max-age"))
242 return false; 245 return false;
243 state = AFTER_MAX_AGE_LABEL; 246 state = AFTER_MAX_AGE_LABEL;
244 break; 247 break;
245 248
246 case AFTER_MAX_AGE_LABEL: 249 case AFTER_MAX_AGE_LABEL:
247 if (IsAsciiWhitespace(*tokenizer.token_begin())) 250 if (IsAsciiWhitespace(*tokenizer.token_begin()))
248 continue; 251 continue;
249 if (*tokenizer.token_begin() != '=') 252 if (*tokenizer.token_begin() != '=')
250 return false; 253 return false;
251 DCHECK(tokenizer.token().length() == 1); 254 DCHECK(tokenizer.token().length() == 1);
wtc 2011/10/25 00:49:57 Nit: it may be better to use DCHECK_EQ. If you us
252 state = AFTER_MAX_AGE_EQUALS; 255 state = AFTER_MAX_AGE_EQUALS;
253 break; 256 break;
254 257
255 case AFTER_MAX_AGE_EQUALS: 258 case AFTER_MAX_AGE_EQUALS:
256 if (IsAsciiWhitespace(*tokenizer.token_begin())) 259 if (IsAsciiWhitespace(*tokenizer.token_begin()))
257 continue; 260 continue;
258 if (!MaxAgeToInt(tokenizer.token_begin(), 261 if (!MaxAgeToInt(tokenizer.token_begin(),
259 tokenizer.token_end(), 262 tokenizer.token_end(),
260 &max_age_candidate)) 263 &max_age_candidate))
261 return false; 264 return false;
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
800 // step 3(b) 803 // step 3(b)
801 if (new_host[i + 1] == '-' || 804 if (new_host[i + 1] == '-' ||
802 new_host[i + label_length] == '-') { 805 new_host[i + label_length] == '-') {
803 return std::string(); 806 return std::string();
804 } 807 }
805 } 808 }
806 809
807 return new_host; 810 return new_host;
808 } 811 }
809 812
813 typedef enum {
wtc 2011/10/25 00:49:57 Can you document what this enum is for? I guess t
agl 2011/10/25 15:00:01 This typeful is significantly larger than the set
814 DOMAIN_GOOGLE_COM = 0,
wtc 2011/10/25 00:49:57 Unless our Style Guide requires this, it is not ne
815 DOMAIN_ANDROID_COM,
816 DOMAIN_GOOGLE_ANALYTICS_COM,
817 DOMAIN_GOOGLEPLEX_COM,
818 DOMAIN_YTIMG_COM,
819 DOMAIN_GOOGLEUSERCONTENT_COM,
820 DOMAIN_YOUTUBE_COM,
821 DOMAIN_GOOGLEAPIS_COM,
822 DOMAIN_GOOGLEADSERVICES_COM,
823 DOMAIN_GOOGLECODE_COM,
824 DOMAIN_APPSPOT_COM,
825 DOMAIN_GOOGLESYNDICATION_COM,
826 DOMAIN_DOUBLECLICK_NET,
827 DOMAIN_GSTATIC_COM,
828 DOMAIN_GMAIL_COM,
829 DOMAIN_GOOGLEMAIL_COM,
830 DOMAIN_GOOGLEGROUPS_COM,
831
832 DOMAIN_PAYPAL_COM,
833 DOMAIN_ELANEX_BIZ,
834 DOMAIN_JOTTIT_COM,
835 DOMAIN_SUNSHINEPRESS_ORG,
836 DOMAIN_NOISEBRIDGE_NET,
837 DOMAIN_NEG9_ORG,
838 DOMAIN_RISEUP_NET,
839 DOMAIN_FACTOR_CC,
840 DOMAIN_MAYFIRST_ORG,
841 DOMAIN_SPLENDIDBACON_COM,
842 DOMAIN_OTTOSPORA_NL,
843 DOMAIN_PAYCHECKRECORDS_COM,
844 DOMAIN_LASTPASS_COM,
845 DOMAIN_KEYERROR_COM,
846 DOMAIN_ENTROPIA_DE,
847 DOMAIN_ROMAB_COM,
848 DOMAIN_LOGENTRIES_COM,
849 DOMAIN_STRIPE_COM,
850 DOMAIN_CLOUDSECURITYALLIANCE_ORG,
851 DOMAIN_SAPO_PT,
852 DOMAIN_MATTMCCUTCHEN_NET,
853 DOMAIN_BETNET_FR,
854 DOMAIN_UPROTECT_IT,
855 DOMAIN_SQUAREUP_COM,
856 DOMAIN_CERT_SE,
857 DOMAIN_CRYPTO_IS,
858 DOMAIN_BUTCHER_NAME,
859 DOMAIN_LINX_NET,
860 DOMAIN_DROPCAM_COM,
861 DOMAIN_INDOVINABANK_COM_VN,
862 DOMAIN_EPOXATE_COM,
863 DOMAIN_TORPROJECT_ORG,
864 DOMAIN_MONEYBOOKERS_COM,
865 DOMAIN_LEDGERSCOPE_NET,
866 DOMAIN_KYPS_NET,
867 DOMAIN_RECURLY_COM,
868 DOMAIN_GREPLIN_COM,
869 DOMAIN_NEARBUYSYSTEMS_COM,
870 DOMAIN_UBERTT_ORG,
871 DOMAIN_TWITTER_COM,
872 DOMAIN_TWIMG_COM,
873 DOMAIN_AKAMAIHD_NET,
874
875 // Boundary value for UMA_HISTOGRAM_ENUMERATION:
876 DOMAIN_NUM_EVENTS
wtc 2011/10/25 00:49:57 NUM_EVENTS sounds strange because these aren't eve
877 } LowResolutionDomainName;
wtc 2011/10/25 00:49:57 typedef enum { ... } LowResolutionDomainName
878
810 struct HSTSPreload { 879 struct HSTSPreload {
811 uint8 length; 880 uint8 length;
812 bool include_subdomains; 881 bool include_subdomains;
813 char dns_name[30]; 882 char dns_name[30];
814 bool https_required; 883 bool https_required;
815 const char* const* required_hashes; 884 const char* const* required_hashes;
885 LowResolutionDomainName low_res_name;
816 }; 886 };
817 887
818 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries, 888 static bool HasPreload(const struct HSTSPreload* entries, size_t num_entries,
819 const std::string& canonicalized_host, size_t i, 889 const std::string& canonicalized_host, size_t i,
820 TransportSecurityState::DomainState* out, bool* ret) { 890 TransportSecurityState::DomainState* out, bool* ret) {
821 for (size_t j = 0; j < num_entries; j++) { 891 for (size_t j = 0; j < num_entries; j++) {
822 if (entries[j].length == canonicalized_host.size() - i && 892 if (entries[j].length == canonicalized_host.size() - i &&
823 memcmp(entries[j].dns_name, &canonicalized_host[i], 893 memcmp(entries[j].dns_name, &canonicalized_host[i],
824 entries[j].length) == 0) { 894 entries[j].length) == 0) {
825 if (!entries[j].include_subdomains && i != 0) { 895 if (!entries[j].include_subdomains && i != 0) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 #if defined(OS_CHROMEOS) 1026 #if defined(OS_CHROMEOS)
957 static const bool kTwitterHSTS = true; 1027 static const bool kTwitterHSTS = true;
958 #else 1028 #else
959 static const bool kTwitterHSTS = false; 1029 static const bool kTwitterHSTS = false;
960 #endif 1030 #endif
961 1031
962 // In the medium term this list is likely to just be hardcoded here. This 1032 // In the medium term this list is likely to just be hardcoded here. This
963 // slightly odd form removes the need for additional relocations records. 1033 // slightly odd form removes the need for additional relocations records.
964 static const struct HSTSPreload kPreloadedSTS[] = { 1034 static const struct HSTSPreload kPreloadedSTS[] = {
965 // (*.)google.com, iff using SSL must use an acceptable certificate. 1035 // (*.)google.com, iff using SSL must use an acceptable certificate.
966 {12, true, "\006google\003com", false, kGoogleAcceptableCerts }, 1036 {12, true, "\006google\003com", false, kGoogleAcceptableCerts,
1037 DOMAIN_GOOGLE_COM },
967 {25, true, "\013pinningtest\007appspot\003com", false, 1038 {25, true, "\013pinningtest\007appspot\003com", false,
968 kTestAcceptableCerts }, 1039 kTestAcceptableCerts, DOMAIN_APPSPOT_COM },
969 // Now we force HTTPS for subtrees of google.com. 1040 // Now we force HTTPS for subtrees of google.com.
970 {19, true, "\006health\006google\003com", true, kGoogleAcceptableCerts }, 1041 {19, true, "\006health\006google\003com", true, kGoogleAcceptableCerts,
971 {21, true, "\010checkout\006google\003com", true, kGoogleAcceptableCerts }, 1042 DOMAIN_GOOGLE_COM },
972 {19, true, "\006chrome\006google\003com", true, kGoogleAcceptableCerts }, 1043 {21, true, "\010checkout\006google\003com", true, kGoogleAcceptableCerts,
973 {17, true, "\004docs\006google\003com", true, kGoogleAcceptableCerts }, 1044 DOMAIN_GOOGLE_COM },
974 {18, true, "\005sites\006google\003com", true, kGoogleAcceptableCerts }, 1045 {19, true, "\006chrome\006google\003com", true, kGoogleAcceptableCerts,
1046 DOMAIN_GOOGLE_COM },
1047 {17, true, "\004docs\006google\003com", true, kGoogleAcceptableCerts,
1048 DOMAIN_GOOGLE_COM },
1049 {18, true, "\005sites\006google\003com", true, kGoogleAcceptableCerts,
1050 DOMAIN_GOOGLE_COM },
975 {25, true, "\014spreadsheets\006google\003com", true, 1051 {25, true, "\014spreadsheets\006google\003com", true,
976 kGoogleAcceptableCerts }, 1052 kGoogleAcceptableCerts, DOMAIN_GOOGLE_COM },
977 {22, false, "\011appengine\006google\003com", true, 1053 {22, false, "\011appengine\006google\003com", true,
978 kGoogleAcceptableCerts }, 1054 kGoogleAcceptableCerts, DOMAIN_GOOGLE_COM },
979 {22, true, "\011encrypted\006google\003com", true, kGoogleAcceptableCerts }, 1055 {22, true, "\011encrypted\006google\003com", true, kGoogleAcceptableCerts,
980 {21, true, "\010accounts\006google\003com", true, kGoogleAcceptableCerts }, 1056 DOMAIN_GOOGLE_COM },
981 {21, true, "\010profiles\006google\003com", true, kGoogleAcceptableCerts }, 1057 {21, true, "\010accounts\006google\003com", true, kGoogleAcceptableCerts,
982 {17, true, "\004mail\006google\003com", true, kGoogleAcceptableCerts }, 1058 DOMAIN_GOOGLE_COM },
1059 {21, true, "\010profiles\006google\003com", true, kGoogleAcceptableCerts,
1060 DOMAIN_GOOGLE_COM },
1061 {17, true, "\004mail\006google\003com", true, kGoogleAcceptableCerts,
1062 DOMAIN_GOOGLE_COM },
983 {23, true, "\012talkgadget\006google\003com", true, 1063 {23, true, "\012talkgadget\006google\003com", true,
984 kGoogleAcceptableCerts }, 1064 kGoogleAcceptableCerts, DOMAIN_GOOGLE_COM },
985 {17, true, "\004talk\006google\003com", true, kGoogleAcceptableCerts }, 1065 {17, true, "\004talk\006google\003com", true, kGoogleAcceptableCerts,
1066 DOMAIN_GOOGLE_COM },
986 {29, true, "\020hostedtalkgadget\006google\003com", true, 1067 {29, true, "\020hostedtalkgadget\006google\003com", true,
987 kGoogleAcceptableCerts }, 1068 kGoogleAcceptableCerts, DOMAIN_GOOGLE_COM },
988 {17, true, "\004plus\006google\003com", true, kGoogleAcceptableCerts }, 1069 {17, true, "\004plus\006google\003com", true, kGoogleAcceptableCerts,
1070 DOMAIN_GOOGLE_COM },
989 // Other Google-related domains that must use HTTPS. 1071 // Other Google-related domains that must use HTTPS.
990 {20, true, "\006market\007android\003com", true, kGoogleAcceptableCerts }, 1072 {20, true, "\006market\007android\003com", true, kGoogleAcceptableCerts,
1073 DOMAIN_ANDROID_COM },
991 {26, true, "\003ssl\020google-analytics\003com", true, 1074 {26, true, "\003ssl\020google-analytics\003com", true,
992 kGoogleAcceptableCerts }, 1075 kGoogleAcceptableCerts, DOMAIN_GOOGLE_ANALYTICS_COM },
993 {18, true, "\005drive\006google\003com", true, kGoogleAcceptableCerts }, 1076 {18, true, "\005drive\006google\003com", true, kGoogleAcceptableCerts,
994 {16, true, "\012googleplex\003com", true, kGoogleAcceptableCerts }, 1077 DOMAIN_GOOGLE_COM },
995 {19, true, "\006groups\006google\003com", true, kGoogleAcceptableCerts }, 1078 {16, true, "\012googleplex\003com", true, kGoogleAcceptableCerts,
1079 DOMAIN_GOOGLEPLEX_COM },
1080 {19, true, "\006groups\006google\003com", true, kGoogleAcceptableCerts,
1081 DOMAIN_GOOGLE_COM },
996 // Other Google-related domains that must use an acceptable certificate 1082 // Other Google-related domains that must use an acceptable certificate
997 // iff using SSL. 1083 // iff using SSL.
998 {11, true, "\005ytimg\003com", false, kGoogleAcceptableCerts }, 1084 {11, true, "\005ytimg\003com", false, kGoogleAcceptableCerts,
999 {23, true, "\021googleusercontent\003com", false, kGoogleAcceptableCerts }, 1085 DOMAIN_YTIMG_COM },
1000 {13, true, "\007youtube\003com", false, kGoogleAcceptableCerts }, 1086 {23, true, "\021googleusercontent\003com", false, kGoogleAcceptableCerts,
1001 {16, true, "\012googleapis\003com", false, kGoogleAcceptableCerts }, 1087 DOMAIN_GOOGLEUSERCONTENT_COM },
1002 {22, true, "\020googleadservices\003com", false, kGoogleAcceptableCerts }, 1088 {13, true, "\007youtube\003com", false, kGoogleAcceptableCerts,
1003 {16, true, "\012googlecode\003com", false, kGoogleAcceptableCerts }, 1089 DOMAIN_YOUTUBE_COM },
1004 {13, true, "\007appspot\003com", false, kGoogleAcceptableCerts }, 1090 {16, true, "\012googleapis\003com", false, kGoogleAcceptableCerts,
1005 {23, true, "\021googlesyndication\003com", false, kGoogleAcceptableCerts }, 1091 DOMAIN_GOOGLEAPIS_COM },
1006 {17, true, "\013doubleclick\003net", false, kGoogleAcceptableCerts }, 1092 {22, true, "\020googleadservices\003com", false, kGoogleAcceptableCerts,
1007 {17, true, "\003ssl\007gstatic\003com", false, kGoogleAcceptableCerts }, 1093 DOMAIN_GOOGLEADSERVICES_COM },
1094 {16, true, "\012googlecode\003com", false, kGoogleAcceptableCerts,
1095 DOMAIN_GOOGLECODE_COM },
1096 {13, true, "\007appspot\003com", false, kGoogleAcceptableCerts,
1097 DOMAIN_APPSPOT_COM },
1098 {23, true, "\021googlesyndication\003com", false, kGoogleAcceptableCerts,
1099 DOMAIN_GOOGLESYNDICATION_COM },
1100 {17, true, "\013doubleclick\003net", false, kGoogleAcceptableCerts,
1101 DOMAIN_DOUBLECLICK_NET },
1102 {17, true, "\003ssl\007gstatic\003com", false, kGoogleAcceptableCerts,
1103 DOMAIN_GSTATIC_COM },
1008 // Exclude the learn.doubleclick.net subdomain because it uses a different 1104 // Exclude the learn.doubleclick.net subdomain because it uses a different
1009 // CA. 1105 // CA.
1010 {23, true, "\005learn\013doubleclick\003net", false, 0 }, 1106 {23, true, "\005learn\013doubleclick\003net", false, 0,
1107 DOMAIN_DOUBLECLICK_NET },
1011 // Now we force HTTPS for other sites that have requested it. 1108 // Now we force HTTPS for other sites that have requested it.
1012 {16, false, "\003www\006paypal\003com", true, 0 }, 1109 {16, false, "\003www\006paypal\003com", true, 0, DOMAIN_PAYPAL_COM },
1013 {16, false, "\003www\006elanex\003biz", true, 0 }, 1110 {16, false, "\003www\006elanex\003biz", true, 0, DOMAIN_ELANEX_BIZ },
1014 {12, true, "\006jottit\003com", true, 0 }, 1111 {12, true, "\006jottit\003com", true, 0, DOMAIN_JOTTIT_COM },
1015 {19, true, "\015sunshinepress\003org", true, 0 }, 1112 {19, true, "\015sunshinepress\003org", true, 0, DOMAIN_SUNSHINEPRESS_ORG },
1016 {21, false, "\003www\013noisebridge\003net", true, 0 }, 1113 {21, false, "\003www\013noisebridge\003net", true, 0,
1017 {10, false, "\004neg9\003org", true, 0 }, 1114 DOMAIN_NOISEBRIDGE_NET },
1018 {12, true, "\006riseup\003net", true, 0 }, 1115 {10, false, "\004neg9\003org", true, 0, DOMAIN_NEG9_ORG },
1019 {11, false, "\006factor\002cc", true, 0 }, 1116 {12, true, "\006riseup\003net", true, 0, DOMAIN_RISEUP_NET },
1020 {22, false, "\007members\010mayfirst\003org", true, 0 }, 1117 {11, false, "\006factor\002cc", true, 0,
1021 {22, false, "\007support\010mayfirst\003org", true, 0 }, 1118 DOMAIN_FACTOR_CC },
1022 {17, false, "\002id\010mayfirst\003org", true, 0 }, 1119 {22, false, "\007members\010mayfirst\003org", true, 0, DOMAIN_MAYFIRST_ORG },
1023 {20, false, "\005lists\010mayfirst\003org", true, 0 }, 1120 {22, false, "\007support\010mayfirst\003org", true, 0, DOMAIN_MAYFIRST_ORG },
1024 {19, true, "\015splendidbacon\003com", true, 0 }, 1121 {17, false, "\002id\010mayfirst\003org", true, 0, DOMAIN_MAYFIRST_ORG },
1025 {28, false, "\016aladdinschools\007appspot\003com", true, 0 }, 1122 {20, false, "\005lists\010mayfirst\003org", true, 0, DOMAIN_MAYFIRST_ORG },
1026 {14, true, "\011ottospora\002nl", true, 0 }, 1123 {19, true, "\015splendidbacon\003com", true, 0, DOMAIN_SPLENDIDBACON_COM },
1027 {25, false, "\003www\017paycheckrecords\003com", true, 0 }, 1124 {28, false, "\016aladdinschools\007appspot\003com", true, 0,
1028 {14, false, "\010lastpass\003com", true, 0 }, 1125 DOMAIN_APPSPOT_COM },
1029 {18, false, "\003www\010lastpass\003com", true, 0 }, 1126 {14, true, "\011ottospora\002nl", true, 0, DOMAIN_OTTOSPORA_NL },
1030 {14, true, "\010keyerror\003com", true, 0 }, 1127 {25, false, "\003www\017paycheckrecords\003com", true, 0,
1031 {13, false, "\010entropia\002de", true, 0 }, 1128 DOMAIN_PAYCHECKRECORDS_COM },
1032 {17, false, "\003www\010entropia\002de", true, 0 }, 1129 {14, false, "\010lastpass\003com", true, 0, DOMAIN_LASTPASS_COM },
1033 {11, true, "\005romab\003com", true, 0 }, 1130 {18, false, "\003www\010lastpass\003com", true, 0, DOMAIN_LASTPASS_COM },
1034 {16, false, "\012logentries\003com", true, 0 }, 1131 {14, true, "\010keyerror\003com", true, 0, DOMAIN_KEYERROR_COM },
1035 {20, false, "\003www\012logentries\003com", true, 0 }, 1132 {13, false, "\010entropia\002de", true, 0, DOMAIN_ENTROPIA_DE },
1036 {12, true, "\006stripe\003com", true, 0 }, 1133 {17, false, "\003www\010entropia\002de", true, 0, DOMAIN_ENTROPIA_DE },
1037 {27, true, "\025cloudsecurityalliance\003org", true, 0 }, 1134 {11, true, "\005romab\003com", true, 0, DOMAIN_ROMAB_COM },
1038 {15, true, "\005login\004sapo\002pt", true, 0 }, 1135 {16, false, "\012logentries\003com", true, 0, DOMAIN_LOGENTRIES_COM },
1039 {19, true, "\015mattmccutchen\003net", true, 0 }, 1136 {20, false, "\003www\012logentries\003com", true, 0, DOMAIN_LOGENTRIES_COM },
1040 {11, true, "\006betnet\002fr", true, 0 }, 1137 {12, true, "\006stripe\003com", true, 0, DOMAIN_STRIPE_COM },
1041 {13, true, "\010uprotect\002it", true, 0 }, 1138 {27, true, "\025cloudsecurityalliance\003org", true, 0,
1042 {14, false, "\010squareup\003com", true, 0 }, 1139 DOMAIN_CLOUDSECURITYALLIANCE_ORG },
1043 {9, true, "\004cert\002se", true, 0 }, 1140 {15, true, "\005login\004sapo\002pt", true, 0, DOMAIN_SAPO_PT },
1044 {11, true, "\006crypto\002is", true, 0 }, 1141 {19, true, "\015mattmccutchen\003net", true, 0, DOMAIN_MATTMCCUTCHEN_NET },
1045 {20, true, "\005simon\007butcher\004name", true, 0 }, 1142 {11, true, "\006betnet\002fr", true, 0, DOMAIN_BETNET_FR },
1046 {10, true, "\004linx\003net", true, 0 }, 1143 {13, true, "\010uprotect\002it", true, 0, DOMAIN_UPROTECT_IT },
1047 {13, false, "\007dropcam\003com", true, 0 }, 1144 {14, false, "\010squareup\003com", true, 0, DOMAIN_SQUAREUP_COM },
1048 {17, false, "\003www\007dropcam\003com", true, 0 }, 1145 {9, true, "\004cert\002se", true, 0, DOMAIN_CERT_SE },
1049 {30, true, "\010ebanking\014indovinabank\003com\002vn", true, 0 }, 1146 {11, true, "\006crypto\002is", true, 0, DOMAIN_CRYPTO_IS },
1050 {13, false, "\007epoxate\003com", true, 0 }, 1147 {20, true, "\005simon\007butcher\004name", true, 0, DOMAIN_BUTCHER_NAME },
1051 {16, false, "\012torproject\003org", true, kTorAcceptableCerts }, 1148 {10, true, "\004linx\003net", true, 0, DOMAIN_LINX_NET },
1052 {21, true, "\004blog\012torproject\003org", true, kTorAcceptableCerts }, 1149 {13, false, "\007dropcam\003com", true, 0, DOMAIN_DROPCAM_COM },
1053 {22, true, "\005check\012torproject\003org", true, kTorAcceptableCerts }, 1150 {17, false, "\003www\007dropcam\003com", true, 0, DOMAIN_DROPCAM_COM },
1054 {20, true, "\003www\012torproject\003org", true, kTorAcceptableCerts }, 1151 {30, true, "\010ebanking\014indovinabank\003com\002vn", true, 0,
1055 {22, true, "\003www\014moneybookers\003com", true, 0 }, 1152 DOMAIN_INDOVINABANK_COM_VN },
1056 {17, false, "\013ledgerscope\003net", true, 0 }, 1153 {13, false, "\007epoxate\003com", true, 0, DOMAIN_EPOXATE_COM },
1057 {21, false, "\003www\013ledgerscope\003net", true, 0 }, 1154 {16, false, "\012torproject\003org", true, kTorAcceptableCerts,
1058 {10, false, "\004kyps\003net", true, 0 }, 1155 DOMAIN_TORPROJECT_ORG },
1059 {14, false, "\003www\004kyps\003net", true, 0 }, 1156 {21, true, "\004blog\012torproject\003org", true, kTorAcceptableCerts,
1060 {17, true, "\003app\007recurly\003com", true, 0 }, 1157 DOMAIN_TORPROJECT_ORG },
1061 {17, true, "\003api\007recurly\003com", true, 0 }, 1158 {22, true, "\005check\012torproject\003org", true, kTorAcceptableCerts,
1062 {13, false, "\007greplin\003com", true, 0 }, 1159 DOMAIN_TORPROJECT_ORG },
1063 {17, false, "\003www\007greplin\003com", true, 0 }, 1160 {20, true, "\003www\012torproject\003org", true, kTorAcceptableCerts,
1064 {27, true, "\006luneta\016nearbuysystems\003com", true, 0 }, 1161 DOMAIN_TORPROJECT_ORG },
1065 {12, true, "\006ubertt\003org", true, 0 }, 1162 {22, true, "\003www\014moneybookers\003com", true, 0,
1066 1163 DOMAIN_MONEYBOOKERS_COM },
1067 {13, false, "\007twitter\003com", kTwitterHSTS, kTwitterComAcceptableCerts }, 1164 {17, false, "\013ledgerscope\003net", true, 0, DOMAIN_LEDGERSCOPE_NET },
1068 {17, true, "\003www\007twitter\003com", kTwitterHSTS, kTwitterComAcceptableCer ts }, 1165 {21, false, "\003www\013ledgerscope\003net", true, 0,
1069 {17, true, "\003api\007twitter\003com", kTwitterHSTS, kTwitterComAcceptableCer ts }, 1166 DOMAIN_LEDGERSCOPE_NET },
1070 {19, true, "\005oauth\007twitter\003com", kTwitterHSTS, kTwitterComAcceptableC erts }, 1167 {10, false, "\004kyps\003net", true, 0, DOMAIN_KYPS_NET },
1071 {20, true, "\006mobile\007twitter\003com", kTwitterHSTS, kTwitterComAcceptable Certs }, 1168 {14, false, "\003www\004kyps\003net", true, 0, DOMAIN_KYPS_NET },
1072 {17, true, "\003dev\007twitter\003com", kTwitterHSTS, kTwitterComAcceptableCer ts }, 1169 {17, true, "\003app\007recurly\003com", true, 0, DOMAIN_RECURLY_COM },
1073 {22, true, "\010business\007twitter\003com", kTwitterHSTS, kTwitterComAcceptab leCerts }, 1170 {17, true, "\003api\007recurly\003com", true, 0, DOMAIN_RECURLY_COM },
1171 {13, false, "\007greplin\003com", true, 0, DOMAIN_GREPLIN_COM },
1172 {17, false, "\003www\007greplin\003com", true, 0, DOMAIN_GREPLIN_COM },
1173 {27, true, "\006luneta\016nearbuysystems\003com", true, 0,
1174 DOMAIN_NEARBUYSYSTEMS_COM },
1175 {12, true, "\006ubertt\003org", true, 0, DOMAIN_UBERTT_ORG },
1176
1177 {13, false, "\007twitter\003com", kTwitterHSTS,
1178 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1179 {17, true, "\003www\007twitter\003com", kTwitterHSTS,
1180 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1181 {17, true, "\003api\007twitter\003com", kTwitterHSTS,
1182 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1183 {19, true, "\005oauth\007twitter\003com", kTwitterHSTS,
1184 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1185 {20, true, "\006mobile\007twitter\003com", kTwitterHSTS,
1186 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1187 {17, true, "\003dev\007twitter\003com", kTwitterHSTS,
1188 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1189 {22, true, "\010business\007twitter\003com", kTwitterHSTS,
1190 kTwitterComAcceptableCerts, DOMAIN_TWITTER_COM },
1074 1191
1075 #if 0 1192 #if 0
1076 // Twitter CDN pins disabled in order to track down pinning failures --agl 1193 // Twitter CDN pins disabled in order to track down pinning failures --agl
1077 {22, true, "\010platform\007twitter\003com", false, kTwitterCDNAcceptableCerts }, 1194 {22, true, "\010platform\007twitter\003com", false,
1078 {15, true, "\003si0\005twimg\003com", false, kTwitterCDNAcceptableCerts }, 1195 kTwitterCDNAcceptableCerts, DOMAIN_TWITTER_COM },
1079 {23, true, "\010twimg0-a\010akamaihd\003net", false, kTwitterCDNAcceptableCert s }, 1196 {15, true, "\003si0\005twimg\003com", false, kTwitterCDNAcceptableCerts,
1197 DOMAIN_TWIMG_COM },
1198 {23, true, "\010twimg0-a\010akamaihd\003net", false,
1199 kTwitterCDNAcceptableCerts, DOMAIN_AKAMAIHD_NET },
1080 #endif 1200 #endif
1081 }; 1201 };
1082 static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS); 1202 static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS);
1083 1203
1084 static const struct HSTSPreload kPreloadedSNISTS[] = { 1204 static const struct HSTSPreload kPreloadedSNISTS[] = {
1085 // These SNI-only domains must always use HTTPS. 1205 // These SNI-only domains must always use HTTPS.
1086 {11, false, "\005gmail\003com", true, kGoogleAcceptableCerts }, 1206 {11, false, "\005gmail\003com", true, kGoogleAcceptableCerts,
1087 {16, false, "\012googlemail\003com", true, kGoogleAcceptableCerts }, 1207 DOMAIN_GMAIL_COM },
1088 {15, false, "\003www\005gmail\003com", true, kGoogleAcceptableCerts }, 1208 {16, false, "\012googlemail\003com", true, kGoogleAcceptableCerts,
1089 {20, false, "\003www\012googlemail\003com", true, kGoogleAcceptableCerts }, 1209 DOMAIN_GOOGLEMAIL_COM },
1210 {15, false, "\003www\005gmail\003com", true, kGoogleAcceptableCerts,
1211 DOMAIN_GMAIL_COM },
1212 {20, false, "\003www\012googlemail\003com", true, kGoogleAcceptableCerts,
1213 DOMAIN_GOOGLEMAIL_COM },
1090 // These SNI-only domains must use an acceptable certificate iff using 1214 // These SNI-only domains must use an acceptable certificate iff using
1091 // HTTPS. 1215 // HTTPS.
1092 {22, true, "\020google-analytics\003com", false, kGoogleAcceptableCerts }, 1216 {22, true, "\020google-analytics\003com", false, kGoogleAcceptableCerts,
1217 DOMAIN_GOOGLE_ANALYTICS_COM },
1093 // www. requires SNI. 1218 // www. requires SNI.
1094 {18, true, "\014googlegroups\003com", false, kGoogleAcceptableCerts }, 1219 {18, true, "\014googlegroups\003com", false, kGoogleAcceptableCerts,
1220 DOMAIN_GOOGLEGROUPS_COM },
1095 }; 1221 };
1096 static const size_t kNumPreloadedSNISTS = ARRAYSIZE_UNSAFE(kPreloadedSNISTS); 1222 static const size_t kNumPreloadedSNISTS = ARRAYSIZE_UNSAFE(kPreloadedSNISTS);
1097 1223
1098 // Returns true if there is an HSTSPreload entry for the host in |entries|, and 1224 // Returns the HSTSPreload entry for the |canonicalized_host| in |entries|,
1099 // if its |required_hashes| member is identical (by address) to |certs|. 1225 // or NULL if there is none. Prefers exact hostname matches to those that
1100 static bool ScanForHostAndCerts( 1226 // match only because HSTSPreload.include_subdomains is true.
1227 //
1228 // |canonicalized_host| should be the hostname as canonicalized by
1229 // CanonicalizeHost.
1230 static const struct HSTSPreload* GetHSTSPreload(
1101 const std::string& canonicalized_host, 1231 const std::string& canonicalized_host,
1102 const struct HSTSPreload* entries, 1232 const struct HSTSPreload* entries,
1103 size_t num_entries, 1233 size_t num_entries) {
1104 const char* const certs[]) { 1234 const struct HSTSPreload* hit = NULL;
1105 bool hit = false;
1106 1235
1107 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) { 1236 for (size_t i = 0; canonicalized_host[i]; i += canonicalized_host[i] + 1) {
1108 for (size_t j = 0; j < num_entries; j++) { 1237 for (size_t j = 0; j < num_entries; j++) {
1109 const struct HSTSPreload& entry = entries[j]; 1238 const struct HSTSPreload* entry = entries + j;
1110 1239
1111 if (i != 0 && !entry.include_subdomains) 1240 if (i != 0 && !entry->include_subdomains)
1112 continue; 1241 continue;
1113 1242
1114 if (entry.length == canonicalized_host.size() - i && 1243 if (entry->length == canonicalized_host.size() - i &&
1115 memcmp(entry.dns_name, &canonicalized_host[i], entry.length) == 0) { 1244 memcmp(entry->dns_name, &canonicalized_host[i], entry->length) == 0) {
1116 hit = entry.required_hashes == certs; 1245 // Return immediately upon exact match.
1117 // Return immediately upon exact match:
1118 if (i == 0) 1246 if (i == 0)
1119 return hit; 1247 return entry;
1248 hit = entry;
1120 } 1249 }
1121 } 1250 }
1122 } 1251 }
1123 1252
1124 return hit; 1253 return hit;
1125 } 1254 }
1126 1255
1127 // static 1256 // static
1128 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host, 1257 bool TransportSecurityState::IsGooglePinnedProperty(const std::string& host,
1129 bool sni_available) { 1258 bool sni_available) {
1130 std::string canonicalized_host = CanonicalizeHost(host); 1259 std::string canonicalized_host = CanonicalizeHost(host);
1260 const struct HSTSPreload* entry =
1261 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
1131 1262
1132 if (ScanForHostAndCerts(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS, 1263 if (entry && entry->required_hashes == kGoogleAcceptableCerts)
1133 kGoogleAcceptableCerts)) {
1134 return true; 1264 return true;
1135 }
1136 1265
1137 if (sni_available) { 1266 if (sni_available) {
1138 if (ScanForHostAndCerts(canonicalized_host, kPreloadedSNISTS, kNumPreloadedS NISTS, 1267 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS,
1139 kGoogleAcceptableCerts)) { 1268 kNumPreloadedSNISTS);
1269 if (entry && entry->required_hashes == kGoogleAcceptableCerts)
1140 return true; 1270 return true;
1141 }
1142 } 1271 }
1143 1272
1144 return false; 1273 return false;
1145 } 1274 }
1146 1275
1276 // static
1277 void TransportSecurityState::ReportUMAPinFailure(const std::string& host,
1278 bool sni_available) {
1279 std::string canonicalized_host = CanonicalizeHost(host);
1280
1281 const struct HSTSPreload* entry =
1282 GetHSTSPreload(canonicalized_host, kPreloadedSTS, kNumPreloadedSTS);
1283
1284 if (!entry && sni_available)
1285 entry = GetHSTSPreload(canonicalized_host, kPreloadedSNISTS,
1286 kNumPreloadedSNISTS);
wtc 2011/10/25 00:49:57 Nit: put curly braces around the "if" body because
1287
1288 if (!entry)
1289 return;
1290
1291 UMA_HISTOGRAM_ENUMERATION(kPinFailure, entry->low_res_name,
1292 DOMAIN_NUM_EVENTS);
wtc 2011/10/25 00:49:57 I checked with jar, the father of Histogram. Here
1293 }
1147 1294
1148 // IsPreloadedSTS returns true if the canonicalized hostname should always be 1295 // IsPreloadedSTS returns true if the canonicalized hostname should always be
1149 // considered to have STS enabled. 1296 // considered to have STS enabled.
1150 bool TransportSecurityState::IsPreloadedSTS( 1297 bool TransportSecurityState::IsPreloadedSTS(
1151 const std::string& canonicalized_host, 1298 const std::string& canonicalized_host,
1152 bool sni_available, 1299 bool sni_available,
1153 DomainState* out) { 1300 DomainState* out) {
1154 DCHECK(CalledOnValidThread()); 1301 DCHECK(CalledOnValidThread());
1155 1302
1156 out->preloaded = true; 1303 out->preloaded = true;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 } 1370 }
1224 1371
1225 LOG(ERROR) << "Rejecting public key chain for domain " << domain 1372 LOG(ERROR) << "Rejecting public key chain for domain " << domain
1226 << ". Validated chain: " << HashesToBase64String(hashes) 1373 << ". Validated chain: " << HashesToBase64String(hashes)
1227 << ", expected: " << HashesToBase64String(public_key_hashes); 1374 << ", expected: " << HashesToBase64String(public_key_hashes);
1228 1375
1229 return false; 1376 return false;
1230 } 1377 }
1231 1378
1232 } // namespace 1379 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698