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 |