| // Copyright 2022 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef CRYPTOHOME_AUTH_BLOCKS_PREPARE_TOKEN_H_ | |
| #define CRYPTOHOME_AUTH_BLOCKS_PREPARE_TOKEN_H_ | |
| #include <memory> | |
| #include <utility> | |
| #include <base/functional/callback.h> | |
| #include <libhwsec-foundation/status/status_chain.h> | |
| #include "cryptohome/auth_factor/type.h" | |
| #include "cryptohome/error/cryptohome_error.h" | |
| #include "cryptohome/key_objects.h" | |
| namespace cryptohome { | |
| // Token that represents an active prepared auth factor. The token can be used | |
| // to terminate the factor, and should automatically do so upon destruction. | |
| // | |
| // Note to subclass implementers: you should include a TerminateOnDestruction | |
| // member in your subclass, to ensure you get the correct destructor behavior. | |
| class PreparedAuthFactorToken { | |
| public: | |
| // Standard callback for function that accept a token. The callback will be | |
| // passed either a valid token on success, or a not-OK status on failure. | |
| using Consumer = base::OnceCallback<void( | |
| CryptohomeStatusOr<std::unique_ptr<PreparedAuthFactorToken>>)>; | |
| // Tokens cannot be copied, since they represent a unique active factor. When | |
| // they are destroyed they will automatically terminate the factor, although | |
| // the Status of this termination is lost in that case. | |
| PreparedAuthFactorToken(AuthFactorType auth_factor_type, PrepareOutput output) | |
| : auth_factor_type_(auth_factor_type), output_(std::move(output)) {} | |
| PreparedAuthFactorToken(const PreparedAuthFactorToken&) = delete; | |
| PreparedAuthFactorToken& operator=(const PreparedAuthFactorToken&) = delete; | |
| virtual ~PreparedAuthFactorToken() = default; | |
| // The type of the auth factor that this token is used for. | |
| AuthFactorType auth_factor_type() const { return auth_factor_type_; } | |
| // The output of the prepare operation. | |
| const PrepareOutput& prepare_output() const { return output_; } | |
| // Terminate the factor. Returns a status reporting any errors with the | |
| // termination process, but note that the factor is considered terminated | |
| // after the call regardless of the result. Subsequent calls to terminate will | |
| // do nothing and return OK. | |
| CryptohomeStatus Terminate() { | |
| if (!terminated_) { | |
| terminated_ = true; | |
| return TerminateAuthFactor(); | |
| } | |
| return ::hwsec_foundation::status::OkStatus<error::CryptohomeError>(); | |
| } | |
| protected: | |
| // Helpful RAII style class that will ensure that Terminate() is called upon | |
| // destruction. Subclasses should include this as their last member. Making it | |
| // the last member is important because you'll almost certainly want your | |
| // TerminateAuthFactor implementation to be called before any of the other | |
| // member variables are destroyed. | |
| class TerminateOnDestruction { | |
| public: | |
| explicit TerminateOnDestruction(PreparedAuthFactorToken& token) | |
| : token_(token) {} | |
| TerminateOnDestruction(const TerminateOnDestruction&) = delete; | |
| TerminateOnDestruction& operator=(const TerminateOnDestruction&) = delete; | |
| ~TerminateOnDestruction() { static_cast<void>(token_.Terminate()); } | |
| private: | |
| PreparedAuthFactorToken& token_; | |
| }; | |
| private: | |
| // Override in subclasses to implement termination. Will be called exactly | |
| // once in the lifetime of the token. | |
| virtual CryptohomeStatus TerminateAuthFactor() = 0; | |
| bool terminated_ = false; | |
| const AuthFactorType auth_factor_type_; | |
| const PrepareOutput output_; | |
| }; | |
| } // namespace cryptohome | |
| #endif // CRYPTOHOME_AUTH_BLOCKS_PREPARE_TOKEN_H_ |