xref: /aosp_15_r20/external/cronet/crypto/signature_verifier.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 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_verifier.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
10*6777b538SAndroid Build Coastguard Worker #include "crypto/openssl_util.h"
11*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/bytestring.h"
12*6777b538SAndroid Build Coastguard Worker #include "third_party/boringssl/src/include/openssl/digest.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 struct SignatureVerifier::VerifyContext {
19*6777b538SAndroid Build Coastguard Worker   bssl::ScopedEVP_MD_CTX ctx;
20*6777b538SAndroid Build Coastguard Worker };
21*6777b538SAndroid Build Coastguard Worker 
22*6777b538SAndroid Build Coastguard Worker SignatureVerifier::SignatureVerifier() = default;
23*6777b538SAndroid Build Coastguard Worker 
24*6777b538SAndroid Build Coastguard Worker SignatureVerifier::~SignatureVerifier() = default;
25*6777b538SAndroid Build Coastguard Worker 
VerifyInit(SignatureAlgorithm signature_algorithm,base::span<const uint8_t> signature,base::span<const uint8_t> public_key_info)26*6777b538SAndroid Build Coastguard Worker bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
27*6777b538SAndroid Build Coastguard Worker                                    base::span<const uint8_t> signature,
28*6777b538SAndroid Build Coastguard Worker                                    base::span<const uint8_t> public_key_info) {
29*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
30*6777b538SAndroid Build Coastguard Worker 
31*6777b538SAndroid Build Coastguard Worker   int pkey_type = EVP_PKEY_NONE;
32*6777b538SAndroid Build Coastguard Worker   const EVP_MD* digest = nullptr;
33*6777b538SAndroid Build Coastguard Worker   switch (signature_algorithm) {
34*6777b538SAndroid Build Coastguard Worker     case RSA_PKCS1_SHA1:
35*6777b538SAndroid Build Coastguard Worker       pkey_type = EVP_PKEY_RSA;
36*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha1();
37*6777b538SAndroid Build Coastguard Worker       break;
38*6777b538SAndroid Build Coastguard Worker     case RSA_PKCS1_SHA256:
39*6777b538SAndroid Build Coastguard Worker     case RSA_PSS_SHA256:
40*6777b538SAndroid Build Coastguard Worker       pkey_type = EVP_PKEY_RSA;
41*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha256();
42*6777b538SAndroid Build Coastguard Worker       break;
43*6777b538SAndroid Build Coastguard Worker     case ECDSA_SHA256:
44*6777b538SAndroid Build Coastguard Worker       pkey_type = EVP_PKEY_EC;
45*6777b538SAndroid Build Coastguard Worker       digest = EVP_sha256();
46*6777b538SAndroid Build Coastguard Worker       break;
47*6777b538SAndroid Build Coastguard Worker   }
48*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(EVP_PKEY_NONE, pkey_type);
49*6777b538SAndroid Build Coastguard Worker   DCHECK(digest);
50*6777b538SAndroid Build Coastguard Worker 
51*6777b538SAndroid Build Coastguard Worker   if (verify_context_)
52*6777b538SAndroid Build Coastguard Worker     return false;
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker   verify_context_ = std::make_unique<VerifyContext>();
55*6777b538SAndroid Build Coastguard Worker   signature_.assign(signature.data(), signature.data() + signature.size());
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker   CBS cbs;
58*6777b538SAndroid Build Coastguard Worker   CBS_init(&cbs, public_key_info.data(), public_key_info.size());
59*6777b538SAndroid Build Coastguard Worker   bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs));
60*6777b538SAndroid Build Coastguard Worker   if (!public_key || CBS_len(&cbs) != 0 ||
61*6777b538SAndroid Build Coastguard Worker       EVP_PKEY_id(public_key.get()) != pkey_type) {
62*6777b538SAndroid Build Coastguard Worker     return false;
63*6777b538SAndroid Build Coastguard Worker   }
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   EVP_PKEY_CTX* pkey_ctx;
66*6777b538SAndroid Build Coastguard Worker   if (!EVP_DigestVerifyInit(verify_context_->ctx.get(), &pkey_ctx, digest,
67*6777b538SAndroid Build Coastguard Worker                             nullptr, public_key.get())) {
68*6777b538SAndroid Build Coastguard Worker     return false;
69*6777b538SAndroid Build Coastguard Worker   }
70*6777b538SAndroid Build Coastguard Worker 
71*6777b538SAndroid Build Coastguard Worker   if (signature_algorithm == RSA_PSS_SHA256) {
72*6777b538SAndroid Build Coastguard Worker     if (!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
73*6777b538SAndroid Build Coastguard Worker         !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, digest) ||
74*6777b538SAndroid Build Coastguard Worker         !EVP_PKEY_CTX_set_rsa_pss_saltlen(
75*6777b538SAndroid Build Coastguard Worker             pkey_ctx, -1 /* match digest and salt length */)) {
76*6777b538SAndroid Build Coastguard Worker       return false;
77*6777b538SAndroid Build Coastguard Worker     }
78*6777b538SAndroid Build Coastguard Worker   }
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker   return true;
81*6777b538SAndroid Build Coastguard Worker }
82*6777b538SAndroid Build Coastguard Worker 
VerifyUpdate(base::span<const uint8_t> data_part)83*6777b538SAndroid Build Coastguard Worker void SignatureVerifier::VerifyUpdate(base::span<const uint8_t> data_part) {
84*6777b538SAndroid Build Coastguard Worker   DCHECK(verify_context_);
85*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
86*6777b538SAndroid Build Coastguard Worker   int rv = EVP_DigestVerifyUpdate(verify_context_->ctx.get(), data_part.data(),
87*6777b538SAndroid Build Coastguard Worker                                   data_part.size());
88*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(rv, 1);
89*6777b538SAndroid Build Coastguard Worker }
90*6777b538SAndroid Build Coastguard Worker 
VerifyFinal()91*6777b538SAndroid Build Coastguard Worker bool SignatureVerifier::VerifyFinal() {
92*6777b538SAndroid Build Coastguard Worker   DCHECK(verify_context_);
93*6777b538SAndroid Build Coastguard Worker   OpenSSLErrStackTracer err_tracer(FROM_HERE);
94*6777b538SAndroid Build Coastguard Worker   int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(), signature_.data(),
95*6777b538SAndroid Build Coastguard Worker                                  signature_.size());
96*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(static_cast<int>(!!rv), rv);
97*6777b538SAndroid Build Coastguard Worker   Reset();
98*6777b538SAndroid Build Coastguard Worker   return rv == 1;
99*6777b538SAndroid Build Coastguard Worker }
100*6777b538SAndroid Build Coastguard Worker 
Reset()101*6777b538SAndroid Build Coastguard Worker void SignatureVerifier::Reset() {
102*6777b538SAndroid Build Coastguard Worker   verify_context_.reset();
103*6777b538SAndroid Build Coastguard Worker   signature_.clear();
104*6777b538SAndroid Build Coastguard Worker }
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker }  // namespace crypto
107