diff options
author | dougsteed <dougsteed@chromium.org> | 2014-09-19 11:46:09 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-19 18:46:27 +0000 |
commit | 0cf460ec9f9b56c22c5101ff599e7e842c541089 (patch) | |
tree | 6e75cdfae5ce1b830e7b1f2e7116c9e3c79b308e | |
parent | 4da78f3fc41cc4adfcc75ab943893fc359f3d2c1 (diff) | |
download | chromium_src-0cf460ec9f9b56c22c5101ff599e7e842c541089.zip chromium_src-0cf460ec9f9b56c22c5101ff599e7e842c541089.tar.gz chromium_src-0cf460ec9f9b56c22c5101ff599e7e842c541089.tar.bz2 |
Generalize crypto::SignatureCreator to allow choice of hash function, so as to support SHA256 (not just SHA1).
BUG=412531
R=rsleevi@chromium.org,davidben@chromium.org
TBR=pfeldman@chromium.org
Review URL: https://codereview.chromium.org/560583002
Cr-Commit-Position: refs/heads/master@{#295747}
-rw-r--r-- | chrome/browser/devtools/device/usb/android_rsa.cc | 5 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_creator.cc | 3 | ||||
-rw-r--r-- | components/ownership/owner_settings_service.cc | 3 | ||||
-rw-r--r-- | components/policy/core/common/cloud/policy_builder.cc | 3 | ||||
-rw-r--r-- | crypto/signature_creator.h | 17 | ||||
-rw-r--r-- | crypto/signature_creator_nss.cc | 33 | ||||
-rw-r--r-- | crypto/signature_creator_openssl.cc | 39 | ||||
-rw-r--r-- | crypto/signature_creator_unittest.cc | 49 | ||||
-rw-r--r-- | remoting/base/rsa_key_pair.cc | 3 |
9 files changed, 136 insertions, 19 deletions
diff --git a/chrome/browser/devtools/device/usb/android_rsa.cc b/chrome/browser/devtools/device/usb/android_rsa.cc index a701845..df804e4 100644 --- a/chrome/browser/devtools/device/usb/android_rsa.cc +++ b/chrome/browser/devtools/device/usb/android_rsa.cc @@ -262,8 +262,9 @@ std::string AndroidRSASign(crypto::RSAPrivateKey* key, const std::string& body) { std::vector<uint8> digest(body.begin(), body.end()); std::vector<uint8> result; - if (!crypto::SignatureCreator::Sign(key, vector_as_array(&digest), - digest.size(), &result)) { + if (!crypto::SignatureCreator::Sign(key, crypto::SignatureCreator::SHA1, + vector_as_array(&digest), digest.size(), + &result)) { return std::string(); } return std::string(result.begin(), result.end()); diff --git a/chrome/browser/extensions/extension_creator.cc b/chrome/browser/extensions/extension_creator.cc index e79b454..fcf31b3 100644 --- a/chrome/browser/extensions/extension_creator.cc +++ b/chrome/browser/extensions/extension_creator.cc @@ -211,7 +211,8 @@ bool ExtensionCreator::SignZip(const base::FilePath& zip_path, crypto::RSAPrivateKey* private_key, std::vector<uint8>* signature) { scoped_ptr<crypto::SignatureCreator> signature_creator( - crypto::SignatureCreator::Create(private_key)); + crypto::SignatureCreator::Create(private_key, + crypto::SignatureCreator::SHA1)); base::ScopedFILE zip_handle(base::OpenFile(zip_path, "rb")); size_t buffer_size = 1 << 16; scoped_ptr<uint8[]> buffer(new uint8[buffer_size]); diff --git a/components/ownership/owner_settings_service.cc b/components/ownership/owner_settings_service.cc index 09c88d3..56bcbe0 100644 --- a/components/ownership/owner_settings_service.cc +++ b/components/ownership/owner_settings_service.cc @@ -32,7 +32,8 @@ std::string AssembleAndSignPolicy(scoped_ptr<em::PolicyData> policy, // Generate the signature. scoped_ptr<crypto::SignatureCreator> signature_creator( - crypto::SignatureCreator::Create(private_key)); + crypto::SignatureCreator::Create(private_key, + crypto::SignatureCreator::SHA1)); signature_creator->Update( reinterpret_cast<const uint8*>(policy_response.policy_data().c_str()), policy_response.policy_data().size()); diff --git a/components/policy/core/common/cloud/policy_builder.cc b/components/policy/core/common/cloud/policy_builder.cc index d6ea5ed..e0d3a1a 100644 --- a/components/policy/core/common/cloud/policy_builder.cc +++ b/components/policy/core/common/cloud/policy_builder.cc @@ -295,7 +295,8 @@ void PolicyBuilder::SignData(const std::string& data, crypto::RSAPrivateKey* key, std::string* signature) { scoped_ptr<crypto::SignatureCreator> signature_creator( - crypto::SignatureCreator::Create(key)); + crypto::SignatureCreator::Create(key, + crypto::SignatureCreator::SHA1)); signature_creator->Update(reinterpret_cast<const uint8*>(data.c_str()), data.size()); std::vector<uint8> signature_bytes; diff --git a/crypto/signature_creator.h b/crypto/signature_creator.h index 0f3e05b..840d1ff 100644 --- a/crypto/signature_creator.h +++ b/crypto/signature_creator.h @@ -24,18 +24,27 @@ namespace crypto { class RSAPrivateKey; // Signs data using a bare private key (as opposed to a full certificate). -// Currently can only sign data using SHA-1 with RSA encryption. +// Currently can only sign data using SHA-1 or SHA-256 with RSA PKCS#1v1.5. class CRYPTO_EXPORT SignatureCreator { public: + // The set of supported hash functions. Extend as required. + enum HashAlgorithm { + SHA1, + SHA256, + }; + ~SignatureCreator(); // Create an instance. The caller must ensure that the provided PrivateKey - // instance outlives the created SignatureCreator. - static SignatureCreator* Create(RSAPrivateKey* key); + // instance outlives the created SignatureCreator. Uses the HashAlgorithm + // specified. + static SignatureCreator* Create(RSAPrivateKey* key, HashAlgorithm hash_alg); + - // Signs the precomputed SHA-1 digest |data| using private |key| as + // Signs the precomputed |hash_alg| digest |data| using private |key| as // specified in PKCS #1 v1.5. static bool Sign(RSAPrivateKey* key, + HashAlgorithm hash_alg, const uint8* data, int data_len, std::vector<uint8>* signature); diff --git a/crypto/signature_creator_nss.cc b/crypto/signature_creator_nss.cc index bc8dc44..47728b0 100644 --- a/crypto/signature_creator_nss.cc +++ b/crypto/signature_creator_nss.cc @@ -15,6 +15,30 @@ namespace crypto { +namespace { + +SECOidTag ToNSSSigOid(SignatureCreator::HashAlgorithm hash_alg) { + switch (hash_alg) { + case SignatureCreator::SHA1: + return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + case SignatureCreator::SHA256: + return SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; + } + return SEC_OID_UNKNOWN; +} + +SECOidTag ToNSSHashOid(SignatureCreator::HashAlgorithm hash_alg) { + switch (hash_alg) { + case SignatureCreator::SHA1: + return SEC_OID_SHA1; + case SignatureCreator::SHA256: + return SEC_OID_SHA256; + } + return SEC_OID_UNKNOWN; +} + +} // namespace + SignatureCreator::~SignatureCreator() { if (sign_context_) { SGN_DestroyContext(sign_context_, PR_TRUE); @@ -23,12 +47,12 @@ SignatureCreator::~SignatureCreator() { } // static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { +SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key, + HashAlgorithm hash_alg) { scoped_ptr<SignatureCreator> result(new SignatureCreator); result->key_ = key; - result->sign_context_ = SGN_NewContext(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, - key->key()); + result->sign_context_ = SGN_NewContext(ToNSSSigOid(hash_alg), key->key()); if (!result->sign_context_) { NOTREACHED(); return NULL; @@ -45,6 +69,7 @@ SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { // static bool SignatureCreator::Sign(RSAPrivateKey* key, + HashAlgorithm hash_alg, const uint8* data, int data_len, std::vector<uint8>* signature) { @@ -54,7 +79,7 @@ bool SignatureCreator::Sign(RSAPrivateKey* key, data_item.len = data_len; SECItem signature_item; - SECStatus rv = SGN_Digest(key->key(), SEC_OID_SHA1, &signature_item, + SECStatus rv = SGN_Digest(key->key(), ToNSSHashOid(hash_alg), &signature_item, &data_item); if (rv != SECSuccess) { NOTREACHED(); diff --git a/crypto/signature_creator_openssl.cc b/crypto/signature_creator_openssl.cc index 3c8f532..51cb3c3e 100644 --- a/crypto/signature_creator_openssl.cc +++ b/crypto/signature_creator_openssl.cc @@ -16,18 +16,49 @@ namespace crypto { +namespace { + +const EVP_MD* ToOpenSSLDigest(SignatureCreator::HashAlgorithm hash_alg) { + switch (hash_alg) { + case SignatureCreator::SHA1: + return EVP_sha1(); + case SignatureCreator::SHA256: + return EVP_sha256(); + } + return NULL; +} + +int ToOpenSSLDigestType(SignatureCreator::HashAlgorithm hash_alg) { + switch (hash_alg) { + case SignatureCreator::SHA1: + return NID_sha1; + case SignatureCreator::SHA256: + return NID_sha256; + } + return NID_undef; +} + +} // namespace + // static -SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { +SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key, + HashAlgorithm hash_alg) { OpenSSLErrStackTracer err_tracer(FROM_HERE); scoped_ptr<SignatureCreator> result(new SignatureCreator); result->key_ = key; - if (!EVP_SignInit_ex(result->sign_context_, EVP_sha1(), NULL)) + const EVP_MD* const digest = ToOpenSSLDigest(hash_alg); + DCHECK(digest); + if (!digest) { + return NULL; + } + if (!EVP_SignInit_ex(result->sign_context_, digest, NULL)) return NULL; return result.release(); } // static bool SignatureCreator::Sign(RSAPrivateKey* key, + HashAlgorithm hash_alg, const uint8* data, int data_len, std::vector<uint8>* signature) { @@ -37,8 +68,8 @@ bool SignatureCreator::Sign(RSAPrivateKey* key, signature->resize(RSA_size(rsa_key.get())); unsigned int len = 0; - bool success = RSA_sign(NID_sha1, data, data_len, vector_as_array(signature), - &len, rsa_key.get()); + bool success = RSA_sign(ToOpenSSLDigestType(hash_alg), data, data_len, + vector_as_array(signature), &len, rsa_key.get()); if (!success) { signature->clear(); return false; diff --git a/crypto/signature_creator_unittest.cc b/crypto/signature_creator_unittest.cc index f0a8888..694becd 100644 --- a/crypto/signature_creator_unittest.cc +++ b/crypto/signature_creator_unittest.cc @@ -7,6 +7,7 @@ #include "base/memory/scoped_ptr.h" #include "base/sha1.h" #include "crypto/rsa_private_key.h" +#include "crypto/sha2.h" #include "crypto/signature_creator.h" #include "crypto/signature_verifier.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,6 +20,12 @@ const uint8 kSHA1WithRSAAlgorithmID[] = { 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 }; +// This is the algorithm ID for SHA-1 with RSA encryption. +const uint8 kSHA256WithRSAAlgorithmID[] = { + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0B, 0x05, 0x00 +}; + } TEST(SignatureCreatorTest, BasicTest) { @@ -34,7 +41,8 @@ TEST(SignatureCreatorTest, BasicTest) { ASSERT_TRUE(key.get()); scoped_ptr<crypto::SignatureCreator> signer( - crypto::SignatureCreator::Create(key.get())); + crypto::SignatureCreator::Create(key.get(), + crypto::SignatureCreator::SHA1)); ASSERT_TRUE(signer.get()); std::string data("Hello, World!"); @@ -76,6 +84,7 @@ TEST(SignatureCreatorTest, SignDigestTest) { std::vector<uint8> signature; ASSERT_TRUE(crypto::SignatureCreator::Sign( key.get(), + crypto::SignatureCreator::SHA1, reinterpret_cast<const uint8*>(sha1.c_str()), sha1.size(), &signature)); @@ -94,3 +103,41 @@ TEST(SignatureCreatorTest, SignDigestTest) { data.size()); ASSERT_TRUE(verifier.VerifyFinal()); } + +TEST(SignatureCreatorTest, SignSHA256DigestTest) { + // Do a verify round trip. + scoped_ptr<crypto::RSAPrivateKey> key_original( + crypto::RSAPrivateKey::Create(1024)); + ASSERT_TRUE(key_original.get()); + + std::vector<uint8> key_info; + key_original->ExportPrivateKey(&key_info); + scoped_ptr<crypto::RSAPrivateKey> key( + crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(key_info)); + ASSERT_TRUE(key.get()); + + std::string data("Hello, World!"); + std::string sha256 = crypto::SHA256HashString(data); + // Sign sha256 of the input data. + std::vector<uint8> signature; + ASSERT_TRUE(crypto::SignatureCreator::Sign( + key.get(), + crypto::SignatureCreator::HashAlgorithm::SHA256, + reinterpret_cast<const uint8*>(sha256.c_str()), + sha256.size(), + &signature)); + + std::vector<uint8> public_key_info; + ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info)); + + // 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())); + + verifier.VerifyUpdate(reinterpret_cast<const uint8*>(data.c_str()), + data.size()); + ASSERT_TRUE(verifier.VerifyFinal()); +} diff --git a/remoting/base/rsa_key_pair.cc b/remoting/base/rsa_key_pair.cc index 28dd2ef..a8ca5d0 100644 --- a/remoting/base/rsa_key_pair.cc +++ b/remoting/base/rsa_key_pair.cc @@ -78,7 +78,8 @@ std::string RsaKeyPair::GetPublicKey() const { std::string RsaKeyPair::SignMessage(const std::string& message) const { scoped_ptr<crypto::SignatureCreator> signature_creator( - crypto::SignatureCreator::Create(key_.get())); + crypto::SignatureCreator::Create(key_.get(), + crypto::SignatureCreator::SHA1)); signature_creator->Update(reinterpret_cast<const uint8*>(message.c_str()), message.length()); std::vector<uint8> signature_buf; |