//
// Copyright (c) 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 TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_
#define TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_

#include <memory>
#include <string>

#include <trunks/scoped_global_session.h>
#include <trunks/tpm_utility_impl.h>

#include "tpm_manager/server/tpm_status.h"

namespace tpm_manager {

// Enable salting for global session.
const bool kGlobalSessionSalted = true;
// Enable encryption for global session.
const bool kGlobalSessionEncryption = true;

/*
 * NvIndexAuthenticator is a helper class which hold the needed variable used
 * for creating and holding the ownership of authorization session and
 * released when desturcting.
 *
 * The usage:
 *  NvIndexAuthenticator nvindex_auth(tpm_status_, &trunks_session_,
 *        trunks_factory_);
 * and then call the helper to initialize a session and get delegate when
 * needed.
 *
 * It is used only in tpm2_nvram_impl.cc currently.
 */
class NvIndexAuthenticator {
 public:
  NvIndexAuthenticator(TpmStatus* tpm_status,
                       std::unique_ptr<trunks::HmacSession>* trunks_session,
                       const trunks::TrunksFactory& factory)
      : tpm_status_(tpm_status),
        trunks_factory_(factory),
        trunks_session_(trunks_session),
        password_delegate_(nullptr),
        session_scope_(nullptr) {
    CHECK(tpm_status_);
  }

  trunks::AuthorizationDelegate* GetDirectAuthDelegate(
      const std::string& authorization_value) {
    if (authorization_value.empty() ||
        tpm_status_->CheckAndNotifyIfTpmOwned() != TpmStatus::kTpmOwned) {
      password_delegate_ =
          trunks_factory_.GetPasswordAuthorization(authorization_value);
      return password_delegate_.get();
    } else {
      return SetupHMACSession(authorization_value);
    }
  }

  trunks::AuthorizationDelegate* GetOwnerAuthDelegate(
      const std::string& owner_password) {
    switch (tpm_status_->CheckAndNotifyIfTpmOwned()) {
      case TpmStatus::kTpmUnowned:
        password_delegate_ = trunks_factory_.GetPasswordAuthorization("");
        return password_delegate_.get();
      case TpmStatus::kTpmPreOwned:
        password_delegate_ = trunks_factory_.GetPasswordAuthorization(
            trunks::kWellKnownPassword);
        return password_delegate_.get();
      case TpmStatus::kTpmOwned:
        // return error if TPM is owned but the owner_password is not availible
        if (owner_password.empty()) {
          // The owner password has been destroyed.
          return nullptr;
        }
        return SetupHMACSession(owner_password);
    }
  }

 private:
  /*
   * helper to initialize the HMAC session
   * return the delegate if initialize successfully. Otherwise, return nullptr.
   */
  trunks::AuthorizationDelegate* SetupHMACSession(
      const std::string& authorization_value) {
    session_scope_ = std::make_unique<trunks::ScopedGlobalHmacSession>(
        &trunks_factory_, kGlobalSessionSalted, kGlobalSessionEncryption,
        trunks_session_);
    if (!*trunks_session_) {
      // Session failure
      return nullptr;
    }
    (*trunks_session_)->SetEntityAuthorizationValue(authorization_value);
    return (*trunks_session_)->GetDelegate();
  }

  TpmStatus* tpm_status_;
  const trunks::TrunksFactory& trunks_factory_;

  std::unique_ptr<trunks::HmacSession>* trunks_session_;
  std::unique_ptr<trunks::AuthorizationDelegate> password_delegate_;
  std::unique_ptr<trunks::ScopedGlobalHmacSession> session_scope_;
};

}  // namespace tpm_manager

#endif  // TPM_MANAGER_SERVER_NV_INDEX_AUTHENTICATOR_H_
