[go: nahoru, domu]

blob: f510546c58998e2c4de44b28b00cb9a618ffd41e [file] [log] [blame]
Avi Drissman201a9a832022-09-13 19:39:251// Copyright 2011 The Chromium Authors
joth@chromium.org70372d42010-10-22 13:12:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
rvargas@google.com4b559b4d2011-04-14 17:37:145#include "crypto/signature_verifier.h"
joth@chromium.org70372d42010-10-22 13:12:346
Peter Boströmfb60ea02021-04-05 21:06:127#include <memory>
8
Hans Wennborg4d0e1802020-04-24 20:19:439#include "base/check_op.h"
rvargas@google.com4b559b4d2011-04-14 17:37:1410#include "crypto/openssl_util.h"
tfarina29a3a1742016-10-28 18:47:3311#include "third_party/boringssl/src/include/openssl/bytestring.h"
12#include "third_party/boringssl/src/include/openssl/digest.h"
13#include "third_party/boringssl/src/include/openssl/evp.h"
14#include "third_party/boringssl/src/include/openssl/rsa.h"
joth@chromium.org70372d42010-10-22 13:12:3415
rvargas@google.com4b559b4d2011-04-14 17:37:1416namespace crypto {
joth@chromium.org70372d42010-10-22 13:12:3417
joth@chromium.orgbe796bb2010-11-18 15:43:4318struct SignatureVerifier::VerifyContext {
davidben74f67442016-10-01 01:45:2219 bssl::ScopedEVP_MD_CTX ctx;
joth@chromium.orgbe796bb2010-11-18 15:43:4320};
21
Chris Watkinsa850a302017-11-30 03:53:4922SignatureVerifier::SignatureVerifier() = default;
joth@chromium.org70372d42010-10-22 13:12:3423
Chris Watkinsa850a302017-11-30 03:53:4924SignatureVerifier::~SignatureVerifier() = default;
joth@chromium.org70372d42010-10-22 13:12:3425
davidben9c97a362016-03-03 16:18:2626bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
David Benjamin8ed923192018-04-13 23:17:0627 base::span<const uint8_t> signature,
28 base::span<const uint8_t> public_key_info) {
David Benjamin8982fe4f2018-02-06 19:30:3229 OpenSSLErrStackTracer err_tracer(FROM_HERE);
30
davidben9c97a362016-03-03 16:18:2631 int pkey_type = EVP_PKEY_NONE;
32 const EVP_MD* digest = nullptr;
33 switch (signature_algorithm) {
34 case RSA_PKCS1_SHA1:
35 pkey_type = EVP_PKEY_RSA;
36 digest = EVP_sha1();
37 break;
38 case RSA_PKCS1_SHA256:
David Benjamin8982fe4f2018-02-06 19:30:3239 case RSA_PSS_SHA256:
davidben9c97a362016-03-03 16:18:2640 pkey_type = EVP_PKEY_RSA;
41 digest = EVP_sha256();
42 break;
43 case ECDSA_SHA256:
44 pkey_type = EVP_PKEY_EC;
45 digest = EVP_sha256();
46 break;
rtenneti@chromium.org2662ed562013-07-03 10:27:4647 }
davidben9c97a362016-03-03 16:18:2648 DCHECK_NE(EVP_PKEY_NONE, pkey_type);
49 DCHECK(digest);
wtc@chromium.org9b8986612013-06-28 17:46:5350
David Benjamin8982fe4f2018-02-06 19:30:3251 if (verify_context_)
52 return false;
wtc@chromium.org9b8986612013-06-28 17:46:5353
Peter Boströmfb60ea02021-04-05 21:06:1254 verify_context_ = std::make_unique<VerifyContext>();
David Benjamin8ed923192018-04-13 23:17:0655 signature_.assign(signature.data(), signature.data() + signature.size());
David Benjamin8982fe4f2018-02-06 19:30:3256
57 CBS cbs;
David Benjamin8ed923192018-04-13 23:17:0658 CBS_init(&cbs, public_key_info.data(), public_key_info.size());
David Benjamin8982fe4f2018-02-06 19:30:3259 bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs));
60 if (!public_key || CBS_len(&cbs) != 0 ||
61 EVP_PKEY_id(public_key.get()) != pkey_type) {
davidben@chromium.orgedfd0f42014-07-22 18:20:3762 return false;
63 }
joth@chromium.orgbe796bb2010-11-18 15:43:4364
wtc@chromium.org9b8986612013-06-28 17:46:5365 EVP_PKEY_CTX* pkey_ctx;
David Benjamin8982fe4f2018-02-06 19:30:3266 if (!EVP_DigestVerifyInit(verify_context_->ctx.get(), &pkey_ctx, digest,
67 nullptr, public_key.get())) {
wtc@chromium.org9b8986612013-06-28 17:46:5368 return false;
69 }
70
David Benjamin8982fe4f2018-02-06 19:30:3271 if (signature_algorithm == RSA_PSS_SHA256) {
72 if (!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
73 !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, digest) ||
74 !EVP_PKEY_CTX_set_rsa_pss_saltlen(
75 pkey_ctx, -1 /* match digest and salt length */)) {
76 return false;
77 }
davidben@chromium.orgedfd0f42014-07-22 18:20:3778 }
David Benjamin8982fe4f2018-02-06 19:30:3279
80 return true;
wtc@chromium.org9b8986612013-06-28 17:46:5381}
82
David Benjamin8ed923192018-04-13 23:17:0683void SignatureVerifier::VerifyUpdate(base::span<const uint8_t> data_part) {
wtc@chromium.org9b8986612013-06-28 17:46:5384 DCHECK(verify_context_);
85 OpenSSLErrStackTracer err_tracer(FROM_HERE);
David Benjamin8ed923192018-04-13 23:17:0686 int rv = EVP_DigestVerifyUpdate(verify_context_->ctx.get(), data_part.data(),
87 data_part.size());
wtc@chromium.org9b8986612013-06-28 17:46:5388 DCHECK_EQ(rv, 1);
89}
90
91bool SignatureVerifier::VerifyFinal() {
92 DCHECK(verify_context_);
93 OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidben4507eaa2015-11-19 19:07:0694 int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(), signature_.data(),
wtc@chromium.org9b8986612013-06-28 17:46:5395 signature_.size());
davidben14071042014-11-11 23:55:5596 DCHECK_EQ(static_cast<int>(!!rv), rv);
wtc@chromium.org9b8986612013-06-28 17:46:5397 Reset();
98 return rv == 1;
99}
100
joth@chromium.org70372d42010-10-22 13:12:34101void SignatureVerifier::Reset() {
davidben74f67442016-10-01 01:45:22102 verify_context_.reset();
joth@chromium.orgbe796bb2010-11-18 15:43:43103 signature_.clear();
joth@chromium.org70372d42010-10-22 13:12:34104}
105
rvargas@google.com4b559b4d2011-04-14 17:37:14106} // namespace crypto