xref: /aosp_15_r20/external/libchrome/base/unguessable_token.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2016 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef BASE_UNGUESSABLE_TOKEN_H_
6*635a8641SAndroid Build Coastguard Worker #define BASE_UNGUESSABLE_TOKEN_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker #include <string.h>
10*635a8641SAndroid Build Coastguard Worker #include <iosfwd>
11*635a8641SAndroid Build Coastguard Worker #include <tuple>
12*635a8641SAndroid Build Coastguard Worker 
13*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/hash.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/token.h"
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker namespace base {
19*635a8641SAndroid Build Coastguard Worker 
20*635a8641SAndroid Build Coastguard Worker struct UnguessableTokenHash;
21*635a8641SAndroid Build Coastguard Worker 
22*635a8641SAndroid Build Coastguard Worker // UnguessableToken is, like Token, a randomly chosen 128-bit value. Unlike
23*635a8641SAndroid Build Coastguard Worker // Token however, a new UnguessableToken must always be generated at runtime
24*635a8641SAndroid Build Coastguard Worker // from a cryptographically strong random source (or copied or serialized and
25*635a8641SAndroid Build Coastguard Worker // deserialized from another such UnguessableToken). It can be used as part of a
26*635a8641SAndroid Build Coastguard Worker // larger aggregate type, or as an ID in and of itself.
27*635a8641SAndroid Build Coastguard Worker //
28*635a8641SAndroid Build Coastguard Worker // UnguessableToken can be used to implement "Capability-Based Security".
29*635a8641SAndroid Build Coastguard Worker // In other words, UnguessableToken can be used when the resource associated
30*635a8641SAndroid Build Coastguard Worker // with the ID needs to be protected against manipulation by other untrusted
31*635a8641SAndroid Build Coastguard Worker // agents in the system, and there is no other convenient way to verify the
32*635a8641SAndroid Build Coastguard Worker // authority of the agent to do so (because the resource is part of a table
33*635a8641SAndroid Build Coastguard Worker // shared across processes, for instance). In such a scheme, knowledge of the
34*635a8641SAndroid Build Coastguard Worker // token value in and of itself is sufficient proof of authority to carry out
35*635a8641SAndroid Build Coastguard Worker // an operation against the associated resource.
36*635a8641SAndroid Build Coastguard Worker //
37*635a8641SAndroid Build Coastguard Worker // Use Create() for creating new UnguessableTokens.
38*635a8641SAndroid Build Coastguard Worker //
39*635a8641SAndroid Build Coastguard Worker // NOTE: It is illegal to send empty UnguessableTokens across processes, and
40*635a8641SAndroid Build Coastguard Worker // sending/receiving empty tokens should be treated as a security issue.
41*635a8641SAndroid Build Coastguard Worker // If there is a valid scenario for sending "no token" across processes,
42*635a8641SAndroid Build Coastguard Worker // base::Optional should be used instead of an empty token.
43*635a8641SAndroid Build Coastguard Worker class BASE_EXPORT UnguessableToken {
44*635a8641SAndroid Build Coastguard Worker  public:
45*635a8641SAndroid Build Coastguard Worker   // Create a unique UnguessableToken.
46*635a8641SAndroid Build Coastguard Worker   static UnguessableToken Create();
47*635a8641SAndroid Build Coastguard Worker 
48*635a8641SAndroid Build Coastguard Worker   // Returns a reference to a global null UnguessableToken. This should only be
49*635a8641SAndroid Build Coastguard Worker   // used for functions that need to return a reference to an UnguessableToken,
50*635a8641SAndroid Build Coastguard Worker   // and should not be used as a general-purpose substitute for invoking the
51*635a8641SAndroid Build Coastguard Worker   // default constructor.
52*635a8641SAndroid Build Coastguard Worker   static const UnguessableToken& Null();
53*635a8641SAndroid Build Coastguard Worker 
54*635a8641SAndroid Build Coastguard Worker   // Return a UnguessableToken built from the high/low bytes provided.
55*635a8641SAndroid Build Coastguard Worker   // It should only be used in deserialization scenarios.
56*635a8641SAndroid Build Coastguard Worker   //
57*635a8641SAndroid Build Coastguard Worker   // NOTE: If the deserialized token is empty, it means that it was never
58*635a8641SAndroid Build Coastguard Worker   // initialized via Create(). This is a security issue, and should be handled.
59*635a8641SAndroid Build Coastguard Worker   static UnguessableToken Deserialize(uint64_t high, uint64_t low);
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   // Creates an empty UnguessableToken.
62*635a8641SAndroid Build Coastguard Worker   // Assign to it with Create() before using it.
63*635a8641SAndroid Build Coastguard Worker   constexpr UnguessableToken() = default;
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker   // NOTE: Serializing an empty UnguessableToken is an illegal operation.
GetHighForSerialization()66*635a8641SAndroid Build Coastguard Worker   uint64_t GetHighForSerialization() const {
67*635a8641SAndroid Build Coastguard Worker     DCHECK(!is_empty());
68*635a8641SAndroid Build Coastguard Worker     return token_.high();
69*635a8641SAndroid Build Coastguard Worker   }
70*635a8641SAndroid Build Coastguard Worker 
71*635a8641SAndroid Build Coastguard Worker   // NOTE: Serializing an empty UnguessableToken is an illegal operation.
GetLowForSerialization()72*635a8641SAndroid Build Coastguard Worker   uint64_t GetLowForSerialization() const {
73*635a8641SAndroid Build Coastguard Worker     DCHECK(!is_empty());
74*635a8641SAndroid Build Coastguard Worker     return token_.low();
75*635a8641SAndroid Build Coastguard Worker   }
76*635a8641SAndroid Build Coastguard Worker 
is_empty()77*635a8641SAndroid Build Coastguard Worker   bool is_empty() const { return token_.is_zero(); }
78*635a8641SAndroid Build Coastguard Worker 
79*635a8641SAndroid Build Coastguard Worker   // Hex representation of the unguessable token.
ToString()80*635a8641SAndroid Build Coastguard Worker   std::string ToString() const { return token_.ToString(); }
81*635a8641SAndroid Build Coastguard Worker 
82*635a8641SAndroid Build Coastguard Worker   explicit operator bool() const { return !is_empty(); }
83*635a8641SAndroid Build Coastguard Worker 
84*635a8641SAndroid Build Coastguard Worker   bool operator<(const UnguessableToken& other) const {
85*635a8641SAndroid Build Coastguard Worker     return token_ < other.token_;
86*635a8641SAndroid Build Coastguard Worker   }
87*635a8641SAndroid Build Coastguard Worker 
88*635a8641SAndroid Build Coastguard Worker   bool operator==(const UnguessableToken& other) const {
89*635a8641SAndroid Build Coastguard Worker     return token_ == other.token_;
90*635a8641SAndroid Build Coastguard Worker   }
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker   bool operator!=(const UnguessableToken& other) const {
93*635a8641SAndroid Build Coastguard Worker     return !(*this == other);
94*635a8641SAndroid Build Coastguard Worker   }
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker  private:
97*635a8641SAndroid Build Coastguard Worker   friend struct UnguessableTokenHash;
98*635a8641SAndroid Build Coastguard Worker   explicit UnguessableToken(const Token& token);
99*635a8641SAndroid Build Coastguard Worker 
100*635a8641SAndroid Build Coastguard Worker   base::Token token_;
101*635a8641SAndroid Build Coastguard Worker };
102*635a8641SAndroid Build Coastguard Worker 
103*635a8641SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& out,
104*635a8641SAndroid Build Coastguard Worker                                      const UnguessableToken& token);
105*635a8641SAndroid Build Coastguard Worker 
106*635a8641SAndroid Build Coastguard Worker // For use in std::unordered_map.
107*635a8641SAndroid Build Coastguard Worker struct UnguessableTokenHash {
operatorUnguessableTokenHash108*635a8641SAndroid Build Coastguard Worker   size_t operator()(const base::UnguessableToken& token) const {
109*635a8641SAndroid Build Coastguard Worker     DCHECK(token);
110*635a8641SAndroid Build Coastguard Worker     return TokenHash()(token.token_);
111*635a8641SAndroid Build Coastguard Worker   }
112*635a8641SAndroid Build Coastguard Worker };
113*635a8641SAndroid Build Coastguard Worker 
114*635a8641SAndroid Build Coastguard Worker }  // namespace base
115*635a8641SAndroid Build Coastguard Worker 
116*635a8641SAndroid Build Coastguard Worker #endif  // BASE_UNGUESSABLE_TOKEN_H_
117