File: signer.cc

package info (click to toggle)
golang-github-google-certificate-transparency 0.0~git20160709.0.0f6e3d1~ds1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, buster
  • size: 5,676 kB
  • sloc: cpp: 35,278; python: 11,838; java: 1,911; sh: 1,885; makefile: 950; xml: 520; ansic: 225
file content (71 lines) | stat: -rw-r--r-- 1,867 bytes parent folder | download
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