[go: nahoru, domu]

blob: 089fdb8bd5f8fba6a0c291c69bd8df02ed9e235a [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/enterprise/connectors/device_trust/key_management/core/ec_signing_key.h"
#include <memory>
#include "base/check.h"
#include "base/check_op.h"
#include "crypto/ec_signature_creator.h"
namespace enterprise_connectors {
namespace {
// An implementation of crypto::UnexportableSigningKey that is backed by an
// instance of crypto::ECPrivateKey.
class ECSigningKey : public crypto::UnexportableSigningKey {
public:
ECSigningKey();
explicit ECSigningKey(base::span<const uint8_t> wrapped);
~ECSigningKey() override;
// crypto::UnexportableSigningKey:
crypto::SignatureVerifier::SignatureAlgorithm Algorithm() const override;
std::vector<uint8_t> GetSubjectPublicKeyInfo() const override;
std::vector<uint8_t> GetWrappedKey() const override;
absl::optional<std::vector<uint8_t>> SignSlowly(
base::span<const uint8_t> data) override;
private:
std::unique_ptr<crypto::ECPrivateKey> key_;
};
ECSigningKey::ECSigningKey() {
key_ = crypto::ECPrivateKey::Create();
DCHECK(key_);
}
ECSigningKey::ECSigningKey(base::span<const uint8_t> wrapped) {
key_ = crypto::ECPrivateKey::CreateFromPrivateKeyInfo(wrapped);
DCHECK(key_);
}
ECSigningKey::~ECSigningKey() = default;
crypto::SignatureVerifier::SignatureAlgorithm ECSigningKey::Algorithm() const {
return crypto::SignatureVerifier::ECDSA_SHA256;
}
std::vector<uint8_t> ECSigningKey::GetSubjectPublicKeyInfo() const {
std::vector<uint8_t> pubkey;
bool ok = key_->ExportPublicKey(&pubkey);
DCHECK(ok);
return pubkey;
}
std::vector<uint8_t> ECSigningKey::GetWrappedKey() const {
std::vector<uint8_t> wrapped;
bool ok = key_->ExportPrivateKey(&wrapped);
DCHECK(ok);
return wrapped;
}
absl::optional<std::vector<uint8_t>> ECSigningKey::SignSlowly(
base::span<const uint8_t> data) {
std::vector<uint8_t> signature;
auto signer = crypto::ECSignatureCreator::Create(key_.get());
DCHECK(signer);
bool ok = signer->Sign(data, &signature);
DCHECK(ok);
return signature;
}
} // namespace
ECSigningKeyProvider::ECSigningKeyProvider() = default;
ECSigningKeyProvider::~ECSigningKeyProvider() = default;
absl::optional<crypto::SignatureVerifier::SignatureAlgorithm>
ECSigningKeyProvider::SelectAlgorithm(
base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
acceptable_algorithms) {
for (auto algo : acceptable_algorithms) {
if (algo == crypto::SignatureVerifier::ECDSA_SHA256)
return crypto::SignatureVerifier::ECDSA_SHA256;
}
return absl::nullopt;
}
std::unique_ptr<crypto::UnexportableSigningKey>
ECSigningKeyProvider::GenerateSigningKeySlowly(
base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
acceptable_algorithms) {
auto algo = SelectAlgorithm(acceptable_algorithms);
if (!algo)
return nullptr;
DCHECK_EQ(crypto::SignatureVerifier::ECDSA_SHA256, *algo);
return std::make_unique<ECSigningKey>();
}
std::unique_ptr<crypto::UnexportableSigningKey>
ECSigningKeyProvider::FromWrappedSigningKeySlowly(
base::span<const uint8_t> wrapped_key) {
return std::make_unique<ECSigningKey>(wrapped_key);
}
} // namespace enterprise_connectors