| 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 "net/base/transport_security_state.h" | 5 #include "net/base/transport_security_state.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 virtual void SetUp() { | 36 virtual void SetUp() { |
| 37 #if defined(USE_OPENSSL) | 37 #if defined(USE_OPENSSL) |
| 38 crypto::EnsureOpenSSLInit(); | 38 crypto::EnsureOpenSSLInit(); |
| 39 #else | 39 #else |
| 40 crypto::EnsureNSSInit(); | 40 crypto::EnsureNSSInit(); |
| 41 #endif | 41 #endif |
| 42 } | 42 } |
| 43 }; | 43 }; |
| 44 | 44 |
| 45 TEST_F(TransportSecurityStateTest, BogusHeaders) { | 45 TEST_F(TransportSecurityStateTest, BogusHeaders) { |
| 46 int max_age = 42; | 46 TransportSecurityState::DomainState state; |
| 47 bool include_subdomains = false; | 47 base::Time now = base::Time::Now(); |
| 48 | 48 |
| 49 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 49 EXPECT_FALSE(state.ParseSTSHeader(now, "")); |
| 50 "", &max_age, &include_subdomains)); | 50 EXPECT_FALSE(state.ParseSTSHeader(now, " ")); |
| 51 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 51 EXPECT_FALSE(state.ParseSTSHeader(now, "abc")); |
| 52 " ", &max_age, &include_subdomains)); | 52 EXPECT_FALSE(state.ParseSTSHeader(now, " abc")); |
| 53 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 53 EXPECT_FALSE(state.ParseSTSHeader(now, " abc ")); |
| 54 "abc", &max_age, &include_subdomains)); | 54 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age")); |
| 55 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 55 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age")); |
| 56 " abc", &max_age, &include_subdomains)); | 56 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age ")); |
| 57 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 57 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=")); |
| 58 " abc ", &max_age, &include_subdomains)); | 58 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age=")); |
| 59 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 59 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age =")); |
| 60 "max-age", &max_age, &include_subdomains)); | 60 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age= ")); |
| 61 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 61 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = ")); |
| 62 " max-age", &max_age, &include_subdomains)); | 62 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = xy")); |
| 63 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 63 EXPECT_FALSE(state.ParseSTSHeader(now, " max-age = 3488a923")); |
| 64 " max-age ", &max_age, &include_subdomains)); | 64 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488a923 ")); |
| 65 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 65 EXPECT_FALSE(state.ParseSTSHeader(now, "max-ag=3488923")); |
| 66 "max-age=", &max_age, &include_subdomains)); | 66 EXPECT_FALSE(state.ParseSTSHeader(now, "max-aged=3488923")); |
| 67 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 67 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age==3488923")); |
| 68 " max-age=", &max_age, &include_subdomains)); | 68 EXPECT_FALSE(state.ParseSTSHeader(now, "amax-age=3488923")); |
| 69 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 69 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=-3488923")); |
| 70 " max-age =", &max_age, &include_subdomains)); | 70 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923;")); |
| 71 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 71 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 e")); |
| 72 " max-age= ", &max_age, &include_subdomains)); | 72 EXPECT_FALSE(state.ParseSTSHeader( |
| 73 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 73 now, "max-age=3488923 includesubdomain")); |
| 74 " max-age = ", &max_age, &include_subdomains)); | 74 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923includesubdomains")); |
| 75 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 75 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923=includesubdomains")); |
| 76 " max-age = xy", &max_age, &include_subdomains)); | 76 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomainx")); |
| 77 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 77 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomain=")); |
| 78 " max-age = 3488a923", &max_age, &include_subdomains)); | 78 EXPECT_FALSE(state.ParseSTSHeader( |
| 79 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 79 now, "max-age=3488923 includesubdomain=true")); |
| 80 "max-age=3488a923 ", &max_age, &include_subdomains)); | 80 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=3488923 includesubdomainsx")); |
| 81 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 81 EXPECT_FALSE(state.ParseSTSHeader( |
| 82 "max-ag=3488923", &max_age, &include_subdomains)); | 82 now, "max-age=3488923 includesubdomains x")); |
| 83 EXPECT_FALSE(TransportSecurityState::ParseHeader( | 83 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889.23 includesubdomains")); |
| 84 "max-aged=3488923", &max_age, &include_subdomains)); | 84 EXPECT_FALSE(state.ParseSTSHeader(now, "max-age=34889 includesubdomains")); |
| 85 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 86 "max-age==3488923", &max_age, &include_subdomains)); | |
| 87 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 88 "amax-age=3488923", &max_age, &include_subdomains)); | |
| 89 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 90 "max-age=-3488923", &max_age, &include_subdomains)); | |
| 91 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 92 "max-age=3488923;", &max_age, &include_subdomains)); | |
| 93 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 94 "max-age=3488923 e", &max_age, &include_subdomains)); | |
| 95 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 96 "max-age=3488923 includesubdomain", &max_age, &include_subdomains)); | |
| 97 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 98 "max-age=3488923includesubdomains", &max_age, &include_subdomains)); | |
| 99 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 100 "max-age=3488923=includesubdomains", &max_age, &include_subdomains)); | |
| 101 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 102 "max-age=3488923 includesubdomainx", &max_age, &include_subdomains)); | |
| 103 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 104 "max-age=3488923 includesubdomain=", &max_age, &include_subdomains)); | |
| 105 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 106 "max-age=3488923 includesubdomain=true", &max_age, &include_subdomains)); | |
| 107 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 108 "max-age=3488923 includesubdomainsx", &max_age, &include_subdomains)); | |
| 109 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 110 "max-age=3488923 includesubdomains x", &max_age, &include_subdomains)); | |
| 111 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 112 "max-age=34889.23 includesubdomains", &max_age, &include_subdomains)); | |
| 113 EXPECT_FALSE(TransportSecurityState::ParseHeader( | |
| 114 "max-age=34889 includesubdomains", &max_age, &include_subdomains)); | |
| 115 | 85 |
| 116 EXPECT_EQ(max_age, 42); | 86 // Check that |state| was not updated by expecting the default |
| 117 EXPECT_FALSE(include_subdomains); | 87 // values for its predictable fields. |
| 88 EXPECT_EQ(state.upgrade_mode, |
| 89 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); |
| 90 EXPECT_FALSE(state.include_subdomains); |
| 91 } |
| 92 |
| 93 static bool GetPublicKeyHash(const net::X509Certificate::OSCertHandle& cert, |
| 94 SHA1Fingerprint* fingerprint) { |
| 95 std::string der_bytes; |
| 96 if (!net::X509Certificate::GetDEREncoded(cert, &der_bytes)) |
| 97 return false; |
| 98 |
| 99 base::StringPiece spki; |
| 100 if (!asn1::ExtractSPKIFromDERCert(der_bytes, &spki)) |
| 101 return false; |
| 102 |
| 103 base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(spki.data()), |
| 104 spki.size(), fingerprint->data); |
| 105 return true; |
| 118 } | 106 } |
| 119 | 107 |
| 120 static std::string GetPinFromCert(X509Certificate* cert) { | 108 static std::string GetPinFromCert(X509Certificate* cert) { |
| 121 SHA1Fingerprint spki_hash; | 109 SHA1Fingerprint spki_hash; |
| 122 if (!TransportSecurityState::GetPublicKeyHash(*cert, &spki_hash)) | 110 EXPECT_TRUE(GetPublicKeyHash(cert->os_cert_handle(), &spki_hash)); |
| 123 return ""; | 111 |
| 124 std::string base64; | 112 std::string base64; |
| 125 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data), | 113 base::Base64Encode(base::StringPiece(reinterpret_cast<char*>(spki_hash.data), |
| 126 sizeof(spki_hash.data)), | 114 sizeof(spki_hash.data)), |
| 127 &base64); | 115 &base64); |
| 128 return "pin-sha1=" + HttpUtil::Quote(base64); | 116 return "pin-sha1=" + HttpUtil::Quote(base64); |
| 129 } | 117 } |
| 130 | 118 |
| 131 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) { | 119 TEST_F(TransportSecurityStateTest, BogusPinsHeaders) { |
| 132 TransportSecurityState::DomainState state; | 120 TransportSecurityState::DomainState state; |
| 133 state.max_age = 42; | |
| 134 SSLInfo ssl_info; | 121 SSLInfo ssl_info; |
| 135 ssl_info.cert = | 122 ssl_info.cert = |
| 136 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); | 123 ImportCertFromFile(GetTestCertsDirectory(), "test_mail_google_com.pem"); |
| 137 std::string good_pin = GetPinFromCert(ssl_info.cert); | 124 std::string good_pin = GetPinFromCert(ssl_info.cert); |
| 125 base::Time now = base::Time::Now(); |
| 138 | 126 |
| 139 // The backup pin is fake --- it just has to not be in the chain. | 127 // The backup pin is fake --- it just has to not be in the chain. |
| 140 std::string backup_pin = "pin-sha1=" + | 128 std::string backup_pin = "pin-sha1=" + |
| 141 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); | 129 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); |
| 142 | 130 |
| 143 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 131 EXPECT_FALSE(state.ParsePinsHeader(now, "", ssl_info)); |
| 144 "", ssl_info, &state)); | 132 EXPECT_FALSE(state.ParsePinsHeader(now, " ", ssl_info)); |
| 145 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 133 EXPECT_FALSE(state.ParsePinsHeader(now, "abc", ssl_info)); |
| 146 " ", ssl_info, &state)); | 134 EXPECT_FALSE(state.ParsePinsHeader(now, " abc", ssl_info)); |
| 147 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 135 EXPECT_FALSE(state.ParsePinsHeader(now, " abc ", ssl_info)); |
| 148 "abc", ssl_info, &state)); | 136 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age", ssl_info)); |
| 149 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 137 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age", ssl_info)); |
| 150 " abc", ssl_info, &state)); | 138 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age ", ssl_info)); |
| 151 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 139 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=", ssl_info)); |
| 152 " abc ", ssl_info, &state)); | 140 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age=", ssl_info)); |
| 153 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 141 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age =", ssl_info)); |
| 154 "max-age", ssl_info, &state)); | 142 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age= ", ssl_info)); |
| 155 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 143 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age = ", ssl_info)); |
| 156 " max-age", ssl_info, &state)); | 144 EXPECT_FALSE(state.ParsePinsHeader(now, " max-age = xy", ssl_info)); |
| 157 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 145 EXPECT_FALSE(state.ParsePinsHeader( |
| 158 " max-age ", ssl_info, &state)); | 146 now, |
| 159 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 147 " max-age = 3488a923", |
| 160 "max-age=", ssl_info, &state)); | 148 ssl_info)); |
| 161 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 149 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488a923 ", ssl_info)); |
| 162 " max-age=", ssl_info, &state)); | 150 EXPECT_FALSE(state.ParsePinsHeader(now, |
| 163 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 164 " max-age =", ssl_info, &state)); | |
| 165 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 166 " max-age= ", ssl_info, &state)); | |
| 167 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 168 " max-age = ", ssl_info, &state)); | |
| 169 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 170 " max-age = xy", ssl_info, &state)); | |
| 171 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 172 " max-age = 3488a923", ssl_info, &state)); | |
| 173 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 174 "max-age=3488a923 ", ssl_info, &state)); | |
| 175 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 176 "max-ag=3488923pins=" + good_pin + "," + backup_pin, | 151 "max-ag=3488923pins=" + good_pin + "," + backup_pin, |
| 177 ssl_info, &state)); | 152 ssl_info)); |
| 178 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 153 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923" + backup_pin, |
| 179 "max-aged=3488923" + backup_pin, | 154 ssl_info)); |
| 180 ssl_info, &state)); | 155 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923; " + backup_pin, |
| 181 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 156 ssl_info)); |
| 182 "max-aged=3488923; " + backup_pin, | 157 EXPECT_FALSE(state.ParsePinsHeader(now, |
| 183 ssl_info, &state)); | |
| 184 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 185 "max-aged=3488923; " + backup_pin + ";" + backup_pin, | 158 "max-aged=3488923; " + backup_pin + ";" + backup_pin, |
| 186 ssl_info, &state)); | 159 ssl_info)); |
| 187 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 160 EXPECT_FALSE(state.ParsePinsHeader(now, |
| 188 "max-aged=3488923; " + good_pin + ";" + good_pin, | 161 "max-aged=3488923; " + good_pin + ";" + good_pin, |
| 189 ssl_info, &state)); | 162 ssl_info)); |
| 190 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 163 EXPECT_FALSE(state.ParsePinsHeader(now, "max-aged=3488923; " + good_pin, |
| 191 "max-aged=3488923; " + good_pin, | 164 ssl_info)); |
| 192 ssl_info, &state)); | 165 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age==3488923", ssl_info)); |
| 193 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 166 EXPECT_FALSE(state.ParsePinsHeader(now, "amax-age=3488923", ssl_info)); |
| 194 "max-age==3488923", ssl_info, &state)); | 167 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=-3488923", ssl_info)); |
| 195 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 168 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488923;", ssl_info)); |
| 196 "amax-age=3488923", ssl_info, &state)); | 169 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=3488923 e", ssl_info)); |
| 197 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 170 EXPECT_FALSE(state.ParsePinsHeader( |
| 198 "max-age=-3488923", ssl_info, &state)); | 171 now, |
| 199 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 172 "max-age=3488923 includesubdomain", |
| 200 "max-age=3488923;", ssl_info, &state)); | 173 ssl_info)); |
| 201 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | 174 EXPECT_FALSE(state.ParsePinsHeader(now, "max-age=34889.23", ssl_info)); |
| 202 "max-age=3488923 e", ssl_info, &state)); | |
| 203 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 204 "max-age=3488923 includesubdomain", ssl_info, &state)); | |
| 205 EXPECT_FALSE(TransportSecurityState::ParsePinsHeader( | |
| 206 "max-age=34889.23", ssl_info, &state)); | |
| 207 | 175 |
| 208 EXPECT_EQ(state.max_age, 42); | 176 // Check that |state| was not updated by expecting the default |
| 177 // values for its predictable fields. |
| 178 EXPECT_EQ(state.upgrade_mode, |
| 179 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); |
| 180 EXPECT_FALSE(state.include_subdomains); |
| 209 } | 181 } |
| 210 | 182 |
| 211 TEST_F(TransportSecurityStateTest, ValidHeaders) { | 183 TEST_F(TransportSecurityStateTest, ValidSTSHeaders) { |
| 212 int max_age = 42; | 184 TransportSecurityState::DomainState state; |
| 213 bool include_subdomains = true; | 185 base::Time expiry; |
| 186 base::Time now = base::Time::Now(); |
| 214 | 187 |
| 215 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 188 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=243")); |
| 216 "max-age=243", &max_age, &include_subdomains)); | 189 expiry = now + base::TimeDelta::FromSeconds(243); |
| 217 EXPECT_EQ(max_age, 243); | 190 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 218 EXPECT_FALSE(include_subdomains); | 191 EXPECT_FALSE(state.include_subdomains); |
| 219 | 192 |
| 220 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 193 EXPECT_TRUE(state.ParseSTSHeader(now, " Max-agE = 567")); |
| 221 " Max-agE = 567", &max_age, &include_subdomains)); | 194 expiry = now + base::TimeDelta::FromSeconds(567); |
| 222 EXPECT_EQ(max_age, 567); | 195 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 223 EXPECT_FALSE(include_subdomains); | 196 EXPECT_FALSE(state.include_subdomains); |
| 224 | 197 |
| 225 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 198 EXPECT_TRUE(state.ParseSTSHeader(now, " mAx-aGe = 890 ")); |
| 226 " mAx-aGe = 890 ", &max_age, &include_subdomains)); | 199 expiry = now + base::TimeDelta::FromSeconds(890); |
| 227 EXPECT_EQ(max_age, 890); | 200 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 228 EXPECT_FALSE(include_subdomains); | 201 EXPECT_FALSE(state.include_subdomains); |
| 229 | 202 |
| 230 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 203 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=123;incLudesUbdOmains")); |
| 231 "max-age=123;incLudesUbdOmains", &max_age, &include_subdomains)); | 204 expiry = now + base::TimeDelta::FromSeconds(123); |
| 232 EXPECT_EQ(max_age, 123); | 205 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 233 EXPECT_TRUE(include_subdomains); | 206 EXPECT_TRUE(state.include_subdomains); |
| 234 | 207 |
| 235 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 208 EXPECT_TRUE(state.ParseSTSHeader(now, "max-age=394082; incLudesUbdOmains")); |
| 236 "max-age=394082; incLudesUbdOmains", &max_age, &include_subdomains)); | 209 expiry = now + base::TimeDelta::FromSeconds(394082); |
| 237 EXPECT_EQ(max_age, 394082); | 210 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 238 EXPECT_TRUE(include_subdomains); | 211 EXPECT_TRUE(state.include_subdomains); |
| 239 | 212 |
| 240 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 213 EXPECT_TRUE(state.ParseSTSHeader( |
| 241 "max-age=39408299 ;incLudesUbdOmains", &max_age, &include_subdomains)); | 214 now, "max-age=39408299 ;incLudesUbdOmains")); |
| 242 EXPECT_EQ(max_age, | 215 expiry = now + base::TimeDelta::FromSeconds( |
| 243 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); | 216 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); |
| 244 EXPECT_TRUE(include_subdomains); | 217 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 218 EXPECT_TRUE(state.include_subdomains); |
| 245 | 219 |
| 246 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 220 EXPECT_TRUE(state.ParseSTSHeader( |
| 247 "max-age=394082038 ; incLudesUbdOmains", &max_age, | 221 now, "max-age=394082038 ; incLudesUbdOmains")); |
| 248 &include_subdomains)); | 222 expiry = now + base::TimeDelta::FromSeconds( |
| 249 EXPECT_EQ(max_age, | 223 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); |
| 250 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); | 224 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 251 EXPECT_TRUE(include_subdomains); | 225 EXPECT_TRUE(state.include_subdomains); |
| 252 | 226 |
| 253 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 227 EXPECT_TRUE(state.ParseSTSHeader( |
| 254 " max-age=0 ; incLudesUbdOmains ", &max_age, &include_subdomains)); | 228 now, " max-age=0 ; incLudesUbdOmains ")); |
| 255 EXPECT_EQ(max_age, 0); | 229 expiry = now + base::TimeDelta::FromSeconds(0); |
| 256 EXPECT_TRUE(include_subdomains); | 230 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 231 EXPECT_TRUE(state.include_subdomains); |
| 257 | 232 |
| 258 EXPECT_TRUE(TransportSecurityState::ParseHeader( | 233 EXPECT_TRUE(state.ParseSTSHeader( |
| 234 now, |
| 259 " max-age=999999999999999999999999999999999999999999999 ;" | 235 " max-age=999999999999999999999999999999999999999999999 ;" |
| 260 " incLudesUbdOmains ", | 236 " incLudesUbdOmains ")); |
| 261 &max_age, &include_subdomains)); | 237 expiry = now + base::TimeDelta::FromSeconds( |
| 262 EXPECT_EQ(max_age, TransportSecurityState::kMaxHSTSAgeSecs); | 238 TransportSecurityState::kMaxHSTSAgeSecs); |
| 263 EXPECT_TRUE(include_subdomains); | 239 EXPECT_EQ(expiry, state.upgrade_expiry); |
| 240 EXPECT_TRUE(state.include_subdomains); |
| 264 } | 241 } |
| 265 | 242 |
| 266 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) { | 243 TEST_F(TransportSecurityStateTest, ValidPinsHeaders) { |
| 267 TransportSecurityState::DomainState state; | 244 TransportSecurityState::DomainState state; |
| 268 state.max_age = 42; | 245 base::Time expiry; |
| 246 base::Time now = base::Time::Now(); |
| 269 | 247 |
| 270 // Set up a realistic SSLInfo with a realistic cert chain. | 248 // Set up a realistic SSLInfo with a realistic cert chain. |
| 271 FilePath certs_dir = GetTestCertsDirectory(); | 249 FilePath certs_dir = GetTestCertsDirectory(); |
| 272 scoped_refptr<X509Certificate> ee_cert = | 250 scoped_refptr<X509Certificate> ee_cert = |
| 273 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); | 251 ImportCertFromFile(certs_dir, "2048-rsa-ee-by-2048-rsa-intermediate.pem"); |
| 274 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); | 252 ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert); |
| 275 scoped_refptr<X509Certificate> intermediate = | 253 scoped_refptr<X509Certificate> intermediate = |
| 276 ImportCertFromFile(certs_dir, "2048-rsa-intermediate.pem"); | 254 ImportCertFromFile(certs_dir, "2048-rsa-intermediate.pem"); |
| 277 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); | 255 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate); |
| 278 X509Certificate::OSCertHandles intermediates; | 256 X509Certificate::OSCertHandles intermediates; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 302 // Normally, ssl_client_socket_nss would do this, but for a unit test we | 280 // Normally, ssl_client_socket_nss would do this, but for a unit test we |
| 303 // fake it. | 281 // fake it. |
| 304 ssl_info.public_key_hashes = result.public_key_hashes; | 282 ssl_info.public_key_hashes = result.public_key_hashes; |
| 305 std::string good_pin = GetPinFromCert(ssl_info.cert); | 283 std::string good_pin = GetPinFromCert(ssl_info.cert); |
| 306 | 284 |
| 307 // The backup pin is fake --- we just need an SPKI hash that does not match | 285 // The backup pin is fake --- we just need an SPKI hash that does not match |
| 308 // the hash of any SPKI in the certificate chain. | 286 // the hash of any SPKI in the certificate chain. |
| 309 std::string backup_pin = "pin-sha1=" + | 287 std::string backup_pin = "pin-sha1=" + |
| 310 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); | 288 HttpUtil::Quote("6dcfXufJLW3J6S/9rRe4vUlBj5g="); |
| 311 | 289 |
| 312 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 290 EXPECT_TRUE(state.ParsePinsHeader( |
| 291 now, |
| 313 "max-age=243; " + good_pin + ";" + backup_pin, | 292 "max-age=243; " + good_pin + ";" + backup_pin, |
| 314 ssl_info, &state)); | 293 ssl_info)); |
| 315 EXPECT_EQ(state.max_age, 243); | 294 expiry = now + base::TimeDelta::FromSeconds(243); |
| 295 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 316 | 296 |
| 317 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 297 EXPECT_TRUE(state.ParsePinsHeader( |
| 298 now, |
| 318 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567", | 299 " " + good_pin + "; " + backup_pin + " ; Max-agE = 567", |
| 319 ssl_info, &state)); | 300 ssl_info)); |
| 320 EXPECT_EQ(state.max_age, 567); | 301 expiry = now + base::TimeDelta::FromSeconds(567); |
| 302 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 321 | 303 |
| 322 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 304 EXPECT_TRUE(state.ParsePinsHeader( |
| 305 now, |
| 323 good_pin + ";" + backup_pin + " ; mAx-aGe = 890 ", | 306 good_pin + ";" + backup_pin + " ; mAx-aGe = 890 ", |
| 324 ssl_info, &state)); | 307 ssl_info)); |
| 325 EXPECT_EQ(state.max_age, 890); | 308 expiry = now + base::TimeDelta::FromSeconds(890); |
| 309 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 326 | 310 |
| 327 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 311 EXPECT_TRUE(state.ParsePinsHeader( |
| 312 now, |
| 328 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", | 313 good_pin + ";" + backup_pin + "; max-age=123;IGNORED;", |
| 329 ssl_info, &state)); | 314 ssl_info)); |
| 330 EXPECT_EQ(state.max_age, 123); | 315 expiry = now + base::TimeDelta::FromSeconds(123); |
| 316 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 331 | 317 |
| 332 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 318 EXPECT_TRUE(state.ParsePinsHeader( |
| 319 now, |
| 333 "max-age=394082;" + backup_pin + ";" + good_pin + "; ", | 320 "max-age=394082;" + backup_pin + ";" + good_pin + "; ", |
| 334 ssl_info, &state)); | 321 ssl_info)); |
| 335 EXPECT_EQ(state.max_age, 394082); | 322 expiry = now + base::TimeDelta::FromSeconds(394082); |
| 323 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 336 | 324 |
| 337 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 325 EXPECT_TRUE(state.ParsePinsHeader( |
| 326 now, |
| 338 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", | 327 "max-age=39408299 ;" + backup_pin + ";" + good_pin + "; ", |
| 339 ssl_info, &state)); | 328 ssl_info)); |
| 340 EXPECT_EQ(state.max_age, | 329 expiry = now + base::TimeDelta::FromSeconds( |
| 341 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); | 330 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 39408299l)); |
| 331 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 342 | 332 |
| 343 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 333 EXPECT_TRUE(state.ParsePinsHeader( |
| 334 now, |
| 344 "max-age=39408038 ; cybers=39408038 ; " + | 335 "max-age=39408038 ; cybers=39408038 ; " + |
| 345 good_pin + ";" + backup_pin + "; ", | 336 good_pin + ";" + backup_pin + "; ", |
| 346 ssl_info, &state)); | 337 ssl_info)); |
| 347 EXPECT_EQ(state.max_age, | 338 expiry = now + base::TimeDelta::FromSeconds( |
| 348 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); | 339 std::min(TransportSecurityState::kMaxHSTSAgeSecs, 394082038l)); |
| 340 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 349 | 341 |
| 350 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 342 EXPECT_TRUE(state.ParsePinsHeader( |
| 343 now, |
| 351 " max-age=0 ; " + good_pin + ";" + backup_pin, | 344 " max-age=0 ; " + good_pin + ";" + backup_pin, |
| 352 ssl_info, &state)); | 345 ssl_info)); |
| 353 EXPECT_EQ(state.max_age, 0); | 346 expiry = now + base::TimeDelta::FromSeconds(0); |
| 347 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 354 | 348 |
| 355 EXPECT_TRUE(TransportSecurityState::ParsePinsHeader( | 349 EXPECT_TRUE(state.ParsePinsHeader( |
| 350 now, |
| 356 " max-age=999999999999999999999999999999999999999999999 ; " + | 351 " max-age=999999999999999999999999999999999999999999999 ; " + |
| 357 backup_pin + ";" + good_pin + "; ", | 352 backup_pin + ";" + good_pin + "; ", |
| 358 ssl_info, &state)); | 353 ssl_info)); |
| 359 EXPECT_EQ(state.max_age, TransportSecurityState::kMaxHSTSAgeSecs); | 354 expiry = now + |
| 355 base::TimeDelta::FromSeconds(TransportSecurityState::kMaxHSTSAgeSecs); |
| 356 EXPECT_EQ(expiry, state.dynamic_spki_hashes_expiry); |
| 360 } | 357 } |
| 361 | 358 |
| 362 TEST_F(TransportSecurityStateTest, SimpleMatches) { | 359 TEST_F(TransportSecurityStateTest, SimpleMatches) { |
| 363 TransportSecurityState state(""); | 360 TransportSecurityState state; |
| 364 TransportSecurityState::DomainState domain_state; | 361 TransportSecurityState::DomainState domain_state; |
| 365 const base::Time current_time(base::Time::Now()); | 362 const base::Time current_time(base::Time::Now()); |
| 366 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 363 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 367 | 364 |
| 368 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 365 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 369 domain_state.expiry = expiry; | 366 domain_state.upgrade_expiry = expiry; |
| 370 state.EnableHost("yahoo.com", domain_state); | 367 state.EnableHost("yahoo.com", domain_state); |
| 371 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 368 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 372 } | 369 } |
| 373 | 370 |
| 374 TEST_F(TransportSecurityStateTest, MatchesCase1) { | 371 TEST_F(TransportSecurityStateTest, MatchesCase1) { |
| 375 TransportSecurityState state(""); | 372 TransportSecurityState state; |
| 376 TransportSecurityState::DomainState domain_state; | 373 TransportSecurityState::DomainState domain_state; |
| 377 const base::Time current_time(base::Time::Now()); | 374 const base::Time current_time(base::Time::Now()); |
| 378 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 375 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 379 | 376 |
| 380 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 377 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 381 domain_state.expiry = expiry; | 378 domain_state.upgrade_expiry = expiry; |
| 382 state.EnableHost("YAhoo.coM", domain_state); | 379 state.EnableHost("YAhoo.coM", domain_state); |
| 383 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 380 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 384 } | 381 } |
| 385 | 382 |
| 386 TEST_F(TransportSecurityStateTest, MatchesCase2) { | 383 TEST_F(TransportSecurityStateTest, MatchesCase2) { |
| 387 TransportSecurityState state(""); | 384 TransportSecurityState state; |
| 388 TransportSecurityState::DomainState domain_state; | 385 TransportSecurityState::DomainState domain_state; |
| 389 const base::Time current_time(base::Time::Now()); | 386 const base::Time current_time(base::Time::Now()); |
| 390 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 387 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 391 | 388 |
| 392 EXPECT_FALSE(state.GetDomainState(&domain_state, "YAhoo.coM", true)); | 389 EXPECT_FALSE(state.GetDomainState("YAhoo.coM", true, &domain_state)); |
| 393 domain_state.expiry = expiry; | 390 domain_state.upgrade_expiry = expiry; |
| 394 state.EnableHost("yahoo.com", domain_state); | 391 state.EnableHost("yahoo.com", domain_state); |
| 395 EXPECT_TRUE(state.GetDomainState(&domain_state, "YAhoo.coM", true)); | 392 EXPECT_TRUE(state.GetDomainState("YAhoo.coM", true, &domain_state)); |
| 396 } | 393 } |
| 397 | 394 |
| 398 TEST_F(TransportSecurityStateTest, SubdomainMatches) { | 395 TEST_F(TransportSecurityStateTest, SubdomainMatches) { |
| 399 TransportSecurityState state(""); | 396 TransportSecurityState state; |
| 400 TransportSecurityState::DomainState domain_state; | 397 TransportSecurityState::DomainState domain_state; |
| 401 const base::Time current_time(base::Time::Now()); | 398 const base::Time current_time(base::Time::Now()); |
| 402 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 399 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 403 | 400 |
| 404 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 401 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 405 domain_state.expiry = expiry; | 402 domain_state.upgrade_expiry = expiry; |
| 406 domain_state.include_subdomains = true; | 403 domain_state.include_subdomains = true; |
| 407 state.EnableHost("yahoo.com", domain_state); | 404 state.EnableHost("yahoo.com", domain_state); |
| 408 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 405 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 409 EXPECT_TRUE(state.GetDomainState(&domain_state, "foo.yahoo.com", true)); | 406 EXPECT_TRUE(state.GetDomainState("foo.yahoo.com", true, &domain_state)); |
| 410 EXPECT_TRUE(state.GetDomainState(&domain_state, | 407 EXPECT_TRUE(state.GetDomainState("foo.bar.yahoo.com", true, &domain_state)); |
| 411 "foo.bar.yahoo.com", | 408 EXPECT_TRUE(state.GetDomainState("foo.bar.baz.yahoo.com", true, |
| 412 true)); | 409 &domain_state)); |
| 413 EXPECT_TRUE(state.GetDomainState(&domain_state, | 410 EXPECT_FALSE(state.GetDomainState("com", true, &domain_state)); |
| 414 "foo.bar.baz.yahoo.com", | |
| 415 true)); | |
| 416 EXPECT_FALSE(state.GetDomainState(&domain_state, "com", true)); | |
| 417 } | |
| 418 | |
| 419 TEST_F(TransportSecurityStateTest, Serialise1) { | |
| 420 TransportSecurityState state(""); | |
| 421 std::string output; | |
| 422 bool dirty; | |
| 423 state.Serialise(&output); | |
| 424 EXPECT_TRUE(state.LoadEntries(output, &dirty)); | |
| 425 EXPECT_FALSE(dirty); | |
| 426 } | |
| 427 | |
| 428 TEST_F(TransportSecurityStateTest, Serialise2) { | |
| 429 TransportSecurityState state(""); | |
| 430 TransportSecurityState::DomainState domain_state; | |
| 431 const base::Time current_time(base::Time::Now()); | |
| 432 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | |
| 433 | |
| 434 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | |
| 435 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; | |
| 436 domain_state.expiry = expiry; | |
| 437 domain_state.include_subdomains = true; | |
| 438 state.EnableHost("yahoo.com", domain_state); | |
| 439 | |
| 440 std::string output; | |
| 441 bool dirty; | |
| 442 state.Serialise(&output); | |
| 443 EXPECT_TRUE(state.LoadEntries(output, &dirty)); | |
| 444 | |
| 445 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | |
| 446 EXPECT_EQ(domain_state.mode, | |
| 447 TransportSecurityState::DomainState::MODE_STRICT); | |
| 448 EXPECT_TRUE(state.GetDomainState(&domain_state, "foo.yahoo.com", true)); | |
| 449 EXPECT_EQ(domain_state.mode, | |
| 450 TransportSecurityState::DomainState::MODE_STRICT); | |
| 451 EXPECT_TRUE(state.GetDomainState(&domain_state, | |
| 452 "foo.bar.yahoo.com", | |
| 453 true)); | |
| 454 EXPECT_EQ(domain_state.mode, | |
| 455 TransportSecurityState::DomainState::MODE_STRICT); | |
| 456 EXPECT_TRUE(state.GetDomainState(&domain_state, | |
| 457 "foo.bar.baz.yahoo.com", | |
| 458 true)); | |
| 459 EXPECT_EQ(domain_state.mode, | |
| 460 TransportSecurityState::DomainState::MODE_STRICT); | |
| 461 EXPECT_FALSE(state.GetDomainState(&domain_state, "com", true)); | |
| 462 } | 411 } |
| 463 | 412 |
| 464 TEST_F(TransportSecurityStateTest, DeleteSince) { | 413 TEST_F(TransportSecurityStateTest, DeleteSince) { |
| 465 TransportSecurityState state(""); | 414 TransportSecurityState state; |
| 466 TransportSecurityState::DomainState domain_state; | 415 TransportSecurityState::DomainState domain_state; |
| 467 const base::Time current_time(base::Time::Now()); | 416 const base::Time current_time(base::Time::Now()); |
| 468 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 417 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 469 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); | 418 const base::Time older = current_time - base::TimeDelta::FromSeconds(1000); |
| 470 | 419 |
| 471 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 420 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 472 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; | 421 domain_state.upgrade_mode = |
| 473 domain_state.expiry = expiry; | 422 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 423 domain_state.upgrade_expiry = expiry; |
| 474 state.EnableHost("yahoo.com", domain_state); | 424 state.EnableHost("yahoo.com", domain_state); |
| 475 | 425 |
| 476 state.DeleteSince(expiry); | 426 state.DeleteSince(expiry); |
| 477 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 427 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 478 state.DeleteSince(older); | 428 state.DeleteSince(older); |
| 479 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 429 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 480 } | 430 } |
| 481 | 431 |
| 482 TEST_F(TransportSecurityStateTest, DeleteHost) { | 432 TEST_F(TransportSecurityStateTest, DeleteHost) { |
| 483 TransportSecurityState state(""); | 433 TransportSecurityState state; |
| 484 TransportSecurityState::DomainState domain_state; | 434 TransportSecurityState::DomainState domain_state; |
| 485 const base::Time current_time(base::Time::Now()); | 435 const base::Time current_time(base::Time::Now()); |
| 486 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 436 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 487 domain_state.mode = TransportSecurityState::DomainState::MODE_STRICT; | 437 domain_state.upgrade_mode = |
| 488 domain_state.expiry = expiry; | 438 TransportSecurityState::DomainState::MODE_FORCE_HTTPS; |
| 439 domain_state.upgrade_expiry = expiry; |
| 489 state.EnableHost("yahoo.com", domain_state); | 440 state.EnableHost("yahoo.com", domain_state); |
| 490 | 441 |
| 491 EXPECT_TRUE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 442 EXPECT_TRUE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 492 EXPECT_FALSE(state.GetDomainState(&domain_state, "example.com", true)); | 443 EXPECT_FALSE(state.GetDomainState("example.com", true, &domain_state)); |
| 493 EXPECT_TRUE(state.DeleteHost("yahoo.com")); | 444 EXPECT_TRUE(state.DeleteHost("yahoo.com")); |
| 494 EXPECT_FALSE(state.GetDomainState(&domain_state, "yahoo.com", true)); | 445 EXPECT_FALSE(state.GetDomainState("yahoo.com", true, &domain_state)); |
| 495 } | |
| 496 | |
| 497 TEST_F(TransportSecurityStateTest, SerialiseOld) { | |
| 498 TransportSecurityState state(""); | |
| 499 // This is an old-style piece of transport state JSON, which has no creation | |
| 500 // date. | |
| 501 std::string output = | |
| 502 "{ " | |
| 503 "\"NiyD+3J1r6z1wjl2n1ALBu94Zj9OsEAMo0kCN8js0Uk=\": {" | |
| 504 "\"expiry\": 1266815027.983453, " | |
| 505 "\"include_subdomains\": false, " | |
| 506 "\"mode\": \"strict\" " | |
| 507 "}" | |
| 508 "}"; | |
| 509 bool dirty; | |
| 510 EXPECT_TRUE(state.LoadEntries(output, &dirty)); | |
| 511 EXPECT_TRUE(dirty); | |
| 512 } | 446 } |
| 513 | 447 |
| 514 TEST_F(TransportSecurityStateTest, IsPreloaded) { | 448 TEST_F(TransportSecurityStateTest, IsPreloaded) { |
| 515 TransportSecurityState state(""); | |
| 516 | |
| 517 const std::string paypal = | 449 const std::string paypal = |
| 518 TransportSecurityState::CanonicalizeHost("paypal.com"); | 450 TransportSecurityState::CanonicalizeHost("paypal.com"); |
| 519 const std::string www_paypal = | 451 const std::string www_paypal = |
| 520 TransportSecurityState::CanonicalizeHost("www.paypal.com"); | 452 TransportSecurityState::CanonicalizeHost("www.paypal.com"); |
| 521 const std::string a_www_paypal = | 453 const std::string a_www_paypal = |
| 522 TransportSecurityState::CanonicalizeHost("a.www.paypal.com"); | 454 TransportSecurityState::CanonicalizeHost("a.www.paypal.com"); |
| 523 const std::string abc_paypal = | 455 const std::string abc_paypal = |
| 524 TransportSecurityState::CanonicalizeHost("a.b.c.paypal.com"); | 456 TransportSecurityState::CanonicalizeHost("a.b.c.paypal.com"); |
| 525 const std::string example = | 457 const std::string example = |
| 526 TransportSecurityState::CanonicalizeHost("example.com"); | 458 TransportSecurityState::CanonicalizeHost("example.com"); |
| 527 const std::string aypal = | 459 const std::string aypal = |
| 528 TransportSecurityState::CanonicalizeHost("aypal.com"); | 460 TransportSecurityState::CanonicalizeHost("aypal.com"); |
| 529 | 461 |
| 462 TransportSecurityState state; |
| 530 TransportSecurityState::DomainState domain_state; | 463 TransportSecurityState::DomainState domain_state; |
| 531 EXPECT_FALSE(state.IsPreloadedSTS(paypal, true, &domain_state)); | 464 |
| 532 EXPECT_TRUE(state.IsPreloadedSTS(www_paypal, true, &domain_state)); | 465 EXPECT_FALSE(state.GetStaticDomainState(paypal, true, &domain_state)); |
| 466 EXPECT_TRUE(state.GetStaticDomainState(www_paypal, true, &domain_state)); |
| 533 EXPECT_FALSE(domain_state.include_subdomains); | 467 EXPECT_FALSE(domain_state.include_subdomains); |
| 534 EXPECT_FALSE(state.IsPreloadedSTS(a_www_paypal, true, &domain_state)); | 468 EXPECT_FALSE(state.GetStaticDomainState(a_www_paypal, true, &domain_state)); |
| 535 EXPECT_FALSE(state.IsPreloadedSTS(abc_paypal, true, &domain_state)); | 469 EXPECT_FALSE(state.GetStaticDomainState(abc_paypal, true, &domain_state)); |
| 536 EXPECT_FALSE(state.IsPreloadedSTS(example, true, &domain_state)); | 470 EXPECT_FALSE(state.GetStaticDomainState(example, true, &domain_state)); |
| 537 EXPECT_FALSE(state.IsPreloadedSTS(aypal, true, &domain_state)); | 471 EXPECT_FALSE(state.GetStaticDomainState(aypal, true, &domain_state)); |
| 538 } | 472 } |
| 539 | 473 |
| 540 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) { | 474 TEST_F(TransportSecurityStateTest, PreloadedDomainSet) { |
| 541 TransportSecurityState state(""); | 475 TransportSecurityState state; |
| 542 TransportSecurityState::DomainState domain_state; | 476 TransportSecurityState::DomainState domain_state; |
| 543 | 477 |
| 544 // The domain wasn't being set, leading to a blank string in the | 478 // The domain wasn't being set, leading to a blank string in the |
| 545 // chrome://net-internals/#hsts UI. So test that. | 479 // chrome://net-internals/#hsts UI. So test that. |
| 546 EXPECT_TRUE(state.GetDomainState(&domain_state, | 480 EXPECT_TRUE(state.GetDomainState("market.android.com", true, &domain_state)); |
| 547 "market.android.com", | |
| 548 true)); | |
| 549 EXPECT_EQ(domain_state.domain, "market.android.com"); | 481 EXPECT_EQ(domain_state.domain, "market.android.com"); |
| 550 EXPECT_TRUE(state.GetDomainState(&domain_state, | 482 EXPECT_TRUE(state.GetDomainState("sub.market.android.com", true, |
| 551 "sub.market.android.com", | 483 &domain_state)); |
| 552 true)); | |
| 553 EXPECT_EQ(domain_state.domain, "market.android.com"); | 484 EXPECT_EQ(domain_state.domain, "market.android.com"); |
| 554 } | 485 } |
| 555 | 486 |
| 556 static bool ShouldRedirect(const char* hostname) { | 487 static bool ShouldRedirect(const char* hostname) { |
| 557 TransportSecurityState state(""); | 488 TransportSecurityState state; |
| 558 TransportSecurityState::DomainState domain_state; | 489 TransportSecurityState::DomainState domain_state; |
| 559 return state.GetDomainState(&domain_state, hostname, true /* SNI ok */) && | 490 return state.GetDomainState(hostname, true /* SNI ok */, &domain_state) && |
| 560 domain_state.ShouldRedirectHTTPToHTTPS(); | 491 domain_state.ShouldRedirectHTTPToHTTPS(); |
| 561 } | 492 } |
| 562 | 493 |
| 563 static bool HasState(const char *hostname) { | 494 static bool HasState(const char* hostname) { |
| 564 TransportSecurityState state(""); | 495 TransportSecurityState state; |
| 565 TransportSecurityState::DomainState domain_state; | 496 TransportSecurityState::DomainState domain_state; |
| 566 return state.GetDomainState(&domain_state, hostname, true /* SNI ok */); | 497 return state.GetDomainState(hostname, true /* SNI ok */, &domain_state); |
| 567 } | 498 } |
| 568 | 499 |
| 569 static bool HasPins(const char *hostname) { | 500 static bool HasPins(const char* hostname, bool sni_enabled) { |
| 570 TransportSecurityState state(""); | 501 TransportSecurityState state; |
| 571 TransportSecurityState::DomainState domain_state; | 502 TransportSecurityState::DomainState domain_state; |
| 572 return state.HasPinsForHost(&domain_state, hostname, true /* SNI ok */); | 503 if (!state.GetDomainState(hostname, sni_enabled, &domain_state)) |
| 504 return false; |
| 505 |
| 506 return domain_state.HasPins(); |
| 507 } |
| 508 |
| 509 static bool HasPins(const char* hostname) { |
| 510 return HasPins(hostname, true); |
| 573 } | 511 } |
| 574 | 512 |
| 575 static bool OnlyPinning(const char *hostname) { | 513 static bool OnlyPinning(const char *hostname) { |
| 576 TransportSecurityState state(""); | 514 TransportSecurityState state; |
| 577 TransportSecurityState::DomainState domain_state; | 515 TransportSecurityState::DomainState domain_state; |
| 578 return state.HasPinsForHost(&domain_state, hostname, true /* SNI ok */) && | 516 if (!state.GetDomainState(hostname, true /* SNI ok */, &domain_state)) |
| 517 return false; |
| 518 |
| 519 return (domain_state.static_spki_hashes.size() > 0 || |
| 520 domain_state.bad_static_spki_hashes.size() > 0 || |
| 521 domain_state.dynamic_spki_hashes.size() > 0) && |
| 579 !domain_state.ShouldRedirectHTTPToHTTPS(); | 522 !domain_state.ShouldRedirectHTTPToHTTPS(); |
| 580 } | 523 } |
| 581 | 524 |
| 582 TEST_F(TransportSecurityStateTest, Preloaded) { | 525 TEST_F(TransportSecurityStateTest, Preloaded) { |
| 583 TransportSecurityState state(""); | 526 TransportSecurityState state; |
| 584 TransportSecurityState::DomainState domain_state; | 527 TransportSecurityState::DomainState domain_state; |
| 585 | 528 |
| 586 // We do more extensive checks for the first domain. | 529 // We do more extensive checks for the first domain. |
| 587 EXPECT_TRUE(state.GetDomainState(&domain_state, "www.paypal.com", true)); | 530 EXPECT_TRUE(state.GetDomainState("www.paypal.com", true, &domain_state)); |
| 588 EXPECT_EQ(domain_state.mode, | 531 EXPECT_EQ(domain_state.upgrade_mode, |
| 589 TransportSecurityState::DomainState::MODE_STRICT); | 532 TransportSecurityState::DomainState::MODE_FORCE_HTTPS); |
| 590 EXPECT_TRUE(domain_state.preloaded); | |
| 591 EXPECT_FALSE(domain_state.include_subdomains); | 533 EXPECT_FALSE(domain_state.include_subdomains); |
| 592 | 534 |
| 593 EXPECT_FALSE(HasState("paypal.com")); | 535 EXPECT_FALSE(HasState("paypal.com")); |
| 594 EXPECT_FALSE(HasState("www2.paypal.com")); | 536 EXPECT_FALSE(HasState("www2.paypal.com")); |
| 595 EXPECT_FALSE(HasState("www2.paypal.com")); | 537 EXPECT_FALSE(HasState("www2.paypal.com")); |
| 596 | 538 |
| 597 // Google hosts: | 539 // Google hosts: |
| 598 | 540 |
| 599 EXPECT_TRUE(ShouldRedirect("chrome.google.com")); | 541 EXPECT_TRUE(ShouldRedirect("chrome.google.com")); |
| 600 EXPECT_TRUE(ShouldRedirect("checkout.google.com")); | 542 EXPECT_TRUE(ShouldRedirect("checkout.google.com")); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 EXPECT_TRUE(OnlyPinning("www.google-analytics.com")); | 581 EXPECT_TRUE(OnlyPinning("www.google-analytics.com")); |
| 640 EXPECT_TRUE(OnlyPinning("googleapis.com")); | 582 EXPECT_TRUE(OnlyPinning("googleapis.com")); |
| 641 EXPECT_TRUE(OnlyPinning("googleadservices.com")); | 583 EXPECT_TRUE(OnlyPinning("googleadservices.com")); |
| 642 EXPECT_TRUE(OnlyPinning("googlecode.com")); | 584 EXPECT_TRUE(OnlyPinning("googlecode.com")); |
| 643 EXPECT_TRUE(OnlyPinning("appspot.com")); | 585 EXPECT_TRUE(OnlyPinning("appspot.com")); |
| 644 EXPECT_TRUE(OnlyPinning("googlesyndication.com")); | 586 EXPECT_TRUE(OnlyPinning("googlesyndication.com")); |
| 645 EXPECT_TRUE(OnlyPinning("doubleclick.net")); | 587 EXPECT_TRUE(OnlyPinning("doubleclick.net")); |
| 646 EXPECT_TRUE(OnlyPinning("googlegroups.com")); | 588 EXPECT_TRUE(OnlyPinning("googlegroups.com")); |
| 647 | 589 |
| 648 // Tests for domains that don't work without SNI. | 590 // Tests for domains that don't work without SNI. |
| 649 EXPECT_FALSE(state.GetDomainState(&domain_state, "gmail.com", false)); | 591 EXPECT_FALSE(state.GetDomainState("gmail.com", false, &domain_state)); |
| 650 EXPECT_FALSE(state.GetDomainState(&domain_state, "www.gmail.com", false)); | 592 EXPECT_FALSE(state.GetDomainState("www.gmail.com", false, &domain_state)); |
| 651 EXPECT_FALSE(state.GetDomainState(&domain_state, "m.gmail.com", false)); | 593 EXPECT_FALSE(state.GetDomainState("m.gmail.com", false, &domain_state)); |
| 652 EXPECT_FALSE(state.GetDomainState(&domain_state, "googlemail.com", false)); | 594 EXPECT_FALSE(state.GetDomainState("googlemail.com", false, &domain_state)); |
| 653 EXPECT_FALSE(state.GetDomainState(&domain_state, | 595 EXPECT_FALSE(state.GetDomainState("www.googlemail.com", false, |
| 654 "www.googlemail.com", | 596 &domain_state)); |
| 655 false)); | 597 EXPECT_FALSE(state.GetDomainState("m.googlemail.com", false, &domain_state)); |
| 656 EXPECT_FALSE(state.GetDomainState(&domain_state, | |
| 657 "m.googlemail.com", | |
| 658 false)); | |
| 659 | 598 |
| 660 // Other hosts: | 599 // Other hosts: |
| 661 | 600 |
| 662 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com")); | 601 EXPECT_TRUE(ShouldRedirect("aladdinschools.appspot.com")); |
| 663 | 602 |
| 664 EXPECT_TRUE(ShouldRedirect("ottospora.nl")); | 603 EXPECT_TRUE(ShouldRedirect("ottospora.nl")); |
| 665 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl")); | 604 EXPECT_TRUE(ShouldRedirect("www.ottospora.nl")); |
| 666 | 605 |
| 667 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com")); | 606 EXPECT_TRUE(ShouldRedirect("www.paycheckrecords.com")); |
| 668 | 607 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 EXPECT_TRUE(ShouldRedirect("simon.butcher.name")); | 685 EXPECT_TRUE(ShouldRedirect("simon.butcher.name")); |
| 747 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name")); | 686 EXPECT_TRUE(ShouldRedirect("foo.simon.butcher.name")); |
| 748 | 687 |
| 749 EXPECT_TRUE(ShouldRedirect("linx.net")); | 688 EXPECT_TRUE(ShouldRedirect("linx.net")); |
| 750 EXPECT_TRUE(ShouldRedirect("foo.linx.net")); | 689 EXPECT_TRUE(ShouldRedirect("foo.linx.net")); |
| 751 | 690 |
| 752 EXPECT_TRUE(ShouldRedirect("dropcam.com")); | 691 EXPECT_TRUE(ShouldRedirect("dropcam.com")); |
| 753 EXPECT_TRUE(ShouldRedirect("www.dropcam.com")); | 692 EXPECT_TRUE(ShouldRedirect("www.dropcam.com")); |
| 754 EXPECT_FALSE(HasState("foo.dropcam.com")); | 693 EXPECT_FALSE(HasState("foo.dropcam.com")); |
| 755 | 694 |
| 756 EXPECT_TRUE(state.GetDomainState(&domain_state, | 695 EXPECT_TRUE(state.GetDomainState("torproject.org", false, &domain_state)); |
| 757 "torproject.org", | 696 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); |
| 758 false)); | 697 EXPECT_TRUE(state.GetDomainState("www.torproject.org", false, |
| 759 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); | 698 &domain_state)); |
| 760 EXPECT_TRUE(state.GetDomainState(&domain_state, | 699 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); |
| 761 "www.torproject.org", | 700 EXPECT_TRUE(state.GetDomainState("check.torproject.org", false, |
| 762 false)); | 701 &domain_state)); |
| 763 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); | 702 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); |
| 764 EXPECT_TRUE(state.GetDomainState(&domain_state, | 703 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", false, |
| 765 "check.torproject.org", | 704 &domain_state)); |
| 766 false)); | 705 EXPECT_FALSE(domain_state.static_spki_hashes.empty()); |
| 767 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); | |
| 768 EXPECT_TRUE(state.GetDomainState(&domain_state, | |
| 769 "blog.torproject.org", | |
| 770 false)); | |
| 771 EXPECT_FALSE(domain_state.preloaded_spki_hashes.empty()); | |
| 772 EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn")); | 706 EXPECT_TRUE(ShouldRedirect("ebanking.indovinabank.com.vn")); |
| 773 EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn")); | 707 EXPECT_TRUE(ShouldRedirect("foo.ebanking.indovinabank.com.vn")); |
| 774 | 708 |
| 775 EXPECT_TRUE(ShouldRedirect("epoxate.com")); | 709 EXPECT_TRUE(ShouldRedirect("epoxate.com")); |
| 776 EXPECT_FALSE(HasState("foo.epoxate.com")); | 710 EXPECT_FALSE(HasState("foo.epoxate.com")); |
| 777 | 711 |
| 778 EXPECT_TRUE(HasPins("torproject.org")); | 712 EXPECT_TRUE(HasPins("torproject.org")); |
| 779 EXPECT_TRUE(HasPins("www.torproject.org")); | 713 EXPECT_TRUE(HasPins("www.torproject.org")); |
| 780 EXPECT_TRUE(HasPins("check.torproject.org")); | 714 EXPECT_TRUE(HasPins("check.torproject.org")); |
| 781 EXPECT_TRUE(HasPins("blog.torproject.org")); | 715 EXPECT_TRUE(HasPins("blog.torproject.org")); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net")); | 764 EXPECT_TRUE(ShouldRedirect("bigshinylock.minazo.net")); |
| 831 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net")); | 765 EXPECT_TRUE(ShouldRedirect("foo.bigshinylock.minazo.net")); |
| 832 | 766 |
| 833 EXPECT_TRUE(ShouldRedirect("crate.io")); | 767 EXPECT_TRUE(ShouldRedirect("crate.io")); |
| 834 EXPECT_TRUE(ShouldRedirect("foo.crate.io")); | 768 EXPECT_TRUE(ShouldRedirect("foo.crate.io")); |
| 835 | 769 |
| 836 EXPECT_TRUE(HasPins("www.twitter.com")); | 770 EXPECT_TRUE(HasPins("www.twitter.com")); |
| 837 } | 771 } |
| 838 | 772 |
| 839 TEST_F(TransportSecurityStateTest, LongNames) { | 773 TEST_F(TransportSecurityStateTest, LongNames) { |
| 840 TransportSecurityState state(""); | 774 TransportSecurityState state; |
| 841 const char kLongName[] = | 775 const char kLongName[] = |
| 842 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd" | 776 "lookupByWaveIdHashAndWaveIdIdAndWaveIdDomainAndWaveletIdIdAnd" |
| 843 "WaveletIdDomainAndBlipBlipid"; | 777 "WaveletIdDomainAndBlipBlipid"; |
| 844 TransportSecurityState::DomainState domain_state; | 778 TransportSecurityState::DomainState domain_state; |
| 845 // Just checks that we don't hit a NOTREACHED. | 779 // Just checks that we don't hit a NOTREACHED. |
| 846 EXPECT_FALSE(state.GetDomainState(&domain_state, kLongName, true)); | 780 EXPECT_FALSE(state.GetDomainState(kLongName, true, &domain_state)); |
| 847 } | |
| 848 | |
| 849 TEST_F(TransportSecurityStateTest, PublicKeyHashes) { | |
| 850 TransportSecurityState state(""); | |
| 851 TransportSecurityState::DomainState domain_state; | |
| 852 EXPECT_FALSE(state.GetDomainState(&domain_state, "example.com", false)); | |
| 853 FingerprintVector hashes; | |
| 854 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | |
| 855 | |
| 856 SHA1Fingerprint hash; | |
| 857 memset(hash.data, '1', sizeof(hash.data)); | |
| 858 domain_state.preloaded_spki_hashes.push_back(hash); | |
| 859 | |
| 860 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | |
| 861 hashes.push_back(hash); | |
| 862 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | |
| 863 hashes[0].data[0] = '2'; | |
| 864 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | |
| 865 | |
| 866 const base::Time current_time(base::Time::Now()); | |
| 867 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | |
| 868 domain_state.expiry = expiry; | |
| 869 state.EnableHost("example.com", domain_state); | |
| 870 std::string ser; | |
| 871 EXPECT_TRUE(state.Serialise(&ser)); | |
| 872 bool dirty; | |
| 873 EXPECT_TRUE(state.LoadEntries(ser, &dirty)); | |
| 874 EXPECT_TRUE(state.GetDomainState(&domain_state, "example.com", false)); | |
| 875 EXPECT_EQ(1u, domain_state.preloaded_spki_hashes.size()); | |
| 876 EXPECT_EQ(0, memcmp(domain_state.preloaded_spki_hashes[0].data, hash.data, | |
| 877 sizeof(hash.data))); | |
| 878 } | 781 } |
| 879 | 782 |
| 880 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { | 783 TEST_F(TransportSecurityStateTest, BuiltinCertPins) { |
| 881 TransportSecurityState state(""); | 784 TransportSecurityState state; |
| 882 TransportSecurityState::DomainState domain_state; | 785 TransportSecurityState::DomainState domain_state; |
| 883 EXPECT_TRUE(state.GetDomainState(&domain_state, | 786 |
| 884 "chrome.google.com", | 787 EXPECT_TRUE(state.GetDomainState("chrome.google.com", true, &domain_state)); |
| 885 true)); | 788 EXPECT_TRUE(HasPins("chrome.google.com")); |
| 886 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "chrome.google.com", true)); | 789 |
| 887 FingerprintVector hashes; | 790 FingerprintVector hashes; |
| 888 // This essential checks that a built-in list does exist. | 791 // Checks that a built-in list does exist. |
| 889 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); | 792 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(hashes)); |
| 890 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "www.paypal.com", true)); | 793 EXPECT_FALSE(HasPins("www.paypal.com")); |
| 891 | 794 |
| 892 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "docs.google.com", true)); | 795 EXPECT_TRUE(HasPins("docs.google.com")); |
| 893 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "1.docs.google.com", true)); | 796 EXPECT_TRUE(HasPins("1.docs.google.com")); |
| 894 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "sites.google.com", true)); | 797 EXPECT_TRUE(HasPins("sites.google.com")); |
| 895 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "drive.google.com", true)); | 798 EXPECT_TRUE(HasPins("drive.google.com")); |
| 896 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 799 EXPECT_TRUE(HasPins("spreadsheets.google.com")); |
| 897 "spreadsheets.google.com", | 800 EXPECT_TRUE(HasPins("health.google.com")); |
| 898 true)); | 801 EXPECT_TRUE(HasPins("checkout.google.com")); |
| 899 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "health.google.com", true)); | 802 EXPECT_TRUE(HasPins("appengine.google.com")); |
| 900 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 803 EXPECT_TRUE(HasPins("market.android.com")); |
| 901 "checkout.google.com", | 804 EXPECT_TRUE(HasPins("encrypted.google.com")); |
| 902 true)); | 805 EXPECT_TRUE(HasPins("accounts.google.com")); |
| 903 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 806 EXPECT_TRUE(HasPins("profiles.google.com")); |
| 904 "appengine.google.com", | 807 EXPECT_TRUE(HasPins("mail.google.com")); |
| 905 true)); | 808 EXPECT_TRUE(HasPins("chatenabled.mail.google.com")); |
| 906 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "market.android.com", true)); | 809 EXPECT_TRUE(HasPins("talkgadget.google.com")); |
| 907 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 810 EXPECT_TRUE(HasPins("hostedtalkgadget.google.com")); |
| 908 "encrypted.google.com", | 811 EXPECT_TRUE(HasPins("talk.google.com")); |
| 909 true)); | 812 EXPECT_TRUE(HasPins("plus.google.com")); |
| 910 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 813 EXPECT_TRUE(HasPins("groups.google.com")); |
| 911 "accounts.google.com", | 814 EXPECT_TRUE(HasPins("apis.google.com")); |
| 912 true)); | |
| 913 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 914 "profiles.google.com", | |
| 915 true)); | |
| 916 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "mail.google.com", true)); | |
| 917 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 918 "chatenabled.mail.google.com", | |
| 919 true)); | |
| 920 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 921 "talkgadget.google.com", | |
| 922 true)); | |
| 923 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 924 "hostedtalkgadget.google.com", | |
| 925 true)); | |
| 926 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "talk.google.com", true)); | |
| 927 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "plus.google.com", true)); | |
| 928 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "groups.google.com", true)); | |
| 929 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "apis.google.com", true)); | |
| 930 | 815 |
| 931 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "ssl.gstatic.com", true)); | 816 EXPECT_TRUE(HasPins("ssl.gstatic.com")); |
| 932 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "www.gstatic.com", true)); | 817 EXPECT_FALSE(HasPins("www.gstatic.com")); |
| 933 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | 818 EXPECT_TRUE(HasPins("ssl.google-analytics.com")); |
| 934 "ssl.google-analytics.com", | 819 EXPECT_TRUE(HasPins("www.googleplex.com")); |
| 935 true)); | |
| 936 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.googleplex.com", true)); | |
| 937 | 820 |
| 938 // Disabled in order to help track down pinning failures --agl | 821 // Disabled in order to help track down pinning failures --agl |
| 939 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "twitter.com", true)); | 822 EXPECT_TRUE(HasPins("twitter.com")); |
| 940 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "foo.twitter.com", true)); | 823 EXPECT_FALSE(HasPins("foo.twitter.com")); |
| 941 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.twitter.com", true)); | 824 EXPECT_TRUE(HasPins("www.twitter.com")); |
| 942 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "api.twitter.com", true)); | 825 EXPECT_TRUE(HasPins("api.twitter.com")); |
| 943 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "oauth.twitter.com", true)); | 826 EXPECT_TRUE(HasPins("oauth.twitter.com")); |
| 944 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "mobile.twitter.com", true)); | 827 EXPECT_TRUE(HasPins("mobile.twitter.com")); |
| 945 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "dev.twitter.com", true)); | 828 EXPECT_TRUE(HasPins("dev.twitter.com")); |
| 946 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "business.twitter.com", | 829 EXPECT_TRUE(HasPins("business.twitter.com")); |
| 947 true)); | 830 EXPECT_TRUE(HasPins("platform.twitter.com")); |
| 948 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "platform.twitter.com", | 831 EXPECT_TRUE(HasPins("si0.twimg.com")); |
| 949 true)); | 832 EXPECT_TRUE(HasPins("twimg0-a.akamaihd.net")); |
| 950 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "si0.twimg.com", true)); | |
| 951 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "twimg0-a.akamaihd.net", | |
| 952 true)); | |
| 953 } | 833 } |
| 954 | 834 |
| 955 static bool AddHash(const std::string& type_and_base64, | 835 static bool AddHash(const std::string& type_and_base64, |
| 956 FingerprintVector* out) { | 836 FingerprintVector* out) { |
| 957 std::string hash_str; | 837 std::string hash_str; |
| 958 if (type_and_base64.find("sha1/") == 0 && | 838 if (type_and_base64.find("sha1/") == 0 && |
| 959 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5), | 839 base::Base64Decode(type_and_base64.substr(5, type_and_base64.size() - 5), |
| 960 &hash_str) && | 840 &hash_str) && |
| 961 hash_str.size() == base::kSHA1Length) { | 841 hash_str.size() == base::kSHA1Length) { |
| 962 SHA1Fingerprint hash; | 842 SHA1Fingerprint hash; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 988 | 868 |
| 989 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; | 869 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; |
| 990 | 870 |
| 991 for (size_t i = 0; kGoodPath[i]; i++) { | 871 for (size_t i = 0; kGoodPath[i]; i++) { |
| 992 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); | 872 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); |
| 993 } | 873 } |
| 994 for (size_t i = 0; kBadPath[i]; i++) { | 874 for (size_t i = 0; kBadPath[i]; i++) { |
| 995 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); | 875 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); |
| 996 } | 876 } |
| 997 | 877 |
| 998 TransportSecurityState state(""); | 878 TransportSecurityState state; |
| 999 TransportSecurityState::DomainState domain_state; | 879 TransportSecurityState::DomainState domain_state; |
| 1000 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "plus.google.com", true)); | 880 EXPECT_TRUE(state.GetDomainState("plus.google.com", true, &domain_state)); |
| 881 EXPECT_TRUE(domain_state.HasPins()); |
| 1001 | 882 |
| 1002 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); | 883 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); |
| 1003 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); | 884 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); |
| 1004 } | 885 } |
| 1005 | 886 |
| 1006 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { | 887 TEST_F(TransportSecurityStateTest, PinValidationWithoutRejectedCerts) { |
| 1007 // kGoodPath is blog.torproject.org. | 888 // kGoodPath is blog.torproject.org. |
| 1008 static const char* kGoodPath[] = { | 889 static const char* kGoodPath[] = { |
| 1009 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", | 890 "sha1/m9lHYJYke9k0GtVZ+bXSQYE8nDI=", |
| 1010 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", | 891 "sha1/o5OZxATDsgmwgcIfIWIneMJ0jkw=", |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1023 | 904 |
| 1024 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; | 905 std::vector<net::SHA1Fingerprint> good_hashes, bad_hashes; |
| 1025 | 906 |
| 1026 for (size_t i = 0; kGoodPath[i]; i++) { | 907 for (size_t i = 0; kGoodPath[i]; i++) { |
| 1027 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); | 908 EXPECT_TRUE(AddHash(kGoodPath[i], &good_hashes)); |
| 1028 } | 909 } |
| 1029 for (size_t i = 0; kBadPath[i]; i++) { | 910 for (size_t i = 0; kBadPath[i]; i++) { |
| 1030 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); | 911 EXPECT_TRUE(AddHash(kBadPath[i], &bad_hashes)); |
| 1031 } | 912 } |
| 1032 | 913 |
| 1033 TransportSecurityState state(""); | 914 TransportSecurityState state; |
| 1034 TransportSecurityState::DomainState domain_state; | 915 TransportSecurityState::DomainState domain_state; |
| 1035 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "blog.torproject.org", true)); | 916 EXPECT_TRUE(state.GetDomainState("blog.torproject.org", true, &domain_state)); |
| 917 EXPECT_TRUE(domain_state.HasPins()); |
| 1036 | 918 |
| 1037 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); | 919 EXPECT_TRUE(domain_state.IsChainOfPublicKeysPermitted(good_hashes)); |
| 1038 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); | 920 EXPECT_FALSE(domain_state.IsChainOfPublicKeysPermitted(bad_hashes)); |
| 1039 } | 921 } |
| 1040 | 922 |
| 1041 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { | 923 TEST_F(TransportSecurityStateTest, OptionalHSTSCertPins) { |
| 1042 TransportSecurityState state(""); | 924 TransportSecurityState state; |
| 1043 TransportSecurityState::DomainState domain_state; | 925 TransportSecurityState::DomainState domain_state; |
| 926 |
| 1044 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); | 927 EXPECT_FALSE(ShouldRedirect("www.google-analytics.com")); |
| 1045 EXPECT_FALSE(state.HasPinsForHost(&domain_state, | |
| 1046 "www.google-analytics.com", | |
| 1047 false)); | |
| 1048 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1049 "www.google-analytics.com", | |
| 1050 true)); | |
| 1051 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "google.com", true)); | |
| 1052 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.google.com", true)); | |
| 1053 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1054 "mail-attachment.googleusercontent.com", | |
| 1055 true)); | |
| 1056 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "www.youtube.com", true)); | |
| 1057 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "i.ytimg.com", true)); | |
| 1058 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "googleapis.com", true)); | |
| 1059 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1060 "ajax.googleapis.com", | |
| 1061 true)); | |
| 1062 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1063 "googleadservices.com", | |
| 1064 true)); | |
| 1065 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1066 "pagead2.googleadservices.com", | |
| 1067 true)); | |
| 1068 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "googlecode.com", true)); | |
| 1069 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1070 "kibbles.googlecode.com", | |
| 1071 true)); | |
| 1072 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "appspot.com", true)); | |
| 1073 EXPECT_TRUE(state.HasPinsForHost(&domain_state, | |
| 1074 "googlesyndication.com", | |
| 1075 true)); | |
| 1076 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "doubleclick.net", true)); | |
| 1077 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "ad.doubleclick.net", true)); | |
| 1078 EXPECT_FALSE(state.HasPinsForHost(&domain_state, | |
| 1079 "learn.doubleclick.net", | |
| 1080 true)); | |
| 1081 EXPECT_TRUE(state.HasPinsForHost(&domain_state, "a.googlegroups.com", true)); | |
| 1082 EXPECT_FALSE(state.HasPinsForHost(&domain_state, | |
| 1083 "a.googlegroups.com", | |
| 1084 false)); | |
| 1085 } | |
| 1086 | 928 |
| 1087 TEST_F(TransportSecurityStateTest, ForcePreloads) { | 929 EXPECT_FALSE(HasPins("www.google-analytics.com", false)); |
| 1088 // This is a docs.google.com override. | 930 EXPECT_TRUE(HasPins("www.google-analytics.com")); |
| 1089 std::string preload("{" | 931 EXPECT_TRUE(HasPins("google.com")); |
| 1090 "\"4AGT3lHihuMSd5rUj7B4u6At0jlSH3HFePovjPR+oLE=\": {" | 932 EXPECT_TRUE(HasPins("www.google.com")); |
| 1091 "\"created\": 0.0," | 933 EXPECT_TRUE(HasPins("mail-attachment.googleusercontent.com")); |
| 1092 "\"expiry\": 2000000000.0," | 934 EXPECT_TRUE(HasPins("www.youtube.com")); |
| 1093 "\"include_subdomains\": false," | 935 EXPECT_TRUE(HasPins("i.ytimg.com")); |
| 1094 "\"mode\": \"pinning-only\"" | 936 EXPECT_TRUE(HasPins("googleapis.com")); |
| 1095 "}}"); | 937 EXPECT_TRUE(HasPins("ajax.googleapis.com")); |
| 1096 | 938 EXPECT_TRUE(HasPins("googleadservices.com")); |
| 1097 TransportSecurityState state(preload); | 939 EXPECT_TRUE(HasPins("pagead2.googleadservices.com")); |
| 1098 TransportSecurityState::DomainState domain_state; | 940 EXPECT_TRUE(HasPins("googlecode.com")); |
| 1099 EXPECT_FALSE(state.HasPinsForHost(&domain_state, "docs.google.com", true)); | 941 EXPECT_TRUE(HasPins("kibbles.googlecode.com")); |
| 1100 EXPECT_TRUE(state.GetDomainState(&domain_state, "docs.google.com", true)); | 942 EXPECT_TRUE(HasPins("appspot.com")); |
| 1101 EXPECT_FALSE(domain_state.ShouldRedirectHTTPToHTTPS()); | 943 EXPECT_TRUE(HasPins("googlesyndication.com")); |
| 944 EXPECT_TRUE(HasPins("doubleclick.net")); |
| 945 EXPECT_TRUE(HasPins("ad.doubleclick.net")); |
| 946 EXPECT_FALSE(HasPins("learn.doubleclick.net")); |
| 947 EXPECT_TRUE(HasPins("a.googlegroups.com")); |
| 948 EXPECT_FALSE(HasPins("a.googlegroups.com", false)); |
| 1102 } | 949 } |
| 1103 | 950 |
| 1104 TEST_F(TransportSecurityStateTest, OverrideBuiltins) { | 951 TEST_F(TransportSecurityStateTest, OverrideBuiltins) { |
| 1105 EXPECT_TRUE(HasPins("google.com")); | 952 EXPECT_TRUE(HasPins("google.com")); |
| 1106 EXPECT_FALSE(ShouldRedirect("google.com")); | 953 EXPECT_FALSE(ShouldRedirect("google.com")); |
| 1107 EXPECT_FALSE(ShouldRedirect("www.google.com")); | 954 EXPECT_FALSE(ShouldRedirect("www.google.com")); |
| 1108 | 955 |
| 1109 TransportSecurityState state(""); | 956 TransportSecurityState state; |
| 1110 TransportSecurityState::DomainState domain_state; | 957 TransportSecurityState::DomainState domain_state; |
| 1111 const base::Time current_time(base::Time::Now()); | 958 const base::Time current_time(base::Time::Now()); |
| 1112 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); | 959 const base::Time expiry = current_time + base::TimeDelta::FromSeconds(1000); |
| 1113 domain_state.expiry = expiry; | 960 domain_state.upgrade_expiry = expiry; |
| 1114 state.EnableHost("www.google.com", domain_state); | 961 state.EnableHost("www.google.com", domain_state); |
| 1115 | 962 |
| 1116 EXPECT_TRUE(state.GetDomainState(&domain_state, "www.google.com", true)); | 963 EXPECT_TRUE(state.GetDomainState("www.google.com", true, &domain_state)); |
| 1117 } | 964 } |
| 1118 | 965 |
| 1119 static const uint8 kSidePinLeafSPKI[] = { | 966 static const uint8 kSidePinLeafSPKI[] = { |
| 1120 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, | 967 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, |
| 1121 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xe4, | 968 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xe4, |
| 1122 0x1d, 0xcc, 0xf2, 0x92, 0xe7, 0x7a, 0xc6, 0x36, 0xf7, 0x1a, 0x62, 0x31, 0x7d, | 969 0x1d, 0xcc, 0xf2, 0x92, 0xe7, 0x7a, 0xc6, 0x36, 0xf7, 0x1a, 0x62, 0x31, 0x7d, |
| 1123 0x37, 0xea, 0x0d, 0xa2, 0xa8, 0x12, 0x2b, 0xc2, 0x1c, 0x82, 0x3e, 0xa5, 0x70, | 970 0x37, 0xea, 0x0d, 0xa2, 0xa8, 0x12, 0x2b, 0xc2, 0x1c, 0x82, 0x3e, 0xa5, 0x70, |
| 1124 0x4a, 0x83, 0x5d, 0x9b, 0x84, 0x82, 0x70, 0xa4, 0x88, 0x98, 0x98, 0x41, 0x29, | 971 0x4a, 0x83, 0x5d, 0x9b, 0x84, 0x82, 0x70, 0xa4, 0x88, 0x98, 0x98, 0x41, 0x29, |
| 1125 0x31, 0xcb, 0x6e, 0x2a, 0x54, 0x65, 0x14, 0x60, 0xcc, 0x00, 0xe8, 0x10, 0x30, | 972 0x31, 0xcb, 0x6e, 0x2a, 0x54, 0x65, 0x14, 0x60, 0xcc, 0x00, 0xe8, 0x10, 0x30, |
| 1126 0x0a, 0x4a, 0xd1, 0xa7, 0x52, 0xfe, 0x2d, 0x31, 0x2a, 0x1d, 0x0d, 0x02, 0x03, | 973 0x0a, 0x4a, 0xd1, 0xa7, 0x52, 0xfe, 0x2d, 0x31, 0x2a, 0x1d, 0x0d, 0x02, 0x03, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1141 0xc3, 0x6e, 0x18, 0xdf, 0x79, 0xc0, 0x59, 0xab, 0xd6, 0x77, 0x37, 0x6a, 0x94, | 988 0xc3, 0x6e, 0x18, 0xdf, 0x79, 0xc0, 0x59, 0xab, 0xd6, 0x77, 0x37, 0x6a, 0x94, |
| 1142 0x5a, 0x7e, 0xfb, 0xa9, 0xc5, 0x54, 0x14, 0x3a, 0x7b, 0x97, 0x17, 0x2a, 0xb6, | 989 0x5a, 0x7e, 0xfb, 0xa9, 0xc5, 0x54, 0x14, 0x3a, 0x7b, 0x97, 0x17, 0x2a, 0xb6, |
| 1143 0x1e, 0x59, 0x4f, 0x2f, 0xb1, 0x15, 0x1a, 0x34, 0x50, 0x32, 0x35, 0x36, | 990 0x1e, 0x59, 0x4f, 0x2f, 0xb1, 0x15, 0x1a, 0x34, 0x50, 0x32, 0x35, 0x36, |
| 1144 }; | 991 }; |
| 1145 | 992 |
| 1146 static const uint8 kSidePinExpectedHash[20] = { | 993 static const uint8 kSidePinExpectedHash[20] = { |
| 1147 0xb5, 0x91, 0x66, 0x47, 0x43, 0x16, 0x62, 0x86, 0xd4, 0x1e, 0x5d, 0x36, 0xe1, | 994 0xb5, 0x91, 0x66, 0x47, 0x43, 0x16, 0x62, 0x86, 0xd4, 0x1e, 0x5d, 0x36, 0xe1, |
| 1148 0xc4, 0x09, 0x3d, 0x2d, 0x1d, 0xea, 0x1e, | 995 0xc4, 0x09, 0x3d, 0x2d, 0x1d, 0xea, 0x1e, |
| 1149 }; | 996 }; |
| 1150 | 997 |
| 1151 TEST_F(TransportSecurityStateTest, ParseSidePins) { | |
| 1152 base::StringPiece leaf_spki(reinterpret_cast<const char*>(kSidePinLeafSPKI), | |
| 1153 sizeof(kSidePinLeafSPKI)); | |
| 1154 base::StringPiece side_info(reinterpret_cast<const char*>(kSidePinInfo), | |
| 1155 sizeof(kSidePinInfo)); | |
| 1156 | |
| 1157 FingerprintVector pub_key_hashes; | |
| 1158 EXPECT_TRUE(TransportSecurityState::ParseSidePin( | |
| 1159 leaf_spki, side_info, &pub_key_hashes)); | |
| 1160 ASSERT_EQ(1u, pub_key_hashes.size()); | |
| 1161 EXPECT_EQ(0, memcmp(pub_key_hashes[0].data, kSidePinExpectedHash, | |
| 1162 sizeof(kSidePinExpectedHash))); | |
| 1163 } | |
| 1164 | |
| 1165 TEST_F(TransportSecurityStateTest, ParseSidePinsFailsWithBadData) { | |
| 1166 uint8 leaf_spki_copy[sizeof(kSidePinLeafSPKI)]; | |
| 1167 memcpy(leaf_spki_copy, kSidePinLeafSPKI, sizeof(leaf_spki_copy)); | |
| 1168 | |
| 1169 uint8 side_info_copy[sizeof(kSidePinInfo)]; | |
| 1170 memcpy(side_info_copy, kSidePinInfo, sizeof(kSidePinInfo)); | |
| 1171 | |
| 1172 base::StringPiece leaf_spki(reinterpret_cast<const char*>(leaf_spki_copy), | |
| 1173 sizeof(leaf_spki_copy)); | |
| 1174 base::StringPiece side_info(reinterpret_cast<const char*>(side_info_copy), | |
| 1175 sizeof(side_info_copy)); | |
| 1176 FingerprintVector pub_key_hashes; | |
| 1177 | |
| 1178 // Tweak |leaf_spki| and expect a failure. | |
| 1179 leaf_spki_copy[10] ^= 1; | |
| 1180 EXPECT_FALSE(TransportSecurityState::ParseSidePin( | |
| 1181 leaf_spki, side_info, &pub_key_hashes)); | |
| 1182 ASSERT_EQ(0u, pub_key_hashes.size()); | |
| 1183 | |
| 1184 // Undo the change to |leaf_spki| and tweak |side_info|. | |
| 1185 leaf_spki_copy[10] ^= 1; | |
| 1186 side_info_copy[30] ^= 1; | |
| 1187 EXPECT_FALSE(TransportSecurityState::ParseSidePin( | |
| 1188 leaf_spki, side_info, &pub_key_hashes)); | |
| 1189 ASSERT_EQ(0u, pub_key_hashes.size()); | |
| 1190 } | |
| 1191 | |
| 1192 TEST_F(TransportSecurityStateTest, DISABLED_ParseSidePinsFuzz) { | |
| 1193 // Disabled because it's too slow for normal tests. Run manually when | |
| 1194 // changing the underlying code. | |
| 1195 | |
| 1196 base::StringPiece leaf_spki(reinterpret_cast<const char*>(kSidePinLeafSPKI), | |
| 1197 sizeof(kSidePinLeafSPKI)); | |
| 1198 uint8 side_info_copy[sizeof(kSidePinInfo)]; | |
| 1199 base::StringPiece side_info(reinterpret_cast<const char*>(side_info_copy), | |
| 1200 sizeof(side_info_copy)); | |
| 1201 FingerprintVector pub_key_hashes; | |
| 1202 static const size_t bit_length = sizeof(kSidePinInfo) * 8; | |
| 1203 | |
| 1204 for (size_t bit_to_flip = 0; bit_to_flip < bit_length; bit_to_flip++) { | |
| 1205 memcpy(side_info_copy, kSidePinInfo, sizeof(kSidePinInfo)); | |
| 1206 | |
| 1207 size_t byte = bit_to_flip >> 3; | |
| 1208 size_t bit = bit_to_flip & 7; | |
| 1209 side_info_copy[byte] ^= (1 << bit); | |
| 1210 | |
| 1211 EXPECT_FALSE(TransportSecurityState::ParseSidePin( | |
| 1212 leaf_spki, side_info, &pub_key_hashes)); | |
| 1213 ASSERT_EQ(0u, pub_key_hashes.size()); | |
| 1214 } | |
| 1215 } | |
| 1216 | |
| 1217 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) { | 998 TEST_F(TransportSecurityStateTest, GooglePinnedProperties) { |
| 1218 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 999 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1219 "www.example.com", true)); | 1000 "www.example.com", true)); |
| 1220 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1001 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1221 "www.paypal.com", true)); | 1002 "www.paypal.com", true)); |
| 1222 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1003 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1223 "mail.twitter.com", true)); | 1004 "mail.twitter.com", true)); |
| 1224 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1005 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1225 "www.google.com.int", true)); | 1006 "www.google.com.int", true)); |
| 1226 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1007 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1271 // Expect to fail for SNI hosts when not searching the SNI list: | 1052 // Expect to fail for SNI hosts when not searching the SNI list: |
| 1272 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1053 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1273 "gmail.com", false)); | 1054 "gmail.com", false)); |
| 1274 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1055 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1275 "googlegroups.com", false)); | 1056 "googlegroups.com", false)); |
| 1276 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( | 1057 EXPECT_FALSE(TransportSecurityState::IsGooglePinnedProperty( |
| 1277 "www.googlegroups.com", false)); | 1058 "www.googlegroups.com", false)); |
| 1278 } | 1059 } |
| 1279 | 1060 |
| 1280 } // namespace net | 1061 } // namespace net |
| OLD | NEW |