blob: 2e2428370dc6be7ac449fc3270b5df4ae42549c2 [file] [log] [blame]
[email protected]3b63f8f42011-03-28 01:54:151// Copyright (c) 2011 The Chromium Authors. All rights reserved.
[email protected]70372d42010-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
[email protected]4b559b4d2011-04-14 17:37:145#include "crypto/signature_verifier.h"
[email protected]70372d42010-10-22 13:12:346
avidd373b8b2015-12-21 21:34:437#include <stdint.h>
[email protected]be796bb2010-11-18 15:43:438
thakisd1a18472016-04-08 22:30:419#include <memory>
[email protected]be796bb2010-11-18 15:43:4310#include <vector>
11
[email protected]70372d42010-10-22 13:12:3412#include "base/logging.h"
[email protected]4b559b4d2011-04-14 17:37:1413#include "crypto/openssl_util.h"
tfarina29a3a1742016-10-28 18:47:3314#include "third_party/boringssl/src/include/openssl/bytestring.h"
15#include "third_party/boringssl/src/include/openssl/digest.h"
16#include "third_party/boringssl/src/include/openssl/evp.h"
17#include "third_party/boringssl/src/include/openssl/rsa.h"
[email protected]70372d42010-10-22 13:12:3418
[email protected]4b559b4d2011-04-14 17:37:1419namespace crypto {
[email protected]70372d42010-10-22 13:12:3420
[email protected]be796bb2010-11-18 15:43:4321struct SignatureVerifier::VerifyContext {
davidben74f67442016-10-01 01:45:2222 bssl::ScopedEVP_MD_CTX ctx;
[email protected]be796bb2010-11-18 15:43:4323};
24
Chris Watkinsa850a302017-11-30 03:53:4925SignatureVerifier::SignatureVerifier() = default;
[email protected]70372d42010-10-22 13:12:3426
Chris Watkinsa850a302017-11-30 03:53:4927SignatureVerifier::~SignatureVerifier() = default;
[email protected]70372d42010-10-22 13:12:3428
davidben9c97a362016-03-03 16:18:2629bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
avidd373b8b2015-12-21 21:34:4330 const uint8_t* signature,
davidbencfb6ad62017-03-23 22:14:3231 size_t signature_len,
avidd373b8b2015-12-21 21:34:4332 const uint8_t* public_key_info,
davidbencfb6ad62017-03-23 22:14:3233 size_t public_key_info_len) {
David Benjamin8982fe4f2018-02-06 19:30:3234 OpenSSLErrStackTracer err_tracer(FROM_HERE);
35
davidben9c97a362016-03-03 16:18:2636 int pkey_type = EVP_PKEY_NONE;
37 const EVP_MD* digest = nullptr;
38 switch (signature_algorithm) {
39 case RSA_PKCS1_SHA1:
40 pkey_type = EVP_PKEY_RSA;
41 digest = EVP_sha1();
42 break;
43 case RSA_PKCS1_SHA256:
David Benjamin8982fe4f2018-02-06 19:30:3244 case RSA_PSS_SHA256:
davidben9c97a362016-03-03 16:18:2645 pkey_type = EVP_PKEY_RSA;
46 digest = EVP_sha256();
47 break;
48 case ECDSA_SHA256:
49 pkey_type = EVP_PKEY_EC;
50 digest = EVP_sha256();
51 break;
[email protected]2662ed562013-07-03 10:27:4652 }
davidben9c97a362016-03-03 16:18:2653 DCHECK_NE(EVP_PKEY_NONE, pkey_type);
54 DCHECK(digest);
[email protected]9b8986612013-06-28 17:46:5355
David Benjamin8982fe4f2018-02-06 19:30:3256 if (verify_context_)
57 return false;
[email protected]9b8986612013-06-28 17:46:5358
David Benjamin8982fe4f2018-02-06 19:30:3259 verify_context_.reset(new VerifyContext);
60 signature_.assign(signature, signature + signature_len);
61
62 CBS cbs;
63 CBS_init(&cbs, public_key_info, public_key_info_len);
64 bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs));
65 if (!public_key || CBS_len(&cbs) != 0 ||
66 EVP_PKEY_id(public_key.get()) != pkey_type) {
[email protected]edfd0f42014-07-22 18:20:3767 return false;
68 }
[email protected]be796bb2010-11-18 15:43:4369
[email protected]9b8986612013-06-28 17:46:5370 EVP_PKEY_CTX* pkey_ctx;
David Benjamin8982fe4f2018-02-06 19:30:3271 if (!EVP_DigestVerifyInit(verify_context_->ctx.get(), &pkey_ctx, digest,
72 nullptr, public_key.get())) {
[email protected]9b8986612013-06-28 17:46:5373 return false;
74 }
75
David Benjamin8982fe4f2018-02-06 19:30:3276 if (signature_algorithm == RSA_PSS_SHA256) {
77 if (!EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING) ||
78 !EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, digest) ||
79 !EVP_PKEY_CTX_set_rsa_pss_saltlen(
80 pkey_ctx, -1 /* match digest and salt length */)) {
81 return false;
82 }
[email protected]edfd0f42014-07-22 18:20:3783 }
David Benjamin8982fe4f2018-02-06 19:30:3284
85 return true;
[email protected]9b8986612013-06-28 17:46:5386}
87
avidd373b8b2015-12-21 21:34:4388void SignatureVerifier::VerifyUpdate(const uint8_t* data_part,
davidbencfb6ad62017-03-23 22:14:3289 size_t data_part_len) {
[email protected]9b8986612013-06-28 17:46:5390 DCHECK(verify_context_);
91 OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidbencfb6ad62017-03-23 22:14:3292 int rv = EVP_DigestVerifyUpdate(verify_context_->ctx.get(), data_part,
93 data_part_len);
[email protected]9b8986612013-06-28 17:46:5394 DCHECK_EQ(rv, 1);
95}
96
97bool SignatureVerifier::VerifyFinal() {
98 DCHECK(verify_context_);
99 OpenSSLErrStackTracer err_tracer(FROM_HERE);
davidben4507eaa2015-11-19 19:07:06100 int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(), signature_.data(),
[email protected]9b8986612013-06-28 17:46:53101 signature_.size());
davidben1407104c2014-11-11 23:55:55102 DCHECK_EQ(static_cast<int>(!!rv), rv);
[email protected]9b8986612013-06-28 17:46:53103 Reset();
104 return rv == 1;
105}
106
[email protected]70372d42010-10-22 13:12:34107void SignatureVerifier::Reset() {
davidben74f67442016-10-01 01:45:22108 verify_context_.reset();
[email protected]be796bb2010-11-18 15:43:43109 signature_.clear();
[email protected]70372d42010-10-22 13:12:34110}
111
[email protected]4b559b4d2011-04-14 17:37:14112} // namespace crypto