Home | History | Annotate | Download | only in profile_resetter
      1 // Copyright 2013 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 CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
      6 #define CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/basictypes.h"
     12 #include "crypto/hmac.h"
     13 
     14 namespace jtl_foundation {
     15 
     16 // A JTL (JSON Traversal Language) program is composed of one or more
     17 // sentences. Each sentence consists of a sequence of operations. The input of
     18 // the program is a hierarchical JSON data structure.
     19 //
     20 // The execution of each sentence starts at the root of an input dictionary. The
     21 // operations include navigation in the JSON data structure, as well as
     22 // comparing the current (leaf) node to fixed values. The program also has a
     23 // separate dictionary as working memory, into which it can memorize data, then
     24 // later recall it for comparisons.
     25 //
     26 // Example program:
     27 // NAVIGATE_ANY
     28 // NAVIGATE(hash("bar"))
     29 // COMPARE_NODE_BOOL(1)
     30 // STORE_BOOL(hash("found_foo"), 1)
     31 // STOP_EXECUTING_SENTENCE
     32 //
     33 // Example input:
     34 // {
     35 //   'key1': 1,
     36 //   'key2': {'foo': 0, 'bar': false, 'baz': 2}
     37 //   'key3': {'foo': 0, 'bar': true, 'baz': 2}
     38 //   'key4': {'foo': 0, 'bar': true, 'baz': 2}
     39 // }
     40 //
     41 // This program navigates from the root of the dictionary to all children
     42 // ("key1", "key2", "key3", "key4") and executes the remaining program on each
     43 // of the children. The navigation happens in depth-first pre-order. On each of
     44 // the children it tries to navigate into the child "bar", which fails for
     45 // "key1", so execution stops for this sub-branch. On key2 the program navigates
     46 // to "bar" and moves the execution context to this node which has the value
     47 // "false". Therefore, the following COMPARE_NODE_BOOL is not fulfilled and the
     48 // execution does not continue on this branch, so we back track and proceed with
     49 // "key3" and its "bar" child. For this node, COMPARE_NODE_BOOL is fulfilled and
     50 // the execution continues to store "found_foo = true" into the working memory
     51 // of the interpreter. Next the interpreter executes STOP_EXECUTING_SENTENCE
     52 // which prevents the traversal from descending into the "key4" branch from the
     53 // NAVIGATE_ANY operation and can therefore speedup the processing.
     54 //
     55 // All node names, and node values of type string, integer and double are hashed
     56 // before being compared to hash values listed in |program|.
     57 
     58 // JTL byte code consists of uint8 opcodes followed by parameters. Parameters
     59 // are either boolean (uint8 with value \x00 or \x01), uint32 (in little-endian
     60 // notation), or hash string of 32 bytes.
     61 // The following opcodes are defined:
     62 enum OpCodes {
     63   // Continues execution with the next operation on the element of a
     64   // dictionary that matches the passed key parameter. If no such element
     65   // exists, the command execution returns from the current instruction.
     66   // Parameters:
     67   // - a 32 byte hash of the target dictionary key.
     68   NAVIGATE = 0x00,
     69   // Continues execution with the next operation on each element of a
     70   // dictionary or list. If no such element exists or the current element is
     71   // neither a dictionary or list, the command execution returns from the
     72   // current instruction.
     73   NAVIGATE_ANY = 0x01,
     74   // Continues execution with the next operation on the parent node of the
     75   // current node. If the current node is the root of the input dictionary, the
     76   // program execution fails with a runtime error.
     77   NAVIGATE_BACK = 0x02,
     78   // Stores a boolean value in the working memory.
     79   // Parameters:
     80   // - a 32 byte hash of the parameter name,
     81   // - the value to store (\x00 or \x01)
     82   STORE_BOOL = 0x10,
     83   // Checks whether a boolean stored in working memory matches the expected
     84   // value and continues execution with the next operation in case of a match.
     85   // Parameters:
     86   // - a 32 byte hash of the parameter name,
     87   // - the expected value (\x00 or \x01),
     88   // - the default value in case the working memory contains no corresponding
     89   //   entry (\x00 or\x01).
     90   COMPARE_STORED_BOOL = 0x11,
     91   // Same as STORE_BOOL but takes a hash instead of a boolean value as
     92   // parameter.
     93   STORE_HASH = 0x12,
     94   // Same as COMPARE_STORED_BOOL but takes a hash instead of two boolean values
     95   // as parameters.
     96   COMPARE_STORED_HASH = 0x13,
     97   // Stores the current node into the working memory. If the current node is not
     98   // a boolean value, the program execution returns from the current
     99   // instruction.
    100   // Parameters:
    101   // - a 32 byte hash of the parameter name.
    102   STORE_NODE_BOOL = 0x14,
    103   // Stores the hashed value of the current node into the working memory. If
    104   // the current node is not a string, integer or double, the program execution
    105   // returns from the current instruction.
    106   // Parameters:
    107   // - a 32 byte hash of the parameter name.
    108   STORE_NODE_HASH = 0x15,
    109   // Parses the value of the current node as a URL, extracts the subcomponent of
    110   // the domain name that is immediately below the registrar-controlled portion,
    111   // and stores the hash of this subcomponent into working memory. In case the
    112   // domain name ends in a suffix not on the Public Suffix List (i.e. is neither
    113   // an ICANN, nor a private domain suffix), the last subcomponent is assumed to
    114   // be the registry, and the second-to-last subcomponent is extracted.
    115   // If the current node is not a string that represents a URL, or if this URL
    116   // does not have a domain component as described above, the program execution
    117   // returns from the current instruction.
    118   // For example, "foo.com", "www.foo.co.uk", "foo.appspot.com", and "foo.bar"
    119   // will all yield (the hash of) "foo" as a result.
    120   // See the unit test for more details.
    121   // Parameters:
    122   // - a 32 byte hash of the parameter name.
    123   STORE_NODE_REGISTERABLE_DOMAIN_HASH = 0x16,
    124   // Compares the current node against a boolean value and continues execution
    125   // with the next operation in case of a match. If the current node does not
    126   // match or is not a boolean value, the program execution returns from the
    127   // current instruction.
    128   // Parameters:
    129   // - a boolean value (\x00 or \x01).
    130   COMPARE_NODE_BOOL = 0x20,
    131   // Compares the hashed value of the current node against the given hash, and
    132   // continues execution with the next operation in case of a match. If the
    133   // current node is not a string, integer or double, or if it is either, but
    134   // its hash does not match, the program execution returns from the current
    135   // instruction.
    136   // Parameters:
    137   // - a 32 byte hash of the expected value.
    138   COMPARE_NODE_HASH = 0x21,
    139   // The negation of the above.
    140   COMPARE_NODE_HASH_NOT = 0x22,
    141   // Compares the current node against a boolean value stored in working memory,
    142   // and continues with the next operation in case of a match. If the current
    143   // node is not a boolean value, the working memory contains no corresponding
    144   // boolean value, or if they do not match, the program execution returns from
    145   // the current instruction.
    146   // Parameters:
    147   // - a 32 byte hash of the parameter name.
    148   COMPARE_NODE_TO_STORED_BOOL = 0x23,
    149   // Compares the hashed value of the current node against a hash value stored
    150   // in working memory, and continues with the next operation in case of a
    151   // match. If the current node is not a string, integer or double, or if the
    152   // working memory contains no corresponding hash string, or if the hashes do
    153   // not match, the program execution returns from the current instruction.
    154   // Parameters:
    155   // - a 32 byte hash of the parameter name.
    156   COMPARE_NODE_TO_STORED_HASH = 0x24,
    157   // Checks whether the current node is a string value that contains the given
    158   // pattern as a substring, and continues execution with the next operation in
    159   // case it does. If the current node is not a string, or if does not match the
    160   // pattern, the program execution returns from the current instruction.
    161   // Parameters:
    162   // - a 32 byte hash of the pattern,
    163   // - a 4 byte unsigned integer: the length (>0) of the pattern in bytes,
    164   // - a 4 byte unsigned integer: the sum of all bytes in the pattern, serving
    165   //   as a heuristic to reduce the number of actual SHA-256 calculations.
    166   COMPARE_NODE_SUBSTRING = 0x25,
    167   // Stop execution in this specific sentence.
    168   STOP_EXECUTING_SENTENCE = 0x30,
    169   // Separator between sentences, starts a new sentence.
    170   END_OF_SENTENCE = 0x31
    171 };
    172 
    173 const size_t kHashSizeInBytes = 32u;
    174 
    175 // A class that provides SHA256 hash values for strings using a fixed hash seed.
    176 class Hasher {
    177  public:
    178   explicit Hasher(const std::string& seed);
    179   ~Hasher();
    180 
    181   std::string GetHash(const std::string& input) const;
    182 
    183   static bool IsHash(const std::string& maybe_hash);
    184 
    185  private:
    186   crypto::HMAC hmac_;
    187   mutable std::map<std::string, std::string> cached_hashes_;
    188   DISALLOW_COPY_AND_ASSIGN(Hasher);
    189 };
    190 
    191 }  // namespace jtl_foundation
    192 
    193 #endif  // CHROME_BROWSER_PROFILE_RESETTER_JTL_FOUNDATION_H_
    194