Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "crypto/signature_verifier.h" | 5 #include "crypto/signature_verifier.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <vector> | 10 #include <vector> |
| 11 | 11 |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/numerics/safe_conversions.h" | |
| 13 #include "crypto/openssl_util.h" | 14 #include "crypto/openssl_util.h" |
| 14 #include "third_party/boringssl/src/include/openssl/bytestring.h" | 15 #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/digest.h" |
| 16 #include "third_party/boringssl/src/include/openssl/evp.h" | 17 #include "third_party/boringssl/src/include/openssl/evp.h" |
| 17 #include "third_party/boringssl/src/include/openssl/rsa.h" | 18 #include "third_party/boringssl/src/include/openssl/rsa.h" |
| 18 | 19 |
| 19 namespace crypto { | 20 namespace crypto { |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 35 struct SignatureVerifier::VerifyContext { | 36 struct SignatureVerifier::VerifyContext { |
| 36 bssl::ScopedEVP_MD_CTX ctx; | 37 bssl::ScopedEVP_MD_CTX ctx; |
| 37 }; | 38 }; |
| 38 | 39 |
| 39 SignatureVerifier::SignatureVerifier() {} | 40 SignatureVerifier::SignatureVerifier() {} |
| 40 | 41 |
| 41 SignatureVerifier::~SignatureVerifier() {} | 42 SignatureVerifier::~SignatureVerifier() {} |
| 42 | 43 |
| 43 bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm, | 44 bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm, |
| 44 const uint8_t* signature, | 45 const uint8_t* signature, |
| 45 int signature_len, | 46 size_t signature_len, |
| 46 const uint8_t* public_key_info, | 47 const uint8_t* public_key_info, |
| 47 int public_key_info_len) { | 48 size_t public_key_info_len) { |
| 48 int pkey_type = EVP_PKEY_NONE; | 49 int pkey_type = EVP_PKEY_NONE; |
| 49 const EVP_MD* digest = nullptr; | 50 const EVP_MD* digest = nullptr; |
| 50 switch (signature_algorithm) { | 51 switch (signature_algorithm) { |
| 51 case RSA_PKCS1_SHA1: | 52 case RSA_PKCS1_SHA1: |
| 52 pkey_type = EVP_PKEY_RSA; | 53 pkey_type = EVP_PKEY_RSA; |
| 53 digest = EVP_sha1(); | 54 digest = EVP_sha1(); |
| 54 break; | 55 break; |
| 55 case RSA_PKCS1_SHA256: | 56 case RSA_PKCS1_SHA256: |
| 56 pkey_type = EVP_PKEY_RSA; | 57 pkey_type = EVP_PKEY_RSA; |
| 57 digest = EVP_sha256(); | 58 digest = EVP_sha256(); |
| 58 break; | 59 break; |
| 59 case ECDSA_SHA256: | 60 case ECDSA_SHA256: |
| 60 pkey_type = EVP_PKEY_EC; | 61 pkey_type = EVP_PKEY_EC; |
| 61 digest = EVP_sha256(); | 62 digest = EVP_sha256(); |
| 62 break; | 63 break; |
| 63 } | 64 } |
| 64 DCHECK_NE(EVP_PKEY_NONE, pkey_type); | 65 DCHECK_NE(EVP_PKEY_NONE, pkey_type); |
| 65 DCHECK(digest); | 66 DCHECK(digest); |
| 66 | 67 |
| 67 return CommonInit(pkey_type, digest, signature, signature_len, | 68 return CommonInit(pkey_type, digest, signature, signature_len, |
| 68 public_key_info, public_key_info_len, nullptr); | 69 public_key_info, public_key_info_len, nullptr); |
| 69 } | 70 } |
| 70 | 71 |
| 71 bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg, | 72 bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg, |
| 72 HashAlgorithm mask_hash_alg, | 73 HashAlgorithm mask_hash_alg, |
| 73 int salt_len, | 74 size_t salt_len, |
| 74 const uint8_t* signature, | 75 const uint8_t* signature, |
| 75 int signature_len, | 76 size_t signature_len, |
| 76 const uint8_t* public_key_info, | 77 const uint8_t* public_key_info, |
| 77 int public_key_info_len) { | 78 size_t public_key_info_len) { |
| 78 OpenSSLErrStackTracer err_tracer(FROM_HERE); | 79 OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 79 const EVP_MD* const digest = ToOpenSSLDigest(hash_alg); | 80 const EVP_MD* const digest = ToOpenSSLDigest(hash_alg); |
| 80 DCHECK(digest); | 81 DCHECK(digest); |
| 81 if (!digest) { | 82 if (!digest) { |
| 82 return false; | 83 return false; |
| 83 } | 84 } |
| 84 | 85 |
| 85 EVP_PKEY_CTX* pkey_ctx; | 86 EVP_PKEY_CTX* pkey_ctx; |
| 86 if (!CommonInit(EVP_PKEY_RSA, digest, signature, signature_len, | 87 if (!CommonInit(EVP_PKEY_RSA, digest, signature, signature_len, |
| 87 public_key_info, public_key_info_len, &pkey_ctx)) { | 88 public_key_info, public_key_info_len, &pkey_ctx)) { |
| 88 return false; | 89 return false; |
| 89 } | 90 } |
| 90 | 91 |
| 91 int rv = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING); | 92 int rv = EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING); |
| 92 if (rv != 1) | 93 if (rv != 1) |
| 93 return false; | 94 return false; |
| 94 const EVP_MD* const mgf_digest = ToOpenSSLDigest(mask_hash_alg); | 95 const EVP_MD* const mgf_digest = ToOpenSSLDigest(mask_hash_alg); |
| 95 DCHECK(mgf_digest); | 96 DCHECK(mgf_digest); |
| 96 if (!mgf_digest) { | 97 if (!mgf_digest) { |
| 97 return false; | 98 return false; |
| 98 } | 99 } |
| 99 return EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest) && | 100 return EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest) && |
| 100 EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len); | 101 EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, |
| 102 base::checked_cast<int>(salt_len)); | |
|
davidben
2017/03/23 19:16:57
This is an int because -1 and -2 are magic values
| |
| 101 } | 103 } |
| 102 | 104 |
| 103 void SignatureVerifier::VerifyUpdate(const uint8_t* data_part, | 105 void SignatureVerifier::VerifyUpdate(const uint8_t* data_part, |
| 104 int data_part_len) { | 106 size_t data_part_len) { |
| 105 DCHECK(verify_context_); | 107 DCHECK(verify_context_); |
| 106 OpenSSLErrStackTracer err_tracer(FROM_HERE); | 108 OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 107 int rv = EVP_DigestVerifyUpdate(verify_context_->ctx.get(), | 109 int rv = EVP_DigestVerifyUpdate(verify_context_->ctx.get(), data_part, |
| 108 data_part, data_part_len); | 110 data_part_len); |
| 109 DCHECK_EQ(rv, 1); | 111 DCHECK_EQ(rv, 1); |
| 110 } | 112 } |
| 111 | 113 |
| 112 bool SignatureVerifier::VerifyFinal() { | 114 bool SignatureVerifier::VerifyFinal() { |
| 113 DCHECK(verify_context_); | 115 DCHECK(verify_context_); |
| 114 OpenSSLErrStackTracer err_tracer(FROM_HERE); | 116 OpenSSLErrStackTracer err_tracer(FROM_HERE); |
| 115 int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(), signature_.data(), | 117 int rv = EVP_DigestVerifyFinal(verify_context_->ctx.get(), signature_.data(), |
| 116 signature_.size()); | 118 signature_.size()); |
| 117 DCHECK_EQ(static_cast<int>(!!rv), rv); | 119 DCHECK_EQ(static_cast<int>(!!rv), rv); |
| 118 Reset(); | 120 Reset(); |
| 119 return rv == 1; | 121 return rv == 1; |
| 120 } | 122 } |
| 121 | 123 |
| 122 bool SignatureVerifier::CommonInit(int pkey_type, | 124 bool SignatureVerifier::CommonInit(int pkey_type, |
| 123 const EVP_MD* digest, | 125 const EVP_MD* digest, |
| 124 const uint8_t* signature, | 126 const uint8_t* signature, |
| 125 int signature_len, | 127 size_t signature_len, |
| 126 const uint8_t* public_key_info, | 128 const uint8_t* public_key_info, |
| 127 int public_key_info_len, | 129 size_t public_key_info_len, |
| 128 EVP_PKEY_CTX** pkey_ctx) { | 130 EVP_PKEY_CTX** pkey_ctx) { |
| 129 if (verify_context_) | 131 if (verify_context_) |
| 130 return false; | 132 return false; |
| 131 | 133 |
| 132 verify_context_.reset(new VerifyContext); | 134 verify_context_.reset(new VerifyContext); |
| 133 | 135 |
| 134 signature_.assign(signature, signature + signature_len); | 136 signature_.assign(signature, signature + signature_len); |
| 135 | 137 |
| 136 CBS cbs; | 138 CBS cbs; |
| 137 CBS_init(&cbs, public_key_info, public_key_info_len); | 139 CBS_init(&cbs, public_key_info, public_key_info_len); |
| 138 bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs)); | 140 bssl::UniquePtr<EVP_PKEY> public_key(EVP_parse_public_key(&cbs)); |
| 139 if (!public_key || CBS_len(&cbs) != 0 || | 141 if (!public_key || CBS_len(&cbs) != 0 || |
| 140 EVP_PKEY_id(public_key.get()) != pkey_type) { | 142 EVP_PKEY_id(public_key.get()) != pkey_type) { |
| 141 return false; | 143 return false; |
| 142 } | 144 } |
| 143 | 145 |
| 144 int rv = EVP_DigestVerifyInit(verify_context_->ctx.get(), pkey_ctx, | 146 int rv = EVP_DigestVerifyInit(verify_context_->ctx.get(), pkey_ctx, |
| 145 digest, nullptr, public_key.get()); | 147 digest, nullptr, public_key.get()); |
| 146 return rv == 1; | 148 return rv == 1; |
| 147 } | 149 } |
| 148 | 150 |
| 149 void SignatureVerifier::Reset() { | 151 void SignatureVerifier::Reset() { |
| 150 verify_context_.reset(); | 152 verify_context_.reset(); |
| 151 signature_.clear(); | 153 signature_.clear(); |
| 152 } | 154 } |
| 153 | 155 |
| 154 } // namespace crypto | 156 } // namespace crypto |
| OLD | NEW |