diff options
author | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-09 08:32:40 +0000 |
---|---|---|
committer | pfeldman@chromium.org <pfeldman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-09 08:32:40 +0000 |
commit | ed31834bbaaec43db09132b2705c7e9c062d5620 (patch) | |
tree | 99356950de57ca16686f7a5d7409abd11a53c970 /crypto | |
parent | 0061349a01cdf6a81ca736b4a2878b19b9543d82 (diff) | |
download | chromium_src-ed31834bbaaec43db09132b2705c7e9c062d5620.zip chromium_src-ed31834bbaaec43db09132b2705c7e9c062d5620.tar.gz chromium_src-ed31834bbaaec43db09132b2705c7e9c062d5620.tar.bz2 |
Introduce RSAPrivateKey::SignDigest
BUG=258017
R=rsleevi@chromium.org
Review URL: https://codereview.chromium.org/18697003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@210524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/signature_creator.h | 7 | ||||
-rw-r--r-- | crypto/signature_creator_nss.cc | 23 | ||||
-rw-r--r-- | crypto/signature_creator_openssl.cc | 22 | ||||
-rw-r--r-- | crypto/signature_creator_unittest.cc | 54 |
4 files changed, 100 insertions, 6 deletions
diff --git a/crypto/signature_creator.h b/crypto/signature_creator.h index 1a1d6e5..6074bcb 100644 --- a/crypto/signature_creator.h +++ b/crypto/signature_creator.h @@ -34,6 +34,13 @@ class CRYPTO_EXPORT SignatureCreator { // instance outlives the created SignatureCreator. static SignatureCreator* Create(RSAPrivateKey* key); + // Signs the precomputed SHA-1 digest |data| using private |key| as + // specified in PKCS #1 v1.5. + static bool Sign(RSAPrivateKey* key, + const uint8* data, + int data_len, + std::vector<uint8>* signature); + // Update the signature with more data. bool Update(const uint8* data_part, int data_part_len); diff --git a/crypto/signature_creator_nss.cc b/crypto/signature_creator_nss.cc index 3a30efb..6c21efe 100644 --- a/crypto/signature_creator_nss.cc +++ b/crypto/signature_creator_nss.cc @@ -43,6 +43,29 @@ SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { return result.release(); } +// static +bool SignatureCreator::Sign(RSAPrivateKey* key, + const uint8* data, + int data_len, + std::vector<uint8>* signature) { + SECItem data_item; + data_item.type = siBuffer; + data_item.data = const_cast<unsigned char*>(data); + data_item.len = data_len; + + SECItem signature_item; + SECStatus rv = SGN_Digest(key->key(), SEC_OID_SHA1, &signature_item, + &data_item); + if (rv != SECSuccess) { + NOTREACHED(); + return false; + } + signature->assign(signature_item.data, + signature_item.data + signature_item.len); + SECITEM_FreeItem(&signature_item, PR_FALSE); + return true; +} + bool SignatureCreator::Update(const uint8* data_part, int data_part_len) { // TODO(wtc): Remove this const_cast when we require NSS 3.12.5. // See NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=518255 diff --git a/crypto/signature_creator_openssl.cc b/crypto/signature_creator_openssl.cc index fa9ba07..e46d3d0 100644 --- a/crypto/signature_creator_openssl.cc +++ b/crypto/signature_creator_openssl.cc @@ -5,6 +5,7 @@ #include "crypto/signature_creator.h" #include <openssl/evp.h> +#include <openssl/rsa.h> #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -24,6 +25,27 @@ SignatureCreator* SignatureCreator::Create(RSAPrivateKey* key) { return result.release(); } +// static +bool SignatureCreator::Sign(RSAPrivateKey* key, + const uint8* data, + int data_len, + std::vector<uint8>* signature) { + RSA* rsa_key = EVP_PKEY_get1_RSA(key->key()); + if (!rsa_key) + return false; + signature->resize(RSA_size(rsa_key)); + + unsigned int len = 0; + bool success = RSA_sign(NID_sha1, data, data_len, vector_as_array(signature), + &len, rsa_key); + if (!success) { + signature->clear(); + return false; + } + signature->resize(len); + return true; +} + SignatureCreator::SignatureCreator() : sign_context_(EVP_MD_CTX_create()) { } diff --git a/crypto/signature_creator_unittest.cc b/crypto/signature_creator_unittest.cc index 2d69223..f0a8888 100644 --- a/crypto/signature_creator_unittest.cc +++ b/crypto/signature_creator_unittest.cc @@ -5,11 +5,22 @@ #include <vector> #include "base/memory/scoped_ptr.h" +#include "base/sha1.h" #include "crypto/rsa_private_key.h" #include "crypto/signature_creator.h" #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 kSHA1WithRSAAlgorithmID[] = { + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 +}; + +} + TEST(SignatureCreatorTest, BasicTest) { // Do a verify round trip. scoped_ptr<crypto::RSAPrivateKey> key_original( @@ -36,12 +47,43 @@ TEST(SignatureCreatorTest, BasicTest) { std::vector<uint8> public_key_info; ASSERT_TRUE(key_original->ExportPublicKey(&public_key_info)); - // This is the algorithm ID for SHA-1 with RSA encryption. - // TODO(aa): Factor this out into some shared location. - const uint8 kSHA1WithRSAAlgorithmID[] = { - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00 - }; + crypto::SignatureVerifier verifier; + ASSERT_TRUE(verifier.VerifyInit( + kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID), + &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()); +} + +TEST(SignatureCreatorTest, SignDigestTest) { + // 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 sha1 = base::SHA1HashString(data); + // Sign sha1 of the input data. + std::vector<uint8> signature; + ASSERT_TRUE(crypto::SignatureCreator::Sign( + key.get(), + reinterpret_cast<const uint8*>(sha1.c_str()), + sha1.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( kSHA1WithRSAAlgorithmID, sizeof(kSHA1WithRSAAlgorithmID), |