blob: 9c2defa93a469b78673f26dd6df54461aab07fcb [file] [log] [blame]
// Copyright 2018 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_CHALLENGE_CREDENTIALS_CHALLENGE_CREDENTIALS_HELPER_H_
#define CRYPTOHOME_CHALLENGE_CREDENTIALS_CHALLENGE_CREDENTIALS_HELPER_H_
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include <base/callback.h>
#include <brillo/secure_blob.h>
#include "cryptohome/key_challenge_service.h"
#include "cryptohome/signature_sealing/structures.h"
namespace cryptohome {
// This class provides generation of credentials for challenge-protected vault
// keysets, and verification of key validity for such keysets.
//
// It's expected that the consumer code instantiates a single instance during
// the whole daemon lifetime. This allows to keep the resource usage
// constrained, e.g., to have a limited number of active TPM sessions.
//
// NOTE: This object supports only one operation (GenerateNew() / Decrypt() /
// VerifyKey()) at a time. Starting a new operation before the previous one
// completes will lead to cancellation of the previous operation (i.e., the
// old operation will complete with a failure).
//
// This class must be used on a single thread only.
class ChallengeCredentialsHelper {
public:
// A simple storage struct for storing the results of Decrypt() or
// GenerateNew(). For Decrypt(), the signature_challenge_info field is always
// nullptr.
class GenerateNewOrDecryptResult {
public:
GenerateNewOrDecryptResult(
std::unique_ptr<structure::SignatureChallengeInfo>
signature_challenge_info,
std::unique_ptr<brillo::SecureBlob> passkey)
: info_(std::move(signature_challenge_info)),
passkey_(std::move(passkey)) {}
// Getters
std::unique_ptr<structure::SignatureChallengeInfo> info() {
return std::move(info_);
}
std::unique_ptr<brillo::SecureBlob> passkey() {
return std::move(passkey_);
}
// Const getters
const structure::SignatureChallengeInfo* info() const {
return info_.get();
}
const brillo::SecureBlob* passkey() const { return passkey_.get(); }
private:
std::unique_ptr<structure::SignatureChallengeInfo> info_;
std::unique_ptr<brillo::SecureBlob> passkey_;
};
// This callback reports result of a GenerateNew() call.
//
// If the operation succeeds, the result struct will contain the |passkey|,
// which can be used for decryption of the user's vault keyset, and
// |signature_challenge_info|, which contains the data to be stored in the
// auth block state. If the operation fails, the argument will be the
// TPMStatus on the details of the failure.
using GenerateNewCallback =
base::OnceCallback<void(TPMStatusOr<GenerateNewOrDecryptResult>)>;
// This callback reports result of a Decrypt() call.
//
// If the operation succeeds, result struct will contain the passkey, which
// can be used for decryption of the user's vault keyset. The
// signature_challenge_info field is always nullptr. If the operation fails,
// the argument will be the TPMStatus on details of the failure.
using DecryptCallback =
base::OnceCallback<void(TPMStatusOr<GenerateNewOrDecryptResult>)>;
// This callback reports result of a VerifyKey() call.
//
// The |is_key_valid| argument will be true iff the operation succeeds and
// the provided key is valid for decryption of the given vault keyset.
// An OK status is returned for successful verification. A status with
// kIncorrectAuth is returned if it failed and the user is at fault.
// Otherwise, other actions are returned.
using VerifyKeyCallback = base::OnceCallback<void(TPMStatus)>;
// The maximum number of attempts that will be made for a single operation
// when it fails with a transient error.
static constexpr int kRetryAttemptCount = 3;
ChallengeCredentialsHelper() = default;
ChallengeCredentialsHelper(const ChallengeCredentialsHelper&) = delete;
ChallengeCredentialsHelper& operator=(const ChallengeCredentialsHelper&) =
delete;
virtual ~ChallengeCredentialsHelper() = default;
// Generates and returns fresh random-based credentials for the given user
// and the referenced key, and also returns the encrypted
// (challenge-protected) representation of the created secrets that should
// be stored in the created vault keyset. This operation may involve making
// challenge request(s) against the specified key.
//
// |obfuscated_username| is the obfuscated username; the created credentials
// will be protected in a way that decrypting them back is possible iff the
// current user is satisfied.
//
// The result is reported via |callback|.
virtual void GenerateNew(
const std::string& account_id,
const structure::ChallengePublicKeyInfo& public_key_info,
const std::string& obfuscated_username,
std::unique_ptr<KeyChallengeService> key_challenge_service,
GenerateNewCallback callback) = 0;
// Builds credentials for the given user, based on the encrypted
// (challenge-protected) representation of the previously created secrets. The
// referred cryptographic key should be the same as the one used for the
// secrets generation via GenerateNew(); although a difference in the key's
// supported algorithms may be tolerated in some cases. This operation
// involves making challenge request(s) against the key.
//
// |keyset_challenge_info| is the encrypted representation of secrets as
// created via GenerateNew().
// The result is reported via |callback|.
virtual void Decrypt(
const std::string& account_id,
const structure::ChallengePublicKeyInfo& public_key_info,
const structure::SignatureChallengeInfo& keyset_challenge_info,
bool locked_to_single_user,
std::unique_ptr<KeyChallengeService> key_challenge_service,
DecryptCallback callback) = 0;
// Verifies that the specified cryptographic key is available and can be used
// for authentication. This operation involves making challenge request(s)
// against the key. This method is intended as a lightweight analog of
// Decrypt() for cases where the actual credentials aren't needed.
//
// The result is reported via |callback|.
virtual void VerifyKey(
const std::string& account_id,
const structure::ChallengePublicKeyInfo& public_key_info,
std::unique_ptr<KeyChallengeService> key_challenge_service,
VerifyKeyCallback callback) = 0;
};
} // namespace cryptohome
#endif // CRYPTOHOME_CHALLENGE_CREDENTIALS_CHALLENGE_CREDENTIALS_HELPER_H_