blob: 033a9dddb475ca10484a4d6534c860d9763c40c5 [file] [log] [blame]
// Copyright 2022 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CRYPTOHOME_ERROR_CRYPTOHOME_ERROR_H_
#define CRYPTOHOME_ERROR_CRYPTOHOME_ERROR_H_
#include <optional>
#include <set>
#include <sstream>
#include <string>
#include <utility>
#include <cryptohome/proto_bindings/UserDataAuth.pb.h>
#include <libhwsec-foundation/error/error.h>
#include <libhwsec-foundation/status/status_chain_or.h>
#include "cryptohome/error/action.h"
namespace cryptohome {
namespace error {
class CryptohomeError : public hwsec_foundation::status::Error {
public:
using BaseErrorType = CryptohomeError;
// Note that while ErrorLocation is represented as an integer, the error
// location specifier defined in locations.h is its own enum. The reason for
// this difference is that this integer have to encompasses values greater
// than the range of the locations specified in locations.h, particularly the
// codes converted from TPMError and related.
using ErrorLocation = int64_t;
// Pull the ErrorAction enum in for convenience.
using Action = ErrorAction;
// Holder for the string and numerical representation of the error location.
class ErrorLocationPair {
public:
ErrorLocationPair(const ErrorLocation input_loc,
const std::string& input_name)
: loc_(input_loc), name_(input_name) {}
// This class is copyable or movable with the default copy/move
// constructor/assigment operator.
// Getter for the location enum or the name.
ErrorLocation location() const { return loc_; }
const std::string& name() const { return name_; }
private:
const ErrorLocation loc_;
const std::string name_;
};
struct MakeStatusTrait {
// |Unactioned| represents an intermediate state, when we create an error
// without fully specifying that error. That allows to require Wrap to be
// called, or otherwise a type mismatch error will be raised.
class Unactioned {
public:
Unactioned(const ErrorLocationPair& loc,
const std::optional<user_data_auth::CryptohomeErrorCode> ec);
hwsec_foundation::status::StatusChain<CryptohomeError> Wrap(
hwsec_foundation::status::StatusChain<CryptohomeError> status) &&;
private:
const ErrorLocationPair loc_;
const std::optional<user_data_auth::CryptohomeErrorCode> ec_;
};
// Create a stub with no recommended error action. We need to wrap another
// |CryptohomeError| for it to become a valid status chain.
Unactioned operator()(
const ErrorLocationPair& loc,
const std::optional<user_data_auth::CryptohomeErrorCode> ec =
std::nullopt);
// Direct creation.
hwsec_foundation::status::StatusChain<CryptohomeError> operator()(
const ErrorLocationPair& loc,
const std::set<Action>& actions,
const std::optional<user_data_auth::CryptohomeErrorCode> ec =
std::nullopt);
};
// Standard constructor taking the error location and actions.
CryptohomeError(const ErrorLocationPair& loc,
const std::set<Action>& actions,
const std::optional<user_data_auth::CryptohomeErrorCode> ec =
std::nullopt);
~CryptohomeError() override = default;
// Return the location id in this error.
ErrorLocation local_location() const { return loc_.location(); }
// Return the recommended actions in this error (but not the wrapped ones).
const std::set<Action>& local_actions() const { return actions_; }
// Return the legacy error code.
std::optional<user_data_auth::CryptohomeErrorCode> local_legacy_error()
const {
return ec_;
}
// If we are wrapping a CryptohomeError - concatenate the error id.
std::string ToString() const override;
private:
// From where was the error triggered?
ErrorLocationPair loc_;
// What do we recommend the upper layers do?
std::set<Action> actions_;
// The legacy dbus error code.
std::optional<user_data_auth::CryptohomeErrorCode> ec_;
};
} // namespace error
// Define an alias in the cryptohome namespace for easier access.
using CryptohomeStatus =
hwsec_foundation::status::StatusChain<error::CryptohomeError>;
template <typename _Et>
using CryptohomeStatusOr =
hwsec_foundation::status::StatusChainOr<_Et, error::CryptohomeError>;
} // namespace cryptohome
#endif // CRYPTOHOME_ERROR_CRYPTOHOME_ERROR_H_