1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "crypto/signature_creator.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/check.h"
11*6777b538SAndroid Build Coastguard Worker #include "crypto/openssl_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "crypto/rsa_private_key.h"
13*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/evp.h"
14*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/rsa.h"
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker namespace crypto {
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker namespace {
19*6777b538SAndroid Build Coastguard Worker
ToOpenSSLDigest(SignatureCreator::HashAlgorithm hash_alg)20*6777b538SAndroid Build Coastguard Worker const EVP_MD* ToOpenSSLDigest(SignatureCreator::HashAlgorithm hash_alg) {
21*6777b538SAndroid Build Coastguard Worker switch (hash_alg) {
22*6777b538SAndroid Build Coastguard Worker case SignatureCreator::SHA1:
23*6777b538SAndroid Build Coastguard Worker return EVP_sha1();
24*6777b538SAndroid Build Coastguard Worker case SignatureCreator::SHA256:
25*6777b538SAndroid Build Coastguard Worker return EVP_sha256();
26*6777b538SAndroid Build Coastguard Worker }
27*6777b538SAndroid Build Coastguard Worker return nullptr;
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker
ToOpenSSLDigestType(SignatureCreator::HashAlgorithm hash_alg)30*6777b538SAndroid Build Coastguard Worker int ToOpenSSLDigestType(SignatureCreator::HashAlgorithm hash_alg) {
31*6777b538SAndroid Build Coastguard Worker switch (hash_alg) {
32*6777b538SAndroid Build Coastguard Worker case SignatureCreator::SHA1:
33*6777b538SAndroid Build Coastguard Worker return NID_sha1;
34*6777b538SAndroid Build Coastguard Worker case SignatureCreator::SHA256:
35*6777b538SAndroid Build Coastguard Worker return NID_sha256;
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker return NID_undef;
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker } // namespace
41*6777b538SAndroid Build Coastguard Worker
42*6777b538SAndroid Build Coastguard Worker SignatureCreator::~SignatureCreator() = default;
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker // static
Create(RSAPrivateKey * key,HashAlgorithm hash_alg)45*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SignatureCreator> SignatureCreator::Create(
46*6777b538SAndroid Build Coastguard Worker RSAPrivateKey* key,
47*6777b538SAndroid Build Coastguard Worker HashAlgorithm hash_alg) {
48*6777b538SAndroid Build Coastguard Worker OpenSSLErrStackTracer err_tracer(FROM_HERE);
49*6777b538SAndroid Build Coastguard Worker std::unique_ptr<SignatureCreator> result(new SignatureCreator);
50*6777b538SAndroid Build Coastguard Worker const EVP_MD* const digest = ToOpenSSLDigest(hash_alg);
51*6777b538SAndroid Build Coastguard Worker DCHECK(digest);
52*6777b538SAndroid Build Coastguard Worker if (!digest) {
53*6777b538SAndroid Build Coastguard Worker return nullptr;
54*6777b538SAndroid Build Coastguard Worker }
55*6777b538SAndroid Build Coastguard Worker if (!EVP_DigestSignInit(result->sign_context_.get(), nullptr, digest, nullptr,
56*6777b538SAndroid Build Coastguard Worker key->key())) {
57*6777b538SAndroid Build Coastguard Worker return nullptr;
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker return result;
60*6777b538SAndroid Build Coastguard Worker }
61*6777b538SAndroid Build Coastguard Worker
62*6777b538SAndroid Build Coastguard Worker // static
Sign(RSAPrivateKey * key,HashAlgorithm hash_alg,const uint8_t * data,int data_len,std::vector<uint8_t> * signature)63*6777b538SAndroid Build Coastguard Worker bool SignatureCreator::Sign(RSAPrivateKey* key,
64*6777b538SAndroid Build Coastguard Worker HashAlgorithm hash_alg,
65*6777b538SAndroid Build Coastguard Worker const uint8_t* data,
66*6777b538SAndroid Build Coastguard Worker int data_len,
67*6777b538SAndroid Build Coastguard Worker std::vector<uint8_t>* signature) {
68*6777b538SAndroid Build Coastguard Worker bssl::UniquePtr<RSA> rsa_key(EVP_PKEY_get1_RSA(key->key()));
69*6777b538SAndroid Build Coastguard Worker if (!rsa_key)
70*6777b538SAndroid Build Coastguard Worker return false;
71*6777b538SAndroid Build Coastguard Worker signature->resize(RSA_size(rsa_key.get()));
72*6777b538SAndroid Build Coastguard Worker
73*6777b538SAndroid Build Coastguard Worker unsigned int len = 0;
74*6777b538SAndroid Build Coastguard Worker if (!RSA_sign(ToOpenSSLDigestType(hash_alg), data, data_len,
75*6777b538SAndroid Build Coastguard Worker signature->data(), &len, rsa_key.get())) {
76*6777b538SAndroid Build Coastguard Worker signature->clear();
77*6777b538SAndroid Build Coastguard Worker return false;
78*6777b538SAndroid Build Coastguard Worker }
79*6777b538SAndroid Build Coastguard Worker signature->resize(len);
80*6777b538SAndroid Build Coastguard Worker return true;
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker
Update(const uint8_t * data_part,int data_part_len)83*6777b538SAndroid Build Coastguard Worker bool SignatureCreator::Update(const uint8_t* data_part, int data_part_len) {
84*6777b538SAndroid Build Coastguard Worker OpenSSLErrStackTracer err_tracer(FROM_HERE);
85*6777b538SAndroid Build Coastguard Worker return !!EVP_DigestSignUpdate(sign_context_.get(), data_part, data_part_len);
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker
Final(std::vector<uint8_t> * signature)88*6777b538SAndroid Build Coastguard Worker bool SignatureCreator::Final(std::vector<uint8_t>* signature) {
89*6777b538SAndroid Build Coastguard Worker OpenSSLErrStackTracer err_tracer(FROM_HERE);
90*6777b538SAndroid Build Coastguard Worker
91*6777b538SAndroid Build Coastguard Worker // Determine the maximum length of the signature.
92*6777b538SAndroid Build Coastguard Worker size_t len = 0;
93*6777b538SAndroid Build Coastguard Worker if (!EVP_DigestSignFinal(sign_context_.get(), nullptr, &len)) {
94*6777b538SAndroid Build Coastguard Worker signature->clear();
95*6777b538SAndroid Build Coastguard Worker return false;
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker signature->resize(len);
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker // Sign it.
100*6777b538SAndroid Build Coastguard Worker if (!EVP_DigestSignFinal(sign_context_.get(), signature->data(), &len)) {
101*6777b538SAndroid Build Coastguard Worker signature->clear();
102*6777b538SAndroid Build Coastguard Worker return false;
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker signature->resize(len);
105*6777b538SAndroid Build Coastguard Worker return true;
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker
SignatureCreator()108*6777b538SAndroid Build Coastguard Worker SignatureCreator::SignatureCreator() : sign_context_(EVP_MD_CTX_new()) {}
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker } // namespace crypto
111