blob: cafeb9db5ddcdefe577878034eaa49c4223154e1 [file] [log] [blame]
// Copyright 2017 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.
//
// Utility classes for cert_provision library.
#include <base/logging.h>
#include <brillo/secure_blob.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/rsa.h>
#include <openssl/sha.h>
#include <openssl/x509.h>
#include "cryptohome/cert_provision_util.h"
namespace {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
static inline void RSA_get0_key(const RSA *rsa, const BIGNUM **n,
const BIGNUM **e, const BIGNUM **d) {
if (n != nullptr) *n = rsa->n;
if (e != nullptr) *e = rsa->e;
if (d != nullptr) *d = rsa->d;
}
#endif
} // namespace
namespace cert_provision {
void ProgressReporter::Step(const std::string& message) {
VLOG(1) << "Step " << cur_step_ << "/" << total_steps_ << ": " << message;
Report(Status::Success, cur_step_, total_steps_, message);
if (cur_step_ < total_steps_) {
cur_step_++;
}
}
void ProgressReporter::Report(Status status,
int cur_step,
int total_steps,
const std::string& message) {
int progress;
if (cur_step == 0) {
progress = 0;
} else if (cur_step >= total_steps) {
progress = 100;
} else {
progress = (cur_step * 100) / total_steps;
}
callback_.Run(status, progress, message);
}
std::string GetKeyID(const brillo::SecureBlob& public_key) {
const unsigned char* ptr = public_key.data();
crypto::ScopedRSA rsa(d2i_RSA_PUBKEY(NULL, &ptr, public_key.size()));
if (!rsa.get()) {
LOG(ERROR) << "Failed to decode public key.";
return std::string();
}
brillo::SecureBlob modulus(RSA_size(rsa.get()));
const BIGNUM* rsa_n;
RSA_get0_key(rsa.get(), &rsa_n, NULL, NULL);
int len = BN_bn2bin(rsa_n, modulus.data());
if (len <= 0) {
LOG(ERROR) << "Failed to extract public key modulus.";
return std::string();
}
modulus.resize(len);
SHA_CTX sha_context;
unsigned char md_value[SHA_DIGEST_LENGTH];
SHA1_Init(&sha_context);
SHA1_Update(&sha_context, modulus.data(), modulus.size());
SHA1_Final(md_value, &sha_context);
return std::string(reinterpret_cast<char*>(md_value), arraysize(md_value));
}
} // namespace cert_provision