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