xref: /aosp_15_r20/external/libchrome/libchrome_tools/patches/Add-base-Token-class.patch (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1From bd984b07c2672500cf1344ee16807e52a42cfe0c Mon Sep 17 00:00:00 2001
2From: Soshun Naito <[email protected]>
3Date: Tue, 6 Aug 2024 08:37:44 +0000
4Subject: [PATCH] base: Add base::Token class
5
6This CL is a cherry-pick of the following CL: https://crrev.com/c/1320190
7It adds token.h and token.cc introduced in the CL above. These files are
8requried to build ARC with [Uuid] attribute in Mojo enabled.
9This CL also replaces unguessable_token.h and unguessable_token.cc with
10those in the original CL to let base::UnguessableToken to inherit
11base::Token.
12
13Bug: b:357737923, b:41420830
14Test: m
15
16Change-Id: I93cc0a588a4268416d3a3ba28e170992794e479d
17---
18 Android.bp                |  2 ++
19 base/token.cc             | 28 +++++++++++++++
20 base/token.h              | 72 +++++++++++++++++++++++++++++++++++++++
21 base/unguessable_token.cc | 20 +++++------
22 base/unguessable_token.h  | 36 ++++++++++++--------
23 5 files changed, 132 insertions(+), 26 deletions(-)
24 create mode 100644 base/token.cc
25 create mode 100644 base/token.h
26
27diff --git a/Android.bp b/Android.bp
28index 340a194ac..c9b031519 100644
29--- a/Android.bp
30+++ b/Android.bp
31@@ -458,6 +458,7 @@ filegroup {
32         "base/timer/hi_res_timer_manager.h",
33         "base/timer/mock_timer.h",
34         "base/timer/timer.h",
35+        "base/token.h",
36         "base/trace_event/common/trace_event_common.h",
37         "base/trace_event/heap_profiler.h",
38         "base/trace_event/trace_event.h",
39@@ -736,6 +737,7 @@ libchromeCommonSrc = [
40     "base/time/time_override.cc",
41     "base/timer/elapsed_timer.cc",
42     "base/timer/timer.cc",
43+    "base/token.cc",
44     "base/unguessable_token.cc",
45     "base/value_iterators.cc",
46     "base/values.cc",
47diff --git a/base/token.cc b/base/token.cc
48new file mode 100644
49index 000000000..e7ad89671
50--- /dev/null
51+++ b/base/token.cc
52@@ -0,0 +1,28 @@
53+// Copyright 2018 The Chromium Authors. All rights reserved.
54+// Use of this source code is governed by a BSD-style license that can be
55+// found in the LICENSE file.
56+
57+#include "base/token.h"
58+
59+#include <inttypes.h>
60+
61+#include "base/rand_util.h"
62+#include "base/strings/stringprintf.h"
63+
64+namespace base {
65+
66+// static
67+Token Token::CreateRandom() {
68+  Token token;
69+
70+  // Use base::RandBytes instead of crypto::RandBytes, because crypto calls the
71+  // base version directly, and to prevent the dependency from base/ to crypto/.
72+  base::RandBytes(&token, sizeof(token));
73+  return token;
74+}
75+
76+std::string Token::ToString() const {
77+  return base::StringPrintf("%016" PRIX64 "%016" PRIX64, high_, low_);
78+}
79+
80+}  // namespace base
81diff --git a/base/token.h b/base/token.h
82new file mode 100644
83index 000000000..f12277e11
84--- /dev/null
85+++ b/base/token.h
86@@ -0,0 +1,72 @@
87+// Copyright 2018 The Chromium Authors. All rights reserved.
88+// Use of this source code is governed by a BSD-style license that can be
89+// found in the LICENSE file.
90+
91+#ifndef BASE_TOKEN_H_
92+#define BASE_TOKEN_H_
93+
94+#include <stdint.h>
95+
96+#include <iosfwd>
97+#include <tuple>
98+
99+#include "base/base_export.h"
100+#include "base/hash.h"
101+
102+namespace base {
103+
104+// A Token is a randomly chosen 128-bit integer. This class supports generation
105+// from a cryptographically strong random source, or constexpr construction over
106+// fixed values (e.g. to store a pre-generated constant value). Tokens are
107+// similar in spirit and purpose to UUIDs, without many of the constraints and
108+// expectations (such as byte layout and string representation) clasically
109+// associated with UUIDs.
110+class BASE_EXPORT Token {
111+ public:
112+  // Constructs a zero Token.
113+  constexpr Token() : high_(0), low_(0) {}
114+
115+  // Constructs a Token with |high| and |low| as its contents.
116+  constexpr Token(uint64_t high, uint64_t low) : high_(high), low_(low) {}
117+
118+  // Constructs a new Token with random |high| and |low| values taken from a
119+  // cryptographically strong random source.
120+  static Token CreateRandom();
121+
122+  // The high and low 64 bits of this Token.
123+  uint64_t high() const { return high_; }
124+  uint64_t low() const { return low_; }
125+
126+  bool is_zero() const { return high_ == 0 && low_ == 0; }
127+
128+  bool operator==(const Token& other) const {
129+    return high_ == other.high_ && low_ == other.low_;
130+  }
131+
132+  bool operator!=(const Token& other) const { return !(*this == other); }
133+
134+  bool operator<(const Token& other) const {
135+    return std::tie(high_, low_) < std::tie(other.high_, other.low_);
136+  }
137+
138+  // Generates a string representation of this Token useful for e.g. logging.
139+  std::string ToString() const;
140+
141+ private:
142+  // Note: Two uint64_t are used instead of uint8_t[16] in order to have a
143+  // simpler implementation, paricularly for |ToString()|, |is_zero()|, and
144+  // constexpr value construction.
145+  uint64_t high_;
146+  uint64_t low_;
147+};
148+
149+// For use in std::unordered_map.
150+struct TokenHash {
151+  size_t operator()(const base::Token& token) const {
152+    return base::HashInts64(token.high(), token.low());
153+  }
154+};
155+
156+}  // namespace base
157+
158+#endif  // BASE_TOKEN_H_
159\ No newline at end of file
160diff --git a/base/unguessable_token.cc b/base/unguessable_token.cc
161index 0d8aad39c..973b4167b 100644
162--- a/base/unguessable_token.cc
163+++ b/base/unguessable_token.cc
164@@ -5,25 +5,23 @@
165 #include "base/unguessable_token.h"
166
167 #include "base/format_macros.h"
168+#include "base/no_destructor.h"
169 #include "base/rand_util.h"
170 #include "base/strings/stringprintf.h"
171
172 namespace base {
173
174-UnguessableToken::UnguessableToken(uint64_t high, uint64_t low)
175-    : high_(high), low_(low) {}
176+UnguessableToken::UnguessableToken(const base::Token& token) : token_(token) {}
177
178-std::string UnguessableToken::ToString() const {
179-  return base::StringPrintf("%016" PRIX64 "%016" PRIX64, high_, low_);
180+// static
181+UnguessableToken UnguessableToken::Create() {
182+  return UnguessableToken(Token::CreateRandom());
183 }
184
185 // static
186-UnguessableToken UnguessableToken::Create() {
187-  UnguessableToken token;
188-  // Use base::RandBytes instead of crypto::RandBytes, because crypto calls the
189-  // base version directly, and to prevent the dependency from base/ to crypto/.
190-  base::RandBytes(&token, sizeof(token));
191-  return token;
192+const UnguessableToken& UnguessableToken::Null() {
193+  static const NoDestructor<UnguessableToken> null_token;
194+  return *null_token;
195 }
196
197 // static
198@@ -31,7 +29,7 @@ UnguessableToken UnguessableToken::Deserialize(uint64_t high, uint64_t low) {
199   // Receiving a zeroed out UnguessableToken from another process means that it
200   // was never initialized via Create(). Treat this case as a security issue.
201   DCHECK(!(high == 0 && low == 0));
202-  return UnguessableToken(high, low);
203+  return UnguessableToken(Token{high, low});
204 }
205
206 std::ostream& operator<<(std::ostream& out, const UnguessableToken& token) {
207diff --git a/base/unguessable_token.h b/base/unguessable_token.h
208index 6858e22a4..7f7b59a3a 100644
209--- a/base/unguessable_token.h
210+++ b/base/unguessable_token.h
211@@ -13,14 +13,17 @@
212 #include "base/base_export.h"
213 #include "base/hash.h"
214 #include "base/logging.h"
215+#include "base/token.h"
216
217 namespace base {
218
219 struct UnguessableTokenHash;
220
221-// A UnguessableToken is an 128-bit token generated from a cryptographically
222-// strong random source. It can be used as part of a larger aggregate type,
223-// or as an ID in and of itself.
224+// UnguessableToken is, like Token, a randomly chosen 128-bit value. Unlike
225+// Token however, a new UnguessableToken must always be generated at runtime
226+// from a cryptographically strong random source (or copied or serialized and
227+// deserialized from another such UnguessableToken). It can be used as part of a
228+// larger aggregate type, or as an ID in and of itself.
229 //
230 // UnguessableToken can be used to implement "Capability-Based Security".
231 // In other words, UnguessableToken can be used when the resource associated
232@@ -42,6 +45,12 @@ class BASE_EXPORT UnguessableToken {
233   // Create a unique UnguessableToken.
234   static UnguessableToken Create();
235
236+  // Returns a reference to a global null UnguessableToken. This should only be
237+  // used for functions that need to return a reference to an UnguessableToken,
238+  // and should not be used as a general-purpose substitute for invoking the
239+  // default constructor.
240+  static const UnguessableToken& Null();
241+
242   // Return a UnguessableToken built from the high/low bytes provided.
243   // It should only be used in deserialization scenarios.
244   //
245@@ -56,28 +65,28 @@ class BASE_EXPORT UnguessableToken {
246   // NOTE: Serializing an empty UnguessableToken is an illegal operation.
247   uint64_t GetHighForSerialization() const {
248     DCHECK(!is_empty());
249-    return high_;
250+    return token_.high();
251   }
252
253   // NOTE: Serializing an empty UnguessableToken is an illegal operation.
254   uint64_t GetLowForSerialization() const {
255     DCHECK(!is_empty());
256-    return low_;
257+    return token_.low();
258   }
259
260-  bool is_empty() const { return high_ == 0 && low_ == 0; }
261+  bool is_empty() const { return token_.is_zero(); }
262
263   // Hex representation of the unguessable token.
264-  std::string ToString() const;
265+  std::string ToString() const { return token_.ToString(); }
266
267   explicit operator bool() const { return !is_empty(); }
268
269   bool operator<(const UnguessableToken& other) const {
270-    return std::tie(high_, low_) < std::tie(other.high_, other.low_);
271+    return token_ < other.token_;
272   }
273
274   bool operator==(const UnguessableToken& other) const {
275-    return high_ == other.high_ && low_ == other.low_;
276+    return token_ == other.token_;
277   }
278
279   bool operator!=(const UnguessableToken& other) const {
280@@ -86,12 +95,9 @@ class BASE_EXPORT UnguessableToken {
281
282  private:
283   friend struct UnguessableTokenHash;
284-  UnguessableToken(uint64_t high, uint64_t low);
285+  explicit UnguessableToken(const Token& token);
286
287-  // Note: Two uint64_t are used instead of uint8_t[16], in order to have a
288-  // simpler ToString() and is_empty().
289-  uint64_t high_ = 0;
290-  uint64_t low_ = 0;
291+  base::Token token_;
292 };
293
294 BASE_EXPORT std::ostream& operator<<(std::ostream& out,
295@@ -101,7 +107,7 @@ BASE_EXPORT std::ostream& operator<<(std::ostream& out,
296 struct UnguessableTokenHash {
297   size_t operator()(const base::UnguessableToken& token) const {
298     DCHECK(token);
299-    return base::HashInts64(token.high_, token.low_);
300+    return TokenHash()(token.token_);
301   }
302 };
303
304--
3052.46.0.rc2.264.g509ed76dc8-goog
306
307