1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_SSL_FALSE_START_BLACKLIST_H_ 6 #define NET_BASE_SSL_FALSE_START_BLACKLIST_H_ 7 8 #include "base/basictypes.h" 9 10 namespace net { 11 12 // SSLFalseStartBlacklist is a set of domains which we believe to be intolerant 13 // to TLS False Start. Because this set is several hundred long, it's 14 // precompiled by the code in ssl_false_start_blacklist_process.cc into a hash 15 // table for fast lookups. 16 class SSLFalseStartBlacklist { 17 public: 18 // IsMember returns true if the given host is in the blacklist. 19 // host: a DNS name in dotted form (i.e. "www.example.com") 20 static bool IsMember(const char* host); 21 22 // Hash returns the modified djb2 hash of the given string. 23 static unsigned Hash(const char* str) { 24 // This is inline because the code which generates the hash table needs to 25 // use it. However, the generating code cannot link against 26 // ssl_false_start_blacklist.cc because that needs the tables which it 27 // generates. 28 const unsigned char* in = reinterpret_cast<const unsigned char*>(str); 29 unsigned hash = 5381; 30 unsigned char c; 31 32 while ((c = *in++)) 33 hash = ((hash << 5) + hash) ^ c; 34 return hash; 35 } 36 37 // LastTwoLabels returns a pointer within |host| to the last two labels of 38 // |host|. For example, if |host| is "a.b.c.d" then LastTwoLabels will return 39 // "c.d". 40 // host: a DNS name in dotted form. 41 // returns: NULL on error, otherwise a pointer inside |host|. 42 static const char* LastTwoLabels(const char* host) { 43 // See comment in |Hash| for why this function is inline. 44 const size_t len = strlen(host); 45 if (len == 0) 46 return NULL; 47 48 unsigned dots_found = 0; 49 size_t i; 50 for (i = len - 1; i < len; i--) { 51 if (host[i] == '.') { 52 dots_found++; 53 if (dots_found == 2) { 54 i++; 55 break; 56 } 57 } 58 } 59 60 if (i > len) 61 i = 0; 62 63 if (dots_found == 0) 64 return NULL; // no names with less than two labels are in the blacklist. 65 if (dots_found == 1) { 66 if (host[0] == '.') 67 return NULL; // ditto 68 } 69 70 return &host[i]; 71 } 72 73 // This is the number of buckets in the blacklist hash table. (Must be a 74 // power of two). 75 static const unsigned kBuckets = 128; 76 77 private: 78 // The following two members are defined in 79 // ssl_false_start_blacklist_data.cc, which is generated by 80 // ssl_false_start_blacklist_process.cc 81 82 // kHashTable contains an offset into |kHashData| for each bucket. The 83 // additional element at the end contains the length of |kHashData|. 84 static const uint32 kHashTable[kBuckets + 1]; 85 // kHashData contains the contents of the hash table. |kHashTable| indexes 86 // into this array. Each bucket consists of zero or more, 8-bit length 87 // prefixed strings. Each string is a DNS name in dotted form. For a given 88 // string x, x and *.x are considered to be in the blacklist. In order to 89 // assign a string to a hash bucket, the last two labels (not including the 90 // root label) are hashed. Thus, the bucket for "www.example.com" is 91 // Hash("example.com"). No names that are less than two labels long are 92 // included in the blacklist. 93 static const char kHashData[]; 94 }; 95 96 } // namespace net 97 98 #endif // NET_BASE_SSL_FALSE_START_BLACKLIST_H_ 99