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