1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
/* -*- indent-tabs-mode: nil -*- */
#include "log/signer.h"
#include <glog/logging.h>
#include <openssl/evp.h>
#include <openssl/opensslv.h>
#include <stdint.h>
#include "log/verifier.h"
#include "proto/ct.pb.h"
#include "util/util.h"
#if OPENSSL_VERSION_NUMBER < 0x10000000
#error "Need OpenSSL >= 1.0.0"
#endif
using cert_trans::Verifier;
namespace cert_trans {
Signer::Signer(EVP_PKEY* pkey) : pkey_(CHECK_NOTNULL(pkey)) {
switch (pkey_->type) {
case EVP_PKEY_EC:
hash_algo_ = ct::DigitallySigned::SHA256;
sig_algo_ = ct::DigitallySigned::ECDSA;
break;
case EVP_PKEY_RSA:
hash_algo_ = ct::DigitallySigned::SHA256;
sig_algo_ = ct::DigitallySigned::RSA;
break;
default:
LOG(FATAL) << "Unsupported key type " << pkey_->type;
}
key_id_ = Verifier::ComputeKeyID(pkey_.get());
}
std::string Signer::KeyID() const {
return key_id_;
}
void Signer::Sign(const std::string& data,
ct::DigitallySigned* signature) const {
signature->set_hash_algorithm(hash_algo_);
signature->set_sig_algorithm(sig_algo_);
signature->set_signature(RawSign(data));
}
Signer::Signer()
: hash_algo_(ct::DigitallySigned::NONE),
sig_algo_(ct::DigitallySigned::ANONYMOUS) {
}
std::string Signer::RawSign(const std::string& data) const {
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
// NOTE: this syntax for setting the hash function requires OpenSSL >= 1.0.0.
CHECK_EQ(1, EVP_SignInit(&ctx, EVP_sha256()));
CHECK_EQ(1, EVP_SignUpdate(&ctx, data.data(), data.size()));
unsigned int sig_size = EVP_PKEY_size(pkey_.get());
unsigned char* sig = new unsigned char[sig_size];
CHECK_EQ(1, EVP_SignFinal(&ctx, sig, &sig_size, pkey_.get()));
EVP_MD_CTX_cleanup(&ctx);
std::string ret(reinterpret_cast<char*>(sig), sig_size);
delete[] sig;
return ret;
}
} // namespace cert_trans
|