summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/install_signer.cc3
-rw-r--r--components/crx_file.gypi1
-rw-r--r--components/crx_file/BUILD.gn1
-rw-r--r--components/crx_file/constants.h21
-rw-r--r--components/crx_file/crx_file.cc8
-rw-r--r--components/policy/core/common/cloud/cloud_policy_validator.cc30
-rw-r--r--components/update_client/client_update_protocol_ecdsa.cc22
-rw-r--r--components/update_client/component_unpacker.cc1
-rw-r--r--components/variations/variations_seed_store.cc24
-rw-r--r--crypto/ec_signature_creator_unittest.cc18
-rw-r--r--crypto/signature_creator_unittest.cc28
-rw-r--r--crypto/signature_verifier.h34
-rw-r--r--crypto/signature_verifier_nss.cc46
-rw-r--r--crypto/signature_verifier_openssl.cc61
-rw-r--r--crypto/signature_verifier_unittest.cc63
-rw-r--r--extensions/browser/verified_contents.cc10
-rw-r--r--net/quic/crypto/proof_verifier_chromium.cc26
17 files changed, 109 insertions, 288 deletions
diff --git a/chrome/browser/extensions/install_signer.cc b/chrome/browser/extensions/install_signer.cc
index 19c3f91..4df8e82 100644
--- a/chrome/browser/extensions/install_signer.cc
+++ b/chrome/browser/extensions/install_signer.cc
@@ -27,7 +27,6 @@
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/common/chrome_switches.h"
-#include "components/crx_file/constants.h"
#include "crypto/random.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
@@ -261,7 +260,7 @@ bool InstallSigner::VerifySignature(const InstallSignature& signature) {
crypto::SignatureVerifier verifier;
if (!verifier.VerifyInit(
- crx_file::kSignatureAlgorithm, sizeof(crx_file::kSignatureAlgorithm),
+ crypto::SignatureVerifier::RSA_PKCS1_SHA1,
reinterpret_cast<const uint8_t*>(signature.signature.data()),
signature.signature.size(),
reinterpret_cast<const uint8_t*>(public_key.data()),
diff --git a/components/crx_file.gypi b/components/crx_file.gypi
index fd99563..3c81095 100644
--- a/components/crx_file.gypi
+++ b/components/crx_file.gypi
@@ -15,7 +15,6 @@
'..',
],
'sources': [
- 'crx_file/constants.h',
'crx_file/crx_file.cc',
'crx_file/crx_file.h',
'crx_file/id_util.cc',
diff --git a/components/crx_file/BUILD.gn b/components/crx_file/BUILD.gn
index ab04a23..a749439 100644
--- a/components/crx_file/BUILD.gn
+++ b/components/crx_file/BUILD.gn
@@ -4,7 +4,6 @@
source_set("crx_file") {
sources = [
- "constants.h",
"crx_file.cc",
"crx_file.h",
"id_util.cc",
diff --git a/components/crx_file/constants.h b/components/crx_file/constants.h
deleted file mode 100644
index 1cc6ede..0000000
--- a/components/crx_file/constants.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_CRX_FILE_CONSTANTS_H_
-#define COMPONENTS_CRX_FILE_CONSTANTS_H_
-
-#include <stdint.h>
-
-namespace crx_file {
-
-// Note: this structure is an ASN.1 which encodes the algorithm used
-// with its parameters. This is defined in PKCS #1 v2.1 (RFC 3447).
-// It is encoding: { OID sha1WithRSAEncryption PARAMETERS NULL }
-const uint8_t kSignatureAlgorithm[15] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00};
-
-} // namespace crx_file
-
-#endif // COMPONENTS_CRX_FILE_CONSTANTS_H_
diff --git a/components/crx_file/crx_file.cc b/components/crx_file/crx_file.cc
index 0bb60e0..7a6240d 100644
--- a/components/crx_file/crx_file.cc
+++ b/components/crx_file/crx_file.cc
@@ -13,7 +13,6 @@
#include "base/numerics/safe_math.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
-#include "components/crx_file/constants.h"
#include "components/crx_file/id_util.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
@@ -160,10 +159,9 @@ CrxFile::ValidateError CrxFile::ValidateSignature(
return ValidateError::CRX_SIGNATURE_INVALID;
crypto::SignatureVerifier verifier;
- if (!verifier.VerifyInit(
- crx_file::kSignatureAlgorithm, sizeof(crx_file::kSignatureAlgorithm),
- &signature.front(), static_cast<int>(signature.size()), &key.front(),
- static_cast<int>(key.size()))) {
+ if (!verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
+ signature.data(), static_cast<int>(signature.size()),
+ key.data(), static_cast<int>(key.size()))) {
// Signature verification initialization failed. This is most likely
// caused by a public key in the wrong format (should encode algorithm).
return ValidateError::CRX_SIGNATURE_VERIFICATION_INITIALIZATION_FAILED;
diff --git a/components/policy/core/common/cloud/cloud_policy_validator.cc b/components/policy/core/common/cloud/cloud_policy_validator.cc
index be2bd6f..ba1f986e 100644
--- a/components/policy/core/common/cloud/cloud_policy_validator.cc
+++ b/components/policy/core/common/cloud/cloud_policy_validator.cc
@@ -30,24 +30,6 @@ namespace {
// Grace interval for policy-from-the-future timestamp checks.
const int kTimestampGraceIntervalHours = 2;
-// DER-encoded ASN.1 object identifier for the SHA1-RSA signature algorithm.
-const uint8_t kSHA1SignatureAlgorithm[] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00};
-
-// DER-encoded ASN.1 object identifier for the SHA256-RSA signature algorithm
-// (source: http://tools.ietf.org/html/rfc5754 section 3.2).
-const uint8_t kSHA256SignatureAlgorithm[] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00};
-
-static_assert(sizeof(kSHA256SignatureAlgorithm) ==
- sizeof(kSHA1SignatureAlgorithm),
- "kSHA256SignatureAlgorithm must be the same size as "
- "kSHA1SignatureAlgorithm");
-
-const int kSignatureAlgorithmSize = sizeof(kSHA1SignatureAlgorithm);
-
const char kMetricPolicyKeyVerification[] = "Enterprise.PolicyKeyVerification";
enum MetricPolicyKeyVerification {
@@ -526,13 +508,13 @@ bool CloudPolicyValidatorBase::VerifySignature(const std::string& data,
const std::string& signature,
SignatureType signature_type) {
crypto::SignatureVerifier verifier;
- const uint8_t* algorithm = NULL;
+ crypto::SignatureVerifier::SignatureAlgorithm algorithm;
switch (signature_type) {
case SHA1:
- algorithm = kSHA1SignatureAlgorithm;
+ algorithm = crypto::SignatureVerifier::RSA_PKCS1_SHA1;
break;
case SHA256:
- algorithm = kSHA256SignatureAlgorithm;
+ algorithm = crypto::SignatureVerifier::RSA_PKCS1_SHA256;
break;
default:
NOTREACHED() << "Invalid signature type: " << signature_type;
@@ -540,9 +522,9 @@ bool CloudPolicyValidatorBase::VerifySignature(const std::string& data,
}
if (!verifier.VerifyInit(
- algorithm, kSignatureAlgorithmSize,
- reinterpret_cast<const uint8_t*>(signature.c_str()), signature.size(),
- reinterpret_cast<const uint8_t*>(key.c_str()), key.size())) {
+ algorithm, reinterpret_cast<const uint8_t*>(signature.c_str()),
+ signature.size(), reinterpret_cast<const uint8_t*>(key.c_str()),
+ key.size())) {
DLOG(ERROR) << "Invalid verification signature/key format";
return false;
}
diff --git a/components/update_client/client_update_protocol_ecdsa.cc b/components/update_client/client_update_protocol_ecdsa.cc
index 8479ceb..cc67b71 100644
--- a/components/update_client/client_update_protocol_ecdsa.cc
+++ b/components/update_client/client_update_protocol_ecdsa.cc
@@ -19,22 +19,6 @@ namespace update_client {
namespace {
-// This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
-// RFC 5758:
-// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
-// ...
-// When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
-// ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
-// as an AlgorithmIdentifier, the encoding MUST omit the parameters
-// field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
-// component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
-// SHA384, or ecdsa-with-SHA512.
-// See also RFC 5480, Appendix A.
-static const uint8_t kECDSAWithSHA256AlgorithmID[] = {
- 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
-};
-
std::vector<uint8_t> SHA256HashStr(const base::StringPiece& str) {
std::vector<uint8_t> result(crypto::kSHA256Length);
crypto::SHA256HashString(str, &result.front(), result.size());
@@ -189,9 +173,9 @@ bool ClientUpdateProtocolEcdsa::ValidateResponse(
// Initialize the signature verifier.
crypto::SignatureVerifier verifier;
if (!verifier.VerifyInit(
- kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
- &signature.front(), static_cast<int>(signature.size()),
- &public_key_.front(), static_cast<int>(public_key_.size()))) {
+ crypto::SignatureVerifier::ECDSA_SHA256, &signature.front(),
+ static_cast<int>(signature.size()), &public_key_.front(),
+ static_cast<int>(public_key_.size()))) {
DVLOG(1) << "Couldn't init SignatureVerifier.";
return false;
}
diff --git a/components/update_client/component_unpacker.cc b/components/update_client/component_unpacker.cc
index b525b4e..91c9b77 100644
--- a/components/update_client/component_unpacker.cc
+++ b/components/update_client/component_unpacker.cc
@@ -21,7 +21,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
-#include "components/crx_file/constants.h"
#include "components/crx_file/crx_file.h"
#include "components/update_client/component_patcher.h"
#include "components/update_client/component_patcher_operation.h"
diff --git a/components/variations/variations_seed_store.cc b/components/variations/variations_seed_store.cc
index 716bb05..65b1efd 100644
--- a/components/variations/variations_seed_store.cc
+++ b/components/variations/variations_seed_store.cc
@@ -39,22 +39,6 @@ bool SignatureVerificationEnabled() {
#endif
}
-// This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
-// RFC 5758:
-// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
-// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
-// ...
-// When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
-// ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
-// as an AlgorithmIdentifier, the encoding MUST omit the parameters
-// field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
-// component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
-// SHA384, or ecdsa-with-SHA512.
-// See also RFC 5480, Appendix A.
-const uint8_t kECDSAWithSHA256AlgorithmID[] = {
- 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
-};
-
// The ECDSA public key of the variations server for verifying variations seed
// signatures.
const uint8_t kPublicKey[] = {
@@ -341,10 +325,10 @@ VariationsSeedStore::VerifySeedSignature(
return VARIATIONS_SEED_SIGNATURE_DECODE_FAILED;
crypto::SignatureVerifier verifier;
- if (!verifier.VerifyInit(
- kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
- reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
- kPublicKey, arraysize(kPublicKey))) {
+ if (!verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
+ reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size(), kPublicKey,
+ arraysize(kPublicKey))) {
return VARIATIONS_SEED_SIGNATURE_INVALID_SIGNATURE;
}
diff --git a/crypto/ec_signature_creator_unittest.cc b/crypto/ec_signature_creator_unittest.cc
index 36c850a..5aa27f2 100644
--- a/crypto/ec_signature_creator_unittest.cc
+++ b/crypto/ec_signature_creator_unittest.cc
@@ -47,25 +47,9 @@ TEST(ECSignatureCreatorTest, BasicTest) {
std::vector<uint8_t> public_key_info;
ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info));
- // This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
- // RFC 5758:
- // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
- // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
- // ...
- // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
- // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
- // as an AlgorithmIdentifier, the encoding MUST omit the parameters
- // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
- // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
- // SHA384, or ecdsa-with-SHA512.
- // See also RFC 5480, Appendix A.
- const uint8_t kECDSAWithSHA256AlgorithmID[] = {
- 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
- };
crypto::SignatureVerifier verifier;
ASSERT_TRUE(verifier.VerifyInit(
- kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
- &signature[0], signature.size(),
+ crypto::SignatureVerifier::ECDSA_SHA256, &signature[0], signature.size(),
&public_key_info.front(), public_key_info.size()));
verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(data.c_str()),
diff --git a/crypto/signature_creator_unittest.cc b/crypto/signature_creator_unittest.cc
index af1a042..fff065e5 100644
--- a/crypto/signature_creator_unittest.cc
+++ b/crypto/signature_creator_unittest.cc
@@ -14,19 +14,6 @@
#include "crypto/signature_verifier.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace {
-
-// This is the algorithm ID for SHA-1 with RSA encryption.
-const uint8_t kSHA1WithRSAAlgorithmID[] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x05, 0x05, 0x00};
-
-// This is the algorithm ID for SHA-1 with RSA encryption.
-const uint8_t kSHA256WithRSAAlgorithmID[] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0B, 0x05, 0x00};
-}
-
TEST(SignatureCreatorTest, BasicTest) {
// Do a verify round trip.
scoped_ptr<crypto::RSAPrivateKey> key_original(
@@ -56,9 +43,8 @@ TEST(SignatureCreatorTest, BasicTest) {
crypto::SignatureVerifier verifier;
ASSERT_TRUE(verifier.VerifyInit(
- kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID),
- &signature.front(), signature.size(),
- &public_key_info.front(), public_key_info.size()));
+ crypto::SignatureVerifier::RSA_PKCS1_SHA1, &signature.front(),
+ signature.size(), &public_key_info.front(), public_key_info.size()));
verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(data.c_str()),
data.size());
@@ -91,9 +77,8 @@ TEST(SignatureCreatorTest, SignDigestTest) {
// Verify the input data.
crypto::SignatureVerifier verifier;
ASSERT_TRUE(verifier.VerifyInit(
- kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID),
- &signature.front(), signature.size(),
- &public_key_info.front(), public_key_info.size()));
+ crypto::SignatureVerifier::RSA_PKCS1_SHA1, &signature.front(),
+ signature.size(), &public_key_info.front(), public_key_info.size()));
verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(data.c_str()),
data.size());
@@ -127,9 +112,8 @@ TEST(SignatureCreatorTest, SignSHA256DigestTest) {
// Verify the input data.
crypto::SignatureVerifier verifier;
ASSERT_TRUE(verifier.VerifyInit(
- kSHA256WithRSAAlgorithmID, sizeof(kSHA256WithRSAAlgorithmID),
- &signature.front(), signature.size(),
- &public_key_info.front(), public_key_info.size()));
+ crypto::SignatureVerifier::RSA_PKCS1_SHA256, &signature.front(),
+ signature.size(), &public_key_info.front(), public_key_info.size()));
verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(data.c_str()),
data.size());
diff --git a/crypto/signature_verifier.h b/crypto/signature_verifier.h
index b26a0df..5b7369f 100644
--- a/crypto/signature_verifier.h
+++ b/crypto/signature_verifier.h
@@ -33,6 +33,13 @@ class CRYPTO_EXPORT SignatureVerifier {
SHA256,
};
+ // The set of supported signature algorithms. Extend as required.
+ enum SignatureAlgorithm {
+ RSA_PKCS1_SHA1,
+ RSA_PKCS1_SHA256,
+ ECDSA_SHA256,
+ };
+
SignatureVerifier();
~SignatureVerifier();
@@ -42,16 +49,7 @@ class CRYPTO_EXPORT SignatureVerifier {
// by one or more VerifyUpdate calls and a VerifyFinal call.
// NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead.
//
- // The signature algorithm is specified as a DER encoded ASN.1
- // AlgorithmIdentifier structure:
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER,
- // parameters ANY DEFINED BY algorithm OPTIONAL }
- //
- // The signature is encoded according to the signature algorithm, but it
- // must not be further encoded in an ASN.1 BIT STRING.
- // Note: An RSA signature is actually a big integer. It must be in
- // big-endian byte order.
+ // The signature is encoded according to the signature algorithm.
//
// The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
// structure, which contains not only the public key but also its type
@@ -59,8 +57,7 @@ class CRYPTO_EXPORT SignatureVerifier {
// SubjectPublicKeyInfo ::= SEQUENCE {
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING }
- bool VerifyInit(const uint8_t* signature_algorithm,
- int signature_algorithm_len,
+ bool VerifyInit(SignatureAlgorithm signature_algorithm,
const uint8_t* signature,
int signature_len,
const uint8_t* public_key_info,
@@ -98,19 +95,10 @@ class CRYPTO_EXPORT SignatureVerifier {
// error occurred.
bool VerifyFinal();
- // Note: we can provide a one-shot interface if there is interest:
- // bool Verify(const uint8_t* data,
- // int data_len,
- // const uint8_t* signature_algorithm,
- // int signature_algorithm_len,
- // const uint8_t* signature,
- // int signature_len,
- // const uint8_t* public_key_info,
- // int public_key_info_len);
-
private:
#if defined(USE_OPENSSL)
- bool CommonInit(const EVP_MD* digest,
+ bool CommonInit(int pkey_type,
+ const EVP_MD* digest,
const uint8_t* signature,
int signature_len,
const uint8_t* public_key_info,
diff --git a/crypto/signature_verifier_nss.cc b/crypto/signature_verifier_nss.cc
index e6cd3e0..edbd3f6 100644
--- a/crypto/signature_verifier_nss.cc
+++ b/crypto/signature_verifier_nss.cc
@@ -30,6 +30,18 @@ HASH_HashType ToNSSHashType(SignatureVerifier::HashAlgorithm hash_alg) {
return HASH_AlgNULL;
}
+SECOidTag ToNSSSignatureType(SignatureVerifier::SignatureAlgorithm sig_alg) {
+ switch (sig_alg) {
+ case SignatureVerifier::RSA_PKCS1_SHA1:
+ return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
+ case SignatureVerifier::RSA_PKCS1_SHA256:
+ return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
+ case SignatureVerifier::ECDSA_SHA256:
+ return SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
+ }
+ return SEC_OID_UNKNOWN;
+}
+
SECStatus VerifyRSAPSS_End(SECKEYPublicKey* public_key,
HASHContext* hash_context,
HASH_HashType mask_hash_alg,
@@ -74,8 +86,7 @@ SignatureVerifier::~SignatureVerifier() {
Reset();
}
-bool SignatureVerifier::VerifyInit(const uint8_t* signature_algorithm,
- int signature_algorithm_len,
+bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
const uint8_t* signature,
int signature_len,
const uint8_t* public_key_info,
@@ -90,37 +101,13 @@ bool SignatureVerifier::VerifyInit(const uint8_t* signature_algorithm,
if (!public_key)
return false;
- PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (!arena) {
- SECKEY_DestroyPublicKey(public_key);
- return false;
- }
-
- SECItem sig_alg_der;
- sig_alg_der.type = siBuffer;
- sig_alg_der.data = const_cast<uint8_t*>(signature_algorithm);
- sig_alg_der.len = signature_algorithm_len;
- SECAlgorithmID sig_alg_id;
- SECStatus rv;
- rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id,
- SEC_ASN1_GET(SECOID_AlgorithmIDTemplate),
- &sig_alg_der);
- if (rv != SECSuccess) {
- SECKEY_DestroyPublicKey(public_key);
- PORT_FreeArena(arena, PR_TRUE);
- return false;
- }
-
SECItem sig;
sig.type = siBuffer;
sig.data = const_cast<uint8_t*>(signature);
sig.len = signature_len;
- SECOidTag hash_alg_tag;
- vfy_context_ = VFY_CreateContextWithAlgorithmID(public_key, &sig,
- &sig_alg_id, &hash_alg_tag,
- NULL);
+ vfy_context_ = VFY_CreateContext(
+ public_key, &sig, ToNSSSignatureType(signature_algorithm), nullptr);
SECKEY_DestroyPublicKey(public_key); // Done with public_key.
- PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id.
if (!vfy_context_) {
// A corrupted RSA signature could be detected without the data, so
// VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE
@@ -128,8 +115,7 @@ bool SignatureVerifier::VerifyInit(const uint8_t* signature_algorithm,
return false;
}
- rv = VFY_Begin(vfy_context_);
- if (rv != SECSuccess) {
+ if (VFY_Begin(vfy_context_) != SECSuccess) {
NOTREACHED();
return false;
}
diff --git a/crypto/signature_verifier_openssl.cc b/crypto/signature_verifier_openssl.cc
index 2e64a58..495abd2 100644
--- a/crypto/signature_verifier_openssl.cc
+++ b/crypto/signature_verifier_openssl.cc
@@ -5,8 +5,8 @@
#include "crypto/signature_verifier.h"
#include <openssl/bytestring.h>
+#include <openssl/digest.h>
#include <openssl/evp.h>
-#include <openssl/x509.h>
#include <stdint.h>
#include <vector>
@@ -44,33 +44,32 @@ SignatureVerifier::~SignatureVerifier() {
Reset();
}
-bool SignatureVerifier::VerifyInit(const uint8_t* signature_algorithm,
- int signature_algorithm_len,
+bool SignatureVerifier::VerifyInit(SignatureAlgorithm signature_algorithm,
const uint8_t* signature,
int signature_len,
const uint8_t* public_key_info,
int public_key_info_len) {
- OpenSSLErrStackTracer err_tracer(FROM_HERE);
- ScopedOpenSSL<X509_ALGOR, X509_ALGOR_free> algorithm(
- d2i_X509_ALGOR(NULL, &signature_algorithm, signature_algorithm_len));
- if (!algorithm.get())
- return false;
- int nid = OBJ_obj2nid(algorithm.get()->algorithm);
- const EVP_MD* digest;
- if (nid == NID_ecdsa_with_SHA1) {
- digest = EVP_sha1();
- } else if (nid == NID_ecdsa_with_SHA256) {
- digest = EVP_sha256();
- } else {
- // This works for PKCS #1 v1.5 RSA signatures, but not for ECDSA
- // signatures.
- digest = EVP_get_digestbyobj(algorithm.get()->algorithm);
+ int pkey_type = EVP_PKEY_NONE;
+ const EVP_MD* digest = nullptr;
+ switch (signature_algorithm) {
+ case RSA_PKCS1_SHA1:
+ pkey_type = EVP_PKEY_RSA;
+ digest = EVP_sha1();
+ break;
+ case RSA_PKCS1_SHA256:
+ pkey_type = EVP_PKEY_RSA;
+ digest = EVP_sha256();
+ break;
+ case ECDSA_SHA256:
+ pkey_type = EVP_PKEY_EC;
+ digest = EVP_sha256();
+ break;
}
- if (!digest)
- return false;
+ DCHECK_NE(EVP_PKEY_NONE, pkey_type);
+ DCHECK(digest);
- return CommonInit(digest, signature, signature_len, public_key_info,
- public_key_info_len, NULL);
+ return CommonInit(pkey_type, digest, signature, signature_len,
+ public_key_info, public_key_info_len, nullptr);
}
bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
@@ -88,8 +87,8 @@ bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
}
EVP_PKEY_CTX* pkey_ctx;
- if (!CommonInit(digest, signature, signature_len, public_key_info,
- public_key_info_len, &pkey_ctx)) {
+ if (!CommonInit(EVP_PKEY_RSA, digest, signature, signature_len,
+ public_key_info, public_key_info_len, &pkey_ctx)) {
return false;
}
@@ -101,11 +100,8 @@ bool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg,
if (!mgf_digest) {
return false;
}
- rv = EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest);
- if (rv != 1)
- return false;
- rv = EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len);
- return rv == 1;
+ return EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf_digest) &&
+ EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, salt_len);
}
void SignatureVerifier::VerifyUpdate(const uint8_t* data_part,
@@ -127,7 +123,8 @@ bool SignatureVerifier::VerifyFinal() {
return rv == 1;
}
-bool SignatureVerifier::CommonInit(const EVP_MD* digest,
+bool SignatureVerifier::CommonInit(int pkey_type,
+ const EVP_MD* digest,
const uint8_t* signature,
int signature_len,
const uint8_t* public_key_info,
@@ -143,8 +140,10 @@ bool SignatureVerifier::CommonInit(const EVP_MD* digest,
CBS cbs;
CBS_init(&cbs, public_key_info, public_key_info_len);
ScopedEVP_PKEY public_key(EVP_parse_public_key(&cbs));
- if (!public_key || CBS_len(&cbs) != 0)
+ if (!public_key || CBS_len(&cbs) != 0 ||
+ EVP_PKEY_id(public_key.get()) != pkey_type) {
return false;
+ }
verify_context_->ctx.reset(EVP_MD_CTX_create());
int rv = EVP_DigestVerifyInit(verify_context_->ctx.get(), pkey_ctx,
diff --git a/crypto/signature_verifier_unittest.cc b/crypto/signature_verifier_unittest.cc
index adcc885..d71ea82 100644
--- a/crypto/signature_verifier_unittest.cc
+++ b/crypto/signature_verifier_unittest.cc
@@ -14,9 +14,9 @@
TEST(SignatureVerifierTest, BasicTest) {
// The input data in this test comes from real certificates.
//
- // tbs_certificate ("to-be-signed certificate", the part of a certificate
- // that is signed), signature_algorithm, and algorithm come from the
- // certificate of bugs.webkit.org.
+ // tbs_certificate ("to-be-signed certificate", the part of a certificate that
+ // is signed), signature, and algorithm come from the certificate of
+ // bugs.webkit.org.
//
// public_key_info comes from the certificate of the issuer, Go Daddy Secure
// Certification Authority.
@@ -116,19 +116,6 @@ TEST(SignatureVerifierTest, BasicTest) {
0x74, 0x2e, 0x6f, 0x72, 0x67, 0x82, 0x0a, 0x77, 0x65, 0x62, 0x6b, 0x69,
0x74, 0x2e, 0x6f, 0x72, 0x67};
- // The signature algorithm is specified as the following ASN.1 structure:
- // AlgorithmIdentifier ::= SEQUENCE {
- // algorithm OBJECT IDENTIFIER,
- // parameters ANY DEFINED BY algorithm OPTIONAL }
- //
- const uint8_t signature_algorithm[15] = {
- 0x30, 0x0d, // a SEQUENCE of length 13 (0xd)
- 0x06, 0x09, // an OBJECT IDENTIFIER of length 9
- // 1.2.840.113549.1.1.5 - sha1WithRSAEncryption
- 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05,
- 0x00, // a NULL of length 0
- };
-
// RSA signature, a big integer in the big-endian byte order.
const uint8_t signature[256] = {
0x1e, 0x6a, 0xe7, 0xe0, 0x4f, 0xe7, 0x4d, 0xd0, 0x69, 0x7c, 0xf8, 0x8f,
@@ -202,12 +189,11 @@ TEST(SignatureVerifierTest, BasicTest) {
crypto::SignatureVerifier verifier;
bool ok;
- // Test 1: feed all of the data to the verifier at once (a single
+ // Test 1: feed all of the data to the verifier at once (a single
// VerifyUpdate call).
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature,
+ sizeof(signature), public_key_info,
+ sizeof(public_key_info));
EXPECT_TRUE(ok);
verifier.VerifyUpdate(tbs_certificate, sizeof(tbs_certificate));
ok = verifier.VerifyFinal();
@@ -215,12 +201,11 @@ TEST(SignatureVerifierTest, BasicTest) {
// Test 2: feed the data to the verifier in three parts (three VerifyUpdate
// calls).
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature,
+ sizeof(signature), public_key_info,
+ sizeof(public_key_info));
EXPECT_TRUE(ok);
- verifier.VerifyUpdate(tbs_certificate, 256);
+ verifier.VerifyUpdate(tbs_certificate, 256);
verifier.VerifyUpdate(tbs_certificate + 256, 256);
verifier.VerifyUpdate(tbs_certificate + 512, sizeof(tbs_certificate) - 512);
ok = verifier.VerifyFinal();
@@ -230,10 +215,9 @@ TEST(SignatureVerifierTest, BasicTest) {
uint8_t bad_tbs_certificate[sizeof(tbs_certificate)];
memcpy(bad_tbs_certificate, tbs_certificate, sizeof(tbs_certificate));
bad_tbs_certificate[10] += 1; // Corrupt one byte of the data.
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- public_key_info, sizeof(public_key_info));
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature,
+ sizeof(signature), public_key_info,
+ sizeof(public_key_info));
EXPECT_TRUE(ok);
verifier.VerifyUpdate(bad_tbs_certificate, sizeof(bad_tbs_certificate));
ok = verifier.VerifyFinal();
@@ -243,8 +227,7 @@ TEST(SignatureVerifierTest, BasicTest) {
uint8_t bad_signature[sizeof(signature)];
memcpy(bad_signature, signature, sizeof(signature));
bad_signature[10] += 1; // Corrupt one byte of the signature.
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1,
bad_signature, sizeof(bad_signature),
public_key_info, sizeof(public_key_info));
@@ -260,20 +243,18 @@ TEST(SignatureVerifierTest, BasicTest) {
uint8_t bad_public_key_info[sizeof(public_key_info)];
memcpy(bad_public_key_info, public_key_info, sizeof(public_key_info));
bad_public_key_info[0] += 1; // Corrupt part of the SPKI syntax.
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- bad_public_key_info, sizeof(bad_public_key_info));
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature,
+ sizeof(signature), bad_public_key_info,
+ sizeof(bad_public_key_info));
EXPECT_FALSE(ok);
// Test 6: import a key with extra data.
uint8_t long_public_key_info[sizeof(public_key_info) + 5];
memset(long_public_key_info, 0, sizeof(long_public_key_info));
memcpy(long_public_key_info, public_key_info, sizeof(public_key_info));
- ok = verifier.VerifyInit(signature_algorithm,
- sizeof(signature_algorithm),
- signature, sizeof(signature),
- long_public_key_info, sizeof(long_public_key_info));
+ ok = verifier.VerifyInit(crypto::SignatureVerifier::RSA_PKCS1_SHA1, signature,
+ sizeof(signature), long_public_key_info,
+ sizeof(long_public_key_info));
EXPECT_FALSE(ok);
}
@@ -1022,7 +1003,7 @@ static bool EncodeRSAPublicKey(const std::vector<uint8_t>& modulus_n,
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING }
//
- // The signature algorithm is specified as the following ASN.1 structure:
+ // The algorithm is specified as the following ASN.1 structure:
// AlgorithmIdentifier ::= SEQUENCE {
// algorithm OBJECT IDENTIFIER,
// parameters ANY DEFINED BY algorithm OPTIONAL }
diff --git a/extensions/browser/verified_contents.cc b/extensions/browser/verified_contents.cc
index 28ed16a..fc2471d 100644
--- a/extensions/browser/verified_contents.cc
+++ b/extensions/browser/verified_contents.cc
@@ -21,14 +21,6 @@ using base::Value;
namespace {
-// Note: this structure is an ASN.1 which encodes the algorithm used with its
-// parameters. The signature algorithm is "RSA256" aka "RSASSA-PKCS-v1_5 using
-// SHA-256 hash algorithm". This is defined in PKCS #1 (RFC 3447).
-// It is encoding: { OID sha256WithRSAEncryption PARAMETERS NULL }
-const uint8_t kSignatureAlgorithm[15] = {0x30, 0x0d, 0x06, 0x09, 0x2a,
- 0x86, 0x48, 0x86, 0xf7, 0x0d,
- 0x01, 0x01, 0x0b, 0x05, 0x00};
-
const char kBlockSizeKey[] = "block_size";
const char kContentHashesKey[] = "content_hashes";
const char kDescriptionKey[] = "description";
@@ -308,7 +300,7 @@ bool VerifiedContents::VerifySignature(const std::string& protected_value,
const std::string& signature_bytes) {
crypto::SignatureVerifier signature_verifier;
if (!signature_verifier.VerifyInit(
- kSignatureAlgorithm, sizeof(kSignatureAlgorithm),
+ crypto::SignatureVerifier::RSA_PKCS1_SHA256,
reinterpret_cast<const uint8_t*>(signature_bytes.data()),
signature_bytes.size(), public_key_, public_key_size_)) {
VLOG(1) << "Could not verify signature - VerifyInit failure";
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc
index 2331a6db..6823550 100644
--- a/net/quic/crypto/proof_verifier_chromium.cc
+++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -371,27 +371,11 @@ bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
return false;
}
} else if (type == X509Certificate::kPublicKeyTypeECDSA) {
- // This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
- // RFC 5758:
- // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
- // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
- // ...
- // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
- // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
- // as an AlgorithmIdentifier, the encoding MUST omit the parameters
- // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
- // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
- // SHA384, or ecdsa-with-SHA512.
- // See also RFC 5480, Appendix A.
- static const uint8_t kECDSAWithSHA256AlgorithmID[] = {
- 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
- };
-
- if (!verifier.VerifyInit(
- kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
- reinterpret_cast<const uint8_t*>(signature.data()),
- signature.size(), reinterpret_cast<const uint8_t*>(spki.data()),
- spki.size())) {
+ if (!verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
+ reinterpret_cast<const uint8_t*>(signature.data()),
+ signature.size(),
+ reinterpret_cast<const uint8_t*>(spki.data()),
+ spki.size())) {
DLOG(WARNING) << "VerifyInit failed";
return false;
}