// Copyright (c) 2012 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.

#include "chaps/object_policy_private_key.h"

#include <base/logging.h>
#include <base/macros.h>

#include "chaps/chaps.h"
#include "chaps/chaps_utility.h"

namespace chaps {

// Read policy list as follows:
//   {attribute, sensitive, read-only {create, copy, modify}, required}
// sensitive - True if attribute cannot be read.
// read-only.create - True if attribute cannot be set with C_CreateObject.
// read-only.copy - True if attribute cannot be set with C_CopyObject.
// read-only.modify - True if attribute cannot be set with C_SetAttributeValue.
// required - True if attribute is required for a valid object.
static const AttributePolicy kPrivateKeyPolicies[] = {
  {CKA_ALWAYS_SENSITIVE, false, {true, true, true}, false},
  {CKA_NEVER_EXTRACTABLE, false, {true, true, true}, false},
  {CKA_UNWRAP_TEMPLATE, false, {false, false, true}, false},
  {CKA_ALWAYS_AUTHENTICATE, false, {false, false, true}, false},
  // RSA-specific attributes.
  {CKA_MODULUS, false, {false, false, true}, false},
  {CKA_PUBLIC_EXPONENT, false, {false, false, true}, false},
  {CKA_PRIVATE_EXPONENT, true, {false, false, true}, false},
  {CKA_PRIME_1, true, {false, false, true}, false},
  {CKA_PRIME_2, true, {false, false, true}, false},
  {CKA_EXPONENT_1, true, {false, false, true}, false},
  {CKA_EXPONENT_2, true, {false, false, true}, false},
  {CKA_COEFFICIENT, true, {false, false, true}, false},
  // ECC-specific attributes.
  {CKA_EC_PARAMS, false, {false, false, true}, false},
  {CKA_VALUE, false, {false, false, true}, false},
  // TPM backed key attributes.
  {kKeyBlobAttribute, true, {false, true, true}, false},
  {kAuthDataAttribute, true, {false, true, true}, false},
};

ObjectPolicyPrivateKey::ObjectPolicyPrivateKey() {
  AddPolicies(kPrivateKeyPolicies, arraysize(kPrivateKeyPolicies));
}

ObjectPolicyPrivateKey::~ObjectPolicyPrivateKey() {}

bool ObjectPolicyPrivateKey::IsObjectComplete() {
  if (!ObjectPolicyCommon::IsObjectComplete())
    return false;

  auto key_type = object_->GetAttributeInt(CKA_KEY_TYPE, -1);
  if (key_type == CKK_RSA) {
    if (!object_->IsAttributePresent(CKA_MODULUS) ||
        !object_->IsAttributePresent(CKA_PUBLIC_EXPONENT)) {
      LOG(ERROR) << "RSA Private key attributes are required. (Missing public "
                    "infomation)";
      return false;
    }
    // Either a private exponent or a TPM key blob must exist.
    if (!object_->IsAttributePresent(CKA_PRIVATE_EXPONENT) &&
        !object_->IsAttributePresent(kKeyBlobAttribute)) {
      LOG(ERROR) << "RSA Private key attributes are required. (Missing private "
                    "information)";
      return false;
    }
  } else if (key_type == CKK_EC) {
    if (!object_->IsAttributePresent(CKA_EC_PARAMS)) {
      LOG(ERROR) << "ECC Private key attributes are required. (Missing public "
                    "information)";
      return false;
    }
    // Either a private exponent or a TPM key blob must exist.
    if (!object_->IsAttributePresent(CKA_VALUE) &&
        !object_->IsAttributePresent(kKeyBlobAttribute)) {
      LOG(ERROR) << "ECC Private key attributes are required. (Missing private "
                    "information)";
      return false;
    }
  } else {
    LOG(ERROR) << "Unknown CKA_KEY_TYPE for private key";
    return false;
  }
  return true;
}

void ObjectPolicyPrivateKey::SetDefaultAttributes() {
  ObjectPolicyKey::SetDefaultAttributes();
  if (!object_->IsAttributePresent(CKA_SUBJECT))
    object_->SetAttributeString(CKA_SUBJECT, "");
  if (!object_->IsAttributePresent(CKA_SENSITIVE))
    object_->SetAttributeBool(CKA_SENSITIVE, true);
  if (!object_->IsAttributePresent(CKA_DECRYPT))
    object_->SetAttributeBool(CKA_DECRYPT, false);
  if (!object_->IsAttributePresent(CKA_SIGN))
    object_->SetAttributeBool(CKA_SIGN, false);
  if (!object_->IsAttributePresent(CKA_SIGN_RECOVER))
    object_->SetAttributeBool(CKA_SIGN_RECOVER, false);
  if (!object_->IsAttributePresent(CKA_UNWRAP))
    object_->SetAttributeBool(CKA_UNWRAP, false);
  if (!object_->IsAttributePresent(CKA_EXTRACTABLE))
    object_->SetAttributeBool(CKA_EXTRACTABLE, false);
  if (!object_->IsAttributePresent(CKA_WRAP_WITH_TRUSTED))
    object_->SetAttributeBool(CKA_WRAP_WITH_TRUSTED, false);
  if (!object_->IsAttributePresent(CKA_ALWAYS_AUTHENTICATE))
    object_->SetAttributeBool(CKA_ALWAYS_AUTHENTICATE, false);
  if (object_->GetStage() == kCreate) {
    CK_ULONG keygen_mechanism = object_->GetAttributeInt(
        CKA_KEY_GEN_MECHANISM, static_cast<int>(CK_UNAVAILABLE_INFORMATION));
    bool keygen_known = (keygen_mechanism != CK_UNAVAILABLE_INFORMATION);
    if (keygen_known && object_->GetAttributeBool(CKA_SENSITIVE, false))
      object_->SetAttributeBool(CKA_ALWAYS_SENSITIVE, true);
    else
      object_->SetAttributeBool(CKA_ALWAYS_SENSITIVE, false);
    if (keygen_known && !object_->GetAttributeBool(CKA_EXTRACTABLE, true))
      object_->SetAttributeBool(CKA_NEVER_EXTRACTABLE, true);
    else
      object_->SetAttributeBool(CKA_NEVER_EXTRACTABLE, false);
  }
}

}  // namespace chaps
