xref: /aosp_15_r20/external/cronet/crypto/signature_creator.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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