chromium/base/unguessable_token.h

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_UNGUESSABLE_TOKEN_H_
#define BASE_UNGUESSABLE_TOKEN_H_

#include <stdint.h>
#include <string.h>

#include <compare>
#include <iosfwd>
#include <string_view>
#include <tuple>

#include "base/base_export.h"
#include "base/check.h"
#include "base/containers/span.h"
#include "base/token.h"

namespace base {

struct UnguessableTokenHash;

// UnguessableToken is, like Token, a randomly chosen 128-bit value. Unlike
// Token, a new UnguessableToken is always generated at runtime from a
// cryptographically strong random source (or copied or serialized and
// deserialized from another such UnguessableToken). Also unlike Token, the ==
// and != operators are constant time. It can be used as part of a larger
// aggregate type, or as an ID in and of itself.
//
// An UnguessableToken is a strong *bearer token*. Bearer tokens are like HTTP
// cookies: if a caller has the token, the callee thereby considers the caller
// authorized to request the operation the callee performs.
//
// UnguessableToken can be used when the resource associated with the ID needs
// to be protected against manipulation by other untrusted agents in the system,
// and there is no other convenient way to verify the authority of the agent to
// do so (because the resource is part of a table shared across processes, for
// instance). In such a scheme, knowledge of the token value in and of itself is
// sufficient proof of authority to carry out an operation on the associated
// resource.
//
// Use Create() for creating new UnguessableTokens.
//
// NOTE: It is illegal to send empty UnguessableTokens across processes, and
// sending/receiving empty tokens should be treated as a security issue. If
// there is a valid scenario for sending "no token" across processes, use
// std::optional instead of an empty token.

class BASE_EXPORT UnguessableToken {};

BASE_EXPORT bool operator==(const UnguessableToken& lhs,
                            const UnguessableToken& rhs);

BASE_EXPORT std::ostream& operator<<(std::ostream& out,
                                     const UnguessableToken& token);

// For use in std::unordered_map.
struct UnguessableTokenHash {};

}  // namespace base

#endif  // BASE_UNGUESSABLE_TOKEN_H_