OLD | NEW |
| (Empty) |
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_ | |
OLD | NEW |