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