13345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Copyright (c) 2010 The Chromium Authors. All rights reserved.
23345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Use of this source code is governed by a BSD-style license that can be
33345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// found in the LICENSE file.
43345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
53345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#ifndef NET_BASE_SSL_FALSE_START_BLACKLIST_H_
63345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#define NET_BASE_SSL_FALSE_START_BLACKLIST_H_
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/basictypes.h"
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merricknamespace net {
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// SSLFalseStartBlacklist is a set of domains which we believe to be intolerant
133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// to TLS False Start. Because this set is several hundred long, it's
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// precompiled by the code in ssl_false_start_blacklist_process.cc into a hash
153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// table for fast lookups.
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickclass SSLFalseStartBlacklist {
173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick public:
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // IsMember returns true if the given host is in the blacklist.
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   host: a DNS name in dotted form (i.e. "www.example.com")
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static bool IsMember(const char* host);
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Hash returns the modified djb2 hash of the given string.
233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static unsigned Hash(const char* str) {
243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // This is inline because the code which generates the hash table needs to
253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // use it. However, the generating code cannot link against
263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // ssl_false_start_blacklist.cc because that needs the tables which it
273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // generates.
283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const unsigned char* in = reinterpret_cast<const unsigned char*>(str);
293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    unsigned hash = 5381;
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    unsigned char c;
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    while ((c = *in++))
333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      hash = ((hash << 5) + hash) ^ c;
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return hash;
353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // LastTwoLabels returns a pointer within |host| to the last two labels of
383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // |host|. For example, if |host| is "a.b.c.d" then LastTwoLabels will return
393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // "c.d".
403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   host: a DNS name in dotted form.
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  //   returns: NULL on error, otherwise a pointer inside |host|.
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char* LastTwoLabels(const char* host) {
433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // See comment in |Hash| for why this function is inline.
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const size_t len = strlen(host);
453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (len == 0)
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return NULL;
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    unsigned dots_found = 0;
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    size_t i;
503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    for (i = len - 1; i < len; i--) {
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (host[i] == '.') {
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        dots_found++;
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        if (dots_found == 2) {
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          i++;
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          break;
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        }
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      }
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (i > len)
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      i = 0;
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (dots_found == 0)
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return NULL;  // no names with less than two labels are in the blacklist.
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (dots_found == 1) {
663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      if (host[0] == '.')
673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        return NULL;  // ditto
683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return &host[i];
713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // This is the number of buckets in the blacklist hash table. (Must be a
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // power of two).
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const unsigned kBuckets = 128;
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick private:
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The following two members are defined in
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // ssl_false_start_blacklist_data.cc, which is generated by
803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // ssl_false_start_blacklist_process.cc
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // kHashTable contains an offset into |kHashData| for each bucket. The
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // additional element at the end contains the length of |kHashData|.
84513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  static const uint32 kHashTable[kBuckets + 1];
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // kHashData contains the contents of the hash table. |kHashTable| indexes
863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // into this array. Each bucket consists of zero or more, 8-bit length
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // prefixed strings. Each string is a DNS name in dotted form. For a given
883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // string x, x and *.x are considered to be in the blacklist. In order to
893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // assign a string to a hash bucket, the last two labels (not including the
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // root label) are hashed. Thus, the bucket for "www.example.com" is
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Hash("example.com"). No names that are less than two labels long are
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // included in the blacklist.
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  static const char kHashData[];
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick};
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace net
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#endif  // NET_BASE_SSL_FALSE_START_BLACKLIST_H_
99