• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
Hash(const char * str)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|.
LastTwoLabels(const char * 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